# HG changeset patch # User dwinter # Date 1294131727 -3600 # Node ID cbf34dd4d7e6203deba1c836edb6060a18ed59ac # Parent 970d26a94fb7894565943610e2c028fa803cf884 commons-math-2.1 added diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ArgumentOutsideDomainException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ArgumentOutsideDomainException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,109 @@ + +
++001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math; +019 +020 /** +021 * Error thrown when a method is called with an out of bounds argument. +022 * +023 * @since 1.2 +024 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +025 */ +026 public class ArgumentOutsideDomainException extends FunctionEvaluationException { +027 +028 /** Serializable version identifier. */ +029 private static final long serialVersionUID = -4965972841162580234L; +030 +031 /** +032 * Constructs an exception with specified formatted detail message. +033 * Message formatting is delegated to {@link java.text.MessageFormat}. +034 * @param argument the failing function argument +035 * @param lower lower bound of the domain +036 * @param upper upper bound of the domain +037 */ +038 public ArgumentOutsideDomainException(double argument, double lower, double upper) { +039 super(argument, +040 "Argument {0} outside domain [{1} ; {2}]", argument, lower, upper); +041 } +042 +043 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ConvergenceException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ConvergenceException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,134 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math; +018 +019 /** +020 * Error thrown when a numerical computation can not be performed because the +021 * numerical result failed to converge to a finite value. +022 * +023 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +024 */ +025 public class ConvergenceException extends MathException { +026 +027 /** Serializable version identifier */ +028 private static final long serialVersionUID = 4883703247677159141L; +029 +030 /** +031 * Default constructor. +032 */ +033 public ConvergenceException() { +034 super("Convergence failed"); +035 } +036 +037 /** +038 * Constructs an exception with specified formatted detail message. +039 * Message formatting is delegated to {@link java.text.MessageFormat}. +040 * @param pattern format specifier +041 * @param arguments format arguments +042 * @since 1.2 +043 */ +044 public ConvergenceException(String pattern, Object ... arguments) { +045 super(pattern, arguments); +046 } +047 +048 /** +049 * Create an exception with a given root cause. +050 * @param cause the exception or error that caused this exception to be thrown +051 */ +052 public ConvergenceException(Throwable cause) { +053 super(cause); +054 } +055 +056 /** +057 * Constructs an exception with specified formatted detail message and root cause. +058 * Message formatting is delegated to {@link java.text.MessageFormat}. +059 * @param cause the exception or error that caused this exception to be thrown +060 * @param pattern format specifier +061 * @param arguments format arguments +062 * @since 1.2 +063 */ +064 public ConvergenceException(Throwable cause, String pattern, Object ... arguments) { +065 super(cause, pattern, arguments); +066 } +067 +068 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ConvergingAlgorithm.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ConvergingAlgorithm.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,202 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math; +018 +019 +020 /** +021 * Interface for algorithms handling convergence settings. +022 * <p> +023 * This interface only deals with convergence parameters setting, not +024 * execution of the algorithms per se. +025 * </p> +026 * @see ConvergenceException +027 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +028 * @since 2.0 +029 */ +030 public interface ConvergingAlgorithm { +031 +032 /** +033 * Set the upper limit for the number of iterations. +034 * <p> +035 * Usually a high iteration count indicates convergence problems. However, +036 * the "reasonable value" varies widely for different algorithms. Users are +037 * advised to use the default value supplied by the algorithm.</p> +038 * <p> +039 * A {@link ConvergenceException} will be thrown if this number +040 * is exceeded.</p> +041 * +042 * @param count maximum number of iterations +043 */ +044 void setMaximalIterationCount(int count); +045 +046 /** +047 * Get the upper limit for the number of iterations. +048 * +049 * @return the actual upper limit +050 */ +051 int getMaximalIterationCount(); +052 +053 /** +054 * Reset the upper limit for the number of iterations to the default. +055 * <p> +056 * The default value is supplied by the algorithm implementation.</p> +057 * +058 * @see #setMaximalIterationCount(int) +059 */ +060 void resetMaximalIterationCount(); +061 +062 /** +063 * Set the absolute accuracy. +064 * <p> +065 * The default is usually chosen so that results in the interval +066 * -10..-0.1 and +0.1..+10 can be found with a reasonable accuracy. If the +067 * expected absolute value of your results is of much smaller magnitude, set +068 * this to a smaller value.</p> +069 * <p> +070 * Algorithms are advised to do a plausibility check with the relative +071 * accuracy, but clients should not rely on this.</p> +072 * +073 * @param accuracy the accuracy. +074 * @throws IllegalArgumentException if the accuracy can't be achieved by +075 * the solver or is otherwise deemed unreasonable. +076 */ +077 void setAbsoluteAccuracy(double accuracy); +078 +079 /** +080 * Get the actual absolute accuracy. +081 * +082 * @return the accuracy +083 */ +084 double getAbsoluteAccuracy(); +085 +086 /** +087 * Reset the absolute accuracy to the default. +088 * <p> +089 * The default value is provided by the algorithm implementation.</p> +090 */ +091 void resetAbsoluteAccuracy(); +092 +093 /** +094 * Set the relative accuracy. +095 * <p> +096 * This is used to stop iterations if the absolute accuracy can't be +097 * achieved due to large values or short mantissa length.</p> +098 * <p> +099 * If this should be the primary criterion for convergence rather then a +100 * safety measure, set the absolute accuracy to a ridiculously small value, +101 * like {@link org.apache.commons.math.util.MathUtils#SAFE_MIN MathUtils.SAFE_MIN}.</p> +102 * +103 * @param accuracy the relative accuracy. +104 * @throws IllegalArgumentException if the accuracy can't be achieved by +105 * the algorithm or is otherwise deemed unreasonable. +106 */ +107 void setRelativeAccuracy(double accuracy); +108 +109 /** +110 * Get the actual relative accuracy. +111 * @return the accuracy +112 */ +113 double getRelativeAccuracy(); +114 +115 /** +116 * Reset the relative accuracy to the default. +117 * The default value is provided by the algorithm implementation. +118 */ +119 void resetRelativeAccuracy(); +120 +121 /** +122 * Get the number of iterations in the last run of the algorithm. +123 * <p> +124 * This is mainly meant for testing purposes. It may occasionally +125 * help track down performance problems: if the iteration count +126 * is notoriously high, check whether the problem is evaluated +127 * properly, and whether another algorithm is more amenable to the +128 * problem.</p> +129 * +130 * @return the last iteration count. +131 * @throws IllegalStateException if there is no result available, either +132 * because no result was yet computed or the last attempt failed. +133 */ +134 int getIterationCount(); +135 +136 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ConvergingAlgorithmImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ConvergingAlgorithmImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,187 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math; +019 +020 +021 /** +022 * Provide a default implementation for several functions useful to generic +023 * converging algorithms. +024 * +025 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +026 * @since 2.0 +027 */ +028 public abstract class ConvergingAlgorithmImpl implements ConvergingAlgorithm{ +029 +030 /** Maximum absolute error. */ +031 protected double absoluteAccuracy; +032 +033 /** Maximum relative error. */ +034 protected double relativeAccuracy; +035 +036 /** Maximum number of iterations. */ +037 protected int maximalIterationCount; +038 +039 /** Default maximum absolute error. */ +040 protected double defaultAbsoluteAccuracy; +041 +042 /** Default maximum relative error. */ +043 protected double defaultRelativeAccuracy; +044 +045 /** Default maximum number of iterations. */ +046 protected int defaultMaximalIterationCount; +047 +048 // Mainly for test framework. +049 /** The last iteration count. */ +050 protected int iterationCount; +051 +052 /** +053 * Construct an algorithm with given iteration count and accuracy. +054 * +055 * @param defaultAbsoluteAccuracy maximum absolute error +056 * @param defaultMaximalIterationCount maximum number of iterations +057 * @throws IllegalArgumentException if f is null or the +058 * defaultAbsoluteAccuracy is not valid +059 */ +060 protected ConvergingAlgorithmImpl(final int defaultMaximalIterationCount, +061 final double defaultAbsoluteAccuracy) { +062 this.defaultAbsoluteAccuracy = defaultAbsoluteAccuracy; +063 this.defaultRelativeAccuracy = 1.0e-14; +064 this.absoluteAccuracy = defaultAbsoluteAccuracy; +065 this.relativeAccuracy = defaultRelativeAccuracy; +066 this.defaultMaximalIterationCount = defaultMaximalIterationCount; +067 this.maximalIterationCount = defaultMaximalIterationCount; +068 this.iterationCount = 0; +069 } +070 +071 /** {@inheritDoc} */ +072 public int getIterationCount() { +073 return iterationCount; +074 } +075 +076 /** {@inheritDoc} */ +077 public void setAbsoluteAccuracy(double accuracy) { +078 absoluteAccuracy = accuracy; +079 } +080 +081 /** {@inheritDoc} */ +082 public double getAbsoluteAccuracy() { +083 return absoluteAccuracy; +084 } +085 +086 /** {@inheritDoc} */ +087 public void resetAbsoluteAccuracy() { +088 absoluteAccuracy = defaultAbsoluteAccuracy; +089 } +090 +091 /** {@inheritDoc} */ +092 public void setMaximalIterationCount(int count) { +093 maximalIterationCount = count; +094 } +095 +096 /** {@inheritDoc} */ +097 public int getMaximalIterationCount() { +098 return maximalIterationCount; +099 } +100 +101 /** {@inheritDoc} */ +102 public void resetMaximalIterationCount() { +103 maximalIterationCount = defaultMaximalIterationCount; +104 } +105 +106 /** {@inheritDoc} */ +107 public void setRelativeAccuracy(double accuracy) { +108 relativeAccuracy = accuracy; +109 } +110 +111 /** {@inheritDoc} */ +112 public double getRelativeAccuracy() { +113 return relativeAccuracy; +114 } +115 +116 /** {@inheritDoc} */ +117 public void resetRelativeAccuracy() { +118 relativeAccuracy = defaultRelativeAccuracy; +119 } +120 +121 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/DimensionMismatchException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/DimensionMismatchException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,129 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math; +018 +019 /** +020 * Error thrown when two dimensions differ. +021 * +022 * @since 1.2 +023 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +024 */ +025 public class DimensionMismatchException extends MathException { +026 +027 /** Serializable version identifier */ +028 private static final long serialVersionUID = -1316089546353786411L; +029 +030 /** First dimension. */ +031 private final int dimension1; +032 +033 /** Second dimension. */ +034 private final int dimension2; +035 +036 /** +037 * Construct an exception from the mismatched dimensions +038 * @param dimension1 first dimension +039 * @param dimension2 second dimension +040 */ +041 public DimensionMismatchException(final int dimension1, final int dimension2) { +042 super("dimension mismatch {0} != {1}", dimension1, dimension2); +043 this.dimension1 = dimension1; +044 this.dimension2 = dimension2; +045 } +046 +047 /** +048 * Get the first dimension +049 * @return first dimension +050 */ +051 public int getDimension1() { +052 return dimension1; +053 } +054 +055 /** +056 * Get the second dimension +057 * @return second dimension +058 */ +059 public int getDimension2() { +060 return dimension2; +061 } +062 +063 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/DuplicateSampleAbscissaException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/DuplicateSampleAbscissaException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,115 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math; +018 +019 /** +020 * Exception thrown when a sample contains several entries at the same abscissa. +021 * +022 * @since 1.2 +023 * @version $Revision: 822454 $ $Date: 2009-10-06 15:29:52 -0400 (Tue, 06 Oct 2009) $ +024 */ +025 public class DuplicateSampleAbscissaException extends MathException { +026 +027 /** Serializable version identifier */ +028 private static final long serialVersionUID = -2271007547170169872L; +029 +030 /** +031 * Construct an exception indicating the duplicate abscissa. +032 * @param abscissa duplicate abscissa +033 * @param i1 index of one entry having the duplicate abscissa +034 * @param i2 index of another entry having the duplicate abscissa +035 */ +036 public DuplicateSampleAbscissaException(double abscissa, int i1, int i2) { +037 super("Abscissa {0} is duplicated at both indices {1} and {2}", +038 abscissa, i1, i2); +039 } +040 +041 /** +042 * Get the duplicate abscissa. +043 * @return duplicate abscissa +044 */ +045 public double getDuplicateAbscissa() { +046 return ((Double) getArguments()[0]).doubleValue(); +047 } +048 +049 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/Field.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/Field.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,117 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math; +018 +019 /** +020 * Interface representing a <a href="http://mathworld.wolfram.com/Field.html">field</a>. +021 * <p> +022 * Classes implementing this interface will often be singletons. +023 * </p> +024 * @param <T> the type of the field elements +025 * @see FieldElement +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 * @since 2.0 +028 */ +029 public interface Field<T> { +030 +031 /** Get the additive identity of the field. +032 * <p> +033 * The additive identity is the element e<sub>0</sub> of the field such that +034 * for all elements a of the field, the equalities a + e<sub>0</sub> = +035 * e<sub>0</sub> + a = a hold. +036 * </p> +037 * @return additive identity of the field +038 */ +039 T getZero(); +040 +041 /** Get the multiplicative identity of the field. +042 * <p> +043 * The multiplicative identity is the element e<sub>1</sub> of the field such that +044 * for all elements a of the field, the equalities a × e<sub>1</sub> = +045 * e<sub>1</sub> × a = a hold. +046 * </p> +047 * @return multiplicative identity of the field +048 */ +049 T getOne(); +050 +051 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/FieldElement.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/FieldElement.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,126 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math; +018 +019 +020 /** +021 * Interface representing <a href="http://mathworld.wolfram.com/Field.html">field</a> elements. +022 * @param <T> the type of the field elements +023 * @see Field +024 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +025 * @since 2.0 +026 */ +027 public interface FieldElement<T> { +028 +029 /** Compute this + a. +030 * @param a element to add +031 * @return a new element representing this + a +032 */ +033 T add(T a); +034 +035 /** Compute this - a. +036 * @param a element to subtract +037 * @return a new element representing this - a +038 */ +039 T subtract(T a); +040 +041 /** Compute this × a. +042 * @param a element to multiply +043 * @return a new element representing this × a +044 */ +045 T multiply(T a); +046 +047 /** Compute this ÷ a. +048 * @param a element to add +049 * @return a new element representing this ÷ a +050 * @exception ArithmeticException if a is the zero of the +051 * additive operation (i.e. additive identity) +052 */ +053 T divide(T a) throws ArithmeticException; +054 +055 /** Get the {@link Field} to which the instance belongs. +056 * @return {@link Field} to which the instance belongs +057 */ +058 Field<T> getField(); +059 +060 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/FunctionEvaluationException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/FunctionEvaluationException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,223 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math; +018 +019 import org.apache.commons.math.linear.ArrayRealVector; +020 +021 /** +022 * Exception thrown when an error occurs evaluating a function. +023 * <p> +024 * Maintains an <code>argument</code> property holding the input value that +025 * caused the function evaluation to fail. +026 * +027 * @version $Revision: 885278 $ $Date: 2009-11-29 16:47:51 -0500 (Sun, 29 Nov 2009) $ +028 */ +029 public class FunctionEvaluationException extends MathException { +030 +031 /** Serializable version identifier. */ +032 private static final long serialVersionUID = -4305020489115478365L; +033 +034 /** Message for failed evaluation. */ +035 private static final String FAILED_EVALUATION_MESSAGE = +036 "evaluation failed for argument = {0}"; +037 +038 /** Argument causing function evaluation failure */ +039 private double[] argument; +040 +041 /** +042 * Construct an exception indicating the argument value +043 * that caused the function evaluation to fail. +044 * +045 * @param argument the failing function argument +046 */ +047 public FunctionEvaluationException(double argument) { +048 super(FAILED_EVALUATION_MESSAGE, argument); +049 this.argument = new double[] { argument }; +050 } +051 +052 /** +053 * Construct an exception indicating the argument value +054 * that caused the function evaluation to fail. +055 * +056 * @param argument the failing function argument +057 * @since 2.0 +058 */ +059 public FunctionEvaluationException(double[] argument) { +060 super(FAILED_EVALUATION_MESSAGE, new ArrayRealVector(argument)); +061 this.argument = argument.clone(); +062 } +063 +064 /** +065 * Constructs an exception with specified formatted detail message. +066 * Message formatting is delegated to {@link java.text.MessageFormat}. +067 * @param argument the failing function argument +068 * @param pattern format specifier +069 * @param arguments format arguments +070 * @since 1.2 +071 */ +072 public FunctionEvaluationException(double argument, +073 String pattern, Object ... arguments) { +074 super(pattern, arguments); +075 this.argument = new double[] { argument }; +076 } +077 +078 /** +079 * Constructs an exception with specified formatted detail message. +080 * Message formatting is delegated to {@link java.text.MessageFormat}. +081 * @param argument the failing function argument +082 * @param pattern format specifier +083 * @param arguments format arguments +084 * @since 2.0 +085 */ +086 public FunctionEvaluationException(double[] argument, +087 String pattern, Object ... arguments) { +088 super(pattern, arguments); +089 this.argument = argument.clone(); +090 } +091 +092 /** +093 * Constructs an exception with specified root cause. +094 * Message formatting is delegated to {@link java.text.MessageFormat}. +095 * @param cause the exception or error that caused this exception to be thrown +096 * @param argument the failing function argument +097 * @since 1.2 +098 */ +099 public FunctionEvaluationException(Throwable cause, double argument) { +100 super(cause); +101 this.argument = new double[] { argument }; +102 } +103 +104 /** +105 * Constructs an exception with specified root cause. +106 * Message formatting is delegated to {@link java.text.MessageFormat}. +107 * @param cause the exception or error that caused this exception to be thrown +108 * @param argument the failing function argument +109 * @since 2.0 +110 */ +111 public FunctionEvaluationException(Throwable cause, double[] argument) { +112 super(cause); +113 this.argument = argument.clone(); +114 } +115 +116 /** +117 * Constructs an exception with specified formatted detail message and root cause. +118 * Message formatting is delegated to {@link java.text.MessageFormat}. +119 * @param cause the exception or error that caused this exception to be thrown +120 * @param argument the failing function argument +121 * @param pattern format specifier +122 * @param arguments format arguments +123 * @since 1.2 +124 */ +125 public FunctionEvaluationException(Throwable cause, +126 double argument, String pattern, +127 Object ... arguments) { +128 super(cause, pattern, arguments); +129 this.argument = new double[] { argument }; +130 } +131 +132 /** +133 * Constructs an exception with specified formatted detail message and root cause. +134 * Message formatting is delegated to {@link java.text.MessageFormat}. +135 * @param cause the exception or error that caused this exception to be thrown +136 * @param argument the failing function argument +137 * @param pattern format specifier +138 * @param arguments format arguments +139 * @since 2.0 +140 */ +141 public FunctionEvaluationException(Throwable cause, +142 double[] argument, String pattern, +143 Object ... arguments) { +144 super(cause, pattern, arguments); +145 this.argument = argument.clone(); +146 } +147 +148 /** +149 * Returns the function argument that caused this exception. +150 * +151 * @return argument that caused function evaluation to fail +152 */ +153 public double[] getArgument() { +154 return argument.clone(); +155 } +156 +157 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/MathConfigurationException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/MathConfigurationException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,134 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math; +018 +019 import java.io.Serializable; +020 +021 /** +022 * Signals a configuration problem with any of the factory methods. +023 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +024 */ +025 public class MathConfigurationException extends MathException implements Serializable{ +026 +027 /** Serializable version identifier */ +028 private static final long serialVersionUID = 5261476508226103366L; +029 +030 /** +031 * Default constructor. +032 */ +033 public MathConfigurationException() { +034 super(); +035 } +036 +037 /** +038 * Constructs an exception with specified formatted detail message. +039 * Message formatting is delegated to {@link java.text.MessageFormat}. +040 * @param pattern format specifier +041 * @param arguments format arguments +042 * @since 1.2 +043 */ +044 public MathConfigurationException(String pattern, Object ... arguments) { +045 super(pattern, arguments); +046 } +047 +048 /** +049 * Create an exception with a given root cause. +050 * @param cause the exception or error that caused this exception to be thrown +051 */ +052 public MathConfigurationException(Throwable cause) { +053 super(cause); +054 } +055 +056 /** +057 * Constructs an exception with specified formatted detail message and root cause. +058 * Message formatting is delegated to {@link java.text.MessageFormat}. +059 * @param cause the exception or error that caused this exception to be thrown +060 * @param pattern format specifier +061 * @param arguments format arguments +062 * @since 1.2 +063 */ +064 public MathConfigurationException(Throwable cause, String pattern, Object ... arguments) { +065 super(cause, pattern, arguments); +066 } +067 +068 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/MathException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/MathException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,257 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math; +018 +019 import java.io.PrintStream; +020 import java.io.PrintWriter; +021 import java.text.MessageFormat; +022 import java.util.Locale; +023 import java.util.MissingResourceException; +024 import java.util.ResourceBundle; +025 +026 +027 /** +028 * Base class for commons-math checked exceptions. +029 * <p> +030 * Supports nesting, emulating JDK 1.4 behavior if necessary.</p> +031 * <p> +032 * Adapted from <a href="http://commons.apache.org/collections/api-release/org/apache/commons/collections/FunctorException.html"/>.</p> +033 * +034 * @version $Revision: 822850 $ $Date: 2009-10-07 14:56:42 -0400 (Wed, 07 Oct 2009) $ +035 */ +036 public class MathException extends Exception { +037 +038 /** Serializable version identifier. */ +039 private static final long serialVersionUID = -9004610152740737812L; +040 +041 /** +042 * Pattern used to build the message. +043 */ +044 private final String pattern; +045 +046 /** +047 * Arguments used to build the message. +048 */ +049 private final Object[] arguments; +050 +051 /** +052 * Constructs a new <code>MathException</code> with no +053 * detail message. +054 */ +055 public MathException() { +056 this.pattern = null; +057 this.arguments = new Object[0]; +058 } +059 +060 /** +061 * Constructs a new <code>MathException</code> with specified +062 * formatted detail message. +063 * Message formatting is delegated to {@link java.text.MessageFormat}. +064 * @param pattern format specifier +065 * @param arguments format arguments +066 */ +067 public MathException(String pattern, Object ... arguments) { +068 this.pattern = pattern; +069 this.arguments = (arguments == null) ? new Object[0] : arguments.clone(); +070 } +071 +072 /** +073 * Constructs a new <code>MathException</code> with specified +074 * nested <code>Throwable</code> root cause. +075 * +076 * @param rootCause the exception or error that caused this exception +077 * to be thrown. +078 */ +079 public MathException(Throwable rootCause) { +080 super(rootCause); +081 this.pattern = getMessage(); +082 this.arguments = new Object[0]; +083 } +084 +085 /** +086 * Constructs a new <code>MathException</code> with specified +087 * formatted detail message and nested <code>Throwable</code> root cause. +088 * Message formatting is delegated to {@link java.text.MessageFormat}. +089 * @param rootCause the exception or error that caused this exception +090 * to be thrown. +091 * @param pattern format specifier +092 * @param arguments format arguments +093 * @since 1.2 +094 */ +095 public MathException(Throwable rootCause, String pattern, Object ... arguments) { +096 super(rootCause); +097 this.pattern = pattern; +098 this.arguments = (arguments == null) ? new Object[0] : arguments.clone(); +099 } +100 +101 /** +102 * Translate a string to a given locale. +103 * @param s string to translate +104 * @param locale locale into which to translate the string +105 * @return translated string or original string +106 * for unsupported locales or unknown strings +107 */ +108 private static String translate(String s, Locale locale) { +109 try { +110 ResourceBundle bundle = +111 ResourceBundle.getBundle("org.apache.commons.math.MessagesResources", locale); +112 if (bundle.getLocale().getLanguage().equals(locale.getLanguage())) { +113 // the value of the resource is the translated string +114 return bundle.getString(s); +115 } +116 +117 } catch (MissingResourceException mre) { +118 // do nothing here +119 } +120 +121 // the locale is not supported or the resource is unknown +122 // don't translate and fall back to using the string as is +123 return s; +124 +125 } +126 +127 /** Gets the pattern used to build the message of this throwable. +128 * +129 * @return the pattern used to build the message of this throwable +130 * @since 1.2 +131 */ +132 public String getPattern() { +133 return pattern; +134 } +135 +136 /** Gets the arguments used to build the message of this throwable. +137 * +138 * @return the arguments used to build the message of this throwable +139 * @since 1.2 +140 */ +141 public Object[] getArguments() { +142 return arguments.clone(); +143 } +144 +145 /** Gets the message in a specified locale. +146 * +147 * @param locale Locale in which the message should be translated +148 * +149 * @return localized message +150 * @since 1.2 +151 */ +152 public String getMessage(final Locale locale) { +153 return (pattern == null) ? "" : new MessageFormat(translate(pattern, locale), locale).format(arguments); +154 } +155 +156 /** {@inheritDoc} */ +157 @Override +158 public String getMessage() { +159 return getMessage(Locale.US); +160 } +161 +162 /** {@inheritDoc} */ +163 @Override +164 public String getLocalizedMessage() { +165 return getMessage(Locale.getDefault()); +166 } +167 +168 /** +169 * Prints the stack trace of this exception to the standard error stream. +170 */ +171 @Override +172 public void printStackTrace() { +173 printStackTrace(System.err); +174 } +175 +176 /** +177 * Prints the stack trace of this exception to the specified stream. +178 * +179 * @param out the <code>PrintStream</code> to use for output +180 */ +181 @Override +182 public void printStackTrace(PrintStream out) { +183 synchronized (out) { +184 PrintWriter pw = new PrintWriter(out, false); +185 printStackTrace(pw); +186 // Flush the PrintWriter before it's GC'ed. +187 pw.flush(); +188 } +189 } +190 +191 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/MathRuntimeException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/MathRuntimeException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,582 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math; +018 +019 import java.io.EOFException; +020 import java.io.IOException; +021 import java.io.PrintStream; +022 import java.io.PrintWriter; +023 import java.text.MessageFormat; +024 import java.text.ParseException; +025 import java.util.ConcurrentModificationException; +026 import java.util.Locale; +027 import java.util.MissingResourceException; +028 import java.util.NoSuchElementException; +029 import java.util.ResourceBundle; +030 +031 /** +032 * Base class for commons-math unchecked exceptions. +033 * +034 * @version $Revision: 822850 $ $Date: 2009-10-07 14:56:42 -0400 (Wed, 07 Oct 2009) $ +035 * @since 2.0 +036 */ +037 public class MathRuntimeException extends RuntimeException { +038 +039 /** Serializable version identifier. */ +040 private static final long serialVersionUID = -5128983364075381060L; +041 +042 /** +043 * Pattern used to build the message. +044 */ +045 private final String pattern; +046 +047 /** +048 * Arguments used to build the message. +049 */ +050 private final Object[] arguments; +051 +052 /** +053 * Constructs a new <code>MathRuntimeException</code> with specified +054 * formatted detail message. +055 * Message formatting is delegated to {@link java.text.MessageFormat}. +056 * @param pattern format specifier +057 * @param arguments format arguments +058 */ +059 public MathRuntimeException(final String pattern, final Object ... arguments) { +060 this.pattern = pattern; +061 this.arguments = (arguments == null) ? new Object[0] : arguments.clone(); +062 } +063 +064 /** +065 * Constructs a new <code>MathRuntimeException</code> with specified +066 * nested <code>Throwable</code> root cause. +067 * +068 * @param rootCause the exception or error that caused this exception +069 * to be thrown. +070 */ +071 public MathRuntimeException(final Throwable rootCause) { +072 super(rootCause); +073 this.pattern = getMessage(); +074 this.arguments = new Object[0]; +075 } +076 +077 /** +078 * Constructs a new <code>MathRuntimeException</code> with specified +079 * formatted detail message and nested <code>Throwable</code> root cause. +080 * Message formatting is delegated to {@link java.text.MessageFormat}. +081 * @param rootCause the exception or error that caused this exception +082 * to be thrown. +083 * @param pattern format specifier +084 * @param arguments format arguments +085 */ +086 public MathRuntimeException(final Throwable rootCause, +087 final String pattern, final Object ... arguments) { +088 super(rootCause); +089 this.pattern = pattern; +090 this.arguments = (arguments == null) ? new Object[0] : arguments.clone(); +091 } +092 +093 /** +094 * Translate a string to a given locale. +095 * @param s string to translate +096 * @param locale locale into which to translate the string +097 * @return translated string or original string +098 * for unsupported locales or unknown strings +099 */ +100 private static String translate(final String s, final Locale locale) { +101 try { +102 ResourceBundle bundle = +103 ResourceBundle.getBundle("org.apache.commons.math.MessagesResources", locale); +104 if (bundle.getLocale().getLanguage().equals(locale.getLanguage())) { +105 // the value of the resource is the translated string +106 return bundle.getString(s); +107 } +108 +109 } catch (MissingResourceException mre) { +110 // do nothing here +111 } +112 +113 // the locale is not supported or the resource is unknown +114 // don't translate and fall back to using the string as is +115 return s; +116 +117 } +118 +119 /** +120 * Builds a message string by from a pattern and its arguments. +121 * @param locale Locale in which the message should be translated +122 * @param pattern format specifier +123 * @param arguments format arguments +124 * @return a message string +125 */ +126 private static String buildMessage(final Locale locale, final String pattern, +127 final Object ... arguments) { +128 return (pattern == null) ? "" : new MessageFormat(translate(pattern, locale), locale).format(arguments); +129 } +130 +131 /** Gets the pattern used to build the message of this throwable. +132 * +133 * @return the pattern used to build the message of this throwable +134 */ +135 public String getPattern() { +136 return pattern; +137 } +138 +139 /** Gets the arguments used to build the message of this throwable. +140 * +141 * @return the arguments used to build the message of this throwable +142 */ +143 public Object[] getArguments() { +144 return arguments.clone(); +145 } +146 +147 /** Gets the message in a specified locale. +148 * +149 * @param locale Locale in which the message should be translated +150 * +151 * @return localized message +152 */ +153 public String getMessage(final Locale locale) { +154 return buildMessage(locale, pattern, arguments); +155 } +156 +157 /** {@inheritDoc} */ +158 @Override +159 public String getMessage() { +160 return getMessage(Locale.US); +161 } +162 +163 /** {@inheritDoc} */ +164 @Override +165 public String getLocalizedMessage() { +166 return getMessage(Locale.getDefault()); +167 } +168 +169 /** +170 * Prints the stack trace of this exception to the standard error stream. +171 */ +172 @Override +173 public void printStackTrace() { +174 printStackTrace(System.err); +175 } +176 +177 /** +178 * Prints the stack trace of this exception to the specified stream. +179 * +180 * @param out the <code>PrintStream</code> to use for output +181 */ +182 @Override +183 public void printStackTrace(final PrintStream out) { +184 synchronized (out) { +185 PrintWriter pw = new PrintWriter(out, false); +186 printStackTrace(pw); +187 // Flush the PrintWriter before it's GC'ed. +188 pw.flush(); +189 } +190 } +191 +192 /** +193 * Constructs a new <code>ArithmeticException</code> with specified formatted detail message. +194 * Message formatting is delegated to {@link java.text.MessageFormat}. +195 * @param pattern format specifier +196 * @param arguments format arguments +197 * @return built exception +198 */ +199 public static ArithmeticException createArithmeticException(final String pattern, +200 final Object ... arguments) { +201 return new ArithmeticException() { +202 +203 /** Serializable version identifier. */ +204 private static final long serialVersionUID = 7705628723242533939L; +205 +206 /** {@inheritDoc} */ +207 @Override +208 public String getMessage() { +209 return buildMessage(Locale.US, pattern, arguments); +210 } +211 +212 /** {@inheritDoc} */ +213 @Override +214 public String getLocalizedMessage() { +215 return buildMessage(Locale.getDefault(), pattern, arguments); +216 } +217 +218 }; +219 } +220 +221 /** +222 * Constructs a new <code>ArrayIndexOutOfBoundsException</code> with specified formatted detail message. +223 * Message formatting is delegated to {@link java.text.MessageFormat}. +224 * @param pattern format specifier +225 * @param arguments format arguments +226 * @return built exception +227 */ +228 public static ArrayIndexOutOfBoundsException createArrayIndexOutOfBoundsException(final String pattern, +229 final Object ... arguments) { +230 return new ArrayIndexOutOfBoundsException() { +231 +232 /** Serializable version identifier. */ +233 private static final long serialVersionUID = -3394748305449283486L; +234 +235 /** {@inheritDoc} */ +236 @Override +237 public String getMessage() { +238 return buildMessage(Locale.US, pattern, arguments); +239 } +240 +241 /** {@inheritDoc} */ +242 @Override +243 public String getLocalizedMessage() { +244 return buildMessage(Locale.getDefault(), pattern, arguments); +245 } +246 +247 }; +248 } +249 +250 /** +251 * Constructs a new <code>EOFException</code> with specified formatted detail message. +252 * Message formatting is delegated to {@link java.text.MessageFormat}. +253 * @param pattern format specifier +254 * @param arguments format arguments +255 * @return built exception +256 */ +257 public static EOFException createEOFException(final String pattern, +258 final Object ... arguments) { +259 return new EOFException() { +260 +261 /** Serializable version identifier. */ +262 private static final long serialVersionUID = 279461544586092584L; +263 +264 /** {@inheritDoc} */ +265 @Override +266 public String getMessage() { +267 return buildMessage(Locale.US, pattern, arguments); +268 } +269 +270 /** {@inheritDoc} */ +271 @Override +272 public String getLocalizedMessage() { +273 return buildMessage(Locale.getDefault(), pattern, arguments); +274 } +275 +276 }; +277 } +278 +279 /** +280 * Constructs a new <code>IOException</code> with specified nested +281 * <code>Throwable</code> root cause. +282 * <p>This factory method allows chaining of other exceptions within an +283 * <code>IOException</code> even for Java 5. The constructor for +284 * <code>IOException</code> with a cause parameter was introduced only +285 * with Java 6.</p> +286 * @param rootCause the exception or error that caused this exception +287 * to be thrown. +288 * @return built exception +289 */ +290 public static IOException createIOException(final Throwable rootCause) { +291 IOException ioe = new IOException(rootCause.getLocalizedMessage()); +292 ioe.initCause(rootCause); +293 return ioe; +294 } +295 +296 /** +297 * Constructs a new <code>IllegalArgumentException</code> with specified formatted detail message. +298 * Message formatting is delegated to {@link java.text.MessageFormat}. +299 * @param pattern format specifier +300 * @param arguments format arguments +301 * @return built exception +302 */ +303 public static IllegalArgumentException createIllegalArgumentException(final String pattern, +304 final Object ... arguments) { +305 return new IllegalArgumentException() { +306 +307 /** Serializable version identifier. */ +308 private static final long serialVersionUID = -6555453980658317913L; +309 +310 /** {@inheritDoc} */ +311 @Override +312 public String getMessage() { +313 return buildMessage(Locale.US, pattern, arguments); +314 } +315 +316 /** {@inheritDoc} */ +317 @Override +318 public String getLocalizedMessage() { +319 return buildMessage(Locale.getDefault(), pattern, arguments); +320 } +321 +322 }; +323 } +324 +325 /** +326 * Constructs a new <code>IllegalArgumentException</code> with specified nested +327 * <code>Throwable</code> root cause. +328 * @param rootCause the exception or error that caused this exception +329 * to be thrown. +330 * @return built exception +331 */ +332 public static IllegalArgumentException createIllegalArgumentException(final Throwable rootCause) { +333 IllegalArgumentException iae = new IllegalArgumentException(rootCause.getLocalizedMessage()); +334 iae.initCause(rootCause); +335 return iae; +336 } +337 +338 /** +339 * Constructs a new <code>IllegalStateException</code> with specified formatted detail message. +340 * Message formatting is delegated to {@link java.text.MessageFormat}. +341 * @param pattern format specifier +342 * @param arguments format arguments +343 * @return built exception +344 */ +345 public static IllegalStateException createIllegalStateException(final String pattern, +346 final Object ... arguments) { +347 return new IllegalStateException() { +348 +349 /** Serializable version identifier. */ +350 private static final long serialVersionUID = -95247648156277208L; +351 +352 /** {@inheritDoc} */ +353 @Override +354 public String getMessage() { +355 return buildMessage(Locale.US, pattern, arguments); +356 } +357 +358 /** {@inheritDoc} */ +359 @Override +360 public String getLocalizedMessage() { +361 return buildMessage(Locale.getDefault(), pattern, arguments); +362 } +363 +364 }; +365 } +366 +367 /** +368 * Constructs a new <code>ConcurrentModificationException</code> with specified formatted detail message. +369 * Message formatting is delegated to {@link java.text.MessageFormat}. +370 * @param pattern format specifier +371 * @param arguments format arguments +372 * @return built exception +373 */ +374 public static ConcurrentModificationException createConcurrentModificationException(final String pattern, +375 final Object ... arguments) { +376 return new ConcurrentModificationException() { +377 +378 /** Serializable version identifier. */ +379 private static final long serialVersionUID = 6134247282754009421L; +380 +381 /** {@inheritDoc} */ +382 @Override +383 public String getMessage() { +384 return buildMessage(Locale.US, pattern, arguments); +385 } +386 +387 /** {@inheritDoc} */ +388 @Override +389 public String getLocalizedMessage() { +390 return buildMessage(Locale.getDefault(), pattern, arguments); +391 } +392 +393 }; +394 } +395 +396 /** +397 * Constructs a new <code>NoSuchElementException</code> with specified formatted detail message. +398 * Message formatting is delegated to {@link java.text.MessageFormat}. +399 * @param pattern format specifier +400 * @param arguments format arguments +401 * @return built exception +402 */ +403 public static NoSuchElementException createNoSuchElementException(final String pattern, +404 final Object ... arguments) { +405 return new NoSuchElementException() { +406 +407 /** Serializable version identifier. */ +408 private static final long serialVersionUID = 7304273322489425799L; +409 +410 /** {@inheritDoc} */ +411 @Override +412 public String getMessage() { +413 return buildMessage(Locale.US, pattern, arguments); +414 } +415 +416 /** {@inheritDoc} */ +417 @Override +418 public String getLocalizedMessage() { +419 return buildMessage(Locale.getDefault(), pattern, arguments); +420 } +421 +422 }; +423 } +424 +425 /** +426 * Constructs a new <code>NullPointerException</code> with specified formatted detail message. +427 * Message formatting is delegated to {@link java.text.MessageFormat}. +428 * @param pattern format specifier +429 * @param arguments format arguments +430 * @return built exception +431 */ +432 public static NullPointerException createNullPointerException(final String pattern, +433 final Object ... arguments) { +434 return new NullPointerException() { +435 +436 /** Serializable version identifier. */ +437 private static final long serialVersionUID = -3075660477939965216L; +438 +439 /** {@inheritDoc} */ +440 @Override +441 public String getMessage() { +442 return buildMessage(Locale.US, pattern, arguments); +443 } +444 +445 /** {@inheritDoc} */ +446 @Override +447 public String getLocalizedMessage() { +448 return buildMessage(Locale.getDefault(), pattern, arguments); +449 } +450 +451 }; +452 } +453 +454 /** +455 * Constructs a new <code>ParseException</code> with specified +456 * formatted detail message. +457 * Message formatting is delegated to {@link java.text.MessageFormat}. +458 * @param offset offset at which error occurred +459 * @param pattern format specifier +460 * @param arguments format arguments +461 * @return built exception +462 */ +463 public static ParseException createParseException(final int offset, +464 final String pattern, +465 final Object ... arguments) { +466 return new ParseException(null, offset) { +467 +468 /** Serializable version identifier. */ +469 private static final long serialVersionUID = -1103502177342465975L; +470 +471 /** {@inheritDoc} */ +472 @Override +473 public String getMessage() { +474 return buildMessage(Locale.US, pattern, arguments); +475 } +476 +477 /** {@inheritDoc} */ +478 @Override +479 public String getLocalizedMessage() { +480 return buildMessage(Locale.getDefault(), pattern, arguments); +481 } +482 +483 }; +484 } +485 +486 /** Create an {@link java.lang.RuntimeException} for an internal error. +487 * @param cause underlying cause +488 * @return an {@link java.lang.RuntimeException} for an internal error +489 */ +490 public static RuntimeException createInternalError(final Throwable cause) { +491 +492 final String pattern = "internal error, please fill a bug report at {0}"; +493 final String argument = "https://issues.apache.org/jira/browse/MATH"; +494 +495 return new RuntimeException() { +496 +497 /** Serializable version identifier. */ +498 private static final long serialVersionUID = -201865440834027016L; +499 +500 /** {@inheritDoc} */ +501 @Override +502 public String getMessage() { +503 return buildMessage(Locale.US, pattern, argument); +504 } +505 +506 /** {@inheritDoc} */ +507 @Override +508 public String getLocalizedMessage() { +509 return buildMessage(Locale.getDefault(), pattern, argument); +510 } +511 +512 }; +513 +514 } +515 +516 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/MaxEvaluationsExceededException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/MaxEvaluationsExceededException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,133 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math; +019 +020 import org.apache.commons.math.ConvergenceException; +021 +022 /** +023 * Error thrown when a numerical computation exceeds its allowed +024 * number of functions evaluations. +025 * +026 * @version $Revision: 779273 $ $Date: 2009-05-27 14:54:48 -0400 (Wed, 27 May 2009) $ +027 * @since 2.0 +028 */ +029 public class MaxEvaluationsExceededException extends ConvergenceException { +030 +031 /** Serializable version identifier. */ +032 private static final long serialVersionUID = -5921271447220129118L; +033 +034 /** Maximal number of evaluations allowed. */ +035 private final int maxEvaluations; +036 +037 /** +038 * Constructs an exception with specified formatted detail message. +039 * Message formatting is delegated to {@link java.text.MessageFormat}. +040 * @param maxEvaluations maximal number of evaluations allowed +041 */ +042 public MaxEvaluationsExceededException(final int maxEvaluations) { +043 super("Maximal number of evaluations ({0}) exceeded", maxEvaluations); +044 this.maxEvaluations = maxEvaluations; +045 } +046 +047 /** +048 * Constructs an exception with specified formatted detail message. +049 * Message formatting is delegated to {@link java.text.MessageFormat}. +050 * @param maxEvaluations the exceeded maximal number of evaluations +051 * @param pattern format specifier +052 * @param arguments format arguments +053 */ +054 public MaxEvaluationsExceededException(final int maxEvaluations, +055 final String pattern, final Object ... arguments) { +056 super(pattern, arguments); +057 this.maxEvaluations = maxEvaluations; +058 } +059 +060 /** Get the maximal number of evaluations allowed. +061 * @return maximal number of evaluations allowed +062 */ +063 public int getMaxEvaluations() { +064 return maxEvaluations; +065 } +066 +067 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/MaxIterationsExceededException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/MaxIterationsExceededException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,133 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math; +019 +020 import org.apache.commons.math.ConvergenceException; +021 +022 /** +023 * Error thrown when a numerical computation exceeds its allowed +024 * number of iterations. +025 * +026 * @version $Revision: 746578 $ $Date: 2009-02-21 15:01:14 -0500 (Sat, 21 Feb 2009) $ +027 * @since 1.2 +028 */ +029 public class MaxIterationsExceededException extends ConvergenceException { +030 +031 /** Serializable version identifier. */ +032 private static final long serialVersionUID = -7821226672760574694L; +033 +034 /** Maximal number of iterations allowed. */ +035 private final int maxIterations; +036 +037 /** +038 * Constructs an exception with specified formatted detail message. +039 * Message formatting is delegated to {@link java.text.MessageFormat}. +040 * @param maxIterations maximal number of iterations allowed +041 */ +042 public MaxIterationsExceededException(final int maxIterations) { +043 super("Maximal number of iterations ({0}) exceeded", maxIterations); +044 this.maxIterations = maxIterations; +045 } +046 +047 /** +048 * Constructs an exception with specified formatted detail message. +049 * Message formatting is delegated to {@link java.text.MessageFormat}. +050 * @param maxIterations the exceeded maximal number of iterations +051 * @param pattern format specifier +052 * @param arguments format arguments +053 */ +054 public MaxIterationsExceededException(final int maxIterations, +055 final String pattern, final Object ... arguments) { +056 super(pattern, arguments); +057 this.maxIterations = maxIterations; +058 } +059 +060 /** Get the maximal number of iterations allowed. +061 * @return maximal number of iterations allowed +062 */ +063 public int getMaxIterations() { +064 return maxIterations; +065 } +066 +067 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/MessagesResources_fr.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/MessagesResources_fr.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,942 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math; +019 +020 import java.util.ListResourceBundle; +021 +022 /** +023 * French localization message resources for the commons-math library. +024 * @version $Revision: 927009 $ $Date: 2010-03-24 07:14:07 -0400 (Wed, 24 Mar 2010) $ +025 * @since 1.2 +026 */ +027 public class MessagesResources_fr +028 extends ListResourceBundle { +029 +030 /** Non-translated/translated messages arrays. */ +031 private static final Object[][] CONTENTS = { +032 +033 // org.apache.commons.math.util.MathUtils +034 { "must have n >= k for binomial coefficient (n,k), got n = {0}, k = {1}", +035 "n doit \u00eatre sup\u00e9rieur ou \u00e9gal \u00e0 k " + +036 "pour le coefficient du bin\u00f4me (n,k), or n = {0}, k = {1}" }, +037 { "must have n >= 0 for binomial coefficient (n,k), got n = {0}", +038 "n doit \u00eatre positif pour le coefficient du bin\u00f4me (n,k), or n = {0}" }, +039 { "must have n >= 0 for n!, got n = {0}", +040 "n doit \u00eatre positif pour le calcul de n!, or n = {0}" }, +041 { "overflow: gcd({0}, {1}) is 2^31", +042 "d\u00e9passement de capacit\u00e9 : le PGCD de {0} et {1} vaut 2^31" }, +043 { "overflow: gcd({0}, {1}) is 2^63", +044 "d\u00e9passement de capacit\u00e9 : le PGCD de {0} et {1} vaut 2^63" }, +045 { "overflow: lcm({0}, {1}) is 2^31", +046 "d\u00e9passement de capacit\u00e9 : le MCM de {0} et {1} vaut 2^31" }, +047 { "overflow: lcm({0}, {1}) is 2^63", +048 "d\u00e9passement de capacit\u00e9 : le MCM de {0} et {1} vaut 2^63" }, +049 { "cannot raise an integral value to a negative power ({0}^{1})", +050 "impossible d''\u00e9lever une valeur enti\u00e8re " + +051 "\u00e0 une puissance n\u00e9gative ({0}^{1})" }, +052 { "invalid rounding method {0}, valid methods: {1} ({2}), {3} ({4}), {5} ({6}), {7} ({8}), {9} ({10}), {11} ({12}), {13} ({14}), {15} ({16})", +053 "m\u00e9thode d''arondi {0} invalide, m\u00e9thodes valides : {1} ({2}), {3} ({4}), {5} ({6}), {7} ({8}), {9} ({10}), {11} ({12}), {13} ({14}), {15} ({16})" }, +054 { "Cannot normalize to an infinite value", +055 "impossible de normaliser vers une valeur infinie" }, +056 { "Cannot normalize to NaN", +057 "impossible de normaliser vers NaN" }, +058 { "Array contains an infinite element, {0} at index {1}", +059 "le tableau contient l''\u00e9l\u00e9ment infini {0} \u00e0 l''index {1}" }, +060 +061 // org.apache.commons.math.FunctionEvaluationException +062 { "evaluation failed for argument = {0}", +063 "erreur d''\u00e9valuation pour l''argument {0}" }, +064 +065 // org.apache.commons.math.DuplicateSampleAbscissaException +066 { "Abscissa {0} is duplicated at both indices {1} and {2}", +067 "Abscisse {0} dupliqu\u00e9e aux indices {1} et {2}" }, +068 +069 // org.apache.commons.math.ConvergenceException +070 { "Convergence failed", +071 "\u00c9chec de convergence" }, +072 +073 // org.apache.commons.math.ArgumentOutsideDomainException +074 { "Argument {0} outside domain [{1} ; {2}]", +075 "Argument {0} hors du domaine [{1} ; {2}]" }, +076 +077 // org.apache.commons.math.MaxIterationsExceededException +078 { "Maximal number of iterations ({0}) exceeded", +079 "Nombre maximal d''it\u00e9rations ({0}) d\u00e9pass\u00e9" }, +080 +081 // org.apache.commons.math.MaxEvaluationsExceededException +082 { "Maximal number of evaluations ({0}) exceeded", +083 "Nombre maximal d''\u00e9valuations ({0}) d\u00e9pass\u00e9" }, +084 +085 // org.apache.commons.math.analysis.interpolation.SplineInterpolator +086 // org.apache.commons.math.analysis.polynomials.PolynomialFunctionLagrangeForm +087 // org.apache.commons.math.DimensionMismatchException +088 // org.apache.commons.math.optimization.LeastSquaresConverter +089 // org.apache.commons.math.optimization.direct.DirectSearchOptimizer +090 // org.apache.commons.math.optimization.general.AbstractLeastSquaresOptimizer +091 // org.apache.commons.math.ode.ContinuousOutputModel +092 // org.apache.commons.math.random.UncorrelatedRandomVectorGenerator +093 // org.apache.commons.math.stat.regression.AbstractMultipleLinearRegression +094 // org.apache.commons.math.stat.inference.ChiSquareTestImpl +095 // org.apache.commons.math.analysis.interpolation.MicrosphereInterpolatingFunction +096 { "dimension mismatch {0} != {1}", +097 "dimensions incompatibles {0} != {1}" }, +098 +099 // org.apache.commons.math.analysis.interpolation.MicrosphereInterpolatingFunction +100 { "no data", +101 "aucune donn\u00e9e" }, +102 +103 // org.apache.commons.math.analysis.interpolation.MicrosphereInterpolator +104 { "brightness exponent should be positive or null, but got {0}", +105 "l''exposant de brillance devrait \u00eatre positif ou null, or e = {0}" }, +106 { "number of microsphere elements must be positive, but got {0}", +107 "le nombre d''\u00e9l\u00e9ments de la microsph\u00e8re devrait \u00eatre positif, or n = {0}" }, +108 +109 // org.apache.commons.math.linear.decomposition.NotPositiveDefiniteMatrixException +110 { "not positive definite matrix", +111 "matrice non d\u00e9finie positive" }, +112 +113 // org.apache.commons.math.linear.decomposition.NotSymmetricMatrixException +114 { "not symmetric matrix", +115 "matrice non symm\u00e9trique" }, +116 +117 // org.apache.commons.math.fraction.FractionConversionException +118 { "Unable to convert {0} to fraction after {1} iterations", +119 "Impossible de convertir {0} en fraction apr\u00e8s {1} it\u00e9rations" }, +120 { "Overflow trying to convert {0} to fraction ({1}/{2})", +121 "D\u00e9passement de capacit\u00e9 lors de la conversion de {0} en fraction ({1}/{2})" }, +122 +123 // org.apache.commons.math.fraction.BigFraction +124 { "numerator is null", +125 "le num\u00e9rateur est null" }, +126 { "denimonator is null", +127 "le d\u00e9nominateur est null" }, +128 { "denominator must be different from 0", +129 "le d\u00e9nominateur doit \u00eatre diff\u00e9rent de 0" }, +130 { "cannot convert NaN value", +131 "les valeurs NaN ne peuvent \u00eatre converties" }, +132 { "cannot convert infinite value", +133 "les valeurs infinies ne peuvent \u00eatre converties" }, +134 +135 // org.apache.commons.math.fraction.AbstractFormat +136 { "denominator format can not be null", +137 "le format du d\u00e9nominateur ne doit pas \u00eatre nul" }, +138 { "numerator format can not be null", +139 "le format du num\u00e9rateur ne doit pas \u00eatre nul" }, +140 +141 // org.apache.commons.math.fraction.FractionFormat +142 { "cannot convert given object to a fraction number: {0}", +143 "impossible de convertir l''objet sous forme d''un nombre rationnel : {0}" }, +144 +145 // org.apache.commons.math.fraction.FractionFormat +146 // org.apache.commons.math.fraction.BigFractionFormat +147 { "unparseable fraction number: \"{0}\"", +148 "\u00e9chec d''analyse du nombre rationnel \"{0}\"" }, +149 { "cannot format given object as a fraction number", +150 "impossible de formater l''objet sous forme d''un nombre rationnel" }, +151 +152 // org.apache.commons.math.fraction.ProperFractionFormat +153 // org.apache.commons.math.fraction.ProperBigFractionFormat +154 { "whole format can not be null", +155 "le format complet ne doit pas \u00eatre nul" }, +156 +157 // org.apache.commons.math.analysis.solvers.UnivariateRealSolverUtils +158 { "function is null", +159 "la fonction est nulle" }, +160 { "bad value for maximum iterations number: {0}", +161 "valeur invalide pour le nombre maximal d''it\u00e9rations : {0}" }, +162 { "invalid bracketing parameters: lower bound={0}, initial={1}, upper bound={2}", +163 "param\u00e8tres d''encadrement invalides : borne inf\u00e9rieure = {0}, valeur initiale = {1}, borne sup\u00e9rieure = {2}" }, +164 { "number of iterations={0}, maximum iterations={1}, initial={2}, lower bound={3}, upper bound={4}," + +165 " final a value={5}, final b value={6}, f(a)={7}, f(b)={8}", +166 "nombre d''it\u00e9rations = {0}, it\u00e9rations maximum = {1}, valeur initiale = {2}," + +167 " borne inf\u00e9rieure = {3}, borne sup\u00e9rieure = {4}," + +168 " valeur a finale = {5}, valeur b finale = {6}, f(a) = {7}, f(b) = {8}" }, +169 +170 // org.apache.commons.math.analysis.solvers.LaguerreSolver +171 { "polynomial degree must be positive: degree={0}", +172 "le polyn\u00f4me doit \u00eatre de degr\u00e9 positif : degr\u00e9 = {0}" }, +173 +174 // org.apache.commons.math.analysis.solvers.SecantSolver +175 { "function values at endpoints do not have different signs, endpoints: [{0}, {1}], values: [{2}, {3}]", +176 "les valeurs de la fonctions aux bornes sont de m\u00eame signe, bornes : [{0}, {1}], valeurs : [{2}, {3}]" }, +177 +178 // org.apache.commons.math.analysis.interpolation.SplineInterpolator +179 // org.apache.commons.math.analysis.polynomials.PolynomialFunctionLagrangeForm +180 { "{0} points are required, got only {1}", +181 "{0} sont n\u00e9cessaires, seuls {1} ont \u00e9t\u00e9 fournis" }, +182 +183 // org.apache.commons.math.analysis.interpolation.SplineInterpolator +184 { "points {0} and {1} are not strictly increasing ({2} >= {3})", +185 "les points {0} et {1} ne sont pas strictement croissants ({2} >= {3})" }, +186 { "points {0} and {1} are not strictly decreasing ({2} <= {3})", +187 "les points {0} et {1} ne sont pas strictement d\u00e9croissants ({2} <= {3})" }, +188 { "points {0} and {1} are not increasing ({2} > {3})", +189 "les points {0} et {1} ne sont pas croissants ({2} > {3})" }, +190 { "points {0} and {1} are not decreasing ({2} < {3})", +191 "les points {0} et {1} ne sont pas d\u00e9croissants ({2} < {3})" }, +192 +193 // org.apache.commons.math.analysis.interpolation.LoessInterpolator +194 { "bandwidth must be in the interval [0,1], but got {0}", +195 "la largeur de bande doit \u00eatre dans l''intervalle [0, 1], alors qu'elle vaut {0}" }, +196 { "the number of robustness iterations must be non-negative, but got {0}", +197 "le nombre d''it\u00e9rations robuste ne peut \u00eatre n\u00e9gatif, alors qu''il est de {0}" }, +198 { "Loess expects the abscissa and ordinate arrays to be of the same size, " + +199 "but got {0} abscissae and {1} ordinatae", +200 "la r\u00e9gression Loess n\u00e9cessite autant d''abscisses que d''ordonn\u00e9es, " + +201 "mais {0} abscisses et {1} ordonn\u00e9es ont \u00e9t\u00e9 fournies" }, +202 { "Loess expects at least 1 point", +203 "la r\u00e9gression Loess n\u00e9cessite au moins un point" }, +204 { "the bandwidth must be large enough to accomodate at least 2 points. There are {0} " + +205 " data points, and bandwidth must be at least {1} but it is only {2}", +206 "la largeur de bande doit \u00eatre assez grande pour supporter au moins 2 points. Il y a {0}" + +207 "donn\u00e9es et la largeur de bande doit \u00eatre au moins de {1}, or elle est seulement de {2}" }, +208 { "all abscissae must be finite real numbers, but {0}-th is {1}", +209 "toutes les abscisses doivent \u00eatre des nombres r\u00e9els finis, mais l''abscisse {0} vaut {1}" }, +210 { "all ordinatae must be finite real numbers, but {0}-th is {1}", +211 "toutes les ordonn\u00e9es doivent \u00eatre des nombres r\u00e9els finis, mais l''ordonn\u00e9e {0} vaut {1}" }, +212 { "all weights must be finite real numbers, but {0}-th is {1}", +213 "tous les poids doivent \u00eatre des nombres r\u00e9els finis, mais le poids {0} vaut {1}" }, +214 { "the abscissae array must be sorted in a strictly increasing order, " + +215 "but the {0}-th element is {1} whereas {2}-th is {3}", +216 "les abscisses doivent \u00eatre en ordre strictement croissant, " + +217 "mais l''\u00e9l\u00e9ment {0} vaut {1} alors que l''\u00e9l\u00e9ment {2} vaut {3}" }, +218 +219 // org.apache.commons.math.util.ContinuedFraction +220 { "Continued fraction convergents diverged to +/- infinity for value {0}", +221 "Divergence de fraction continue \u00e0 l''infini pour la valeur {0}" }, +222 { "Continued fraction convergents failed to converge for value {0}", +223 "\u00c9chec de convergence de fraction continue pour la valeur {0}" }, +224 { "Continued fraction diverged to NaN for value {0}", +225 "Divergence de fraction continue \u00e0 NaN pour la valeur {0}"}, +226 +227 // org.apache.commons.math.util.DefaultTransformer +228 { "Conversion Exception in Transformation, Object is null", +229 "Exception de conversion dans une transformation, l''objet est nul" }, +230 { "Conversion Exception in Transformation: {0}", +231 "Exception de conversion dans une transformation : {0}" }, +232 +233 // org.apache.commons.math.optimization.MultiStartOptimizer +234 { "no optimum computed yet", +235 "aucun optimum n''a encore \u00e9t\u00e9 calcul\u00e9" }, +236 +237 // org.apache.commons.math.optimization.direct.DirectSearchOptimizer +238 { "simplex must contain at least one point", +239 "le simplex doit contenir au moins un point" }, +240 { "equal vertices {0} and {1} in simplex configuration", +241 "sommets {0} et {1} \u00e9gaux dans la configuration du simplex" }, +242 +243 // org.apache.commons.math.estimation.AbstractEstimation +244 { "maximal number of evaluations exceeded ({0})", +245 "nombre maximal d''\u00e9valuations d\u00e9pass\u00e9 ({0})" }, +246 +247 // org.apache.commons.math.optimization.general.AbstractLeastSquaresOptimizer +248 { "unable to compute covariances: singular problem", +249 "impossible de calculer les covariances : probl\u00e8me singulier"}, +250 { "no degrees of freedom ({0} measurements, {1} parameters)", +251 "aucun degr\u00e9 de libert\u00e9 ({0} mesures, {1} param\u00e8tres)" }, +252 +253 // org.apache.commons.math.optimization.general.GaussNewtonOptimizer +254 { "unable to solve: singular problem", +255 "r\u00e9solution impossible : probl\u00e8me singulier" }, +256 +257 // org.apache.commons.math.optimization.general.LevenbergMarquardtEstimator +258 { "cost relative tolerance is too small ({0}), no further reduction in the sum of squares is possible", +259 "trop petite tol\u00e9rance relative sur le co\u00fbt ({0}), aucune r\u00e9duction de la somme des carr\u00e9s n''est possible" }, +260 { "parameters relative tolerance is too small ({0}), no further improvement in the approximate solution is possible", +261 "trop petite tol\u00e9rance relative sur les param\u00e8tres ({0}), aucune am\u00e9lioration de la solution approximative n''est possible" }, +262 { "orthogonality tolerance is too small ({0}), solution is orthogonal to the jacobian", +263 "trop petite tol\u00e9rance sur l''orthogonalit\u00e9 ({0}), la solution est orthogonale \u00e0 la jacobienne" }, +264 { "unable to perform Q.R decomposition on the {0}x{1} jacobian matrix", +265 "impossible de calculer la factorisation Q.R de la matrice jacobienne {0}x{1}" }, +266 +267 // org.apache.commons.math.optimization.general.NonLinearConjugateGradientOptimizer +268 { "unable to bracket optimum in line search", +269 "impossible d''encadrer l''optimum lors de la recherche lin\u00e9aire" }, +270 +271 // org.apache.commons.math.optimization.fitting.HarmonicCoefficientsGuesser +272 { "unable to first guess the harmonic coefficients", +273 "impossible de faire une premi\u00e8re estimation des coefficients harmoniques" }, +274 +275 // org.apache.commons.math.optimization.fitting.HarmonicCoefficientsGuesser +276 { "sample contains {0} observed points, at least {1} are required", +277 "l''\u00e9chantillon ne contient que {0} points alors qu''au moins {1} sont n\u00e9cessaires" }, +278 +279 // org.apache.commons.math.optimization.linear.NoFeasibleSolutionException +280 { "no feasible solution", +281 "aucune solution r\u00e9alisable" }, +282 +283 // org.apache.commons.math.optimization.linear.UnboundedSolutionException +284 { "unbounded solution", +285 "solution non born\u00e9e" }, +286 +287 // org.apache.commons.math.geometry.CardanEulerSingularityException +288 { "Cardan angles singularity", +289 "singularit\u00e9 d''angles de Cardan" }, +290 { "Euler angles singularity", +291 "singularit\u00e9 d''angles d''Euler" }, +292 +293 // org.apache.commons.math.geometry.Rotation +294 { "a {0}x{1} matrix cannot be a rotation matrix", +295 "une matrice {0}x{1} ne peut pas \u00eatre une matrice de rotation" }, +296 { "the closest orthogonal matrix has a negative determinant {0}", +297 "la matrice orthogonale la plus proche a un d\u00e9terminant n\u00e9gatif {0}" }, +298 { "unable to orthogonalize matrix in {0} iterations", +299 "impossible de rendre la matrice orthogonale en {0} it\u00e9rations" }, +300 +301 // org.apache.commons.math.ode.nonstiff.AdaptiveStepsizeIntegrator +302 { "minimal step size ({0,number,0.00E00}) reached, integration needs {1,number,0.00E00}", +303 "pas minimal ({0,number,0.00E00}) atteint, l''int\u00e9gration n\u00e9cessite {1,number,0.00E00}" }, +304 { "dimensions mismatch: state vector has dimension {0}, absolute tolerance vector has dimension {1}", +305 "incompatibilit\u00e9 de dimensions entre le vecteur d''\u00e9tat ({0}), et le vecteur de tol\u00e9rance absolue ({1})" }, +306 { "dimensions mismatch: state vector has dimension {0}, relative tolerance vector has dimension {1}", +307 "incompatibilit\u00e9 de dimensions entre le vecteur d''\u00e9tat ({0}), et le vecteur de tol\u00e9rance relative ({1})" }, +308 +309 // org.apache.commons.math.ode.nonstiff.AdaptiveStepsizeIntegrator, +310 // org.apache.commons.math.ode.nonstiff.RungeKuttaIntegrator +311 { "dimensions mismatch: ODE problem has dimension {0}, initial state vector has dimension {1}", +312 "incompatibilit\u00e9 de dimensions entre le probl\u00e8me ODE ({0}), et le vecteur d''\u00e9tat initial ({1})" }, +313 { "dimensions mismatch: ODE problem has dimension {0}, final state vector has dimension {1}", +314 "incompatibilit\u00e9 de dimensions entre le probl\u00e8me ODE ({0}), et le vecteur d''\u00e9tat final ({1})" }, +315 { "too small integration interval: length = {0}", +316 "intervalle d''int\u00e9gration trop petit : {0}" }, +317 +318 // org.apache.commons.math.ode.MultistepIntegrator +319 { "{0} method needs at least one previous point", +320 "la m\u00e9thode {0} n\u00e9cessite au moins un point pr\u00e9c\u00e9dent" }, +321 +322 // org.apache.commons.math.ode.ContinuousOutputModel +323 // org.apache.commons.math.optimization.direct.DirectSearchOptimizer +324 { "unexpected exception caught", +325 "exception inattendue lev\u00e9e" }, +326 { "propagation direction mismatch", +327 "directions de propagation incoh\u00e9rentes" }, +328 { "{0} wide hole between models time ranges", +329 "trou de longueur {0} entre les domaines temporels des mod\u00e8les" }, +330 +331 // org.apache.commons.math.optimization.direct.DirectSearchOptimizer +332 { "none of the {0} start points lead to convergence", +333 "aucun des {0} points de d\u00e9part n''aboutit \u00e0 une convergence" }, +334 +335 // org.apache.commons.math.random.ValueServer +336 { "unknown mode {0}, known modes: {1} ({2}), {3} ({4}), {5} ({6}), {7} ({8}), {9} ({10}) and {11} ({12})", +337 "mode {0} inconnu, modes connus : {1} ({2}), {3} ({4}), {5} ({6}), {7} ({8}), {9} ({10}) et {11} ({12})" }, +338 { "digest not initialized", +339 "mod\u00e8le empirique non initialis\u00e9" }, +340 +341 // org.apache.commons.math.random.EmpiricalDistributionImpl +342 { "distribution not loaded", +343 "aucune distribution n''a \u00e9t\u00e9 charg\u00e9e" }, +344 { "no bin selected", +345 "aucun compartiment s\u00e9lectionn\u00e9" }, +346 { "input data comes from unsupported datasource: {0}, supported sources: {1}, {2}", +347 "les donn\u00e9es d''entr\u00e9e proviennent " + +348 "d''une source non support\u00e9e : {0}, sources support\u00e9es : {1}, {2}" }, +349 +350 // org.apache.commons.math.random.EmpiricalDistributionImpl +351 // org.apache.commons.math.random.ValueServer +352 { "URL {0} contains no data", +353 "l''adresse {0} ne contient aucune donn\u00e9e" }, +354 +355 // org.apache.commons.math.random.AbstractRandomGenerator +356 // org.apache.commons.math.random.BitsStreamGenerator +357 { "upper bound must be positive ({0})", +358 "la borne sup\u00e9rieure doit \u00eatre positive ({0})" }, +359 +360 // org.apache.commons.math.random.RandomDataImpl +361 { "length must be positive ({0})", +362 "la longueur doit \u00eatre positive ({0})" }, +363 { "upper bound ({0}) must be greater than lower bound ({1})", +364 "la borne sup\u00e9rieure ({0}) doit \u00eatre sup\u00e9rieure" + +365 " \u00e0 la borne inf\u00e9rieure ({1})" }, +366 { "permutation k ({0}) exceeds n ({1})", +367 "la permutation k ({0}) d\u00e9passe n ({1})" }, +368 { "permutation k ({0}) must be positive", +369 "la permutation k ({0}) doit \u00eatre positive" }, +370 { "sample size ({0}) exceeds collection size ({1})", +371 "la taille de l''\u00e9chantillon ({0}) d\u00e9passe la taille de la collection ({1})" }, +372 +373 // org.apache.commons.math.linear.decomposition.EigenDecompositionImpl +374 { "cannot solve degree {0} equation", +375 "impossible de r\u00e9soudre une \u00e9quation de degr\u00e9 {0}" }, +376 { "eigen decomposition of assymetric matrices not supported yet", +377 "la d\u00e9composition en valeurs/vecteurs propres de matrices " + +378 "non sym\u00e9triques n''est pas encore disponible" }, +379 +380 // org.apache.commons.math.linear.decomposition.NonSquareMatrixException +381 // org.apache.commons.math.stat.regression.AbstractMultipleLinearRegression +382 { "a {0}x{1} matrix was provided instead of a square matrix", +383 "une matrice {0}x{1} a \u00e9t\u00e9 fournie \u00e0 la place d''une matrice carr\u00e9e" }, +384 +385 // org.apache.commons.math.linear.decomposition.SingularMatrixException +386 { "matrix is singular", +387 "matrice singuli\u00e8re" }, +388 +389 // org.apache.commons.math.linear.decomposition.SingularValueDecompositionImpl +390 { "cutoff singular value is {0}, should be at most {1}", +391 "la valeur singuli\u00e8re de coupure vaut {0}, elle ne devrait pas d\u00e9passer {1}" }, +392 +393 // org.apache.commons.math.linear.decomposition.CholeskyDecompositionImpl +394 // org.apache.commons.math.linear.decomposition.EigenDecompositionImpl +395 // org.apache.commons.math.linear.decomposition.LUDecompositionImpl +396 // org.apache.commons.math.linear.decomposition.QRDecompositionImpl +397 // org.apache.commons.math.linear.decomposition.SingularValueDecompositionImpl +398 { "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +399 "dimensions incoh\u00e9rentes : {0}x{1} \u00e0 la place de {2}x{3}" }, +400 +401 // org.apache.commons.math.linear.decomposition.CholeskyDecompositionImpl +402 // org.apache.commons.math.linear.decomposition.EigenDecompositionImpl +403 // org.apache.commons.math.linear.decomposition.LUDecompositionImpl +404 // org.apache.commons.math.linear.decomposition.QRDecompositionImpl +405 // org.apache.commons.math.linear.decomposition.SingularValueDecompositionImpl +406 // org.apache.commons.math.linear.ArrayRealVector +407 // org.apache.commons.math.linear.SparseRealVector +408 { "vector length mismatch: got {0} but expected {1}", +409 "taille de vecteur invalide : {0} au lieu de {1} attendue" }, +410 +411 // org.apache.commons.math.linear.ArrayRealVector +412 // org.apache.commons.math.linear.ArrayFieldVector +413 // org.apache.commons.math.linear.SparseRealVector +414 { "index {0} out of allowed range [{1}, {2}]", +415 "index {0} hors de la plage autoris\u00e9e [{1}, {2}]" }, +416 { "vector must have at least one element", +417 "un vecteur doit comporter au moins un \u00e9l\u00e9ment" }, +418 { "position {0} and size {1} don't fit to the size of the input array {2}", +419 "la position {0} et la taille {1} sont incompatibles avec la taille du tableau d''entr\u00e9e {2}"}, +420 +421 // org.apache.commons.math.linear.AbstractRealMatrix +422 // org.apache.commons.math.linear.AbstractFieldMatrix +423 { "invalid row dimension: {0} (must be positive)", +424 "nombre de lignes invalide : {0} (doit \u00eatre positif)" }, +425 { "invalid column dimension: {0} (must be positive)", +426 "nombre de colonnes invalide : {0} (doit \u00eatre positif)" }, +427 { "matrix must have at least one row", +428 "une matrice doit comporter au moins une ligne" }, +429 { "matrix must have at least one column", +430 "une matrice doit comporter au moins une colonne" }, +431 +432 // org.apache.commons.math.linear.AbstractRealMatrix +433 // org.apache.commons.math.linear.AbstractFieldMatrix +434 // org.apache.commons.math.stat.inference.ChiSquareTestImpl +435 { "some rows have length {0} while others have length {1}", +436 "certaines lignes ont une longueur de {0} alors que d''autres ont une longueur de {1}" }, +437 +438 // org.apache.commons.math.linear.MatrixUtils +439 { "row index {0} out of allowed range [{1}, {2}]", +440 "index de ligne {0} hors de la plage autoris\u00e9e [{1}, {2}]" }, +441 { "column index {0} out of allowed range [{1}, {2}]", +442 "index de colonne {0} hors de la plage autoris\u00e9e [{1}, {2}]" }, +443 { "initial row {0} after final row {1}", +444 "ligne initiale {0} apr\u00e8s la ligne finale {1}" }, +445 { "initial column {0} after final column {1}", +446 "colonne initiale {0} apr\u00e8s la colonne finale {1}" }, +447 { "empty selected row index array", +448 "tableau des indices de lignes s\u00e9lectionn\u00e9es vide" }, +449 { "empty selected column index array", +450 "tableau des indices de colonnes s\u00e9lectionn\u00e9es vide" }, +451 { "{0}x{1} and {2}x{3} matrices are not addition compatible", +452 "les dimensions {0}x{1} et {2}x{3} sont incompatibles pour l'addition matricielle" }, +453 { "{0}x{1} and {2}x{3} matrices are not subtraction compatible", +454 "les dimensions {0}x{1} et {2}x{3} sont incompatibles pour la soustraction matricielle" }, +455 { "{0}x{1} and {2}x{3} matrices are not multiplication compatible", +456 "les dimensions {0}x{1} et {2}x{3} sont incompatibles pour la multiplication matricielle" }, +457 +458 // org.apache.commons.math.linear.BlockRealMatrix +459 { "wrong array shape (block length = {0}, expected {1})", +460 "forme de tableau erron\u00e9e (bloc de longueur {0} au lieu des {1} attendus)" }, +461 +462 // org.apache.commons.math.complex.Complex +463 { "cannot compute nth root for null or negative n: {0}", +464 "impossible de calculer la racine ni\u00e8me pour n n\u00e9gatif ou nul : {0}" }, +465 +466 // org.apache.commons.math.complex.ComplexFormat +467 { "unparseable complex number: \"{0}\"", +468 "\u00e9chec d''analyse du nombre complexe \"{0}\"" }, +469 { "cannot format a {0} instance as a complex number", +470 "impossible de formater une instance de {0} comme un nombre complexe" }, +471 { "empty string for imaginary character", +472 "cha\u00eene vide pour le caract\u00e8 imaginaire" }, +473 { "null imaginary format", +474 "format imaginaire nul" }, +475 { "null real format", +476 "format r\u00e9el nul" }, +477 +478 // org.apache.commons.math.complex.ComplexUtils +479 { "negative complex module {0}", +480 "module n\u00e9gatif ({0}) pour un nombre complexe" }, +481 +482 // org.apache.commons.math.geometry.Vector3DFormat +483 { "unparseable 3D vector: \"{0}\"", +484 "\u00e9chec d''analyse du vecteur de dimension 3 \"{0}\"" }, +485 { "cannot format a {0} instance as a 3D vector", +486 "impossible de formater une instance de {0} comme un vecteur de dimension 3" }, +487 +488 // org.apache.commons.math.linear.RealVectorFormat +489 { "unparseable real vector: \"{0}\"", +490 "\u00e9chec d''analyse du vecteur r\u00e9el \"{0}\"" }, +491 { "cannot format a {0} instance as a real vector", +492 "impossible de formater une instance de {0} comme un vecteur r\u00e9el" }, +493 +494 // org.apache.commons.math.util.ResizableDoubleArray +495 { "the index specified: {0} is larger than the current maximal index {1}", +496 "l''index sp\u00e9cifi\u00e9 ({0}) d\u00e9passe l''index maximal courant ({1})" }, +497 { "elements cannot be retrieved from a negative array index {0}", +498 "impossible d''extraire un \u00e9l\u00e9ment \u00e0 un index n\u00e9gatif ({0})" }, +499 { "cannot set an element at a negative index {0}", +500 "impossible de mettre un \u00e9l\u00e9ment \u00e0 un index n\u00e9gatif ({0})" }, +501 { "cannot substitute an element from an empty array", +502 "impossible de substituer un \u00e9l\u00e9ment dans un tableau vide" }, +503 { "contraction criteria ({0}) smaller than the expansion factor ({1}). This would " + +504 "lead to a never ending loop of expansion and contraction as a newly expanded " + +505 "internal storage array would immediately satisfy the criteria for contraction.", +506 "crit\u00e8re de contraction ({0}) inf\u00e9rieur au facteur d''extension. Ceci " + +507 "induit une boucle infinie d''extensions/contractions car tout tableau de stockage " + +508 "fra\u00eechement \u00e9tendu respecte imm\u00e9diatement le crit\u00e8re de contraction."}, +509 { "contraction criteria smaller than one ({0}). This would lead to a never ending " + +510 "loop of expansion and contraction as an internal storage array length equal " + +511 "to the number of elements would satisfy the contraction criteria.", +512 "crit\u00e8re de contraction inf\u00e9rieur \u00e0 un ({0}). Ceci induit une boucle " + +513 "infinie d''extensions/contractions car tout tableau de stockage de longueur \u00e9gale " + +514 "au nombre d''\u00e9l\u00e9ments respecte le crit\u00e8re de contraction." }, +515 { "expansion factor smaller than one ({0})", +516 "facteur d''extension inf\u00e9rieur \u00e0 un ({0})"}, +517 { "cannot discard {0} elements from a {1} elements array", +518 "impossible d''enlever {0} \u00e9l\u00e9ments d''un tableau en contenant {1}"}, +519 { "cannot discard a negative number of elements ({0})", +520 "impossible d''enlever un nombre d''\u00e9l\u00e9ments{0} n\u00e9gatif"}, +521 { "unsupported expansion mode {0}, supported modes are {1} ({2}) and {3} ({4})", +522 "mode d''extension {0} no support\u00e9, les modes support\u00e9s sont {1} ({2}) et {3} ({4})" }, +523 { "initial capacity ({0}) is not positive", +524 "la capacit\u00e9 initiale ({0}) n''est pas positive" }, +525 { "index ({0}) is not positive", +526 "l''indice ({0}) n''est pas positif" }, +527 +528 // org.apache.commons.math.analysis.polynomials.PolynomialFunction +529 // org.apache.commons.math.analysis.polynomials.PolynomialFunctionNewtonForm +530 { "empty polynomials coefficients array", +531 "tableau de coefficients polyn\u00f4miaux vide" }, +532 +533 // org.apache.commons.math.analysis.polynomials.PolynomialFunctionNewtonForm +534 { "array sizes should have difference 1 ({0} != {1} + 1)", +535 "les tableaux devraient avoir une diff\u00e9rence de taille de 1 ({0} != {1} + 1)" }, +536 +537 // org.apache.commons.math.analysis.polynomials.PolynomialFunctionLagrangeForm +538 { "identical abscissas x[{0}] == x[{1}] == {2} cause division by zero", +539 "division par z\u00e9ro caus\u00e9e par les abscisses identiques x[{0}] == x[{1}] == {2}" }, +540 +541 // org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction +542 { "spline partition must have at least {0} points, got {1}", +543 "une partiction spline n\u00e9cessite au moins {0} points, seuls {1} ont \u00e9t\u00e9 fournis" }, +544 { "knot values must be strictly increasing", +545 "les n\u0153uds d''interpolation doivent \u00eatre strictement croissants" }, +546 { "number of polynomial interpolants must match the number of segments ({0} != {1} - 1)", +547 "le nombre d''interpolants polyn\u00f4miaux doit correspondre au nombre de segments ({0} != {1} - 1)" }, +548 +549 // org.apache.commons.math.analysis.solvers.UnivariateRealSolverImpl +550 { "function to solve cannot be null", +551 "la fonction \u00e0 r\u00e9soudre ne peux pas \u00eatre nulle" }, +552 { "invalid interval, initial value parameters: lower={0}, initial={1}, upper={2}", +553 "param\u00e8tres de l''intervalle initial invalides : borne inf = {0}, valeur initiale = {1}, borne sup = {2}" }, +554 +555 // org.apache.commons.math.analysis.solvers.UnivariateRealSolverImpl +556 // org.apache.commons.math.analysis.solvers.BrentSolver +557 { "function values at endpoints do not have different signs. Endpoints: [{0}, {1}], Values: [{2}, {3}]", +558 "les valeurs de la fonction aux bornes n''ont pas des signes diff\u00e9rents. Bornes : [{0}, {1}], valeurs : [{2}, {3}]" }, +559 +560 // org.apache.commons.math.analysis.solvers.UnivariateRealSolverImpl +561 // org.apache.commons.math.analysis.integration.UnivariateRealIntegratorImpl +562 // org.apache.commons.math.transform.FastFourierTransformer +563 { "endpoints do not specify an interval: [{0}, {1}]", +564 "les extr\u00e9mit\u00e9s ne constituent pas un intervalle : [{0}, {1}]" }, +565 +566 // org.apache.commons.math.analysis.solvers.LaguerreSolver +567 { "function is not polynomial", +568 "la fonction n''est pas p\u00f4lynomiale" }, +569 +570 // org.apache.commons.math.analysis.solvers.NewtonSolver +571 { "function is not differentiable", +572 "la fonction n''est pas diff\u00e9rentiable" }, +573 +574 // org.apache.commons.math.analysis.integration.UnivariateRealIntegratorImpl +575 { "invalid iteration limits: min={0}, max={1}", +576 "limites d''it\u00e9rations invalides : min = {0}, max = {1}" }, +577 +578 // org.apache.commons.math.analysis.integration.LegendreGaussIntegrator +579 { "{0} points Legendre-Gauss integrator not supported," + +580 " number of points must be in the {1}-{2} range", +581 "int\u00e9grateur de Legendre-Gauss non support\u00e9 en {0} points, " + +582 "le nombre de points doit \u00eatre entre {1} et {2}" }, +583 +584 // org.apache.commons.math.fraction.Fraction +585 { "zero denominator in fraction {0}/{1}", +586 "d\u00e9nominateur null dans le nombre rationnel {0}/{1}" }, +587 { "overflow in fraction {0}/{1}, cannot negate", +588 "d\u00e9passement de capacit\u00e9 pour la fraction {0}/{1}, son signe ne peut \u00eatre chang\u00e9" }, +589 { "overflow, numerator too large after multiply: {0}", +590 "d\u00e9passement de capacit\u00e9 pour le num\u00e9rateur apr\u00e8s multiplication : {0}" }, +591 { "the fraction to divide by must not be zero: {0}/{1}", +592 "division par un nombre rationnel nul : {0}/{1}" }, +593 { "null fraction", +594 "fraction nulle" }, +595 +596 // org.apache.commons.math.geometry.Rotation +597 { "zero norm for rotation axis", +598 "norme nulle pour un axe de rotation" }, +599 { "zero norm for rotation defining vector", +600 "norme nulle pour un axe de d\u00e9finition de rotation" }, +601 +602 // org.apache.commons.math.geometry.Vector3D +603 // org.apache.commons.math.linear.ArrayRealVector +604 { "cannot normalize a zero norm vector", +605 "impossible de normer un vecteur de norme nulle" }, +606 { "zero norm", +607 "norme nulle" }, +608 +609 // org.apache.commons.math.ConvergingAlgorithmImpl +610 { "no result available", +611 "aucun r\u00e9sultat n''est disponible" }, +612 +613 // org.apache.commons.math.linear.BigMatrixImpl +614 { "first {0} rows are not initialized yet", +615 "les {0} premi\u00e8res lignes ne sont pas encore initialis\u00e9es" }, +616 { "first {0} columns are not initialized yet", +617 "les {0} premi\u00e8res colonnes ne sont pas encore initialis\u00e9es" }, +618 +619 // org.apache.commons.math.stat.Frequency +620 { "class ({0}) does not implement Comparable", +621 "la classe ({0}) n''implante pas l''interface Comparable" }, +622 { "instance of class {0} not comparable to existing values", +623 "l''instance de la classe {0} n''est pas comparable aux valeurs existantes" }, +624 +625 // org.apache.commons.math.stat.StatUtils +626 { "input arrays must have the same positive length ({0} and {1})", +627 "les tableaux d''entr\u00e9e doivent avoir la m\u00eame taille positive ({0} et {1})" }, +628 { "input arrays must have the same length and at least two elements ({0} and {1})", +629 "les tableaux d''entr\u00e9e doivent avoir la m\u00eame taille" + +630 " et au moins deux \u00e9l\u00e9ments ({0} et {1})" }, +631 +632 // org.apache.commons.math.stat.correlation.Covariance +633 { "arrays must have the same length and both must have at " + +634 "least two elements. xArray has size {0}, yArray has {1} elements", +635 "les tableaux doivent avoir la m\u00eame taille " + +636 "et comporter au moins deux \u00e9l\u00e9ments. " + +637 "xArray a une taille de {0}, yArray a {1} \u00e9l\u00e9ments"}, +638 { "insufficient data: only {0} rows and {1} columns.", +639 "donn\u00e9es insuffisantes : seulement {0} lignes et {1} colonnes." }, +640 +641 // org.apache.commons.math.stat.correlation.PearsonsCorrelation +642 { "covariance matrix is null", +643 "la matrice de covariance est nulle" }, +644 { "invalid array dimensions. xArray has size {0}; yArray has {1} elements", +645 "dimensions de tableaux invalides. xArray a une taille de {0}, " + +646 "yArray a {1} \u00e9l\u00e9ments" }, +647 +648 // org.apache.commons.math.stat.descriptive.DescriptiveStatistics +649 { "window size must be positive ({0})", +650 "la taille de la fen\u00eatre doit \u00eatre positive ({0})" }, +651 { "percentile implementation {0} does not support {1}", +652 "l''implantation de pourcentage {0} ne dispose pas de la m\u00e9thode {1}" }, +653 { "cannot access {0} method in percentile implementation {1}", +654 "acc\u00e8s impossible \u00e0 la m\u00e9thode {0}" + +655 " dans l''implantation de pourcentage {1}" }, +656 { "out of bounds quantile value: {0}, must be in (0, 100]", +657 "valeur de quantile {0} hors bornes, doit \u00eatre dans l''intervalle ]0, 100]" }, +658 +659 // org.apache.commons.math.stat.descriptive.moment.Variance +660 // org.apache.commons.math.stat.descriptive.moment.SemiVariance +661 // org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic +662 // org.apache.commons.math.stat.descriptive.AbstractUnivariateStatistic +663 { "input values array is null", +664 "le tableau des valeurs d''entr\u00e9es est nul" }, +665 +666 // org.apache.commons.math.stat.descriptive.AbstractUnivariateStatistic +667 { "start position cannot be negative ({0})", +668 "la position de d\u00e9part ne peut pas \u00eatre n\u00e9gative" }, +669 { "length cannot be negative ({0})", +670 "la longueur ne peut pas \u00eatre n\u00e9gative" }, +671 { "subarray ends after array end", +672 "le sous-tableau se termine apr\u00e8s la fin du tableau" }, +673 +674 // org.apache.commons.math.stat.descriptive.moment.GeometricMean +675 // org.apache.commons.math.stat.descriptive.MultivariateSummaryStatistics +676 // org.apache.commons.math.stat.descriptive.SummaryStatistics +677 { "{0} values have been added before statistic is configured", +678 "{0} valeurs ont \u00e9t\u00e9 ajout\u00e9es " + +679 "avant que la statistique ne soit configur\u00e9e" }, +680 +681 // org.apache.commons.math.stat.descriptive.moment.Kurtosis +682 { "statistics constructed from external moments cannot be incremented", +683 "les statistiques bas\u00e9es sur des moments externes ne peuvent pas \u00eatre incr\u00e9ment\u00e9es" }, +684 { "statistics constructed from external moments cannot be cleared", +685 "les statistiques bas\u00e9es sur des moments externes ne peuvent pas \u00eatre remises \u00e0 z\u00e9ro" }, +686 +687 // org.apache.commons.math.stat.inference.ChiSquareTestImpl +688 { "expected array length = {0}, must be at least 2", +689 "le tableau des valeurs attendues a une longueur de {0}, elle devrait \u00eatre au moins de 2" }, +690 { "observed array length = {0}, must be at least 2", +691 "le tableau des valeurs observ\u00e9es a une longueur de {0}, elle devrait \u00eatre au moins de 2" }, +692 { "observed counts are all 0 in first observed array", +693 "aucune occurrence dans le premier tableau des observations" }, +694 { "observed counts are all 0 in second observed array", +695 "aucune occurrence dans le second tableau des observations" }, +696 { "observed counts are both zero for entry {0}", +697 "les occurrences observ\u00e9es sont toutes deux nulles pour l'entr\u00e9e {0}" }, +698 { "invalid row dimension: {0} (must be at least 2)", +699 "nombre de lignes invalide : {0} (doit \u00eatre au moins de 2)" }, +700 { "invalid column dimension: {0} (must be at least 2)", +701 "nombre de colonnes invalide : {0} (doit \u00eatre au moins de 2)" }, +702 { "element {0} is not positive: {1}", +703 "l''\u00e9l\u00e9ment {0} n''est pas positif : {1}" }, +704 { "element {0} is negative: {1}", +705 "l''\u00e9l\u00e9ment {0} est n\u00e9gatif : {1}" }, +706 { "element ({0}, {1}) is negative: {2}", +707 "l''\u00e9l\u00e9ment ({0}, {1}) est n\u00e9gatif : {2}" }, +708 +709 // org.apache.commons.math.stat.inference.OneWayAnovaImpl +710 { "two or more categories required, got {0}", +711 "deux cat\u00e9gories ou plus sont n\u00e9cessaires, il y en a {0}" }, +712 { "two or more values required in each category, one has {0}", +713 "deux valeurs ou plus sont n\u00e9cessaires pour chaque cat\u00e9gorie, une cat\u00e9gorie en a {0}" }, +714 +715 // org.apache.commons.math.stat.inference.TTestImpl +716 { "insufficient data for t statistic, needs at least 2, got {0}", +717 "deux valeurs ou plus sont n\u00e9cessaires pour la statistique t, il y en a {0}" }, +718 +719 // org.apache.commons.math.stat.inference.ChiSquareTestImpl +720 // org.apache.commons.math.stat.inference.TTestImpl +721 // org.apache.commons.math.stat.inference.OneWayAnovaImpl +722 // org.apache.commons.math.stat.Regression +723 { "out of bounds significance level {0}, must be between {1} and {2}", +724 "niveau de signification {0} hors domaine, doit \u00eatre entre {1} et {2}" }, +725 +726 // org.apache.commons.math.stat.regression.AbstractMultipleLinearRegression +727 { "not enough data ({0} rows) for this many predictors ({1} predictors)", +728 "pas assez de donn\u00e9es ({0} lignes) pour {1} pr\u00e9dicteurs" }, +729 +730 // org.apache.commons.math.distribution.AbstractContinuousDistribution +731 // org.apache.commons.math.distribution.AbstractIntegerDistribution +732 // org.apache.commons.math.distribution.ExponentialDistributionImpl +733 // org.apache.commons.math.distribution.BinomialDistributionImpl +734 // org.apache.commons.math.distribution.CauchyDistributionImpl +735 // org.apache.commons.math.distribution.PascalDistributionImpl +736 // org.apache.commons.math.distribution.WeibullDistributionImpl +737 { "{0} out of [{1}, {2}] range", +738 "{0} hors du domaine [{1}, {2}]" }, +739 +740 // org.apache.commons.math.distribution.AbstractDistribution +741 // org.apache.commons.math.distribution.AbstractIntegerDistribution +742 { "lower endpoint ({0}) must be less than or equal to upper endpoint ({1})", +743 "la borne inf\u00e9rieure ({0}) devrait \u00eatre inf\u00e9rieure " + +744 "ou \u00e9gale \u00e0 la borne sup\u00e9rieure ({1})" }, +745 +746 // org.apache.commons.math.distribution.AbstractContinuousDistribution +747 { "Cumulative probability function returned NaN for argument {0} p = {1}", +748 "Fonction de probabilit\u00e9 cumulative retourn\u00e9 NaN \u00e0 l''argument de {0} p = {1}" }, +749 { "This distribution does not have a density function implemented", +750 "La fonction de densit\u00e9 pour cette distribution n'a pas \u00e9t\u00e9 mis en oeuvre" }, +751 +752 // org.apache.commons.math.distribution.AbstractIntegerDistribution +753 { "Discrete cumulative probability function returned NaN for argument {0}", +754 "Discr\u00e8tes fonction de probabilit\u00e9 cumulative retourn\u00e9 NaN \u00e0 l''argument de {0}" }, +755 +756 +757 // org.apache.commons.math.distribution.BinomialDistributionImpl +758 { "number of trials must be non-negative ({0})", +759 "le nombre d''essais ne doit pas \u00eatre n\u00e9gatif ({0})" }, +760 +761 // org.apache.commons.math.distribution.ExponentialDistributionImpl +762 // org.apache.commons.math.random.RandomDataImpl +763 { "mean must be positive ({0})", +764 "la moyenne doit \u00eatre positive ({0})" }, +765 +766 // org.apache.commons.math.distribution.FDistributionImpl +767 // org.apache.commons.math.distribution.TDistributionImpl +768 { "degrees of freedom must be positive ({0})", +769 "les degr\u00e9s de libert\u00e9 doivent \u00eatre positifs ({0})" }, +770 +771 // org.apache.commons.math.distribution.GammaDistributionImpl +772 { "alpha must be positive ({0})", +773 "alpha doit \u00eatre positif ({0})" }, +774 { "beta must be positive ({0})", +775 "beta doit \u00eatre positif ({0})" }, +776 +777 // org.apache.commons.math.distribution.HypergeometricDistributionImpl +778 { "number of successes ({0}) must be less than or equal to population size ({1})", +779 "le nombre de succ\u00e8s doit \u00eatre inf\u00e9rieur " + +780 "ou \u00e9gal \u00e0 la taille de la population ({1})" }, +781 { "sample size ({0}) must be less than or equal to population size ({1})", +782 "la taille de l''\u00e9chantillon doit \u00eatre inf\u00e9rieure " + +783 "ou \u00e9gale \u00e0 la taille de la population ({1})" }, +784 { "population size must be positive ({0})", +785 "la taille de la population doit \u00eatre positive ({0})" }, +786 +787 // org.apache.commons.math.distribution.HypergeometricDistributionImpl +788 // org.apache.commons.math.random.RandomDataImpl +789 { "sample size must be positive ({0})", +790 "la taille de l''\u00e9chantillon doit \u00eatre positive ({0})" }, +791 +792 // org.apache.commons.math.distribution.HypergeometricDistributionImpl +793 // org.apache.commons.math.distribution.PascalDistributionImpl +794 { "number of successes must be non-negative ({0})", +795 "le nombre de succ\u00e8s ne doit pas \u00eatre n\u00e9gatif ({0})" }, +796 +797 // org.apache.commons.math.distribution.NormalDistributionImpl +798 // org.apache.commons.math.random.RandomDataImpl +799 { "standard deviation must be positive ({0})", +800 "l''\u00e9cart type doit \u00eatre positif ({0})" }, +801 +802 // org.apache.commons.math.distribution.PoissonDistributionImpl +803 // org.apache.commons.math.random.RandomDataImpl +804 { "the Poisson mean must be positive ({0})", +805 "la moyenne de Poisson doit \u00eatre positive ({0})" }, +806 +807 // org.apache.commons.math.distribution.WeibullDistributionImpl +808 { "shape must be positive ({0})", +809 "le facteur de forme doit \u00eatre positif ({0})" }, +810 +811 // org.apache.commons.math.distribution.WeibullDistributionImpl +812 // org.apache.commons.math.distribution.CauchyDistributionImpl +813 { "scale must be positive ({0})", +814 "l''\u00e9chelle doit \u00eatre positive ({0})" }, +815 +816 // org.apache.commons.math.distribution.ZipfDistributionImpl +817 { "invalid number of elements {0} (must be positive)", +818 "nombre d''\u00e9l\u00e9ments {0} invalide (doit \u00eatre positif)" }, +819 { "invalid exponent {0} (must be positive)", +820 "exposant {0} invalide (doit \u00eatre positif)" }, +821 +822 // org.apache.commons.math.transform.FastHadamardTransformer +823 { "{0} is not a power of 2", +824 "{0} n''est pas une puissance de 2" }, +825 +826 // org.apache.commons.math.transform.FastFourierTransformer +827 { "cannot compute 0-th root of unity, indefinite result", +828 "impossible de calculer la racine z\u00e9roi\u00e8me de l''unit\u00e9, " + +829 "r\u00e9sultat ind\u00e9fini" }, +830 { "roots of unity have not been computed yet", +831 "les racines de l''unit\u00e9 n''ont pas encore \u00e9t\u00e9 calcul\u00e9es" }, +832 { "out of range root of unity index {0} (must be in [{1};{2}])", +833 "index de racine de l''unit\u00e9 hors domaine (devrait \u00eatre dans [{1}; {2}])" }, +834 { "number of sample is not positive: {0}", +835 "le nombre d''\u00e9chantillons n''est pas positif : {0}" }, +836 { "{0} is not a power of 2, consider padding for fix", +837 "{0} n''est pas une puissance de 2, ajoutez des \u00e9l\u00e9ments pour corriger" }, +838 { "some dimensions don't match: {0} != {1}", +839 "certaines dimensions sont incoh\u00e9rentes : {0} != {1}" }, +840 +841 // org.apache.commons.math.transform.FastCosineTransformer +842 { "{0} is not a power of 2 plus one", +843 "{0} n''est pas une puissance de 2 plus un" }, +844 +845 // org.apache.commons.math.transform.FastSineTransformer +846 { "first element is not 0: {0}", +847 "le premier \u00e9l\u00e9ment n''est pas nul : {0}" }, +848 +849 // org.apache.commons.math.util.OpenIntToDoubleHashMap +850 { "map has been modified while iterating", +851 "la table d''adressage a \u00e9t\u00e9 modifi\u00e9e pendant l''it\u00e9ration" }, +852 { "iterator exhausted", +853 "it\u00e9ration achev\u00e9e" }, +854 +855 // org.apache.commons.math.MathRuntimeException +856 { "internal error, please fill a bug report at {0}", +857 "erreur interne, veuillez signaler l''erreur \u00e0 {0}" } +858 +859 }; +860 +861 /** +862 * Simple constructor. +863 */ +864 public MessagesResources_fr() { +865 } +866 +867 /** +868 * Get the non-translated/translated messages arrays from this resource bundle. +869 * @return non-translated/translated messages arrays +870 */ +871 @Override +872 public Object[][] getContents() { +873 return CONTENTS.clone(); +874 } +875 +876 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/BinaryFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/BinaryFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,183 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.analysis; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 +022 +023 +024 /** +025 * Base class for {@link BivariateRealFunction} that can be composed with other functions. +026 * +027 * @since 2.1 +028 * @version $Revision: 924453 $ $Date: 2010-03-17 16:05:20 -0400 (Wed, 17 Mar 2010) $ +029 */ +030 public abstract class BinaryFunction implements BivariateRealFunction { +031 +032 /** The + operator method wrapped as a {@link BinaryFunction}. */ +033 public static final BinaryFunction ADD = new BinaryFunction() { +034 /** {@inheritDoc} */ +035 @Override +036 public double value(double x, double y) { +037 return x + y; +038 } +039 }; +040 +041 /** The - operator method wrapped as a {@link BinaryFunction}. */ +042 public static final BinaryFunction SUBTRACT = new BinaryFunction() { +043 /** {@inheritDoc} */ +044 @Override +045 public double value(double x, double y) { +046 return x - y; +047 } +048 }; +049 +050 /** The * operator method wrapped as a {@link BinaryFunction}. */ +051 public static final BinaryFunction MULTIPLY = new BinaryFunction() { +052 /** {@inheritDoc} */ +053 @Override +054 public double value(double x, double y) { +055 return x * y; +056 } +057 }; +058 +059 /** The / operator method wrapped as a {@link BinaryFunction}. */ +060 public static final BinaryFunction DIVIDE = new BinaryFunction() { +061 /** {@inheritDoc} */ +062 @Override +063 public double value(double x, double y) { +064 return x / y; +065 } +066 }; +067 +068 /** The {@code Math.pow} method wrapped as a {@link BinaryFunction}. */ +069 public static final BinaryFunction POW = new BinaryFunction() { +070 /** {@inheritDoc} */ +071 @Override +072 public double value(double x, double y) { +073 return Math.pow(x, y); +074 } +075 }; +076 +077 /** The {@code Math.atan2} method wrapped as a {@link BinaryFunction}. */ +078 public static final BinaryFunction ATAN2 = new BinaryFunction() { +079 /** {@inheritDoc} */ +080 @Override +081 public double value(double x, double y) { +082 return Math.atan2(x, y); +083 } +084 }; +085 +086 /** {@inheritDoc} */ +087 public abstract double value(double x, double y) throws FunctionEvaluationException; +088 +089 /** Get a composable function by fixing the first argument of the instance. +090 * @param fixedX fixed value of the first argument +091 * @return a function such that {@code f.value(y) == value(fixedX, y)} +092 */ +093 public ComposableFunction fix1stArgument(final double fixedX) { +094 return new ComposableFunction() { +095 @Override +096 /** {@inheritDoc} */ +097 public double value(double x) throws FunctionEvaluationException { +098 return BinaryFunction.this.value(fixedX, x); +099 } +100 }; +101 } +102 +103 /** Get a composable function by fixing the second argument of the instance. +104 * @param fixedY fixed value of the second argument +105 * @return a function such that {@code f.value(x) == value(x, fixedY)} +106 */ +107 public ComposableFunction fix2ndArgument(final double fixedY) { +108 return new ComposableFunction() { +109 @Override +110 /** {@inheritDoc} */ +111 public double value(double x) throws FunctionEvaluationException { +112 return BinaryFunction.this.value(x, fixedY); +113 } +114 }; +115 } +116 +117 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/BivariateRealFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/BivariateRealFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,107 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.analysis; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 +022 +023 +024 /** +025 * An interface representing a bivariate real function. +026 * +027 * @since 2.1 +028 * @version $Revision: 924453 $ $Date: 2010-03-17 16:05:20 -0400 (Wed, 17 Mar 2010) $ +029 */ +030 public interface BivariateRealFunction { +031 +032 /** +033 * Compute the value for the function. +034 * @param x abscissa for which the function value should be computed +035 * @param y ordinate for which the function value should be computed +036 * @return the value +037 * @throws FunctionEvaluationException if the function evaluation fails +038 */ +039 double value(double x, double y) throws FunctionEvaluationException; +040 +041 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/ComposableFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/ComposableFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,571 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.analysis; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 +022 +023 /** +024 * Base class for {@link UnivariateRealFunction} that can be composed with other functions. +025 * +026 * @since 2.1 +027 * @version $Revision: 924453 $ $Date: 2010-03-17 16:05:20 -0400 (Wed, 17 Mar 2010) $ +028 */ +029 public abstract class ComposableFunction implements UnivariateRealFunction { +030 +031 /** The constant function always returning 0. */ +032 public static final ComposableFunction ZERO = new ComposableFunction() { +033 /** {@inheritDoc} */ +034 @Override +035 public double value(double d) { +036 return 0; +037 } +038 }; +039 +040 /** The constant function always returning 1. */ +041 public static final ComposableFunction ONE = new ComposableFunction() { +042 /** {@inheritDoc} */ +043 @Override +044 public double value(double d) { +045 return 1; +046 } +047 }; +048 +049 /** The identity function. */ +050 public static final ComposableFunction IDENTITY = new ComposableFunction() { +051 /** {@inheritDoc} */ +052 @Override +053 public double value(double d) { +054 return d; +055 } +056 }; +057 +058 /** The {@code Math.abs} method wrapped as a {@link ComposableFunction}. */ +059 public static final ComposableFunction ABS = new ComposableFunction() { +060 /** {@inheritDoc} */ +061 @Override +062 public double value(double d) { +063 return Math.abs(d); +064 } +065 }; +066 +067 /** The - operator wrapped as a {@link ComposableFunction}. */ +068 public static final ComposableFunction NEGATE = new ComposableFunction() { +069 /** {@inheritDoc} */ +070 @Override +071 public double value(double d) { +072 return -d; +073 } +074 }; +075 +076 /** The invert operator wrapped as a {@link ComposableFunction}. */ +077 public static final ComposableFunction INVERT = new ComposableFunction () { +078 /** {@inheritDoc} */ +079 @Override +080 public double value(double d){ +081 return 1/d; +082 } +083 }; +084 +085 /** The {@code Math.sin} method wrapped as a {@link ComposableFunction}. */ +086 public static final ComposableFunction SIN = new ComposableFunction() { +087 /** {@inheritDoc} */ +088 @Override +089 public double value(double d) { +090 return Math.sin(d); +091 } +092 }; +093 +094 /** The {@code Math.sqrt} method wrapped as a {@link ComposableFunction}. */ +095 public static final ComposableFunction SQRT = new ComposableFunction() { +096 /** {@inheritDoc} */ +097 @Override +098 public double value(double d) { +099 return Math.sqrt(d); +100 } +101 }; +102 +103 /** The {@code Math.sinh} method wrapped as a {@link ComposableFunction}. */ +104 public static final ComposableFunction SINH = new ComposableFunction() { +105 /** {@inheritDoc} */ +106 @Override +107 public double value(double d) { +108 return Math.sinh(d); +109 } +110 }; +111 +112 /** The {@code Math.exp} method wrapped as a {@link ComposableFunction}. */ +113 public static final ComposableFunction EXP = new ComposableFunction() { +114 /** {@inheritDoc} */ +115 @Override +116 public double value(double d) { +117 return Math.exp(d); +118 } +119 }; +120 +121 /** The {@code Math.expm1} method wrapped as a {@link ComposableFunction}. */ +122 public static final ComposableFunction EXPM1 = new ComposableFunction() { +123 /** {@inheritDoc} */ +124 @Override +125 public double value(double d) { +126 return Math.expm1(d); +127 } +128 }; +129 +130 /** The {@code Math.asin} method wrapped as a {@link ComposableFunction}. */ +131 public static final ComposableFunction ASIN = new ComposableFunction() { +132 /** {@inheritDoc} */ +133 @Override +134 public double value(double d) { +135 return Math.asin(d); +136 } +137 }; +138 +139 /** The {@code Math.atan} method wrapped as a {@link ComposableFunction}. */ +140 public static final ComposableFunction ATAN = new ComposableFunction() { +141 /** {@inheritDoc} */ +142 @Override +143 public double value(double d) { +144 return Math.atan(d); +145 } +146 }; +147 +148 /** The {@code Math.tan} method wrapped as a {@link ComposableFunction}. */ +149 public static final ComposableFunction TAN = new ComposableFunction() { +150 /** {@inheritDoc} */ +151 @Override +152 public double value(double d) { +153 return Math.tan(d); +154 } +155 }; +156 +157 /** The {@code Math.tanh} method wrapped as a {@link ComposableFunction}. */ +158 public static final ComposableFunction TANH = new ComposableFunction() { +159 /** {@inheritDoc} */ +160 @Override +161 public double value(double d) { +162 return Math.tanh(d); +163 } +164 }; +165 +166 /** The {@code Math.cbrt} method wrapped as a {@link ComposableFunction}. */ +167 public static final ComposableFunction CBRT = new ComposableFunction() { +168 /** {@inheritDoc} */ +169 @Override +170 public double value(double d) { +171 return Math.cbrt(d); +172 } +173 }; +174 +175 /** The {@code Math.ceil} method wrapped as a {@link ComposableFunction}. */ +176 public static final ComposableFunction CEIL = new ComposableFunction() { +177 /** {@inheritDoc} */ +178 @Override +179 public double value(double d) { +180 return Math.ceil(d); +181 } +182 }; +183 +184 /** The {@code Math.floor} method wrapped as a {@link ComposableFunction}. */ +185 public static final ComposableFunction FLOOR = new ComposableFunction() { +186 /** {@inheritDoc} */ +187 @Override +188 public double value(double d) { +189 return Math.floor(d); +190 } +191 }; +192 +193 /** The {@code Math.log} method wrapped as a {@link ComposableFunction}. */ +194 public static final ComposableFunction LOG = new ComposableFunction() { +195 /** {@inheritDoc} */ +196 @Override +197 public double value(double d) { +198 return Math.log(d); +199 } +200 }; +201 +202 /** The {@code Math.log10} method wrapped as a {@link ComposableFunction}. */ +203 public static final ComposableFunction LOG10 = new ComposableFunction() { +204 /** {@inheritDoc} */ +205 @Override +206 public double value(double d) { +207 return Math.log10(d); +208 } +209 }; +210 +211 /** The {@code Math.log1p} method wrapped as a {@link ComposableFunction}. */ +212 public static final ComposableFunction LOG1P = new ComposableFunction () { +213 @Override +214 public double value(double d){ +215 return Math.log1p(d); +216 } +217 }; +218 +219 /** The {@code Math.cos} method wrapped as a {@link ComposableFunction}. */ +220 public static final ComposableFunction COS = new ComposableFunction() { +221 /** {@inheritDoc} */ +222 @Override +223 public double value(double d) { +224 return Math.cos(d); +225 } +226 }; +227 +228 /** The {@code Math.abs} method wrapped as a {@link ComposableFunction}. */ +229 public static final ComposableFunction ACOS = new ComposableFunction() { +230 /** {@inheritDoc} */ +231 @Override +232 public double value(double d) { +233 return Math.acos(d); +234 } +235 }; +236 +237 /** The {@code Math.cosh} method wrapped as a {@link ComposableFunction}. */ +238 public static final ComposableFunction COSH = new ComposableFunction() { +239 /** {@inheritDoc} */ +240 @Override +241 public double value(double d) { +242 return Math.cosh(d); +243 } +244 }; +245 +246 /** The {@code Math.rint} method wrapped as a {@link ComposableFunction}. */ +247 public static final ComposableFunction RINT = new ComposableFunction() { +248 /** {@inheritDoc} */ +249 @Override +250 public double value(double d) { +251 return Math.rint(d); +252 } +253 }; +254 +255 /** The {@code Math.signum} method wrapped as a {@link ComposableFunction}. */ +256 public static final ComposableFunction SIGNUM = new ComposableFunction() { +257 /** {@inheritDoc} */ +258 @Override +259 public double value(double d) { +260 return Math.signum(d); +261 } +262 }; +263 +264 /** The {@code Math.ulp} method wrapped as a {@link ComposableFunction}. */ +265 public static final ComposableFunction ULP = new ComposableFunction() { +266 /** {@inheritDoc} */ +267 @Override +268 public double value(double d) { +269 return Math.ulp(d); +270 } +271 }; +272 +273 /** Precompose the instance with another function. +274 * <p> +275 * The composed function h created by {@code h = g.of(f)} is such +276 * that {@code h.value(x) == g.value(f.value(x))} for all x. +277 * </p> +278 * @param f function to compose with +279 * @return a new function which computes {@code this.value(f.value(x))} +280 * @see #postCompose(UnivariateRealFunction) +281 */ +282 public ComposableFunction of(final UnivariateRealFunction f) { +283 return new ComposableFunction() { +284 @Override +285 /** {@inheritDoc} */ +286 public double value(double x) throws FunctionEvaluationException { +287 return ComposableFunction.this.value(f.value(x)); +288 } +289 }; +290 } +291 +292 /** Postcompose the instance with another function. +293 * <p> +294 * The composed function h created by {@code h = g.postCompose(f)} is such +295 * that {@code h.value(x) == f.value(g.value(x))} for all x. +296 * </p> +297 * @param f function to compose with +298 * @return a new function which computes {@code f.value(this.value(x))} +299 * @see #of(UnivariateRealFunction) +300 */ +301 public ComposableFunction postCompose(final UnivariateRealFunction f) { +302 return new ComposableFunction() { +303 @Override +304 /** {@inheritDoc} */ +305 public double value(double x) throws FunctionEvaluationException { +306 return f.value(ComposableFunction.this.value(x)); +307 } +308 }; +309 } +310 +311 /** +312 * Return a function combining the instance and another function. +313 * <p> +314 * The function h created by {@code h = g.combine(f, combiner)} is such that +315 * {@code h.value(x) == combiner.value(g.value(x), f.value(x))} for all x. +316 * </p> +317 * @param f function to combine with the instance +318 * @param combiner bivariate function used for combining +319 * @return a new function which computes {@code combine.value(this.value(x), f.value(x))} +320 */ +321 public ComposableFunction combine(final UnivariateRealFunction f, +322 final BivariateRealFunction combiner) { +323 return new ComposableFunction() { +324 @Override +325 /** {@inheritDoc} */ +326 public double value(double x) throws FunctionEvaluationException { +327 return combiner.value(ComposableFunction.this.value(x), f.value(x)); +328 } +329 }; +330 } +331 +332 /** +333 * Return a function adding the instance and another function. +334 * @param f function to combine with the instance +335 * @return a new function which computes {@code this.value(x) + f.value(x)} +336 */ +337 public ComposableFunction add(final UnivariateRealFunction f) { +338 return new ComposableFunction() { +339 @Override +340 /** {@inheritDoc} */ +341 public double value(double x) throws FunctionEvaluationException { +342 return ComposableFunction.this.value(x) + f.value(x); +343 } +344 }; +345 } +346 +347 /** +348 * Return a function adding a constant term to the instance. +349 * @param a term to add +350 * @return a new function which computes {@code this.value(x) + a} +351 */ +352 public ComposableFunction add(final double a) { +353 return new ComposableFunction() { +354 @Override +355 /** {@inheritDoc} */ +356 public double value(double x) throws FunctionEvaluationException { +357 return ComposableFunction.this.value(x) + a; +358 } +359 }; +360 } +361 +362 /** +363 * Return a function subtracting another function from the instance. +364 * @param f function to combine with the instance +365 * @return a new function which computes {@code this.value(x) - f.value(x)} +366 */ +367 public ComposableFunction subtract(final UnivariateRealFunction f) { +368 return new ComposableFunction() { +369 @Override +370 /** {@inheritDoc} */ +371 public double value(double x) throws FunctionEvaluationException { +372 return ComposableFunction.this.value(x) - f.value(x); +373 } +374 }; +375 } +376 +377 /** +378 * Return a function multiplying the instance and another function. +379 * @param f function to combine with the instance +380 * @return a new function which computes {@code this.value(x) * f.value(x)} +381 */ +382 public ComposableFunction multiply(final UnivariateRealFunction f) { +383 return new ComposableFunction() { +384 @Override +385 /** {@inheritDoc} */ +386 public double value(double x) throws FunctionEvaluationException { +387 return ComposableFunction.this.value(x) * f.value(x); +388 } +389 }; +390 } +391 +392 /** +393 * Return a function scaling the instance by a constant factor. +394 * @param scaleFactor constant scaling factor +395 * @return a new function which computes {@code this.value(x) * scaleFactor} +396 */ +397 public ComposableFunction multiply(final double scaleFactor) { +398 return new ComposableFunction() { +399 @Override +400 /** {@inheritDoc} */ +401 public double value(double x) throws FunctionEvaluationException { +402 return ComposableFunction.this.value(x) * scaleFactor; +403 } +404 }; +405 } +406 /** +407 * Return a function dividing the instance by another function. +408 * @param f function to combine with the instance +409 * @return a new function which computes {@code this.value(x) / f.value(x)} +410 */ +411 public ComposableFunction divide(final UnivariateRealFunction f) { +412 return new ComposableFunction() { +413 @Override +414 /** {@inheritDoc} */ +415 public double value(double x) throws FunctionEvaluationException { +416 return ComposableFunction.this.value(x) / f.value(x); +417 } +418 }; +419 } +420 +421 /** +422 * Generates a function that iteratively apply instance function on all +423 * elements of an array. +424 * <p> +425 * The generated function behaves as follows: +426 * <ul> +427 * <li>initialize result = initialValue</li> +428 * <li>iterate: {@code result = combiner.value(result, +429 * this.value(nextMultivariateEntry));}</li> +430 * <li>return result</li> +431 * </ul> +432 * </p> +433 * @param combiner combiner to use between entries +434 * @param initialValue initial value to use before first entry +435 * @return a new function that iteratively applie instance function on all +436 * elements of an array. +437 */ +438 public MultivariateRealFunction asCollector(final BivariateRealFunction combiner, +439 final double initialValue) { +440 return new MultivariateRealFunction() { +441 /** {@inheritDoc} */ +442 public double value(double[] point) +443 throws FunctionEvaluationException, IllegalArgumentException { +444 double result = initialValue; +445 for (final double entry : point) { +446 result = combiner.value(result, ComposableFunction.this.value(entry)); +447 } +448 return result; +449 } +450 }; +451 } +452 +453 /** +454 * Generates a function that iteratively apply instance function on all +455 * elements of an array. +456 * <p> +457 * Calling this method is equivalent to call {@link +458 * #asCollector(BivariateRealFunction, double) asCollector(BivariateRealFunction, 0.0)}. +459 * </p> +460 * @param combiner combiner to use between entries +461 * @return a new function that iteratively applie instance function on all +462 * elements of an array. +463 * @see #asCollector(BivariateRealFunction, double) +464 */ +465 public MultivariateRealFunction asCollector(final BivariateRealFunction combiner) { +466 return asCollector(combiner, 0.0); +467 } +468 +469 /** +470 * Generates a function that iteratively apply instance function on all +471 * elements of an array. +472 * <p> +473 * Calling this method is equivalent to call {@link +474 * #asCollector(BivariateRealFunction, double) asCollector(BinaryFunction.ADD, initialValue)}. +475 * </p> +476 * @param initialValue initial value to use before first entry +477 * @return a new function that iteratively applie instance function on all +478 * elements of an array. +479 * @see #asCollector(BivariateRealFunction, double) +480 * @see BinaryFunction#ADD +481 */ +482 public MultivariateRealFunction asCollector(final double initialValue) { +483 return asCollector(BinaryFunction.ADD, initialValue); +484 } +485 +486 /** +487 * Generates a function that iteratively apply instance function on all +488 * elements of an array. +489 * <p> +490 * Calling this method is equivalent to call {@link +491 * #asCollector(BivariateRealFunction, double) asCollector(BinaryFunction.ADD, 0.0)}. +492 * </p> +493 * @return a new function that iteratively applie instance function on all +494 * elements of an array. +495 * @see #asCollector(BivariateRealFunction, double) +496 * @see BinaryFunction#ADD +497 */ +498 public MultivariateRealFunction asCollector() { +499 return asCollector(BinaryFunction.ADD, 0.0); +500 } +501 +502 /** {@inheritDoc} */ +503 public abstract double value(double x) throws FunctionEvaluationException; +504 +505 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/DifferentiableMultivariateRealFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/DifferentiableMultivariateRealFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,117 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.analysis; +019 +020 /** +021 * Extension of {@link MultivariateRealFunction} representing a differentiable +022 * multivariate real function. +023 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +024 * @since 2.0 +025 */ +026 public interface DifferentiableMultivariateRealFunction extends MultivariateRealFunction { +027 +028 /** +029 * Returns the partial derivative of the function with respect to a point coordinate. +030 * <p> +031 * The partial derivative is defined with respect to point coordinate +032 * x<sub>k</sub>. If the partial derivatives with respect to all coordinates are +033 * needed, it may be more efficient to use the {@link #gradient()} method which will +034 * compute them all at once. +035 * </p> +036 * @param k index of the coordinate with respect to which the partial +037 * derivative is computed +038 * @return the partial derivative function with respect to k<sup>th</sup> point coordinate +039 */ +040 MultivariateRealFunction partialDerivative(int k); +041 +042 /** +043 * Returns the gradient function. +044 * <p>If only one partial derivative with respect to a specific coordinate is +045 * needed, it may be more efficient to use the {@link #partialDerivative(int)} method +046 * which will compute only the specified component.</p> +047 * @return the gradient function +048 */ +049 MultivariateVectorialFunction gradient(); +050 +051 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/DifferentiableMultivariateVectorialFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/DifferentiableMultivariateVectorialFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,102 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.analysis; +019 +020 +021 /** +022 * Extension of {@link MultivariateVectorialFunction} representing a differentiable +023 * multivariate vectorial function. +024 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +025 * @since 2.0 +026 */ +027 public interface DifferentiableMultivariateVectorialFunction +028 extends MultivariateVectorialFunction { +029 +030 /** +031 * Returns the jacobian function. +032 * @return the jacobian function +033 */ +034 MultivariateMatrixFunction jacobian(); +035 +036 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/DifferentiableUnivariateMatrixFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/DifferentiableUnivariateMatrixFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,101 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis; +018 +019 /** +020 * Extension of {@link UnivariateMatrixFunction} representing a differentiable univariate matrix function. +021 * +022 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +023 * @since 2.0 +024 */ +025 public interface DifferentiableUnivariateMatrixFunction +026 extends UnivariateMatrixFunction { +027 +028 /** +029 * Returns the derivative of the function +030 * +031 * @return the derivative function +032 */ +033 UnivariateMatrixFunction derivative(); +034 +035 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/DifferentiableUnivariateRealFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/DifferentiableUnivariateRealFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,100 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis; +018 +019 /** +020 * Extension of {@link UnivariateRealFunction} representing a differentiable univariate real function. +021 * +022 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +023 */ +024 public interface DifferentiableUnivariateRealFunction +025 extends UnivariateRealFunction { +026 +027 /** +028 * Returns the derivative of the function +029 * +030 * @return the derivative function +031 */ +032 UnivariateRealFunction derivative(); +033 +034 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/DifferentiableUnivariateVectorialFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/DifferentiableUnivariateVectorialFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,101 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis; +018 +019 /** +020 * Extension of {@link UnivariateVectorialFunction} representing a differentiable univariate vectorial function. +021 * +022 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +023 * @since 2.0 +024 */ +025 public interface DifferentiableUnivariateVectorialFunction +026 extends UnivariateVectorialFunction { +027 +028 /** +029 * Returns the derivative of the function +030 * +031 * @return the derivative function +032 */ +033 UnivariateVectorialFunction derivative(); +034 +035 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/MultivariateMatrixFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/MultivariateMatrixFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,106 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.analysis; +019 +020 +021 import org.apache.commons.math.FunctionEvaluationException; +022 +023 /** +024 * An interface representing a multivariate matrix function. +025 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +026 * @since 2.0 +027 */ +028 public interface MultivariateMatrixFunction { +029 +030 /** +031 * Compute the value for the function at the given point. +032 * @param point point at which the function must be evaluated +033 * @return function value for the given point +034 * @exception FunctionEvaluationException if the function evaluation fails +035 * @exception IllegalArgumentException if points dimension is wrong +036 */ +037 double[][] value(double[] point) +038 throws FunctionEvaluationException, IllegalArgumentException; +039 +040 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/MultivariateRealFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/MultivariateRealFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,105 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.analysis; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 +022 /** +023 * An interface representing a multivariate real function. +024 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +025 * @since 2.0 +026 */ +027 public interface MultivariateRealFunction { +028 +029 /** +030 * Compute the value for the function at the given point. +031 * @param point point at which the function must be evaluated +032 * @return function value for the given point +033 * @exception FunctionEvaluationException if the function evaluation fails +034 * @exception IllegalArgumentException if points dimension is wrong +035 */ +036 double value(double[] point) +037 throws FunctionEvaluationException, IllegalArgumentException; +038 +039 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/MultivariateVectorialFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/MultivariateVectorialFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,105 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.analysis; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 +022 /** +023 * An interface representing a multivariate vectorial function. +024 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +025 * @since 2.0 +026 */ +027 public interface MultivariateVectorialFunction { +028 +029 /** +030 * Compute the value for the function at the given point. +031 * @param point point at which the function must be evaluated +032 * @return function value for the given point +033 * @exception FunctionEvaluationException if the function evaluation fails +034 * @exception IllegalArgumentException if points dimension is wrong +035 */ +036 double[] value(double[] point) +037 throws FunctionEvaluationException, IllegalArgumentException; +038 +039 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/UnivariateMatrixFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/UnivariateMatrixFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,103 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis; +018 +019 import org.apache.commons.math.FunctionEvaluationException; +020 +021 /** +022 * An interface representing a univariate matrix function. +023 * +024 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +025 * @since 2.0 +026 */ +027 public interface UnivariateMatrixFunction { +028 +029 /** +030 * Compute the value for the function. +031 * @param x the point for which the function value should be computed +032 * @return the value +033 * @throws FunctionEvaluationException if the function evaluation fails +034 */ +035 double[][] value(double x) throws FunctionEvaluationException; +036 +037 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/UnivariateRealFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/UnivariateRealFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,102 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis; +018 +019 import org.apache.commons.math.FunctionEvaluationException; +020 +021 /** +022 * An interface representing a univariate real function. +023 * +024 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +025 */ +026 public interface UnivariateRealFunction { +027 +028 /** +029 * Compute the value for the function. +030 * @param x the point for which the function value should be computed +031 * @return the value +032 * @throws FunctionEvaluationException if the function evaluation fails +033 */ +034 double value(double x) throws FunctionEvaluationException; +035 +036 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/UnivariateVectorialFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/UnivariateVectorialFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,103 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis; +018 +019 import org.apache.commons.math.FunctionEvaluationException; +020 +021 /** +022 * An interface representing a univariate vectorial function. +023 * +024 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +025 * @since 2.0 +026 */ +027 public interface UnivariateVectorialFunction { +028 +029 /** +030 * Compute the value for the function. +031 * @param x the point for which the function value should be computed +032 * @return the value +033 * @throws FunctionEvaluationException if the function evaluation fails +034 */ +035 double[] value(double x) throws FunctionEvaluationException; +036 +037 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/integration/LegendreGaussIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/integration/LegendreGaussIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,301 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.integration; +018 +019 import org.apache.commons.math.ConvergenceException; +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.MaxIterationsExceededException; +023 import org.apache.commons.math.analysis.UnivariateRealFunction; +024 +025 /** +026 * Implements the <a href="http://mathworld.wolfram.com/Legendre-GaussQuadrature.html"> +027 * Legendre-Gauss</a> quadrature formula. +028 * <p> +029 * Legendre-Gauss integrators are efficient integrators that can +030 * accurately integrate functions with few functions evaluations. A +031 * Legendre-Gauss integrator using an n-points quadrature formula can +032 * integrate exactly 2n-1 degree polynomialss. +033 * </p> +034 * <p> +035 * These integrators evaluate the function on n carefully chosen +036 * abscissas in each step interval (mapped to the canonical [-1 1] interval). +037 * The evaluation abscissas are not evenly spaced and none of them are +038 * at the interval endpoints. This implies the function integrated can be +039 * undefined at integration interval endpoints. +040 * </p> +041 * <p> +042 * The evaluation abscissas x<sub>i</sub> are the roots of the degree n +043 * Legendre polynomial. The weights a<sub>i</sub> of the quadrature formula +044 * integrals from -1 to +1 ∫ Li<sup>2</sup> where Li (x) = +045 * ∏ (x-x<sub>k</sub>)/(x<sub>i</sub>-x<sub>k</sub>) for k != i. +046 * </p> +047 * <p> +048 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +049 * @since 1.2 +050 */ +051 +052 public class LegendreGaussIntegrator extends UnivariateRealIntegratorImpl { +053 +054 /** Abscissas for the 2 points method. */ +055 private static final double[] ABSCISSAS_2 = { +056 -1.0 / Math.sqrt(3.0), +057 1.0 / Math.sqrt(3.0) +058 }; +059 +060 /** Weights for the 2 points method. */ +061 private static final double[] WEIGHTS_2 = { +062 1.0, +063 1.0 +064 }; +065 +066 /** Abscissas for the 3 points method. */ +067 private static final double[] ABSCISSAS_3 = { +068 -Math.sqrt(0.6), +069 0.0, +070 Math.sqrt(0.6) +071 }; +072 +073 /** Weights for the 3 points method. */ +074 private static final double[] WEIGHTS_3 = { +075 5.0 / 9.0, +076 8.0 / 9.0, +077 5.0 / 9.0 +078 }; +079 +080 /** Abscissas for the 4 points method. */ +081 private static final double[] ABSCISSAS_4 = { +082 -Math.sqrt((15.0 + 2.0 * Math.sqrt(30.0)) / 35.0), +083 -Math.sqrt((15.0 - 2.0 * Math.sqrt(30.0)) / 35.0), +084 Math.sqrt((15.0 - 2.0 * Math.sqrt(30.0)) / 35.0), +085 Math.sqrt((15.0 + 2.0 * Math.sqrt(30.0)) / 35.0) +086 }; +087 +088 /** Weights for the 4 points method. */ +089 private static final double[] WEIGHTS_4 = { +090 (90.0 - 5.0 * Math.sqrt(30.0)) / 180.0, +091 (90.0 + 5.0 * Math.sqrt(30.0)) / 180.0, +092 (90.0 + 5.0 * Math.sqrt(30.0)) / 180.0, +093 (90.0 - 5.0 * Math.sqrt(30.0)) / 180.0 +094 }; +095 +096 /** Abscissas for the 5 points method. */ +097 private static final double[] ABSCISSAS_5 = { +098 -Math.sqrt((35.0 + 2.0 * Math.sqrt(70.0)) / 63.0), +099 -Math.sqrt((35.0 - 2.0 * Math.sqrt(70.0)) / 63.0), +100 0.0, +101 Math.sqrt((35.0 - 2.0 * Math.sqrt(70.0)) / 63.0), +102 Math.sqrt((35.0 + 2.0 * Math.sqrt(70.0)) / 63.0) +103 }; +104 +105 /** Weights for the 5 points method. */ +106 private static final double[] WEIGHTS_5 = { +107 (322.0 - 13.0 * Math.sqrt(70.0)) / 900.0, +108 (322.0 + 13.0 * Math.sqrt(70.0)) / 900.0, +109 128.0 / 225.0, +110 (322.0 + 13.0 * Math.sqrt(70.0)) / 900.0, +111 (322.0 - 13.0 * Math.sqrt(70.0)) / 900.0 +112 }; +113 +114 /** Abscissas for the current method. */ +115 private final double[] abscissas; +116 +117 /** Weights for the current method. */ +118 private final double[] weights; +119 +120 /** Build a Legendre-Gauss integrator. +121 * @param n number of points desired (must be between 2 and 5 inclusive) +122 * @param defaultMaximalIterationCount maximum number of iterations +123 * @exception IllegalArgumentException if the number of points is not +124 * in the supported range +125 */ +126 public LegendreGaussIntegrator(final int n, final int defaultMaximalIterationCount) +127 throws IllegalArgumentException { +128 super(defaultMaximalIterationCount); +129 switch(n) { +130 case 2 : +131 abscissas = ABSCISSAS_2; +132 weights = WEIGHTS_2; +133 break; +134 case 3 : +135 abscissas = ABSCISSAS_3; +136 weights = WEIGHTS_3; +137 break; +138 case 4 : +139 abscissas = ABSCISSAS_4; +140 weights = WEIGHTS_4; +141 break; +142 case 5 : +143 abscissas = ABSCISSAS_5; +144 weights = WEIGHTS_5; +145 break; +146 default : +147 throw MathRuntimeException.createIllegalArgumentException( +148 "{0} points Legendre-Gauss integrator not supported, " + +149 "number of points must be in the {1}-{2} range", +150 n, 2, 5); +151 } +152 +153 } +154 +155 /** {@inheritDoc} */ +156 @Deprecated +157 public double integrate(final double min, final double max) +158 throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException { +159 return integrate(f, min, max); +160 } +161 +162 /** {@inheritDoc} */ +163 public double integrate(final UnivariateRealFunction f, +164 final double min, final double max) +165 throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException { +166 +167 clearResult(); +168 verifyInterval(min, max); +169 verifyIterationCount(); +170 +171 // compute first estimate with a single step +172 double oldt = stage(f, min, max, 1); +173 +174 int n = 2; +175 for (int i = 0; i < maximalIterationCount; ++i) { +176 +177 // improve integral with a larger number of steps +178 final double t = stage(f, min, max, n); +179 +180 // estimate error +181 final double delta = Math.abs(t - oldt); +182 final double limit = +183 Math.max(absoluteAccuracy, +184 relativeAccuracy * (Math.abs(oldt) + Math.abs(t)) * 0.5); +185 +186 // check convergence +187 if ((i + 1 >= minimalIterationCount) && (delta <= limit)) { +188 setResult(t, i); +189 return result; +190 } +191 +192 // prepare next iteration +193 double ratio = Math.min(4, Math.pow(delta / limit, 0.5 / abscissas.length)); +194 n = Math.max((int) (ratio * n), n + 1); +195 oldt = t; +196 +197 } +198 +199 throw new MaxIterationsExceededException(maximalIterationCount); +200 +201 } +202 +203 /** +204 * Compute the n-th stage integral. +205 * @param f the integrand function +206 * @param min the lower bound for the interval +207 * @param max the upper bound for the interval +208 * @param n number of steps +209 * @return the value of n-th stage integral +210 * @throws FunctionEvaluationException if an error occurs evaluating the +211 * function +212 */ +213 private double stage(final UnivariateRealFunction f, +214 final double min, final double max, final int n) +215 throws FunctionEvaluationException { +216 +217 // set up the step for the current stage +218 final double step = (max - min) / n; +219 final double halfStep = step / 2.0; +220 +221 // integrate over all elementary steps +222 double midPoint = min + halfStep; +223 double sum = 0.0; +224 for (int i = 0; i < n; ++i) { +225 for (int j = 0; j < abscissas.length; ++j) { +226 sum += weights[j] * f.value(midPoint + halfStep * abscissas[j]); +227 } +228 midPoint += step; +229 } +230 +231 return halfStep * sum; +232 +233 } +234 +235 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/integration/RombergIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/integration/RombergIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,186 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.integration; +018 +019 import org.apache.commons.math.FunctionEvaluationException; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.MaxIterationsExceededException; +022 import org.apache.commons.math.analysis.UnivariateRealFunction; +023 +024 /** +025 * Implements the <a href="http://mathworld.wolfram.com/RombergIntegration.html"> +026 * Romberg Algorithm</a> for integration of real univariate functions. For +027 * reference, see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X, +028 * chapter 3. +029 * <p> +030 * Romberg integration employs k successive refinements of the trapezoid +031 * rule to remove error terms less than order O(N^(-2k)). Simpson's rule +032 * is a special case of k = 2.</p> +033 * +034 * @version $Revision: 824822 $ $Date: 2009-10-13 11:56:51 -0400 (Tue, 13 Oct 2009) $ +035 * @since 1.2 +036 */ +037 public class RombergIntegrator extends UnivariateRealIntegratorImpl { +038 +039 /** +040 * Construct an integrator for the given function. +041 * +042 * @param f function to integrate +043 * @deprecated as of 2.0 the integrand function is passed as an argument +044 * to the {@link #integrate(UnivariateRealFunction, double, double)}method. +045 */ +046 @Deprecated +047 public RombergIntegrator(UnivariateRealFunction f) { +048 super(f, 32); +049 } +050 +051 /** +052 * Construct an integrator. +053 */ +054 public RombergIntegrator() { +055 super(32); +056 } +057 +058 /** {@inheritDoc} */ +059 @Deprecated +060 public double integrate(final double min, final double max) +061 throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException { +062 return integrate(f, min, max); +063 } +064 +065 /** {@inheritDoc} */ +066 public double integrate(final UnivariateRealFunction f, +067 final double min, final double max) +068 throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException { +069 +070 final int m = maximalIterationCount + 1; +071 double previousRow[] = new double[m]; +072 double currentRow[] = new double[m]; +073 +074 clearResult(); +075 verifyInterval(min, max); +076 verifyIterationCount(); +077 +078 TrapezoidIntegrator qtrap = new TrapezoidIntegrator(); +079 currentRow[0] = qtrap.stage(f, min, max, 0); +080 double olds = currentRow[0]; +081 for (int i = 1; i <= maximalIterationCount; ++i) { +082 +083 // switch rows +084 final double[] tmpRow = previousRow; +085 previousRow = currentRow; +086 currentRow = tmpRow; +087 +088 currentRow[0] = qtrap.stage(f, min, max, i); +089 for (int j = 1; j <= i; j++) { +090 // Richardson extrapolation coefficient +091 final double r = (1L << (2 * j)) - 1; +092 final double tIJm1 = currentRow[j - 1]; +093 currentRow[j] = tIJm1 + (tIJm1 - previousRow[j - 1]) / r; +094 } +095 final double s = currentRow[i]; +096 if (i >= minimalIterationCount) { +097 final double delta = Math.abs(s - olds); +098 final double rLimit = relativeAccuracy * (Math.abs(olds) + Math.abs(s)) * 0.5; +099 if ((delta <= rLimit) || (delta <= absoluteAccuracy)) { +100 setResult(s, i); +101 return result; +102 } +103 } +104 olds = s; +105 } +106 throw new MaxIterationsExceededException(maximalIterationCount); +107 } +108 +109 /** {@inheritDoc} */ +110 @Override +111 protected void verifyIterationCount() throws IllegalArgumentException { +112 super.verifyIterationCount(); +113 // at most 32 bisection refinements due to higher order divider +114 if (maximalIterationCount > 32) { +115 throw MathRuntimeException.createIllegalArgumentException( +116 "invalid iteration limits: min={0}, max={1}", +117 0, 32); +118 } +119 } +120 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/integration/SimpsonIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/integration/SimpsonIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,177 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.integration; +018 +019 import org.apache.commons.math.FunctionEvaluationException; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.MaxIterationsExceededException; +022 import org.apache.commons.math.analysis.UnivariateRealFunction; +023 +024 /** +025 * Implements the <a href="http://mathworld.wolfram.com/SimpsonsRule.html"> +026 * Simpson's Rule</a> for integration of real univariate functions. For +027 * reference, see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X, +028 * chapter 3. +029 * <p> +030 * This implementation employs basic trapezoid rule as building blocks to +031 * calculate the Simpson's rule of alternating 2/3 and 4/3.</p> +032 * +033 * @version $Revision: 825919 $ $Date: 2009-10-16 10:51:55 -0400 (Fri, 16 Oct 2009) $ +034 * @since 1.2 +035 */ +036 public class SimpsonIntegrator extends UnivariateRealIntegratorImpl { +037 +038 /** +039 * Construct an integrator for the given function. +040 * +041 * @param f function to integrate +042 * @deprecated as of 2.0 the integrand function is passed as an argument +043 * to the {@link #integrate(UnivariateRealFunction, double, double)}method. +044 */ +045 @Deprecated +046 public SimpsonIntegrator(UnivariateRealFunction f) { +047 super(f, 64); +048 } +049 +050 /** +051 * Construct an integrator. +052 */ +053 public SimpsonIntegrator() { +054 super(64); +055 } +056 +057 /** {@inheritDoc} */ +058 @Deprecated +059 public double integrate(final double min, final double max) +060 throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException { +061 return integrate(f, min, max); +062 } +063 +064 /** {@inheritDoc} */ +065 public double integrate(final UnivariateRealFunction f, +066 final double min, final double max) +067 throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException { +068 +069 clearResult(); +070 verifyInterval(min, max); +071 verifyIterationCount(); +072 +073 TrapezoidIntegrator qtrap = new TrapezoidIntegrator(); +074 if (minimalIterationCount == 1) { +075 final double s = (4 * qtrap.stage(f, min, max, 1) - qtrap.stage(f, min, max, 0)) / 3.0; +076 setResult(s, 1); +077 return result; +078 } +079 // Simpson's rule requires at least two trapezoid stages. +080 double olds = 0; +081 double oldt = qtrap.stage(f, min, max, 0); +082 for (int i = 1; i <= maximalIterationCount; ++i) { +083 final double t = qtrap.stage(f, min, max, i); +084 final double s = (4 * t - oldt) / 3.0; +085 if (i >= minimalIterationCount) { +086 final double delta = Math.abs(s - olds); +087 final double rLimit = +088 relativeAccuracy * (Math.abs(olds) + Math.abs(s)) * 0.5; +089 if ((delta <= rLimit) || (delta <= absoluteAccuracy)) { +090 setResult(s, i); +091 return result; +092 } +093 } +094 olds = s; +095 oldt = t; +096 } +097 throw new MaxIterationsExceededException(maximalIterationCount); +098 } +099 +100 /** {@inheritDoc} */ +101 @Override +102 protected void verifyIterationCount() throws IllegalArgumentException { +103 super.verifyIterationCount(); +104 // at most 64 bisection refinements +105 if (maximalIterationCount > 64) { +106 throw MathRuntimeException.createIllegalArgumentException( +107 "invalid iteration limits: min={0}, max={1}", +108 0, 64); +109 } +110 } +111 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,208 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.integration; +018 +019 import org.apache.commons.math.FunctionEvaluationException; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.MaxIterationsExceededException; +022 import org.apache.commons.math.analysis.UnivariateRealFunction; +023 +024 /** +025 * Implements the <a href="http://mathworld.wolfram.com/TrapezoidalRule.html"> +026 * Trapezoidal Rule</a> for integration of real univariate functions. For +027 * reference, see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X, +028 * chapter 3. +029 * <p> +030 * The function should be integrable.</p> +031 * +032 * @version $Revision: 825919 $ $Date: 2009-10-16 10:51:55 -0400 (Fri, 16 Oct 2009) $ +033 * @since 1.2 +034 */ +035 public class TrapezoidIntegrator extends UnivariateRealIntegratorImpl { +036 +037 /** Intermediate result. */ +038 private double s; +039 +040 /** +041 * Construct an integrator for the given function. +042 * +043 * @param f function to integrate +044 * @deprecated as of 2.0 the integrand function is passed as an argument +045 * to the {@link #integrate(UnivariateRealFunction, double, double)}method. +046 */ +047 @Deprecated +048 public TrapezoidIntegrator(UnivariateRealFunction f) { +049 super(f, 64); +050 } +051 +052 /** +053 * Construct an integrator. +054 */ +055 public TrapezoidIntegrator() { +056 super(64); +057 } +058 +059 /** +060 * Compute the n-th stage integral of trapezoid rule. This function +061 * should only be called by API <code>integrate()</code> in the package. +062 * To save time it does not verify arguments - caller does. +063 * <p> +064 * The interval is divided equally into 2^n sections rather than an +065 * arbitrary m sections because this configuration can best utilize the +066 * alrealy computed values.</p> +067 * +068 * @param f the integrand function +069 * @param min the lower bound for the interval +070 * @param max the upper bound for the interval +071 * @param n the stage of 1/2 refinement, n = 0 is no refinement +072 * @return the value of n-th stage integral +073 * @throws FunctionEvaluationException if an error occurs evaluating the +074 * function +075 */ +076 double stage(final UnivariateRealFunction f, +077 final double min, final double max, final int n) +078 throws FunctionEvaluationException { +079 +080 if (n == 0) { +081 s = 0.5 * (max - min) * (f.value(min) + f.value(max)); +082 return s; +083 } else { +084 final long np = 1L << (n-1); // number of new points in this stage +085 double sum = 0; +086 final double spacing = (max - min) / np; // spacing between adjacent new points +087 double x = min + 0.5 * spacing; // the first new point +088 for (long i = 0; i < np; i++) { +089 sum += f.value(x); +090 x += spacing; +091 } +092 // add the new sum to previously calculated result +093 s = 0.5 * (s + sum * spacing); +094 return s; +095 } +096 } +097 +098 /** {@inheritDoc} */ +099 @Deprecated +100 public double integrate(final double min, final double max) +101 throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException { +102 return integrate(f, min, max); +103 } +104 +105 /** {@inheritDoc} */ +106 public double integrate(final UnivariateRealFunction f, +107 final double min, final double max) +108 throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException { +109 +110 clearResult(); +111 verifyInterval(min, max); +112 verifyIterationCount(); +113 +114 double oldt = stage(f, min, max, 0); +115 for (int i = 1; i <= maximalIterationCount; ++i) { +116 final double t = stage(f, min, max, i); +117 if (i >= minimalIterationCount) { +118 final double delta = Math.abs(t - oldt); +119 final double rLimit = +120 relativeAccuracy * (Math.abs(oldt) + Math.abs(t)) * 0.5; +121 if ((delta <= rLimit) || (delta <= absoluteAccuracy)) { +122 setResult(t, i); +123 return result; +124 } +125 } +126 oldt = t; +127 } +128 throw new MaxIterationsExceededException(maximalIterationCount); +129 } +130 +131 /** {@inheritDoc} */ +132 @Override +133 protected void verifyIterationCount() throws IllegalArgumentException { +134 super.verifyIterationCount(); +135 // at most 64 bisection refinements +136 if (maximalIterationCount > 64) { +137 throw MathRuntimeException.createIllegalArgumentException( +138 "invalid iteration limits: min={0}, max={1}", +139 0, 64); +140 } +141 } +142 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/integration/UnivariateRealIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/integration/UnivariateRealIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,173 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.integration; +018 +019 import org.apache.commons.math.ConvergenceException; +020 import org.apache.commons.math.ConvergingAlgorithm; +021 import org.apache.commons.math.FunctionEvaluationException; +022 import org.apache.commons.math.analysis.UnivariateRealFunction; +023 +024 /** +025 * Interface for univariate real integration algorithms. +026 * +027 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +028 * @since 1.2 +029 */ +030 public interface UnivariateRealIntegrator extends ConvergingAlgorithm { +031 +032 /** +033 * Set the lower limit for the number of iterations. +034 * <p> +035 * Minimal iteration is needed to avoid false early convergence, e.g. +036 * the sample points happen to be zeroes of the function. Users can +037 * use the default value or choose one that they see as appropriate.</p> +038 * <p> +039 * A <code>ConvergenceException</code> will be thrown if this number +040 * is not met.</p> +041 * +042 * @param count minimum number of iterations +043 */ +044 void setMinimalIterationCount(int count); +045 +046 /** +047 * Get the lower limit for the number of iterations. +048 * +049 * @return the actual lower limit +050 */ +051 int getMinimalIterationCount(); +052 +053 /** +054 * Reset the lower limit for the number of iterations to the default. +055 * <p> +056 * The default value is supplied by the implementation.</p> +057 * +058 * @see #setMinimalIterationCount(int) +059 */ +060 void resetMinimalIterationCount(); +061 +062 /** +063 * Integrate the function in the given interval. +064 * +065 * @param min the lower bound for the interval +066 * @param max the upper bound for the interval +067 * @return the value of integral +068 * @throws ConvergenceException if the maximum iteration count is exceeded +069 * or the integrator detects convergence problems otherwise +070 * @throws FunctionEvaluationException if an error occurs evaluating the +071 * function +072 * @throws IllegalArgumentException if min > max or the endpoints do not +073 * satisfy the requirements specified by the integrator +074 * @deprecated replaced by {@link #integrate(UnivariateRealFunction, double, double)} +075 * since 2.0 +076 */ +077 @Deprecated +078 double integrate(double min, double max) throws ConvergenceException, +079 FunctionEvaluationException, IllegalArgumentException; +080 +081 /** +082 * Integrate the function in the given interval. +083 * +084 * @param f the integrand function +085 * @param min the lower bound for the interval +086 * @param max the upper bound for the interval +087 * @return the value of integral +088 * @throws ConvergenceException if the maximum iteration count is exceeded +089 * or the integrator detects convergence problems otherwise +090 * @throws FunctionEvaluationException if an error occurs evaluating the +091 * function +092 * @throws IllegalArgumentException if min > max or the endpoints do not +093 * satisfy the requirements specified by the integrator +094 */ +095 double integrate(UnivariateRealFunction f, double min, double max) throws ConvergenceException, +096 FunctionEvaluationException, IllegalArgumentException; +097 +098 /** +099 * Get the result of the last run of the integrator. +100 * +101 * @return the last result +102 * @throws IllegalStateException if there is no result available, either +103 * because no result was yet computed or the last attempt failed +104 */ +105 double getResult() throws IllegalStateException; +106 +107 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,244 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.integration; +018 +019 import org.apache.commons.math.ConvergingAlgorithmImpl; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.analysis.UnivariateRealFunction; +022 +023 /** +024 * Provide a default implementation for several generic functions. +025 * +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 * @since 1.2 +028 */ +029 public abstract class UnivariateRealIntegratorImpl +030 extends ConvergingAlgorithmImpl implements UnivariateRealIntegrator { +031 +032 /** Serializable version identifier. */ +033 private static final long serialVersionUID = 6248808456637441533L; +034 +035 /** minimum number of iterations */ +036 protected int minimalIterationCount; +037 +038 /** default minimum number of iterations */ +039 protected int defaultMinimalIterationCount; +040 +041 /** indicates whether an integral has been computed */ +042 protected boolean resultComputed = false; +043 +044 /** the last computed integral */ +045 protected double result; +046 +047 /** The integrand functione. +048 * @deprecated as of 2.0 the integrand function is passed as an argument +049 * to the {@link #integrate(UnivariateRealFunction, double, double)}method. */ +050 @Deprecated +051 protected UnivariateRealFunction f; +052 +053 /** +054 * Construct an integrator with given iteration count and accuracy. +055 * +056 * @param f the integrand function +057 * @param defaultMaximalIterationCount maximum number of iterations +058 * @throws IllegalArgumentException if f is null or the iteration +059 * limits are not valid +060 * @deprecated as of 2.0 the integrand function is passed as an argument +061 * to the {@link #integrate(UnivariateRealFunction, double, double)}method. +062 */ +063 @Deprecated +064 protected UnivariateRealIntegratorImpl(final UnivariateRealFunction f, +065 final int defaultMaximalIterationCount) +066 throws IllegalArgumentException { +067 super(defaultMaximalIterationCount, 1.0e-15); +068 if (f == null) { +069 throw MathRuntimeException.createIllegalArgumentException("function is null"); +070 } +071 +072 this.f = f; +073 +074 // parameters that are problem specific +075 setRelativeAccuracy(1.0e-6); +076 this.defaultMinimalIterationCount = 3; +077 this.minimalIterationCount = defaultMinimalIterationCount; +078 +079 verifyIterationCount(); +080 } +081 +082 /** +083 * Construct an integrator with given iteration count and accuracy. +084 * +085 * @param defaultMaximalIterationCount maximum number of iterations +086 * @throws IllegalArgumentException if f is null or the iteration +087 * limits are not valid +088 */ +089 protected UnivariateRealIntegratorImpl(final int defaultMaximalIterationCount) +090 throws IllegalArgumentException { +091 super(defaultMaximalIterationCount, 1.0e-15); +092 +093 // parameters that are problem specific +094 setRelativeAccuracy(1.0e-6); +095 this.defaultMinimalIterationCount = 3; +096 this.minimalIterationCount = defaultMinimalIterationCount; +097 +098 verifyIterationCount(); +099 } +100 +101 /** +102 * Access the last computed integral. +103 * +104 * @return the last computed integral +105 * @throws IllegalStateException if no integral has been computed +106 */ +107 public double getResult() throws IllegalStateException { +108 if (resultComputed) { +109 return result; +110 } else { +111 throw MathRuntimeException.createIllegalStateException("no result available"); +112 } +113 } +114 +115 /** +116 * Convenience function for implementations. +117 * +118 * @param newResult the result to set +119 * @param iterationCount the iteration count to set +120 */ +121 protected final void setResult(double newResult, int iterationCount) { +122 this.result = newResult; +123 this.iterationCount = iterationCount; +124 this.resultComputed = true; +125 } +126 +127 /** +128 * Convenience function for implementations. +129 */ +130 protected final void clearResult() { +131 this.iterationCount = 0; +132 this.resultComputed = false; +133 } +134 +135 /** {@inheritDoc} */ +136 public void setMinimalIterationCount(int count) { +137 minimalIterationCount = count; +138 } +139 +140 /** {@inheritDoc} */ +141 public int getMinimalIterationCount() { +142 return minimalIterationCount; +143 } +144 +145 /** {@inheritDoc} */ +146 public void resetMinimalIterationCount() { +147 minimalIterationCount = defaultMinimalIterationCount; +148 } +149 +150 /** +151 * Verifies that the endpoints specify an interval. +152 * +153 * @param lower lower endpoint +154 * @param upper upper endpoint +155 * @throws IllegalArgumentException if not interval +156 */ +157 protected void verifyInterval(double lower, double upper) throws +158 IllegalArgumentException { +159 if (lower >= upper) { +160 throw MathRuntimeException.createIllegalArgumentException( +161 "endpoints do not specify an interval: [{0}, {1}]", +162 lower, upper); +163 } +164 } +165 +166 /** +167 * Verifies that the upper and lower limits of iterations are valid. +168 * +169 * @throws IllegalArgumentException if not valid +170 */ +171 protected void verifyIterationCount() throws IllegalArgumentException { +172 if ((minimalIterationCount <= 0) || (maximalIterationCount <= minimalIterationCount)) { +173 throw MathRuntimeException.createIllegalArgumentException( +174 "invalid iteration limits: min={0}, max={1}", +175 minimalIterationCount, maximalIterationCount); +176 } +177 } +178 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,356 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.interpolation; +018 +019 import org.apache.commons.math.util.MathUtils; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.DimensionMismatchException; +022 import org.apache.commons.math.analysis.BivariateRealFunction; +023 +024 /** +025 * Function that implements the +026 * <a href="http://en.wikipedia.org/wiki/Bicubic_interpolation"> +027 * bicubic spline interpolation</a>. +028 * +029 * @version $Revision$ $Date$ +030 * @since 2.1 +031 */ +032 public class BicubicSplineInterpolatingFunction +033 implements BivariateRealFunction { +034 /** +035 * Matrix to compute the spline coefficients from the function values +036 * and function derivatives values +037 */ +038 private static final double[][] AINV = { +039 { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, +040 { 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 }, +041 { -3,3,0,0,-2,-1,0,0,0,0,0,0,0,0,0,0 }, +042 { 2,-2,0,0,1,1,0,0,0,0,0,0,0,0,0,0 }, +043 { 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 }, +044 { 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0 }, +045 { 0,0,0,0,0,0,0,0,-3,3,0,0,-2,-1,0,0 }, +046 { 0,0,0,0,0,0,0,0,2,-2,0,0,1,1,0,0 }, +047 { -3,0,3,0,0,0,0,0,-2,0,-1,0,0,0,0,0 }, +048 { 0,0,0,0,-3,0,3,0,0,0,0,0,-2,0,-1,0 }, +049 { 9,-9,-9,9,6,3,-6,-3,6,-6,3,-3,4,2,2,1 }, +050 { -6,6,6,-6,-3,-3,3,3,-4,4,-2,2,-2,-2,-1,-1 }, +051 { 2,0,-2,0,0,0,0,0,1,0,1,0,0,0,0,0 }, +052 { 0,0,0,0,2,0,-2,0,0,0,0,0,1,0,1,0 }, +053 { -6,6,6,-6,-4,-2,4,2,-3,3,-3,3,-2,-1,-2,-1 }, +054 { 4,-4,-4,4,2,2,-2,-2,2,-2,2,-2,1,1,1,1 } +055 }; +056 +057 /** Samples x-coordinates */ +058 private final double[] xval; +059 /** Samples y-coordinates */ +060 private final double[] yval; +061 /** Set of cubic splines pacthing the whole data grid */ +062 private final BicubicSplineFunction[][] splines; +063 +064 /** +065 * @param x Sample values of the x-coordinate, in increasing order +066 * @param y Sample values of the y-coordinate, in increasing order +067 * @param z Values of the function on every grid point +068 * @param dZdX Values of the partial derivative of function with respect +069 * to x on every grid point +070 * @param dZdY Values of the partial derivative of function with respect +071 * to y on every grid point +072 * @param dZdXdY Values of the cross partial derivative of function on +073 * every grid point +074 * @throws DimensionMismatchException if the various arrays do not contain +075 * the expected number of elements. +076 * @throws IllegalArgumentException if {@code x} or {@code y} are not strictly +077 * increasing. +078 */ +079 public BicubicSplineInterpolatingFunction(double[] x, +080 double[] y, +081 double[][] z, +082 double[][] dZdX, +083 double[][] dZdY, +084 double[][] dZdXdY) +085 throws DimensionMismatchException { +086 final int xLen = x.length; +087 final int yLen = y.length; +088 +089 if (xLen == 0 || yLen == 0 || z.length == 0 || z[0].length == 0) { +090 throw MathRuntimeException.createIllegalArgumentException("no data"); +091 } +092 if (xLen != z.length) { +093 throw new DimensionMismatchException(xLen, z.length); +094 } +095 if (xLen != dZdX.length) { +096 throw new DimensionMismatchException(xLen, dZdX.length); +097 } +098 if (xLen != dZdY.length) { +099 throw new DimensionMismatchException(xLen, dZdY.length); +100 } +101 if (xLen != dZdXdY.length) { +102 throw new DimensionMismatchException(xLen, dZdXdY.length); +103 } +104 +105 MathUtils.checkOrder(x, 1, true); +106 MathUtils.checkOrder(y, 1, true); +107 +108 xval = x.clone(); +109 yval = y.clone(); +110 +111 final int lastI = xLen - 1; +112 final int lastJ = yLen - 1; +113 splines = new BicubicSplineFunction[lastI][lastJ]; +114 +115 for (int i = 0; i < lastI; i++) { +116 if (z[i].length != yLen) { +117 throw new DimensionMismatchException(z[i].length, yLen); +118 } +119 if (dZdX[i].length != yLen) { +120 throw new DimensionMismatchException(dZdX[i].length, yLen); +121 } +122 if (dZdY[i].length != yLen) { +123 throw new DimensionMismatchException(dZdY[i].length, yLen); +124 } +125 if (dZdXdY[i].length != yLen) { +126 throw new DimensionMismatchException(dZdXdY[i].length, yLen); +127 } +128 final int ip1 = i + 1; +129 for (int j = 0; j < lastJ; j++) { +130 final int jp1 = j + 1; +131 final double[] beta = new double[] { +132 z[i][j], z[ip1][j], z[i][jp1], z[ip1][jp1], +133 dZdX[i][j], dZdX[ip1][j], dZdX[i][jp1], dZdX[ip1][jp1], +134 dZdY[i][j], dZdY[ip1][j], dZdY[i][jp1], dZdY[ip1][jp1], +135 dZdXdY[i][j], dZdXdY[ip1][j], dZdXdY[i][jp1], dZdXdY[ip1][jp1] +136 }; +137 +138 splines[i][j] = new BicubicSplineFunction(computeSplineCoefficients(beta)); +139 } +140 } +141 } +142 +143 /** +144 * {@inheritDoc} +145 */ +146 public double value(double x, double y) { +147 final int i = searchIndex(x, xval); +148 if (i == -1) { +149 throw MathRuntimeException.createIllegalArgumentException("{0} out of [{1}, {2}] range", +150 x, xval[0], xval[xval.length - 1]); +151 } +152 final int j = searchIndex(y, yval); +153 if (j == -1) { +154 throw MathRuntimeException.createIllegalArgumentException("{0} out of [{1}, {2}] range", +155 y, yval[0], yval[yval.length - 1]); +156 } +157 +158 final double xN = (x - xval[i]) / (xval[i + 1] - xval[i]); +159 final double yN = (y - yval[j]) / (yval[j + 1] - yval[j]); +160 +161 return splines[i][j].value(xN, yN); +162 } +163 +164 /** +165 * @param c coordinate +166 * @param val coordinate samples +167 * @return the index in {@code val} corresponding to the interval +168 * containing {@code c}, or {@code -1} if {@code c} is out of the +169 * range defined by the end values of {@code val} +170 */ +171 private int searchIndex(double c, double[] val) { +172 if (c < val[0]) { +173 return -1; +174 } +175 +176 int max = val.length; +177 for (int i = 1; i < max; i++) { +178 if (c <= val[i]) { +179 return i - 1; +180 } +181 } +182 +183 return -1; +184 } +185 +186 /** +187 * Compute the spline coefficients from the list of function values and +188 * function partial derivatives values at the four corners of a grid +189 * element. They must be specified in the following order: +190 * <ul> +191 * <li>f(0,0)</li> +192 * <li>f(1,0)</li> +193 * <li>f(0,1)</li> +194 * <li>f(1,1)</li> +195 * <li>fx(0,0)</li> +196 * <li>fx(1,0)</li> +197 * <li>fx(0,1)</li> +198 * <li>fx(1,1)</li> +199 * <li>fy(0,0)</li> +200 * <li>fy(1,0)</li> +201 * <li>fy(0,1)</li> +202 * <li>fy(1,1)</li> +203 * <li>fxy(0,0)</li> +204 * <li>fxy(1,0)</li> +205 * <li>fxy(0,1)</li> +206 * <li>fxy(1,1)</li> +207 * </ul> +208 * @param beta List of function values and function partial derivatives +209 * values +210 * @return the spline coefficients +211 */ +212 private double[] computeSplineCoefficients(double[] beta) { +213 final double[] a = new double[16]; +214 +215 for (int i = 0; i < 16; i++) { +216 double result = 0; +217 final double[] row = AINV[i]; +218 for (int j = 0; j < 16; j++) { +219 result += row[j] * beta[j]; +220 } +221 a[i] = result; +222 } +223 +224 return a; +225 } +226 } +227 /** +228 * 2D-spline function. +229 * +230 * @version $Revision$ $Date$ +231 */ +232 class BicubicSplineFunction +233 implements BivariateRealFunction { +234 //CHECKSTYLE: stop MultipleVariableDeclarations +235 /** Coefficients */ +236 private final double +237 a00, a01, a02, a03, +238 a10, a11, a12, a13, +239 a20, a21, a22, a23, +240 a30, a31, a32, a33; +241 //CHECKSTYLE: resume MultipleVariableDeclarations +242 +243 /** +244 * @param a Spline coefficients +245 */ +246 public BicubicSplineFunction(double[] a) { +247 this.a00 = a[0]; +248 this.a10 = a[1]; +249 this.a20 = a[2]; +250 this.a30 = a[3]; +251 this.a01 = a[4]; +252 this.a11 = a[5]; +253 this.a21 = a[6]; +254 this.a31 = a[7]; +255 this.a02 = a[8]; +256 this.a12 = a[9]; +257 this.a22 = a[10]; +258 this.a32 = a[11]; +259 this.a03 = a[12]; +260 this.a13 = a[13]; +261 this.a23 = a[14]; +262 this.a33 = a[15]; +263 } +264 +265 /** +266 * @param x x-coordinate of the interpolation point +267 * @param y y-coordinate of the interpolation point +268 * @return the interpolated value. +269 */ +270 public double value(double x, double y) { +271 if (x < 0 || x > 1) { +272 throw MathRuntimeException.createIllegalArgumentException("{0} out of [{1}, {2}] range", +273 x, 0, 1); +274 } +275 if (y < 0 || y > 1) { +276 throw MathRuntimeException.createIllegalArgumentException("{0} out of [{1}, {2}] range", +277 y, 0, 1); +278 } +279 +280 final double x2 = x * x; +281 final double x3 = x2 * x; +282 final double y2 = y * y; +283 final double y3 = y2 * y; +284 +285 return a00 + a01 * y + a02 * y2 + a03 * y3 + +286 a10 * x + a11 * x * y + a12 * x * y2 + a13 * x * y3 + +287 a20 * x2 + a21 * x2 * y + a22 * x2 * y2 + a23 * x2 * y3 + +288 a30 * x3 + a31 * x3 * y + a32 * x3 * y2 + a33 * x3 * y3; +289 } +290 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/BivariateRealGridInterpolator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/BivariateRealGridInterpolator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,111 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.interpolation; +018 +019 import org.apache.commons.math.MathException; +020 import org.apache.commons.math.analysis.BivariateRealFunction; +021 +022 /** +023 * Interface representing a bivariate real interpolating function where the +024 * sample points must be specified on a regular grid. +025 * +026 * @version $Revision$ $Date$ +027 */ +028 public interface BivariateRealGridInterpolator { +029 +030 /** +031 * Computes an interpolating function for the data set. +032 * +033 * @param xval all the x-coordinates of the interpolation points, sorted +034 * in increasing order. +035 * @param yval all the y-coordinates of the interpolation points, sorted +036 * in increasing order. +037 * @param zval the values of the interpolation points on all the grid knots: +038 * {@code zval[i][j] = f(xval[i], yval[j])} +039 * @return a function which interpolates the data set +040 * @throws MathException if arguments violate assumptions made by the +041 * interpolation algorithm +042 */ +043 BivariateRealFunction interpolate(double[] xval, double[] yval, double[][] zval) +044 throws MathException; +045 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/DividedDifferenceInterpolator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/DividedDifferenceInterpolator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,183 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.interpolation; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.DuplicateSampleAbscissaException; +022 import org.apache.commons.math.analysis.polynomials.PolynomialFunctionLagrangeForm; +023 import org.apache.commons.math.analysis.polynomials.PolynomialFunctionNewtonForm; +024 +025 /** +026 * Implements the <a href=" +027 * "http://mathworld.wolfram.com/NewtonsDividedDifferenceInterpolationFormula.html"> +028 * Divided Difference Algorithm</a> for interpolation of real univariate +029 * functions. For reference, see <b>Introduction to Numerical Analysis</b>, +030 * ISBN 038795452X, chapter 2. +031 * <p> +032 * The actual code of Neville's evaluation is in PolynomialFunctionLagrangeForm, +033 * this class provides an easy-to-use interface to it.</p> +034 * +035 * @version $Revision: 825919 $ $Date: 2009-10-16 10:51:55 -0400 (Fri, 16 Oct 2009) $ +036 * @since 1.2 +037 */ +038 public class DividedDifferenceInterpolator implements UnivariateRealInterpolator, +039 Serializable { +040 +041 /** serializable version identifier */ +042 private static final long serialVersionUID = 107049519551235069L; +043 +044 /** +045 * Computes an interpolating function for the data set. +046 * +047 * @param x the interpolating points array +048 * @param y the interpolating values array +049 * @return a function which interpolates the data set +050 * @throws DuplicateSampleAbscissaException if arguments are invalid +051 */ +052 public PolynomialFunctionNewtonForm interpolate(double x[], double y[]) throws +053 DuplicateSampleAbscissaException { +054 +055 /** +056 * a[] and c[] are defined in the general formula of Newton form: +057 * p(x) = a[0] + a[1](x-c[0]) + a[2](x-c[0])(x-c[1]) + ... + +058 * a[n](x-c[0])(x-c[1])...(x-c[n-1]) +059 */ +060 PolynomialFunctionLagrangeForm.verifyInterpolationArray(x, y); +061 +062 /** +063 * When used for interpolation, the Newton form formula becomes +064 * p(x) = f[x0] + f[x0,x1](x-x0) + f[x0,x1,x2](x-x0)(x-x1) + ... + +065 * f[x0,x1,...,x[n-1]](x-x0)(x-x1)...(x-x[n-2]) +066 * Therefore, a[k] = f[x0,x1,...,xk], c[k] = x[k]. +067 * <p> +068 * Note x[], y[], a[] have the same length but c[]'s size is one less.</p> +069 */ +070 final double[] c = new double[x.length-1]; +071 System.arraycopy(x, 0, c, 0, c.length); +072 +073 final double[] a = computeDividedDifference(x, y); +074 return new PolynomialFunctionNewtonForm(a, c); +075 +076 } +077 +078 /** +079 * Returns a copy of the divided difference array. +080 * <p> +081 * The divided difference array is defined recursively by <pre> +082 * f[x0] = f(x0) +083 * f[x0,x1,...,xk] = (f(x1,...,xk) - f(x0,...,x[k-1])) / (xk - x0) +084 * </pre></p> +085 * <p> +086 * The computational complexity is O(N^2).</p> +087 * +088 * @param x the interpolating points array +089 * @param y the interpolating values array +090 * @return a fresh copy of the divided difference array +091 * @throws DuplicateSampleAbscissaException if any abscissas coincide +092 */ +093 protected static double[] computeDividedDifference(final double x[], final double y[]) +094 throws DuplicateSampleAbscissaException { +095 +096 PolynomialFunctionLagrangeForm.verifyInterpolationArray(x, y); +097 +098 final double[] divdiff = y.clone(); // initialization +099 +100 final int n = x.length; +101 final double[] a = new double [n]; +102 a[0] = divdiff[0]; +103 for (int i = 1; i < n; i++) { +104 for (int j = 0; j < n-i; j++) { +105 final double denominator = x[j+i] - x[j]; +106 if (denominator == 0.0) { +107 // This happens only when two abscissas are identical. +108 throw new DuplicateSampleAbscissaException(x[j], j, j+i); +109 } +110 divdiff[j] = (divdiff[j+1] - divdiff[j]) / denominator; +111 } +112 a[i] = divdiff[0]; +113 } +114 +115 return a; +116 } +117 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/LoessInterpolator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/LoessInterpolator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,541 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.interpolation; +018 +019 import java.io.Serializable; +020 import java.util.Arrays; +021 +022 import org.apache.commons.math.MathException; +023 import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; +024 +025 /** +026 * Implements the <a href="http://en.wikipedia.org/wiki/Local_regression"> +027 * Local Regression Algorithm</a> (also Loess, Lowess) for interpolation of +028 * real univariate functions. +029 * <p/> +030 * For reference, see +031 * <a href="http://www.math.tau.ac.il/~yekutiel/MA seminar/Cleveland 1979.pdf"> +032 * William S. Cleveland - Robust Locally Weighted Regression and Smoothing +033 * Scatterplots</a> +034 * <p/> +035 * This class implements both the loess method and serves as an interpolation +036 * adapter to it, allowing to build a spline on the obtained loess fit. +037 * +038 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +039 * @since 2.0 +040 */ +041 public class LoessInterpolator +042 implements UnivariateRealInterpolator, Serializable { +043 +044 /** Default value of the bandwidth parameter. */ +045 public static final double DEFAULT_BANDWIDTH = 0.3; +046 +047 /** Default value of the number of robustness iterations. */ +048 public static final int DEFAULT_ROBUSTNESS_ITERS = 2; +049 +050 /** +051 * Default value for accuracy. +052 * @since 2.1 +053 */ +054 public static final double DEFAULT_ACCURACY = 1e-12; +055 +056 /** serializable version identifier. */ +057 private static final long serialVersionUID = 5204927143605193821L; +058 +059 /** +060 * The bandwidth parameter: when computing the loess fit at +061 * a particular point, this fraction of source points closest +062 * to the current point is taken into account for computing +063 * a least-squares regression. +064 * <p/> +065 * A sensible value is usually 0.25 to 0.5. +066 */ +067 private final double bandwidth; +068 +069 /** +070 * The number of robustness iterations parameter: this many +071 * robustness iterations are done. +072 * <p/> +073 * A sensible value is usually 0 (just the initial fit without any +074 * robustness iterations) to 4. +075 */ +076 private final int robustnessIters; +077 +078 /** +079 * If the median residual at a certain robustness iteration +080 * is less than this amount, no more iterations are done. +081 */ +082 private final double accuracy; +083 +084 /** +085 * Constructs a new {@link LoessInterpolator} +086 * with a bandwidth of {@link #DEFAULT_BANDWIDTH}, +087 * {@link #DEFAULT_ROBUSTNESS_ITERS} robustness iterations +088 * and an accuracy of {#link #DEFAULT_ACCURACY}. +089 * See {@link #LoessInterpolator(double, int, double)} for an explanation of +090 * the parameters. +091 */ +092 public LoessInterpolator() { +093 this.bandwidth = DEFAULT_BANDWIDTH; +094 this.robustnessIters = DEFAULT_ROBUSTNESS_ITERS; +095 this.accuracy = DEFAULT_ACCURACY; +096 } +097 +098 /** +099 * Constructs a new {@link LoessInterpolator} +100 * with given bandwidth and number of robustness iterations. +101 * <p> +102 * Calling this constructor is equivalent to calling {link {@link +103 * #LoessInterpolator(double, int, double) LoessInterpolator(bandwidth, +104 * robustnessIters, LoessInterpolator.DEFAULT_ACCURACY)} +105 * </p> +106 * +107 * @param bandwidth when computing the loess fit at +108 * a particular point, this fraction of source points closest +109 * to the current point is taken into account for computing +110 * a least-squares regression.</br> +111 * A sensible value is usually 0.25 to 0.5, the default value is +112 * {@link #DEFAULT_BANDWIDTH}. +113 * @param robustnessIters This many robustness iterations are done.</br> +114 * A sensible value is usually 0 (just the initial fit without any +115 * robustness iterations) to 4, the default value is +116 * {@link #DEFAULT_ROBUSTNESS_ITERS}. +117 * @throws MathException if bandwidth does not lie in the interval [0,1] +118 * or if robustnessIters is negative. +119 * @see #LoessInterpolator(double, int, double) +120 */ +121 public LoessInterpolator(double bandwidth, int robustnessIters) throws MathException { +122 this(bandwidth, robustnessIters, DEFAULT_ACCURACY); +123 } +124 +125 /** +126 * Constructs a new {@link LoessInterpolator} +127 * with given bandwidth, number of robustness iterations and accuracy. +128 * +129 * @param bandwidth when computing the loess fit at +130 * a particular point, this fraction of source points closest +131 * to the current point is taken into account for computing +132 * a least-squares regression.</br> +133 * A sensible value is usually 0.25 to 0.5, the default value is +134 * {@link #DEFAULT_BANDWIDTH}. +135 * @param robustnessIters This many robustness iterations are done.</br> +136 * A sensible value is usually 0 (just the initial fit without any +137 * robustness iterations) to 4, the default value is +138 * {@link #DEFAULT_ROBUSTNESS_ITERS}. +139 * @param accuracy If the median residual at a certain robustness iteration +140 * is less than this amount, no more iterations are done. +141 * @throws MathException if bandwidth does not lie in the interval [0,1] +142 * or if robustnessIters is negative. +143 * @see #LoessInterpolator(double, int) +144 * @since 2.1 +145 */ +146 public LoessInterpolator(double bandwidth, int robustnessIters, double accuracy) throws MathException { +147 if (bandwidth < 0 || bandwidth > 1) { +148 throw new MathException("bandwidth must be in the interval [0,1], but got {0}", +149 bandwidth); +150 } +151 this.bandwidth = bandwidth; +152 if (robustnessIters < 0) { +153 throw new MathException("the number of robustness iterations must " + +154 "be non-negative, but got {0}", +155 robustnessIters); +156 } +157 this.robustnessIters = robustnessIters; +158 this.accuracy = accuracy; +159 } +160 +161 /** +162 * Compute an interpolating function by performing a loess fit +163 * on the data at the original abscissae and then building a cubic spline +164 * with a +165 * {@link org.apache.commons.math.analysis.interpolation.SplineInterpolator} +166 * on the resulting fit. +167 * +168 * @param xval the arguments for the interpolation points +169 * @param yval the values for the interpolation points +170 * @return A cubic spline built upon a loess fit to the data at the original abscissae +171 * @throws MathException if some of the following conditions are false: +172 * <ul> +173 * <li> Arguments and values are of the same size that is greater than zero</li> +174 * <li> The arguments are in a strictly increasing order</li> +175 * <li> All arguments and values are finite real numbers</li> +176 * </ul> +177 */ +178 public final PolynomialSplineFunction interpolate( +179 final double[] xval, final double[] yval) throws MathException { +180 return new SplineInterpolator().interpolate(xval, smooth(xval, yval)); +181 } +182 +183 /** +184 * Compute a weighted loess fit on the data at the original abscissae. +185 * +186 * @param xval the arguments for the interpolation points +187 * @param yval the values for the interpolation points +188 * @param weights point weights: coefficients by which the robustness weight of a point is multiplied +189 * @return values of the loess fit at corresponding original abscissae +190 * @throws MathException if some of the following conditions are false: +191 * <ul> +192 * <li> Arguments and values are of the same size that is greater than zero</li> +193 * <li> The arguments are in a strictly increasing order</li> +194 * <li> All arguments and values are finite real numbers</li> +195 * </ul> +196 * @since 2.1 +197 */ +198 public final double[] smooth(final double[] xval, final double[] yval, final double[] weights) +199 throws MathException { +200 if (xval.length != yval.length) { +201 throw new MathException( +202 "Loess expects the abscissa and ordinate arrays " + +203 "to be of the same size, " + +204 "but got {0} abscissae and {1} ordinatae", +205 xval.length, yval.length); +206 } +207 +208 final int n = xval.length; +209 +210 if (n == 0) { +211 throw new MathException("Loess expects at least 1 point"); +212 } +213 +214 checkAllFiniteReal(xval, "all abscissae must be finite real numbers, but {0}-th is {1}"); +215 checkAllFiniteReal(yval, "all ordinatae must be finite real numbers, but {0}-th is {1}"); +216 checkAllFiniteReal(weights, "all weights must be finite real numbers, but {0}-th is {1}"); +217 +218 checkStrictlyIncreasing(xval); +219 +220 if (n == 1) { +221 return new double[]{yval[0]}; +222 } +223 +224 if (n == 2) { +225 return new double[]{yval[0], yval[1]}; +226 } +227 +228 int bandwidthInPoints = (int) (bandwidth * n); +229 +230 if (bandwidthInPoints < 2) { +231 throw new MathException( +232 "the bandwidth must be large enough to " + +233 "accomodate at least 2 points. There are {0} " + +234 " data points, and bandwidth must be at least {1} " + +235 " but it is only {2}", +236 n, 2.0 / n, bandwidth); +237 } +238 +239 final double[] res = new double[n]; +240 +241 final double[] residuals = new double[n]; +242 final double[] sortedResiduals = new double[n]; +243 +244 final double[] robustnessWeights = new double[n]; +245 +246 // Do an initial fit and 'robustnessIters' robustness iterations. +247 // This is equivalent to doing 'robustnessIters+1' robustness iterations +248 // starting with all robustness weights set to 1. +249 Arrays.fill(robustnessWeights, 1); +250 +251 for (int iter = 0; iter <= robustnessIters; ++iter) { +252 final int[] bandwidthInterval = {0, bandwidthInPoints - 1}; +253 // At each x, compute a local weighted linear regression +254 for (int i = 0; i < n; ++i) { +255 final double x = xval[i]; +256 +257 // Find out the interval of source points on which +258 // a regression is to be made. +259 if (i > 0) { +260 updateBandwidthInterval(xval, weights, i, bandwidthInterval); +261 } +262 +263 final int ileft = bandwidthInterval[0]; +264 final int iright = bandwidthInterval[1]; +265 +266 // Compute the point of the bandwidth interval that is +267 // farthest from x +268 final int edge; +269 if (xval[i] - xval[ileft] > xval[iright] - xval[i]) { +270 edge = ileft; +271 } else { +272 edge = iright; +273 } +274 +275 // Compute a least-squares linear fit weighted by +276 // the product of robustness weights and the tricube +277 // weight function. +278 // See http://en.wikipedia.org/wiki/Linear_regression +279 // (section "Univariate linear case") +280 // and http://en.wikipedia.org/wiki/Weighted_least_squares +281 // (section "Weighted least squares") +282 double sumWeights = 0; +283 double sumX = 0; +284 double sumXSquared = 0; +285 double sumY = 0; +286 double sumXY = 0; +287 double denom = Math.abs(1.0 / (xval[edge] - x)); +288 for (int k = ileft; k <= iright; ++k) { +289 final double xk = xval[k]; +290 final double yk = yval[k]; +291 final double dist = (k < i) ? x - xk : xk - x; +292 final double w = tricube(dist * denom) * robustnessWeights[k] * weights[k]; +293 final double xkw = xk * w; +294 sumWeights += w; +295 sumX += xkw; +296 sumXSquared += xk * xkw; +297 sumY += yk * w; +298 sumXY += yk * xkw; +299 } +300 +301 final double meanX = sumX / sumWeights; +302 final double meanY = sumY / sumWeights; +303 final double meanXY = sumXY / sumWeights; +304 final double meanXSquared = sumXSquared / sumWeights; +305 +306 final double beta; +307 if (Math.sqrt(Math.abs(meanXSquared - meanX * meanX)) < accuracy) { +308 beta = 0; +309 } else { +310 beta = (meanXY - meanX * meanY) / (meanXSquared - meanX * meanX); +311 } +312 +313 final double alpha = meanY - beta * meanX; +314 +315 res[i] = beta * x + alpha; +316 residuals[i] = Math.abs(yval[i] - res[i]); +317 } +318 +319 // No need to recompute the robustness weights at the last +320 // iteration, they won't be needed anymore +321 if (iter == robustnessIters) { +322 break; +323 } +324 +325 // Recompute the robustness weights. +326 +327 // Find the median residual. +328 // An arraycopy and a sort are completely tractable here, +329 // because the preceding loop is a lot more expensive +330 System.arraycopy(residuals, 0, sortedResiduals, 0, n); +331 Arrays.sort(sortedResiduals); +332 final double medianResidual = sortedResiduals[n / 2]; +333 +334 if (Math.abs(medianResidual) < accuracy) { +335 break; +336 } +337 +338 for (int i = 0; i < n; ++i) { +339 final double arg = residuals[i] / (6 * medianResidual); +340 if (arg >= 1) { +341 robustnessWeights[i] = 0; +342 } else { +343 final double w = 1 - arg * arg; +344 robustnessWeights[i] = w * w; +345 } +346 } +347 } +348 +349 return res; +350 } +351 +352 /** +353 * Compute a loess fit on the data at the original abscissae. +354 * +355 * @param xval the arguments for the interpolation points +356 * @param yval the values for the interpolation points +357 * @return values of the loess fit at corresponding original abscissae +358 * @throws MathException if some of the following conditions are false: +359 * <ul> +360 * <li> Arguments and values are of the same size that is greater than zero</li> +361 * <li> The arguments are in a strictly increasing order</li> +362 * <li> All arguments and values are finite real numbers</li> +363 * </ul> +364 */ +365 public final double[] smooth(final double[] xval, final double[] yval) +366 throws MathException { +367 if (xval.length != yval.length) { +368 throw new MathException( +369 "Loess expects the abscissa and ordinate arrays " + +370 "to be of the same size, " + +371 "but got {0} abscissae and {1} ordinatae", +372 xval.length, yval.length); +373 } +374 +375 final double[] unitWeights = new double[xval.length]; +376 Arrays.fill(unitWeights, 1.0); +377 +378 return smooth(xval, yval, unitWeights); +379 } +380 +381 /** +382 * Given an index interval into xval that embraces a certain number of +383 * points closest to xval[i-1], update the interval so that it embraces +384 * the same number of points closest to xval[i], ignoring zero weights. +385 * +386 * @param xval arguments array +387 * @param weights weights array +388 * @param i the index around which the new interval should be computed +389 * @param bandwidthInterval a two-element array {left, right} such that: <p/> +390 * <tt>(left==0 or xval[i] - xval[left-1] > xval[right] - xval[i])</tt> +391 * <p/> and also <p/> +392 * <tt>(right==xval.length-1 or xval[right+1] - xval[i] > xval[i] - xval[left])</tt>. +393 * The array will be updated. +394 */ +395 private static void updateBandwidthInterval(final double[] xval, final double[] weights, +396 final int i, +397 final int[] bandwidthInterval) { +398 final int left = bandwidthInterval[0]; +399 final int right = bandwidthInterval[1]; +400 +401 // The right edge should be adjusted if the next point to the right +402 // is closer to xval[i] than the leftmost point of the current interval +403 int nextRight = nextNonzero(weights, right); +404 if (nextRight < xval.length && xval[nextRight] - xval[i] < xval[i] - xval[left]) { +405 int nextLeft = nextNonzero(weights, bandwidthInterval[0]); +406 bandwidthInterval[0] = nextLeft; +407 bandwidthInterval[1] = nextRight; +408 } +409 } +410 +411 /** +412 * Returns the smallest index j such that j > i && (j==weights.length || weights[j] != 0) +413 * @param weights weights array +414 * @param i the index from which to start search; must be < weights.length +415 * @return the smallest index j such that j > i && (j==weights.length || weights[j] != 0) +416 */ +417 private static int nextNonzero(final double[] weights, final int i) { +418 int j = i + 1; +419 while(j < weights.length && weights[j] == 0) { +420 j++; +421 } +422 return j; +423 } +424 +425 /** +426 * Compute the +427 * <a href="http://en.wikipedia.org/wiki/Local_regression#Weight_function">tricube</a> +428 * weight function +429 * +430 * @param x the argument +431 * @return (1-|x|^3)^3 +432 */ +433 private static double tricube(final double x) { +434 final double tmp = 1 - x * x * x; +435 return tmp * tmp * tmp; +436 } +437 +438 /** +439 * Check that all elements of an array are finite real numbers. +440 * +441 * @param values the values array +442 * @param pattern pattern of the error message +443 * @throws MathException if one of the values is not a finite real number +444 */ +445 private static void checkAllFiniteReal(final double[] values, final String pattern) +446 throws MathException { +447 for (int i = 0; i < values.length; i++) { +448 final double x = values[i]; +449 if (Double.isInfinite(x) || Double.isNaN(x)) { +450 throw new MathException(pattern, i, x); +451 } +452 } +453 } +454 +455 /** +456 * Check that elements of the abscissae array are in a strictly +457 * increasing order. +458 * +459 * @param xval the abscissae array +460 * @throws MathException if the abscissae array +461 * is not in a strictly increasing order +462 */ +463 private static void checkStrictlyIncreasing(final double[] xval) +464 throws MathException { +465 for (int i = 0; i < xval.length; ++i) { +466 if (i >= 1 && xval[i - 1] >= xval[i]) { +467 throw new MathException( +468 "the abscissae array must be sorted in a strictly " + +469 "increasing order, but the {0}-th element is {1} " + +470 "whereas {2}-th is {3}", +471 i - 1, xval[i - 1], i, xval[i]); +472 } +473 } +474 } +475 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,309 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.interpolation; +018 +019 import java.util.ArrayList; +020 import java.util.HashMap; +021 import java.util.List; +022 import java.util.Map; +023 +024 import org.apache.commons.math.DimensionMismatchException; +025 import org.apache.commons.math.MathRuntimeException; +026 import org.apache.commons.math.analysis.MultivariateRealFunction; +027 import org.apache.commons.math.linear.ArrayRealVector; +028 import org.apache.commons.math.linear.RealVector; +029 import org.apache.commons.math.random.UnitSphereRandomVectorGenerator; +030 +031 /** +032 * Interpolating function that implements the +033 * <a href="http://www.dudziak.com/microsphere.php">Microsphere Projection</a>. +034 * +035 * @version $Revision: 825919 $ $Date: 2009-10-16 10:51:55 -0400 (Fri, 16 Oct 2009) $ +036 */ +037 public class MicrosphereInterpolatingFunction +038 implements MultivariateRealFunction { +039 /** +040 * Space dimension. +041 */ +042 private final int dimension; +043 /** +044 * Internal accounting data for the interpolation algorithm. +045 * Each element of the list corresponds to one surface element of +046 * the microsphere. +047 */ +048 private final List<MicrosphereSurfaceElement> microsphere; +049 /** +050 * Exponent used in the power law that computes the weights of the +051 * sample data. +052 */ +053 private final double brightnessExponent; +054 /** +055 * Sample data. +056 */ +057 private final Map<RealVector, Double> samples; +058 +059 /** +060 * Class for storing the accounting data needed to perform the +061 * microsphere projection. +062 */ +063 private static class MicrosphereSurfaceElement { +064 +065 /** Normal vector characterizing a surface element. */ +066 private final RealVector normal; +067 +068 /** Illumination received from the brightest sample. */ +069 private double brightestIllumination; +070 +071 /** Brightest sample. */ +072 private Map.Entry<RealVector, Double> brightestSample; +073 +074 /** +075 * @param n Normal vector characterizing a surface element +076 * of the microsphere. +077 */ +078 MicrosphereSurfaceElement(double[] n) { +079 normal = new ArrayRealVector(n); +080 } +081 +082 /** +083 * Return the normal vector. +084 * @return the normal vector +085 */ +086 RealVector normal() { +087 return normal; +088 } +089 +090 /** +091 * Reset "illumination" and "sampleIndex". +092 */ +093 void reset() { +094 brightestIllumination = 0; +095 brightestSample = null; +096 } +097 +098 /** +099 * Store the illumination and index of the brightest sample. +100 * @param illuminationFromSample illumination received from sample +101 * @param sample current sample illuminating the element +102 */ +103 void store(final double illuminationFromSample, +104 final Map.Entry<RealVector, Double> sample) { +105 if (illuminationFromSample > this.brightestIllumination) { +106 this.brightestIllumination = illuminationFromSample; +107 this.brightestSample = sample; +108 } +109 } +110 +111 /** +112 * Get the illumination of the element. +113 * @return the illumination. +114 */ +115 double illumination() { +116 return brightestIllumination; +117 } +118 +119 /** +120 * Get the sample illuminating the element the most. +121 * @return the sample. +122 */ +123 Map.Entry<RealVector, Double> sample() { +124 return brightestSample; +125 } +126 } +127 +128 /** +129 * @param xval the arguments for the interpolation points. +130 * {@code xval[i][0]} is the first component of interpolation point +131 * {@code i}, {@code xval[i][1]} is the second component, and so on +132 * until {@code xval[i][d-1]}, the last component of that interpolation +133 * point (where {@code dimension} is thus the dimension of the sampled +134 * space). +135 * @param yval the values for the interpolation points +136 * @param brightnessExponent Brightness dimming factor. +137 * @param microsphereElements Number of surface elements of the +138 * microsphere. +139 * @param rand Unit vector generator for creating the microsphere. +140 * @throws DimensionMismatchException if the lengths of {@code yval} and +141 * {@code xval} (equal to {@code n}, the number of interpolation points) +142 * do not match, or the the arrays {@code xval[0]} ... {@code xval[n]}, +143 * have lengths different from {@code dimension}. +144 * @throws IllegalArgumentException if there are no data (xval null or zero length) +145 */ +146 public MicrosphereInterpolatingFunction(double[][] xval, +147 double[] yval, +148 int brightnessExponent, +149 int microsphereElements, +150 UnitSphereRandomVectorGenerator rand) +151 throws DimensionMismatchException, IllegalArgumentException { +152 if (xval.length == 0 || xval[0] == null) { +153 throw MathRuntimeException.createIllegalArgumentException("no data"); +154 } +155 +156 if (xval.length != yval.length) { +157 throw new DimensionMismatchException(xval.length, yval.length); +158 } +159 +160 dimension = xval[0].length; +161 this.brightnessExponent = brightnessExponent; +162 +163 // Copy data samples. +164 samples = new HashMap<RealVector, Double>(yval.length); +165 for (int i = 0; i < xval.length; ++i) { +166 final double[] xvalI = xval[i]; +167 if ( xvalI.length != dimension) { +168 throw new DimensionMismatchException(xvalI.length, dimension); +169 } +170 +171 samples.put(new ArrayRealVector(xvalI), yval[i]); +172 } +173 +174 microsphere = new ArrayList<MicrosphereSurfaceElement>(microsphereElements); +175 // Generate the microsphere, assuming that a fairly large number of +176 // randomly generated normals will represent a sphere. +177 for (int i = 0; i < microsphereElements; i++) { +178 microsphere.add(new MicrosphereSurfaceElement(rand.nextVector())); +179 } +180 +181 } +182 +183 /** +184 * @param point Interpolation point. +185 * @return the interpolated value. +186 */ +187 public double value(double[] point) { +188 +189 final RealVector p = new ArrayRealVector(point); +190 +191 // Reset. +192 for (MicrosphereSurfaceElement md : microsphere) { +193 md.reset(); +194 } +195 +196 // Compute contribution of each sample points to the microsphere elements illumination +197 for (Map.Entry<RealVector, Double> sd : samples.entrySet()) { +198 +199 // Vector between interpolation point and current sample point. +200 final RealVector diff = sd.getKey().subtract(p); +201 final double diffNorm = diff.getNorm(); +202 +203 if (Math.abs(diffNorm) < Math.ulp(1d)) { +204 // No need to interpolate, as the interpolation point is +205 // actually (very close to) one of the sampled points. +206 return sd.getValue(); +207 } +208 +209 for (MicrosphereSurfaceElement md : microsphere) { +210 final double w = Math.pow(diffNorm, -brightnessExponent); +211 md.store(cosAngle(diff, md.normal()) * w, sd); +212 } +213 +214 } +215 +216 // Interpolation calculation. +217 double value = 0; +218 double totalWeight = 0; +219 for (MicrosphereSurfaceElement md : microsphere) { +220 final double iV = md.illumination(); +221 final Map.Entry<RealVector, Double> sd = md.sample(); +222 if (sd != null) { +223 value += iV * sd.getValue(); +224 totalWeight += iV; +225 } +226 } +227 +228 return value / totalWeight; +229 +230 } +231 +232 /** +233 * Compute the cosine of the angle between 2 vectors. +234 * +235 * @param v Vector. +236 * @param w Vector. +237 * @return cosine of the angle +238 */ +239 private double cosAngle(final RealVector v, final RealVector w) { +240 return v.dotProduct(w) / (v.getNorm() * w.getNorm()); +241 } +242 +243 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,189 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.interpolation; +018 +019 import org.apache.commons.math.MathException; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.analysis.MultivariateRealFunction; +022 import org.apache.commons.math.random.UnitSphereRandomVectorGenerator; +023 +024 /** +025 * Interpolator that implements the algorithm described in +026 * <em>William Dudziak</em>'s +027 * <a href="http://www.dudziak.com/microsphere.pdf">MS thesis</a> +028 * @since 2.1 +029 * +030 * @version $Revision: 924794 $ $Date: 2010-03-18 10:15:50 -0400 (Thu, 18 Mar 2010) $ +031 */ +032 public class MicrosphereInterpolator +033 implements MultivariateRealInterpolator { +034 +035 /** +036 * Default number of surface elements that composes the microsphere. +037 */ +038 public static final int DEFAULT_MICROSPHERE_ELEMENTS = 2000; +039 +040 /** +041 * Default exponent used the weights calculation. +042 */ +043 public static final int DEFAULT_BRIGHTNESS_EXPONENT = 2; +044 +045 /** +046 * Number of surface elements of the microsphere. +047 */ +048 private int microsphereElements; +049 +050 /** +051 * Exponent used in the power law that computes the weights of the +052 * sample data. +053 */ +054 private int brightnessExponent; +055 +056 /** Create a microsphere interpolator with default settings. +057 * <p>Calling this constructor is equivalent to call {@link +058 * #MicrosphereInterpolator(int, int) +059 * MicrosphereInterpolator(MicrosphereInterpolator.DEFAULT_MICROSPHERE_ELEMENTS, +060 * MicrosphereInterpolator.DEFAULT_BRIGHTNESS_EXPONENT)}.</p> +061 * weights of the sample data +062 */ +063 public MicrosphereInterpolator() { +064 this(DEFAULT_MICROSPHERE_ELEMENTS, DEFAULT_BRIGHTNESS_EXPONENT); +065 } +066 +067 /** Create a microsphere interpolator. +068 * @param microsphereElements number of surface elements of the microsphere +069 * @param brightnessExponent exponent used in the power law that computes the +070 * weights of the sample data +071 * @throws IllegalArgumentException if {@code microsphereElements <= 0} +072 * or {@code brightnessExponent < 0} +073 */ +074 public MicrosphereInterpolator(final int microsphereElements, +075 final int brightnessExponent) { +076 setMicropshereElements(microsphereElements); +077 setBrightnessExponent(brightnessExponent); +078 } +079 +080 /** +081 * {@inheritDoc} +082 */ +083 public MultivariateRealFunction interpolate(final double[][] xval, +084 final double[] yval) +085 throws MathException, IllegalArgumentException { +086 final UnitSphereRandomVectorGenerator rand +087 = new UnitSphereRandomVectorGenerator(xval[0].length); +088 return new MicrosphereInterpolatingFunction(xval, yval, +089 brightnessExponent, +090 microsphereElements, +091 rand); +092 } +093 +094 /** +095 * Set the brightness exponent. +096 * @param brightnessExponent Exponent for computing the distance dimming +097 * factor. +098 * @throws IllegalArgumentException if {@code brightnessExponent < 0}. +099 */ +100 public void setBrightnessExponent(final int brightnessExponent) { +101 if (brightnessExponent < 0) { +102 throw MathRuntimeException.createIllegalArgumentException( +103 "brightness exponent should be positive or null, but got {0}", +104 brightnessExponent); +105 } +106 this.brightnessExponent = brightnessExponent; +107 } +108 +109 /** +110 * Set the number of microsphere elements. +111 * @param elements Number of surface elements of the microsphere. +112 * @throws IllegalArgumentException if {@code microsphereElements <= 0}. +113 */ +114 public void setMicropshereElements(final int elements) { +115 if (microsphereElements < 0) { +116 throw MathRuntimeException.createIllegalArgumentException( +117 "number of microsphere elements must be positive, but got {0}", +118 microsphereElements); +119 } +120 this.microsphereElements = elements; +121 } +122 +123 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/MultivariateRealInterpolator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/MultivariateRealInterpolator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,112 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.interpolation; +018 +019 import org.apache.commons.math.MathException; +020 import org.apache.commons.math.analysis.MultivariateRealFunction; +021 +022 /** +023 * Interface representing a univariate real interpolating function. +024 * +025 * @since 2.1 +026 * @version $Revision: 924794 $ $Date: 2010-03-18 10:15:50 -0400 (Thu, 18 Mar 2010) $ +027 */ +028 public interface MultivariateRealInterpolator { +029 +030 /** +031 * Computes an interpolating function for the data set. +032 * +033 * @param xval the arguments for the interpolation points. +034 * {@code xval[i][0]} is the first component of interpolation point +035 * {@code i}, {@code xval[i][1]} is the second component, and so on +036 * until {@code xval[i][d-1]}, the last component of that interpolation +037 * point (where {@code d} is thus the dimension of the space). +038 * @param yval the values for the interpolation points +039 * @return a function which interpolates the data set +040 * @throws MathException if arguments violate assumptions made by the +041 * interpolation algorithm or some dimension mismatch occurs +042 * @throws IllegalArgumentException if there are no data (xval null or zero length) +043 */ +044 MultivariateRealFunction interpolate(double[][] xval, double[] yval) +045 throws MathException, IllegalArgumentException; +046 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/NevilleInterpolator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/NevilleInterpolator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,120 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.interpolation; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathException; +022 import org.apache.commons.math.analysis.polynomials.PolynomialFunctionLagrangeForm; +023 +024 /** +025 * Implements the <a href="http://mathworld.wolfram.com/NevillesAlgorithm.html"> +026 * Neville's Algorithm</a> for interpolation of real univariate functions. For +027 * reference, see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X, +028 * chapter 2. +029 * <p> +030 * The actual code of Neville's evalution is in PolynomialFunctionLagrangeForm, +031 * this class provides an easy-to-use interface to it.</p> +032 * +033 * @version $Revision: 799857 $ $Date: 2009-08-01 09:07:12 -0400 (Sat, 01 Aug 2009) $ +034 * @since 1.2 +035 */ +036 public class NevilleInterpolator implements UnivariateRealInterpolator, +037 Serializable { +038 +039 /** serializable version identifier */ +040 static final long serialVersionUID = 3003707660147873733L; +041 +042 /** +043 * Computes an interpolating function for the data set. +044 * +045 * @param x the interpolating points array +046 * @param y the interpolating values array +047 * @return a function which interpolates the data set +048 * @throws MathException if arguments are invalid +049 */ +050 public PolynomialFunctionLagrangeForm interpolate(double x[], double y[]) +051 throws MathException { +052 return new PolynomialFunctionLagrangeForm(x, y); +053 } +054 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/SmoothingBicubicSplineInterpolator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,236 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.interpolation; +018 +019 import org.apache.commons.math.DimensionMismatchException; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.MathException; +022 import org.apache.commons.math.util.MathUtils; +023 import org.apache.commons.math.analysis.UnivariateRealFunction; +024 import org.apache.commons.math.analysis.BivariateRealFunction; +025 import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; +026 +027 /** +028 * Generates a bicubic interpolation function. +029 * Before interpolating, smoothing of the input data is performed using +030 * splines. +031 * See <b>Handbook on splines for the user</b>, ISBN 084939404X, +032 * chapter 2. +033 * +034 * @version $Revision$ $Date$ +035 * @since 2.1 +036 */ +037 public class SmoothingBicubicSplineInterpolator +038 implements BivariateRealGridInterpolator { +039 /** +040 * {@inheritDoc} +041 */ +042 public BivariateRealFunction interpolate(final double[] xval, +043 final double[] yval, +044 final double[][] zval) +045 throws MathException, IllegalArgumentException { +046 if (xval.length == 0 || yval.length == 0 || zval.length == 0) { +047 throw MathRuntimeException.createIllegalArgumentException("no data"); +048 } +049 if (xval.length != zval.length) { +050 throw new DimensionMismatchException(xval.length, zval.length); +051 } +052 +053 MathUtils.checkOrder(xval, 1, true); +054 MathUtils.checkOrder(yval, 1, true); +055 +056 final int xLen = xval.length; +057 final int yLen = yval.length; +058 +059 // Samples (first index is y-coordinate, i.e. subarray variable is x) +060 // 0 <= i < xval.length +061 // 0 <= j < yval.length +062 // zX[j][i] = f(xval[i], yval[j]) +063 final double[][] zX = new double[yLen][xLen]; +064 for (int i = 0; i < xLen; i++) { +065 if (zval[i].length != yLen) { +066 throw new DimensionMismatchException(zval[i].length, yLen); +067 } +068 +069 for (int j = 0; j < yLen; j++) { +070 zX[j][i] = zval[i][j]; +071 } +072 } +073 +074 final SplineInterpolator spInterpolator = new SplineInterpolator(); +075 +076 // For each line y[j] (0 <= j < yLen), construct a 1D spline with +077 // respect to variable x +078 final PolynomialSplineFunction[] ySplineX = new PolynomialSplineFunction[yLen]; +079 for (int j = 0; j < yLen; j++) { +080 ySplineX[j] = spInterpolator.interpolate(xval, zX[j]); +081 } +082 +083 // For every knot (xval[i], yval[j]) of the grid, calculate corrected +084 // values zY_1 +085 final double[][] zY_1 = new double[xLen][yLen]; +086 for (int j = 0; j < yLen; j++) { +087 final PolynomialSplineFunction f = ySplineX[j]; +088 for (int i = 0; i < xLen; i++) { +089 zY_1[i][j] = f.value(xval[i]); +090 } +091 } +092 +093 // For each line x[i] (0 <= i < xLen), construct a 1D spline with +094 // respect to variable y generated by array zY_1[i] +095 final PolynomialSplineFunction[] xSplineY = new PolynomialSplineFunction[xLen]; +096 for (int i = 0; i < xLen; i++) { +097 xSplineY[i] = spInterpolator.interpolate(yval, zY_1[i]); +098 } +099 +100 // For every knot (xval[i], yval[j]) of the grid, calculate corrected +101 // values zY_2 +102 final double[][] zY_2 = new double[xLen][yLen]; +103 for (int i = 0; i < xLen; i++) { +104 final PolynomialSplineFunction f = xSplineY[i]; +105 for (int j = 0; j < yLen; j++) { +106 zY_2[i][j] = f.value(yval[j]); +107 } +108 } +109 +110 // Partial derivatives with respect to x at the grid knots +111 final double[][] dZdX = new double[xLen][yLen]; +112 for (int j = 0; j < yLen; j++) { +113 final UnivariateRealFunction f = ySplineX[j].derivative(); +114 for (int i = 0; i < xLen; i++) { +115 dZdX[i][j] = f.value(xval[i]); +116 } +117 } +118 +119 // Partial derivatives with respect to y at the grid knots +120 final double[][] dZdY = new double[xLen][yLen]; +121 for (int i = 0; i < xLen; i++) { +122 final UnivariateRealFunction f = xSplineY[i].derivative(); +123 for (int j = 0; j < yLen; j++) { +124 dZdY[i][j] = f.value(yval[j]); +125 } +126 } +127 +128 // Cross partial derivatives +129 final double[][] dZdXdY = new double[xLen][yLen]; +130 for (int i = 0; i < xLen ; i++) { +131 final int nI = nextIndex(i, xLen); +132 final int pI = previousIndex(i); +133 for (int j = 0; j < yLen; j++) { +134 final int nJ = nextIndex(j, yLen); +135 final int pJ = previousIndex(j); +136 dZdXdY[i][j] = (zY_2[nI][nJ] - zY_2[nI][pJ] - +137 zY_2[pI][nJ] + zY_2[pI][pJ]) / +138 ((xval[nI] - xval[pI]) * (yval[nJ] - yval[pJ])) ; +139 } +140 } +141 +142 // Create the interpolating splines +143 return new BicubicSplineInterpolatingFunction(xval, yval, zY_2, +144 dZdX, dZdY, dZdXdY); +145 } +146 +147 /** +148 * Compute the next index of an array, clipping if necessary. +149 * It is assumed (but not checked) that {@code i} is larger than or equal to 0}. +150 * +151 * @param i Index +152 * @param max Upper limit of the array +153 * @return the next index +154 */ +155 private int nextIndex(int i, int max) { +156 final int index = i + 1; +157 return index < max ? index : index - 1; +158 } +159 /** +160 * Compute the previous index of an array, clipping if necessary. +161 * It is assumed (but not checked) that {@code i} is smaller than the size of the array. +162 * +163 * @param i Index +164 * @return the previous index +165 */ +166 private int previousIndex(int i) { +167 final int index = i - 1; +168 return index >= 0 ? index : 0; +169 } +170 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/SplineInterpolator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/SplineInterpolator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,191 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.interpolation; +018 +019 import org.apache.commons.math.MathRuntimeException; +020 import org.apache.commons.math.analysis.polynomials.PolynomialFunction; +021 import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; +022 +023 /** +024 * Computes a natural (also known as "free", "unclamped") cubic spline interpolation for the data set. +025 * <p> +026 * The {@link #interpolate(double[], double[])} method returns a {@link PolynomialSplineFunction} +027 * consisting of n cubic polynomials, defined over the subintervals determined by the x values, +028 * x[0] < x[i] ... < x[n]. The x values are referred to as "knot points."</p> +029 * <p> +030 * The value of the PolynomialSplineFunction at a point x that is greater than or equal to the smallest +031 * knot point and strictly less than the largest knot point is computed by finding the subinterval to which +032 * x belongs and computing the value of the corresponding polynomial at <code>x - x[i] </code> where +033 * <code>i</code> is the index of the subinterval. See {@link PolynomialSplineFunction} for more details. +034 * </p> +035 * <p> +036 * The interpolating polynomials satisfy: <ol> +037 * <li>The value of the PolynomialSplineFunction at each of the input x values equals the +038 * corresponding y value.</li> +039 * <li>Adjacent polynomials are equal through two derivatives at the knot points (i.e., adjacent polynomials +040 * "match up" at the knot points, as do their first and second derivatives).</li> +041 * </ol></p> +042 * <p> +043 * The cubic spline interpolation algorithm implemented is as described in R.L. Burden, J.D. Faires, +044 * <u>Numerical Analysis</u>, 4th Ed., 1989, PWS-Kent, ISBN 0-53491-585-X, pp 126-131. +045 * </p> +046 * +047 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +048 * +049 */ +050 public class SplineInterpolator implements UnivariateRealInterpolator { +051 +052 /** +053 * Computes an interpolating function for the data set. +054 * @param x the arguments for the interpolation points +055 * @param y the values for the interpolation points +056 * @return a function which interpolates the data set +057 */ +058 public PolynomialSplineFunction interpolate(double x[], double y[]) { +059 if (x.length != y.length) { +060 throw MathRuntimeException.createIllegalArgumentException( +061 "dimension mismatch {0} != {1}", x.length, y.length); +062 } +063 +064 if (x.length < 3) { +065 throw MathRuntimeException.createIllegalArgumentException( +066 "{0} points are required, got only {1}", 3, x.length); +067 } +068 +069 // Number of intervals. The number of data points is n + 1. +070 int n = x.length - 1; +071 +072 for (int i = 0; i < n; i++) { +073 if (x[i] >= x[i + 1]) { +074 throw MathRuntimeException.createIllegalArgumentException( +075 "points {0} and {1} are not strictly increasing ({2} >= {3})", +076 i, i+1, x[i], x[i+1]); +077 } +078 } +079 +080 // Differences between knot points +081 double h[] = new double[n]; +082 for (int i = 0; i < n; i++) { +083 h[i] = x[i + 1] - x[i]; +084 } +085 +086 double mu[] = new double[n]; +087 double z[] = new double[n + 1]; +088 mu[0] = 0d; +089 z[0] = 0d; +090 double g = 0; +091 for (int i = 1; i < n; i++) { +092 g = 2d * (x[i+1] - x[i - 1]) - h[i - 1] * mu[i -1]; +093 mu[i] = h[i] / g; +094 z[i] = (3d * (y[i + 1] * h[i - 1] - y[i] * (x[i + 1] - x[i - 1])+ y[i - 1] * h[i]) / +095 (h[i - 1] * h[i]) - h[i - 1] * z[i - 1]) / g; +096 } +097 +098 // cubic spline coefficients -- b is linear, c quadratic, d is cubic (original y's are constants) +099 double b[] = new double[n]; +100 double c[] = new double[n + 1]; +101 double d[] = new double[n]; +102 +103 z[n] = 0d; +104 c[n] = 0d; +105 +106 for (int j = n -1; j >=0; j--) { +107 c[j] = z[j] - mu[j] * c[j + 1]; +108 b[j] = (y[j + 1] - y[j]) / h[j] - h[j] * (c[j + 1] + 2d * c[j]) / 3d; +109 d[j] = (c[j + 1] - c[j]) / (3d * h[j]); +110 } +111 +112 PolynomialFunction polynomials[] = new PolynomialFunction[n]; +113 double coefficients[] = new double[4]; +114 for (int i = 0; i < n; i++) { +115 coefficients[0] = y[i]; +116 coefficients[1] = b[i]; +117 coefficients[2] = c[i]; +118 coefficients[3] = d[i]; +119 polynomials[i] = new PolynomialFunction(coefficients); +120 } +121 +122 return new PolynomialSplineFunction(x, polynomials); +123 } +124 +125 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/UnivariateRealInterpolator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/interpolation/UnivariateRealInterpolator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,105 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.interpolation; +018 +019 import org.apache.commons.math.MathException; +020 import org.apache.commons.math.analysis.UnivariateRealFunction; +021 +022 /** +023 * Interface representing a univariate real interpolating function. +024 * +025 * @version $Revision: 821626 $ $Date: 2009-10-04 17:57:30 -0400 (Sun, 04 Oct 2009) $ +026 */ +027 public interface UnivariateRealInterpolator { +028 +029 /** +030 * Computes an interpolating function for the data set. +031 * @param xval the arguments for the interpolation points +032 * @param yval the values for the interpolation points +033 * @return a function which interpolates the data set +034 * @throws MathException if arguments violate assumptions made by the +035 * interpolation algorithm +036 */ +037 UnivariateRealFunction interpolate(double xval[], double yval[]) +038 throws MathException; +039 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/polynomials/PolynomialFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/polynomials/PolynomialFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,418 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.polynomials; +018 +019 import java.io.Serializable; +020 import java.util.Arrays; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction; +024 import org.apache.commons.math.analysis.UnivariateRealFunction; +025 +026 /** +027 * Immutable representation of a real polynomial function with real coefficients. +028 * <p> +029 * <a href="http://mathworld.wolfram.com/HornersMethod.html">Horner's Method</a> +030 * is used to evaluate the function.</p> +031 * +032 * @version $Revision: 922714 $ $Date: 2010-03-13 20:35:14 -0500 (Sat, 13 Mar 2010) $ +033 */ +034 public class PolynomialFunction implements DifferentiableUnivariateRealFunction, Serializable { +035 +036 /** Message for empty coefficients array. */ +037 private static final String EMPTY_ARRAY_MESSAGE = +038 "empty polynomials coefficients array"; +039 +040 /** +041 * Serialization identifier +042 */ +043 private static final long serialVersionUID = -7726511984200295583L; +044 +045 /** +046 * The coefficients of the polynomial, ordered by degree -- i.e., +047 * coefficients[0] is the constant term and coefficients[n] is the +048 * coefficient of x^n where n is the degree of the polynomial. +049 */ +050 private final double coefficients[]; +051 +052 /** +053 * Construct a polynomial with the given coefficients. The first element +054 * of the coefficients array is the constant term. Higher degree +055 * coefficients follow in sequence. The degree of the resulting polynomial +056 * is the index of the last non-null element of the array, or 0 if all elements +057 * are null. +058 * <p> +059 * The constructor makes a copy of the input array and assigns the copy to +060 * the coefficients property.</p> +061 * +062 * @param c polynomial coefficients +063 * @throws NullPointerException if c is null +064 * @throws IllegalArgumentException if c is empty +065 */ +066 public PolynomialFunction(double c[]) { +067 super(); +068 if (c.length < 1) { +069 throw MathRuntimeException.createIllegalArgumentException(EMPTY_ARRAY_MESSAGE); +070 } +071 int l = c.length; +072 while ((l > 1) && (c[l - 1] == 0)) { +073 --l; +074 } +075 this.coefficients = new double[l]; +076 System.arraycopy(c, 0, this.coefficients, 0, l); +077 } +078 +079 /** +080 * Compute the value of the function for the given argument. +081 * <p> +082 * The value returned is <br> +083 * <code>coefficients[n] * x^n + ... + coefficients[1] * x + coefficients[0]</code> +084 * </p> +085 * +086 * @param x the argument for which the function value should be computed +087 * @return the value of the polynomial at the given point +088 * @see UnivariateRealFunction#value(double) +089 */ +090 public double value(double x) { +091 return evaluate(coefficients, x); +092 } +093 +094 +095 /** +096 * Returns the degree of the polynomial +097 * +098 * @return the degree of the polynomial +099 */ +100 public int degree() { +101 return coefficients.length - 1; +102 } +103 +104 /** +105 * Returns a copy of the coefficients array. +106 * <p> +107 * Changes made to the returned copy will not affect the coefficients of +108 * the polynomial.</p> +109 * +110 * @return a fresh copy of the coefficients array +111 */ +112 public double[] getCoefficients() { +113 return coefficients.clone(); +114 } +115 +116 /** +117 * Uses Horner's Method to evaluate the polynomial with the given coefficients at +118 * the argument. +119 * +120 * @param coefficients the coefficients of the polynomial to evaluate +121 * @param argument the input value +122 * @return the value of the polynomial +123 * @throws IllegalArgumentException if coefficients is empty +124 * @throws NullPointerException if coefficients is null +125 */ +126 protected static double evaluate(double[] coefficients, double argument) { +127 int n = coefficients.length; +128 if (n < 1) { +129 throw MathRuntimeException.createIllegalArgumentException(EMPTY_ARRAY_MESSAGE); +130 } +131 double result = coefficients[n - 1]; +132 for (int j = n -2; j >=0; j--) { +133 result = argument * result + coefficients[j]; +134 } +135 return result; +136 } +137 +138 /** +139 * Add a polynomial to the instance. +140 * @param p polynomial to add +141 * @return a new polynomial which is the sum of the instance and p +142 */ +143 public PolynomialFunction add(final PolynomialFunction p) { +144 +145 // identify the lowest degree polynomial +146 final int lowLength = Math.min(coefficients.length, p.coefficients.length); +147 final int highLength = Math.max(coefficients.length, p.coefficients.length); +148 +149 // build the coefficients array +150 double[] newCoefficients = new double[highLength]; +151 for (int i = 0; i < lowLength; ++i) { +152 newCoefficients[i] = coefficients[i] + p.coefficients[i]; +153 } +154 System.arraycopy((coefficients.length < p.coefficients.length) ? +155 p.coefficients : coefficients, +156 lowLength, +157 newCoefficients, lowLength, +158 highLength - lowLength); +159 +160 return new PolynomialFunction(newCoefficients); +161 +162 } +163 +164 /** +165 * Subtract a polynomial from the instance. +166 * @param p polynomial to subtract +167 * @return a new polynomial which is the difference the instance minus p +168 */ +169 public PolynomialFunction subtract(final PolynomialFunction p) { +170 +171 // identify the lowest degree polynomial +172 int lowLength = Math.min(coefficients.length, p.coefficients.length); +173 int highLength = Math.max(coefficients.length, p.coefficients.length); +174 +175 // build the coefficients array +176 double[] newCoefficients = new double[highLength]; +177 for (int i = 0; i < lowLength; ++i) { +178 newCoefficients[i] = coefficients[i] - p.coefficients[i]; +179 } +180 if (coefficients.length < p.coefficients.length) { +181 for (int i = lowLength; i < highLength; ++i) { +182 newCoefficients[i] = -p.coefficients[i]; +183 } +184 } else { +185 System.arraycopy(coefficients, lowLength, newCoefficients, lowLength, +186 highLength - lowLength); +187 } +188 +189 return new PolynomialFunction(newCoefficients); +190 +191 } +192 +193 /** +194 * Negate the instance. +195 * @return a new polynomial +196 */ +197 public PolynomialFunction negate() { +198 double[] newCoefficients = new double[coefficients.length]; +199 for (int i = 0; i < coefficients.length; ++i) { +200 newCoefficients[i] = -coefficients[i]; +201 } +202 return new PolynomialFunction(newCoefficients); +203 } +204 +205 /** +206 * Multiply the instance by a polynomial. +207 * @param p polynomial to multiply by +208 * @return a new polynomial +209 */ +210 public PolynomialFunction multiply(final PolynomialFunction p) { +211 +212 double[] newCoefficients = new double[coefficients.length + p.coefficients.length - 1]; +213 +214 for (int i = 0; i < newCoefficients.length; ++i) { +215 newCoefficients[i] = 0.0; +216 for (int j = Math.max(0, i + 1 - p.coefficients.length); +217 j < Math.min(coefficients.length, i + 1); +218 ++j) { +219 newCoefficients[i] += coefficients[j] * p.coefficients[i-j]; +220 } +221 } +222 +223 return new PolynomialFunction(newCoefficients); +224 +225 } +226 +227 /** +228 * Returns the coefficients of the derivative of the polynomial with the given coefficients. +229 * +230 * @param coefficients the coefficients of the polynomial to differentiate +231 * @return the coefficients of the derivative or null if coefficients has length 1. +232 * @throws IllegalArgumentException if coefficients is empty +233 * @throws NullPointerException if coefficients is null +234 */ +235 protected static double[] differentiate(double[] coefficients) { +236 int n = coefficients.length; +237 if (n < 1) { +238 throw MathRuntimeException.createIllegalArgumentException(EMPTY_ARRAY_MESSAGE); +239 } +240 if (n == 1) { +241 return new double[]{0}; +242 } +243 double[] result = new double[n - 1]; +244 for (int i = n - 1; i > 0; i--) { +245 result[i - 1] = i * coefficients[i]; +246 } +247 return result; +248 } +249 +250 /** +251 * Returns the derivative as a PolynomialRealFunction +252 * +253 * @return the derivative polynomial +254 */ +255 public PolynomialFunction polynomialDerivative() { +256 return new PolynomialFunction(differentiate(coefficients)); +257 } +258 +259 /** +260 * Returns the derivative as a UnivariateRealFunction +261 * +262 * @return the derivative function +263 */ +264 public UnivariateRealFunction derivative() { +265 return polynomialDerivative(); +266 } +267 +268 /** Returns a string representation of the polynomial. +269 +270 * <p>The representation is user oriented. Terms are displayed lowest +271 * degrees first. The multiplications signs, coefficients equals to +272 * one and null terms are not displayed (except if the polynomial is 0, +273 * in which case the 0 constant term is displayed). Addition of terms +274 * with negative coefficients are replaced by subtraction of terms +275 * with positive coefficients except for the first displayed term +276 * (i.e. we display <code>-3</code> for a constant negative polynomial, +277 * but <code>1 - 3 x + x^2</code> if the negative coefficient is not +278 * the first one displayed).</p> +279 +280 * @return a string representation of the polynomial +281 +282 */ +283 @Override +284 public String toString() { +285 +286 StringBuffer s = new StringBuffer(); +287 if (coefficients[0] == 0.0) { +288 if (coefficients.length == 1) { +289 return "0"; +290 } +291 } else { +292 s.append(Double.toString(coefficients[0])); +293 } +294 +295 for (int i = 1; i < coefficients.length; ++i) { +296 +297 if (coefficients[i] != 0) { +298 +299 if (s.length() > 0) { +300 if (coefficients[i] < 0) { +301 s.append(" - "); +302 } else { +303 s.append(" + "); +304 } +305 } else { +306 if (coefficients[i] < 0) { +307 s.append("-"); +308 } +309 } +310 +311 double absAi = Math.abs(coefficients[i]); +312 if ((absAi - 1) != 0) { +313 s.append(Double.toString(absAi)); +314 s.append(' '); +315 } +316 +317 s.append("x"); +318 if (i > 1) { +319 s.append('^'); +320 s.append(Integer.toString(i)); +321 } +322 } +323 +324 } +325 +326 return s.toString(); +327 +328 } +329 +330 /** {@inheritDoc} */ +331 @Override +332 public int hashCode() { +333 final int prime = 31; +334 int result = 1; +335 result = prime * result + Arrays.hashCode(coefficients); +336 return result; +337 } +338 +339 /** {@inheritDoc} */ +340 @Override +341 public boolean equals(Object obj) { +342 if (this == obj) +343 return true; +344 if (!(obj instanceof PolynomialFunction)) +345 return false; +346 PolynomialFunction other = (PolynomialFunction) obj; +347 if (!Arrays.equals(coefficients, other.coefficients)) +348 return false; +349 return true; +350 } +351 +352 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/polynomials/PolynomialFunctionLagrangeForm.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/polynomials/PolynomialFunctionLagrangeForm.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,375 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.polynomials; +018 +019 import org.apache.commons.math.DuplicateSampleAbscissaException; +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.analysis.UnivariateRealFunction; +023 +024 /** +025 * Implements the representation of a real polynomial function in +026 * <a href="http://mathworld.wolfram.com/LagrangeInterpolatingPolynomial.html"> +027 * Lagrange Form</a>. For reference, see <b>Introduction to Numerical +028 * Analysis</b>, ISBN 038795452X, chapter 2. +029 * <p> +030 * The approximated function should be smooth enough for Lagrange polynomial +031 * to work well. Otherwise, consider using splines instead.</p> +032 * +033 * @version $Revision: 922708 $ $Date: 2010-03-13 20:15:47 -0500 (Sat, 13 Mar 2010) $ +034 * @since 1.2 +035 */ +036 public class PolynomialFunctionLagrangeForm implements UnivariateRealFunction { +037 +038 /** +039 * The coefficients of the polynomial, ordered by degree -- i.e. +040 * coefficients[0] is the constant term and coefficients[n] is the +041 * coefficient of x^n where n is the degree of the polynomial. +042 */ +043 private double coefficients[]; +044 +045 /** +046 * Interpolating points (abscissas). +047 */ +048 private final double x[]; +049 +050 /** +051 * Function values at interpolating points. +052 */ +053 private final double y[]; +054 +055 /** +056 * Whether the polynomial coefficients are available. +057 */ +058 private boolean coefficientsComputed; +059 +060 /** +061 * Construct a Lagrange polynomial with the given abscissas and function +062 * values. The order of interpolating points are not important. +063 * <p> +064 * The constructor makes copy of the input arrays and assigns them.</p> +065 * +066 * @param x interpolating points +067 * @param y function values at interpolating points +068 * @throws IllegalArgumentException if input arrays are not valid +069 */ +070 public PolynomialFunctionLagrangeForm(double x[], double y[]) +071 throws IllegalArgumentException { +072 +073 verifyInterpolationArray(x, y); +074 this.x = new double[x.length]; +075 this.y = new double[y.length]; +076 System.arraycopy(x, 0, this.x, 0, x.length); +077 System.arraycopy(y, 0, this.y, 0, y.length); +078 coefficientsComputed = false; +079 } +080 +081 /** +082 * Calculate the function value at the given point. +083 * +084 * @param z the point at which the function value is to be computed +085 * @return the function value +086 * @throws FunctionEvaluationException if a runtime error occurs +087 * @see UnivariateRealFunction#value(double) +088 */ +089 public double value(double z) throws FunctionEvaluationException { +090 try { +091 return evaluate(x, y, z); +092 } catch (DuplicateSampleAbscissaException e) { +093 throw new FunctionEvaluationException(e, z, e.getPattern(), e.getArguments()); +094 } +095 } +096 +097 /** +098 * Returns the degree of the polynomial. +099 * +100 * @return the degree of the polynomial +101 */ +102 public int degree() { +103 return x.length - 1; +104 } +105 +106 /** +107 * Returns a copy of the interpolating points array. +108 * <p> +109 * Changes made to the returned copy will not affect the polynomial.</p> +110 * +111 * @return a fresh copy of the interpolating points array +112 */ +113 public double[] getInterpolatingPoints() { +114 double[] out = new double[x.length]; +115 System.arraycopy(x, 0, out, 0, x.length); +116 return out; +117 } +118 +119 /** +120 * Returns a copy of the interpolating values array. +121 * <p> +122 * Changes made to the returned copy will not affect the polynomial.</p> +123 * +124 * @return a fresh copy of the interpolating values array +125 */ +126 public double[] getInterpolatingValues() { +127 double[] out = new double[y.length]; +128 System.arraycopy(y, 0, out, 0, y.length); +129 return out; +130 } +131 +132 /** +133 * Returns a copy of the coefficients array. +134 * <p> +135 * Changes made to the returned copy will not affect the polynomial.</p> +136 * <p> +137 * Note that coefficients computation can be ill-conditioned. Use with caution +138 * and only when it is necessary.</p> +139 * +140 * @return a fresh copy of the coefficients array +141 */ +142 public double[] getCoefficients() { +143 if (!coefficientsComputed) { +144 computeCoefficients(); +145 } +146 double[] out = new double[coefficients.length]; +147 System.arraycopy(coefficients, 0, out, 0, coefficients.length); +148 return out; +149 } +150 +151 /** +152 * Evaluate the Lagrange polynomial using +153 * <a href="http://mathworld.wolfram.com/NevillesAlgorithm.html"> +154 * Neville's Algorithm</a>. It takes O(N^2) time. +155 * <p> +156 * This function is made public static so that users can call it directly +157 * without instantiating PolynomialFunctionLagrangeForm object.</p> +158 * +159 * @param x the interpolating points array +160 * @param y the interpolating values array +161 * @param z the point at which the function value is to be computed +162 * @return the function value +163 * @throws DuplicateSampleAbscissaException if the sample has duplicate abscissas +164 * @throws IllegalArgumentException if inputs are not valid +165 */ +166 public static double evaluate(double x[], double y[], double z) throws +167 DuplicateSampleAbscissaException, IllegalArgumentException { +168 +169 verifyInterpolationArray(x, y); +170 +171 int nearest = 0; +172 final int n = x.length; +173 final double[] c = new double[n]; +174 final double[] d = new double[n]; +175 double min_dist = Double.POSITIVE_INFINITY; +176 for (int i = 0; i < n; i++) { +177 // initialize the difference arrays +178 c[i] = y[i]; +179 d[i] = y[i]; +180 // find out the abscissa closest to z +181 final double dist = Math.abs(z - x[i]); +182 if (dist < min_dist) { +183 nearest = i; +184 min_dist = dist; +185 } +186 } +187 +188 // initial approximation to the function value at z +189 double value = y[nearest]; +190 +191 for (int i = 1; i < n; i++) { +192 for (int j = 0; j < n-i; j++) { +193 final double tc = x[j] - z; +194 final double td = x[i+j] - z; +195 final double divider = x[j] - x[i+j]; +196 if (divider == 0.0) { +197 // This happens only when two abscissas are identical. +198 throw new DuplicateSampleAbscissaException(x[i], i, i+j); +199 } +200 // update the difference arrays +201 final double w = (c[j+1] - d[j]) / divider; +202 c[j] = tc * w; +203 d[j] = td * w; +204 } +205 // sum up the difference terms to get the final value +206 if (nearest < 0.5*(n-i+1)) { +207 value += c[nearest]; // fork down +208 } else { +209 nearest--; +210 value += d[nearest]; // fork up +211 } +212 } +213 +214 return value; +215 } +216 +217 /** +218 * Calculate the coefficients of Lagrange polynomial from the +219 * interpolation data. It takes O(N^2) time. +220 * <p> +221 * Note this computation can be ill-conditioned. Use with caution +222 * and only when it is necessary.</p> +223 * +224 * @throws ArithmeticException if any abscissas coincide +225 */ +226 protected void computeCoefficients() throws ArithmeticException { +227 +228 final int n = degree() + 1; +229 coefficients = new double[n]; +230 for (int i = 0; i < n; i++) { +231 coefficients[i] = 0.0; +232 } +233 +234 // c[] are the coefficients of P(x) = (x-x[0])(x-x[1])...(x-x[n-1]) +235 final double[] c = new double[n+1]; +236 c[0] = 1.0; +237 for (int i = 0; i < n; i++) { +238 for (int j = i; j > 0; j--) { +239 c[j] = c[j-1] - c[j] * x[i]; +240 } +241 c[0] *= -x[i]; +242 c[i+1] = 1; +243 } +244 +245 final double[] tc = new double[n]; +246 for (int i = 0; i < n; i++) { +247 // d = (x[i]-x[0])...(x[i]-x[i-1])(x[i]-x[i+1])...(x[i]-x[n-1]) +248 double d = 1; +249 for (int j = 0; j < n; j++) { +250 if (i != j) { +251 d *= x[i] - x[j]; +252 } +253 } +254 if (d == 0.0) { +255 // This happens only when two abscissas are identical. +256 for (int k = 0; k < n; ++k) { +257 if ((i != k) && (x[i] == x[k])) { +258 throw MathRuntimeException.createArithmeticException("identical abscissas x[{0}] == x[{1}] == {2} cause division by zero", +259 i, k, x[i]); +260 } +261 } +262 } +263 final double t = y[i] / d; +264 // Lagrange polynomial is the sum of n terms, each of which is a +265 // polynomial of degree n-1. tc[] are the coefficients of the i-th +266 // numerator Pi(x) = (x-x[0])...(x-x[i-1])(x-x[i+1])...(x-x[n-1]). +267 tc[n-1] = c[n]; // actually c[n] = 1 +268 coefficients[n-1] += t * tc[n-1]; +269 for (int j = n-2; j >= 0; j--) { +270 tc[j] = c[j+1] + tc[j+1] * x[i]; +271 coefficients[j] += t * tc[j]; +272 } +273 } +274 +275 coefficientsComputed = true; +276 } +277 +278 /** +279 * Verifies that the interpolation arrays are valid. +280 * <p> +281 * The arrays features checked by this method are that both arrays have the +282 * same length and this length is at least 2. +283 * </p> +284 * <p> +285 * The interpolating points must be distinct. However it is not +286 * verified here, it is checked in evaluate() and computeCoefficients(). +287 * </p> +288 * +289 * @param x the interpolating points array +290 * @param y the interpolating values array +291 * @throws IllegalArgumentException if not valid +292 * @see #evaluate(double[], double[], double) +293 * @see #computeCoefficients() +294 */ +295 public static void verifyInterpolationArray(double x[], double y[]) +296 throws IllegalArgumentException { +297 +298 if (x.length != y.length) { +299 throw MathRuntimeException.createIllegalArgumentException( +300 "dimension mismatch {0} != {1}", x.length, y.length); +301 } +302 +303 if (x.length < 2) { +304 throw MathRuntimeException.createIllegalArgumentException( +305 "{0} points are required, got only {1}", 2, x.length); +306 } +307 +308 } +309 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/polynomials/PolynomialFunctionNewtonForm.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/polynomials/PolynomialFunctionNewtonForm.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,286 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.polynomials; +018 +019 import org.apache.commons.math.FunctionEvaluationException; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.analysis.UnivariateRealFunction; +022 +023 /** +024 * Implements the representation of a real polynomial function in +025 * Newton Form. For reference, see <b>Elementary Numerical Analysis</b>, +026 * ISBN 0070124477, chapter 2. +027 * <p> +028 * The formula of polynomial in Newton form is +029 * p(x) = a[0] + a[1](x-c[0]) + a[2](x-c[0])(x-c[1]) + ... + +030 * a[n](x-c[0])(x-c[1])...(x-c[n-1]) +031 * Note that the length of a[] is one more than the length of c[]</p> +032 * +033 * @version $Revision: 922708 $ $Date: 2010-03-13 20:15:47 -0500 (Sat, 13 Mar 2010) $ +034 * @since 1.2 +035 */ +036 public class PolynomialFunctionNewtonForm implements UnivariateRealFunction { +037 +038 /** +039 * The coefficients of the polynomial, ordered by degree -- i.e. +040 * coefficients[0] is the constant term and coefficients[n] is the +041 * coefficient of x^n where n is the degree of the polynomial. +042 */ +043 private double coefficients[]; +044 +045 /** +046 * Centers of the Newton polynomial. +047 */ +048 private final double c[]; +049 +050 /** +051 * When all c[i] = 0, a[] becomes normal polynomial coefficients, +052 * i.e. a[i] = coefficients[i]. +053 */ +054 private final double a[]; +055 +056 /** +057 * Whether the polynomial coefficients are available. +058 */ +059 private boolean coefficientsComputed; +060 +061 /** +062 * Construct a Newton polynomial with the given a[] and c[]. The order of +063 * centers are important in that if c[] shuffle, then values of a[] would +064 * completely change, not just a permutation of old a[]. +065 * <p> +066 * The constructor makes copy of the input arrays and assigns them.</p> +067 * +068 * @param a the coefficients in Newton form formula +069 * @param c the centers +070 * @throws IllegalArgumentException if input arrays are not valid +071 */ +072 public PolynomialFunctionNewtonForm(double a[], double c[]) +073 throws IllegalArgumentException { +074 +075 verifyInputArray(a, c); +076 this.a = new double[a.length]; +077 this.c = new double[c.length]; +078 System.arraycopy(a, 0, this.a, 0, a.length); +079 System.arraycopy(c, 0, this.c, 0, c.length); +080 coefficientsComputed = false; +081 } +082 +083 /** +084 * Calculate the function value at the given point. +085 * +086 * @param z the point at which the function value is to be computed +087 * @return the function value +088 * @throws FunctionEvaluationException if a runtime error occurs +089 * @see UnivariateRealFunction#value(double) +090 */ +091 public double value(double z) throws FunctionEvaluationException { +092 return evaluate(a, c, z); +093 } +094 +095 /** +096 * Returns the degree of the polynomial. +097 * +098 * @return the degree of the polynomial +099 */ +100 public int degree() { +101 return c.length; +102 } +103 +104 /** +105 * Returns a copy of coefficients in Newton form formula. +106 * <p> +107 * Changes made to the returned copy will not affect the polynomial.</p> +108 * +109 * @return a fresh copy of coefficients in Newton form formula +110 */ +111 public double[] getNewtonCoefficients() { +112 double[] out = new double[a.length]; +113 System.arraycopy(a, 0, out, 0, a.length); +114 return out; +115 } +116 +117 /** +118 * Returns a copy of the centers array. +119 * <p> +120 * Changes made to the returned copy will not affect the polynomial.</p> +121 * +122 * @return a fresh copy of the centers array +123 */ +124 public double[] getCenters() { +125 double[] out = new double[c.length]; +126 System.arraycopy(c, 0, out, 0, c.length); +127 return out; +128 } +129 +130 /** +131 * Returns a copy of the coefficients array. +132 * <p> +133 * Changes made to the returned copy will not affect the polynomial.</p> +134 * +135 * @return a fresh copy of the coefficients array +136 */ +137 public double[] getCoefficients() { +138 if (!coefficientsComputed) { +139 computeCoefficients(); +140 } +141 double[] out = new double[coefficients.length]; +142 System.arraycopy(coefficients, 0, out, 0, coefficients.length); +143 return out; +144 } +145 +146 /** +147 * Evaluate the Newton polynomial using nested multiplication. It is +148 * also called <a href="http://mathworld.wolfram.com/HornersRule.html"> +149 * Horner's Rule</a> and takes O(N) time. +150 * +151 * @param a the coefficients in Newton form formula +152 * @param c the centers +153 * @param z the point at which the function value is to be computed +154 * @return the function value +155 * @throws FunctionEvaluationException if a runtime error occurs +156 * @throws IllegalArgumentException if inputs are not valid +157 */ +158 public static double evaluate(double a[], double c[], double z) throws +159 FunctionEvaluationException, IllegalArgumentException { +160 +161 verifyInputArray(a, c); +162 +163 int n = c.length; +164 double value = a[n]; +165 for (int i = n-1; i >= 0; i--) { +166 value = a[i] + (z - c[i]) * value; +167 } +168 +169 return value; +170 } +171 +172 /** +173 * Calculate the normal polynomial coefficients given the Newton form. +174 * It also uses nested multiplication but takes O(N^2) time. +175 */ +176 protected void computeCoefficients() { +177 final int n = degree(); +178 +179 coefficients = new double[n+1]; +180 for (int i = 0; i <= n; i++) { +181 coefficients[i] = 0.0; +182 } +183 +184 coefficients[0] = a[n]; +185 for (int i = n-1; i >= 0; i--) { +186 for (int j = n-i; j > 0; j--) { +187 coefficients[j] = coefficients[j-1] - c[i] * coefficients[j]; +188 } +189 coefficients[0] = a[i] - c[i] * coefficients[0]; +190 } +191 +192 coefficientsComputed = true; +193 } +194 +195 /** +196 * Verifies that the input arrays are valid. +197 * <p> +198 * The centers must be distinct for interpolation purposes, but not +199 * for general use. Thus it is not verified here.</p> +200 * +201 * @param a the coefficients in Newton form formula +202 * @param c the centers +203 * @throws IllegalArgumentException if not valid +204 * @see org.apache.commons.math.analysis.interpolation.DividedDifferenceInterpolator#computeDividedDifference(double[], +205 * double[]) +206 */ +207 protected static void verifyInputArray(double a[], double c[]) throws +208 IllegalArgumentException { +209 +210 if (a.length < 1 || c.length < 1) { +211 throw MathRuntimeException.createIllegalArgumentException( +212 "empty polynomials coefficients array"); +213 } +214 if (a.length != c.length + 1) { +215 throw MathRuntimeException.createIllegalArgumentException( +216 "array sizes should have difference 1 ({0} != {1} + 1)", +217 a.length, c.length); +218 } +219 } +220 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/polynomials/PolynomialSplineFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/polynomials/PolynomialSplineFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,293 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.polynomials; +018 +019 import java.util.Arrays; +020 +021 import org.apache.commons.math.ArgumentOutsideDomainException; +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction; +024 import org.apache.commons.math.analysis.UnivariateRealFunction; +025 +026 /** +027 * Represents a polynomial spline function. +028 * <p> +029 * A <strong>polynomial spline function</strong> consists of a set of +030 * <i>interpolating polynomials</i> and an ascending array of domain +031 * <i>knot points</i>, determining the intervals over which the spline function +032 * is defined by the constituent polynomials. The polynomials are assumed to +033 * have been computed to match the values of another function at the knot +034 * points. The value consistency constraints are not currently enforced by +035 * <code>PolynomialSplineFunction</code> itself, but are assumed to hold among +036 * the polynomials and knot points passed to the constructor.</p> +037 * <p> +038 * N.B.: The polynomials in the <code>polynomials</code> property must be +039 * centered on the knot points to compute the spline function values. +040 * See below.</p> +041 * <p> +042 * The domain of the polynomial spline function is +043 * <code>[smallest knot, largest knot]</code>. Attempts to evaluate the +044 * function at values outside of this range generate IllegalArgumentExceptions. +045 * </p> +046 * <p> +047 * The value of the polynomial spline function for an argument <code>x</code> +048 * is computed as follows: +049 * <ol> +050 * <li>The knot array is searched to find the segment to which <code>x</code> +051 * belongs. If <code>x</code> is less than the smallest knot point or greater +052 * than the largest one, an <code>IllegalArgumentException</code> +053 * is thrown.</li> +054 * <li> Let <code>j</code> be the index of the largest knot point that is less +055 * than or equal to <code>x</code>. The value returned is <br> +056 * <code>polynomials[j](x - knot[j])</code></li></ol></p> +057 * +058 * @version $Revision: 922708 $ $Date: 2010-03-13 20:15:47 -0500 (Sat, 13 Mar 2010) $ +059 */ +060 public class PolynomialSplineFunction +061 implements DifferentiableUnivariateRealFunction { +062 +063 /** Spline segment interval delimiters (knots). Size is n+1 for n segments. */ +064 private final double knots[]; +065 +066 /** +067 * The polynomial functions that make up the spline. The first element +068 * determines the value of the spline over the first subinterval, the +069 * second over the second, etc. Spline function values are determined by +070 * evaluating these functions at <code>(x - knot[i])</code> where i is the +071 * knot segment to which x belongs. +072 */ +073 private final PolynomialFunction polynomials[]; +074 +075 /** +076 * Number of spline segments = number of polynomials +077 * = number of partition points - 1 +078 */ +079 private final int n; +080 +081 +082 /** +083 * Construct a polynomial spline function with the given segment delimiters +084 * and interpolating polynomials. +085 * <p> +086 * The constructor copies both arrays and assigns the copies to the knots +087 * and polynomials properties, respectively.</p> +088 * +089 * @param knots spline segment interval delimiters +090 * @param polynomials polynomial functions that make up the spline +091 * @throws NullPointerException if either of the input arrays is null +092 * @throws IllegalArgumentException if knots has length less than 2, +093 * <code>polynomials.length != knots.length - 1 </code>, or the knots array +094 * is not strictly increasing. +095 * +096 */ +097 public PolynomialSplineFunction(double knots[], PolynomialFunction polynomials[]) { +098 if (knots.length < 2) { +099 throw MathRuntimeException.createIllegalArgumentException( +100 "spline partition must have at least {0} points, got {1}", +101 2, knots.length); +102 } +103 if (knots.length - 1 != polynomials.length) { +104 throw MathRuntimeException.createIllegalArgumentException( +105 "number of polynomial interpolants must match the number of segments ({0} != {1} - 1)", +106 polynomials.length, knots.length); +107 } +108 if (!isStrictlyIncreasing(knots)) { +109 throw MathRuntimeException.createIllegalArgumentException( +110 "knot values must be strictly increasing"); +111 } +112 +113 this.n = knots.length -1; +114 this.knots = new double[n + 1]; +115 System.arraycopy(knots, 0, this.knots, 0, n + 1); +116 this.polynomials = new PolynomialFunction[n]; +117 System.arraycopy(polynomials, 0, this.polynomials, 0, n); +118 } +119 +120 /** +121 * Compute the value for the function. +122 * <p> +123 * Throws FunctionEvaluationException if v is outside of the domain of the +124 * function. The domain is [smallest knot, largest knot].</p> +125 * <p> +126 * See {@link PolynomialSplineFunction} for details on the algorithm for +127 * computing the value of the function.</p> +128 * +129 * @param v the point for which the function value should be computed +130 * @return the value +131 * @throws ArgumentOutsideDomainException if v is outside of the domain of +132 * of the spline function (less than the smallest knot point or greater +133 * than the largest knot point) +134 */ +135 public double value(double v) throws ArgumentOutsideDomainException { +136 if (v < knots[0] || v > knots[n]) { +137 throw new ArgumentOutsideDomainException(v, knots[0], knots[n]); +138 } +139 int i = Arrays.binarySearch(knots, v); +140 if (i < 0) { +141 i = -i - 2; +142 } +143 //This will handle the case where v is the last knot value +144 //There are only n-1 polynomials, so if v is the last knot +145 //then we will use the last polynomial to calculate the value. +146 if ( i >= polynomials.length ) { +147 i--; +148 } +149 return polynomials[i].value(v - knots[i]); +150 } +151 +152 /** +153 * Returns the derivative of the polynomial spline function as a UnivariateRealFunction +154 * @return the derivative function +155 */ +156 public UnivariateRealFunction derivative() { +157 return polynomialSplineDerivative(); +158 } +159 +160 /** +161 * Returns the derivative of the polynomial spline function as a PolynomialSplineFunction +162 * +163 * @return the derivative function +164 */ +165 public PolynomialSplineFunction polynomialSplineDerivative() { +166 PolynomialFunction derivativePolynomials[] = new PolynomialFunction[n]; +167 for (int i = 0; i < n; i++) { +168 derivativePolynomials[i] = polynomials[i].polynomialDerivative(); +169 } +170 return new PolynomialSplineFunction(knots, derivativePolynomials); +171 } +172 +173 /** +174 * Returns the number of spline segments = the number of polynomials +175 * = the number of knot points - 1. +176 * +177 * @return the number of spline segments +178 */ +179 public int getN() { +180 return n; +181 } +182 +183 /** +184 * Returns a copy of the interpolating polynomials array. +185 * <p> +186 * Returns a fresh copy of the array. Changes made to the copy will +187 * not affect the polynomials property.</p> +188 * +189 * @return the interpolating polynomials +190 */ +191 public PolynomialFunction[] getPolynomials() { +192 PolynomialFunction p[] = new PolynomialFunction[n]; +193 System.arraycopy(polynomials, 0, p, 0, n); +194 return p; +195 } +196 +197 /** +198 * Returns an array copy of the knot points. +199 * <p> +200 * Returns a fresh copy of the array. Changes made to the copy +201 * will not affect the knots property.</p> +202 * +203 * @return the knot points +204 */ +205 public double[] getKnots() { +206 double out[] = new double[n + 1]; +207 System.arraycopy(knots, 0, out, 0, n + 1); +208 return out; +209 } +210 +211 /** +212 * Determines if the given array is ordered in a strictly increasing +213 * fashion. +214 * +215 * @param x the array to examine. +216 * @return <code>true</code> if the elements in <code>x</code> are ordered +217 * in a stricly increasing manner. <code>false</code>, otherwise. +218 */ +219 private static boolean isStrictlyIncreasing(double[] x) { +220 for (int i = 1; i < x.length; ++i) { +221 if (x[i - 1] >= x[i]) { +222 return false; +223 } +224 } +225 return true; +226 } +227 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/polynomials/PolynomialsUtils.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/polynomials/PolynomialsUtils.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,346 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.polynomials; +018 +019 import java.util.ArrayList; +020 +021 import org.apache.commons.math.fraction.BigFraction; +022 +023 /** +024 * A collection of static methods that operate on or return polynomials. +025 * +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 * @since 2.0 +028 */ +029 public class PolynomialsUtils { +030 +031 /** Coefficients for Chebyshev polynomials. */ +032 private static final ArrayList<BigFraction> CHEBYSHEV_COEFFICIENTS; +033 +034 /** Coefficients for Hermite polynomials. */ +035 private static final ArrayList<BigFraction> HERMITE_COEFFICIENTS; +036 +037 /** Coefficients for Laguerre polynomials. */ +038 private static final ArrayList<BigFraction> LAGUERRE_COEFFICIENTS; +039 +040 /** Coefficients for Legendre polynomials. */ +041 private static final ArrayList<BigFraction> LEGENDRE_COEFFICIENTS; +042 +043 static { +044 +045 // initialize recurrence for Chebyshev polynomials +046 // T0(X) = 1, T1(X) = 0 + 1 * X +047 CHEBYSHEV_COEFFICIENTS = new ArrayList<BigFraction>(); +048 CHEBYSHEV_COEFFICIENTS.add(BigFraction.ONE); +049 CHEBYSHEV_COEFFICIENTS.add(BigFraction.ZERO); +050 CHEBYSHEV_COEFFICIENTS.add(BigFraction.ONE); +051 +052 // initialize recurrence for Hermite polynomials +053 // H0(X) = 1, H1(X) = 0 + 2 * X +054 HERMITE_COEFFICIENTS = new ArrayList<BigFraction>(); +055 HERMITE_COEFFICIENTS.add(BigFraction.ONE); +056 HERMITE_COEFFICIENTS.add(BigFraction.ZERO); +057 HERMITE_COEFFICIENTS.add(BigFraction.TWO); +058 +059 // initialize recurrence for Laguerre polynomials +060 // L0(X) = 1, L1(X) = 1 - 1 * X +061 LAGUERRE_COEFFICIENTS = new ArrayList<BigFraction>(); +062 LAGUERRE_COEFFICIENTS.add(BigFraction.ONE); +063 LAGUERRE_COEFFICIENTS.add(BigFraction.ONE); +064 LAGUERRE_COEFFICIENTS.add(BigFraction.MINUS_ONE); +065 +066 // initialize recurrence for Legendre polynomials +067 // P0(X) = 1, P1(X) = 0 + 1 * X +068 LEGENDRE_COEFFICIENTS = new ArrayList<BigFraction>(); +069 LEGENDRE_COEFFICIENTS.add(BigFraction.ONE); +070 LEGENDRE_COEFFICIENTS.add(BigFraction.ZERO); +071 LEGENDRE_COEFFICIENTS.add(BigFraction.ONE); +072 +073 } +074 +075 /** +076 * Private constructor, to prevent instantiation. +077 */ +078 private PolynomialsUtils() { +079 } +080 +081 /** +082 * Create a Chebyshev polynomial of the first kind. +083 * <p><a href="http://mathworld.wolfram.com/ChebyshevPolynomialoftheFirstKind.html">Chebyshev +084 * polynomials of the first kind</a> are orthogonal polynomials. +085 * They can be defined by the following recurrence relations: +086 * <pre> +087 * T<sub>0</sub>(X) = 1 +088 * T<sub>1</sub>(X) = X +089 * T<sub>k+1</sub>(X) = 2X T<sub>k</sub>(X) - T<sub>k-1</sub>(X) +090 * </pre></p> +091 * @param degree degree of the polynomial +092 * @return Chebyshev polynomial of specified degree +093 */ +094 public static PolynomialFunction createChebyshevPolynomial(final int degree) { +095 return buildPolynomial(degree, CHEBYSHEV_COEFFICIENTS, +096 new RecurrenceCoefficientsGenerator() { +097 private final BigFraction[] coeffs = { BigFraction.ZERO, BigFraction.TWO, BigFraction.ONE }; +098 /** {@inheritDoc} */ +099 public BigFraction[] generate(int k) { +100 return coeffs; +101 } +102 }); +103 } +104 +105 /** +106 * Create a Hermite polynomial. +107 * <p><a href="http://mathworld.wolfram.com/HermitePolynomial.html">Hermite +108 * polynomials</a> are orthogonal polynomials. +109 * They can be defined by the following recurrence relations: +110 * <pre> +111 * H<sub>0</sub>(X) = 1 +112 * H<sub>1</sub>(X) = 2X +113 * H<sub>k+1</sub>(X) = 2X H<sub>k</sub>(X) - 2k H<sub>k-1</sub>(X) +114 * </pre></p> +115 +116 * @param degree degree of the polynomial +117 * @return Hermite polynomial of specified degree +118 */ +119 public static PolynomialFunction createHermitePolynomial(final int degree) { +120 return buildPolynomial(degree, HERMITE_COEFFICIENTS, +121 new RecurrenceCoefficientsGenerator() { +122 /** {@inheritDoc} */ +123 public BigFraction[] generate(int k) { +124 return new BigFraction[] { +125 BigFraction.ZERO, +126 BigFraction.TWO, +127 new BigFraction(2 * k)}; +128 } +129 }); +130 } +131 +132 /** +133 * Create a Laguerre polynomial. +134 * <p><a href="http://mathworld.wolfram.com/LaguerrePolynomial.html">Laguerre +135 * polynomials</a> are orthogonal polynomials. +136 * They can be defined by the following recurrence relations: +137 * <pre> +138 * L<sub>0</sub>(X) = 1 +139 * L<sub>1</sub>(X) = 1 - X +140 * (k+1) L<sub>k+1</sub>(X) = (2k + 1 - X) L<sub>k</sub>(X) - k L<sub>k-1</sub>(X) +141 * </pre></p> +142 * @param degree degree of the polynomial +143 * @return Laguerre polynomial of specified degree +144 */ +145 public static PolynomialFunction createLaguerrePolynomial(final int degree) { +146 return buildPolynomial(degree, LAGUERRE_COEFFICIENTS, +147 new RecurrenceCoefficientsGenerator() { +148 /** {@inheritDoc} */ +149 public BigFraction[] generate(int k) { +150 final int kP1 = k + 1; +151 return new BigFraction[] { +152 new BigFraction(2 * k + 1, kP1), +153 new BigFraction(-1, kP1), +154 new BigFraction(k, kP1)}; +155 } +156 }); +157 } +158 +159 /** +160 * Create a Legendre polynomial. +161 * <p><a href="http://mathworld.wolfram.com/LegendrePolynomial.html">Legendre +162 * polynomials</a> are orthogonal polynomials. +163 * They can be defined by the following recurrence relations: +164 * <pre> +165 * P<sub>0</sub>(X) = 1 +166 * P<sub>1</sub>(X) = X +167 * (k+1) P<sub>k+1</sub>(X) = (2k+1) X P<sub>k</sub>(X) - k P<sub>k-1</sub>(X) +168 * </pre></p> +169 * @param degree degree of the polynomial +170 * @return Legendre polynomial of specified degree +171 */ +172 public static PolynomialFunction createLegendrePolynomial(final int degree) { +173 return buildPolynomial(degree, LEGENDRE_COEFFICIENTS, +174 new RecurrenceCoefficientsGenerator() { +175 /** {@inheritDoc} */ +176 public BigFraction[] generate(int k) { +177 final int kP1 = k + 1; +178 return new BigFraction[] { +179 BigFraction.ZERO, +180 new BigFraction(k + kP1, kP1), +181 new BigFraction(k, kP1)}; +182 } +183 }); +184 } +185 +186 /** Get the coefficients array for a given degree. +187 * @param degree degree of the polynomial +188 * @param coefficients list where the computed coefficients are stored +189 * @param generator recurrence coefficients generator +190 * @return coefficients array +191 */ +192 private static PolynomialFunction buildPolynomial(final int degree, +193 final ArrayList<BigFraction> coefficients, +194 final RecurrenceCoefficientsGenerator generator) { +195 +196 final int maxDegree = (int) Math.floor(Math.sqrt(2 * coefficients.size())) - 1; +197 synchronized (PolynomialsUtils.class) { +198 if (degree > maxDegree) { +199 computeUpToDegree(degree, maxDegree, generator, coefficients); +200 } +201 } +202 +203 // coefficient for polynomial 0 is l [0] +204 // coefficients for polynomial 1 are l [1] ... l [2] (degrees 0 ... 1) +205 // coefficients for polynomial 2 are l [3] ... l [5] (degrees 0 ... 2) +206 // coefficients for polynomial 3 are l [6] ... l [9] (degrees 0 ... 3) +207 // coefficients for polynomial 4 are l[10] ... l[14] (degrees 0 ... 4) +208 // coefficients for polynomial 5 are l[15] ... l[20] (degrees 0 ... 5) +209 // coefficients for polynomial 6 are l[21] ... l[27] (degrees 0 ... 6) +210 // ... +211 final int start = degree * (degree + 1) / 2; +212 +213 final double[] a = new double[degree + 1]; +214 for (int i = 0; i <= degree; ++i) { +215 a[i] = coefficients.get(start + i).doubleValue(); +216 } +217 +218 // build the polynomial +219 return new PolynomialFunction(a); +220 +221 } +222 +223 /** Compute polynomial coefficients up to a given degree. +224 * @param degree maximal degree +225 * @param maxDegree current maximal degree +226 * @param generator recurrence coefficients generator +227 * @param coefficients list where the computed coefficients should be appended +228 */ +229 private static void computeUpToDegree(final int degree, final int maxDegree, +230 final RecurrenceCoefficientsGenerator generator, +231 final ArrayList<BigFraction> coefficients) { +232 +233 int startK = (maxDegree - 1) * maxDegree / 2; +234 for (int k = maxDegree; k < degree; ++k) { +235 +236 // start indices of two previous polynomials Pk(X) and Pk-1(X) +237 int startKm1 = startK; +238 startK += k; +239 +240 // Pk+1(X) = (a[0] + a[1] X) Pk(X) - a[2] Pk-1(X) +241 BigFraction[] ai = generator.generate(k); +242 +243 BigFraction ck = coefficients.get(startK); +244 BigFraction ckm1 = coefficients.get(startKm1); +245 +246 // degree 0 coefficient +247 coefficients.add(ck.multiply(ai[0]).subtract(ckm1.multiply(ai[2]))); +248 +249 // degree 1 to degree k-1 coefficients +250 for (int i = 1; i < k; ++i) { +251 final BigFraction ckPrev = ck; +252 ck = coefficients.get(startK + i); +253 ckm1 = coefficients.get(startKm1 + i); +254 coefficients.add(ck.multiply(ai[0]).add(ckPrev.multiply(ai[1])).subtract(ckm1.multiply(ai[2]))); +255 } +256 +257 // degree k coefficient +258 final BigFraction ckPrev = ck; +259 ck = coefficients.get(startK + k); +260 coefficients.add(ck.multiply(ai[0]).add(ckPrev.multiply(ai[1]))); +261 +262 // degree k+1 coefficient +263 coefficients.add(ck.multiply(ai[1])); +264 +265 } +266 +267 } +268 +269 /** Interface for recurrence coefficients generation. */ +270 private static interface RecurrenceCoefficientsGenerator { +271 /** +272 * Generate recurrence coefficients. +273 * @param k highest degree of the polynomials used in the recurrence +274 * @return an array of three coefficients such that +275 * P<sub>k+1</sub>(X) = (a[0] + a[1] X) P<sub>k</sub>(X) - a[2] P<sub>k-1</sub>(X) +276 */ +277 BigFraction[] generate(int k); +278 } +279 +280 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/BisectionSolver.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/BisectionSolver.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,175 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.solvers; +018 +019 import org.apache.commons.math.FunctionEvaluationException; +020 import org.apache.commons.math.MaxIterationsExceededException; +021 import org.apache.commons.math.analysis.UnivariateRealFunction; +022 +023 /** +024 * Implements the <a href="http://mathworld.wolfram.com/Bisection.html"> +025 * bisection algorithm</a> for finding zeros of univariate real functions. +026 * <p> +027 * The function should be continuous but not necessarily smooth.</p> +028 * +029 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +030 */ +031 public class BisectionSolver extends UnivariateRealSolverImpl { +032 +033 /** +034 * Construct a solver for the given function. +035 * +036 * @param f function to solve. +037 * @deprecated as of 2.0 the function to solve is passed as an argument +038 * to the {@link #solve(UnivariateRealFunction, double, double)} or +039 * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} +040 * method. +041 */ +042 @Deprecated +043 public BisectionSolver(UnivariateRealFunction f) { +044 super(f, 100, 1E-6); +045 } +046 +047 /** +048 * Construct a solver. +049 * +050 */ +051 public BisectionSolver() { +052 super(100, 1E-6); +053 } +054 +055 /** {@inheritDoc} */ +056 @Deprecated +057 public double solve(double min, double max, double initial) +058 throws MaxIterationsExceededException, FunctionEvaluationException { +059 return solve(f, min, max); +060 } +061 +062 /** {@inheritDoc} */ +063 @Deprecated +064 public double solve(double min, double max) +065 throws MaxIterationsExceededException, FunctionEvaluationException { +066 return solve(f, min, max); +067 } +068 +069 /** {@inheritDoc} */ +070 public double solve(final UnivariateRealFunction f, double min, double max, double initial) +071 throws MaxIterationsExceededException, FunctionEvaluationException { +072 return solve(min, max); +073 } +074 +075 /** {@inheritDoc} */ +076 public double solve(final UnivariateRealFunction f, double min, double max) +077 throws MaxIterationsExceededException, FunctionEvaluationException { +078 +079 clearResult(); +080 verifyInterval(min,max); +081 double m; +082 double fm; +083 double fmin; +084 +085 int i = 0; +086 while (i < maximalIterationCount) { +087 m = UnivariateRealSolverUtils.midpoint(min, max); +088 fmin = f.value(min); +089 fm = f.value(m); +090 +091 if (fm * fmin > 0.0) { +092 // max and m bracket the root. +093 min = m; +094 } else { +095 // min and m bracket the root. +096 max = m; +097 } +098 +099 if (Math.abs(max - min) <= absoluteAccuracy) { +100 m = UnivariateRealSolverUtils.midpoint(min, max); +101 setResult(m, i); +102 return m; +103 } +104 ++i; +105 } +106 +107 throw new MaxIterationsExceededException(maximalIterationCount); +108 } +109 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/BrentSolver.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/BrentSolver.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,416 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.solvers; +018 +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.MaxIterationsExceededException; +023 import org.apache.commons.math.analysis.UnivariateRealFunction; +024 +025 /** +026 * Implements the <a href="http://mathworld.wolfram.com/BrentsMethod.html"> +027 * Brent algorithm</a> for finding zeros of real univariate functions. +028 * <p> +029 * The function should be continuous but not necessarily smooth.</p> +030 * +031 * @version $Revision:670469 $ $Date:2008-06-23 10:01:38 +0200 (lun., 23 juin 2008) $ +032 */ +033 public class BrentSolver extends UnivariateRealSolverImpl { +034 +035 /** +036 * Default absolute accuracy +037 * @since 2.1 +038 */ +039 public static final double DEFAULT_ABSOLUTE_ACCURACY = 1E-6; +040 +041 /** Default maximum number of iterations +042 * @since 2.1 +043 */ +044 public static final int DEFAULT_MAXIMUM_ITERATIONS = 100; +045 +046 /** Error message for non-bracketing interval. */ +047 private static final String NON_BRACKETING_MESSAGE = +048 "function values at endpoints do not have different signs. " + +049 "Endpoints: [{0}, {1}], Values: [{2}, {3}]"; +050 +051 /** Serializable version identifier */ +052 private static final long serialVersionUID = 7694577816772532779L; +053 +054 /** +055 * Construct a solver for the given function. +056 * +057 * @param f function to solve. +058 * @deprecated as of 2.0 the function to solve is passed as an argument +059 * to the {@link #solve(UnivariateRealFunction, double, double)} or +060 * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} +061 * method. +062 */ +063 @Deprecated +064 public BrentSolver(UnivariateRealFunction f) { +065 super(f, DEFAULT_MAXIMUM_ITERATIONS, DEFAULT_ABSOLUTE_ACCURACY); +066 } +067 +068 /** +069 * Construct a solver with default properties. +070 */ +071 public BrentSolver() { +072 super(DEFAULT_MAXIMUM_ITERATIONS, DEFAULT_ABSOLUTE_ACCURACY); +073 } +074 +075 /** +076 * Construct a solver with the given absolute accuracy. +077 * +078 * @param absoluteAccuracy lower bound for absolute accuracy of solutions returned by the solver +079 * @since 2.1 +080 */ +081 public BrentSolver(double absoluteAccuracy) { +082 super(DEFAULT_MAXIMUM_ITERATIONS, absoluteAccuracy); +083 } +084 +085 /** +086 * Contstruct a solver with the given maximum iterations and absolute accuracy. +087 * +088 * @param maximumIterations maximum number of iterations +089 * @param absoluteAccuracy lower bound for absolute accuracy of solutions returned by the solver +090 * @since 2.1 +091 */ +092 public BrentSolver(int maximumIterations, double absoluteAccuracy) { +093 super(maximumIterations, absoluteAccuracy); +094 } +095 +096 /** {@inheritDoc} */ +097 @Deprecated +098 public double solve(double min, double max) +099 throws MaxIterationsExceededException, FunctionEvaluationException { +100 return solve(f, min, max); +101 } +102 +103 /** {@inheritDoc} */ +104 @Deprecated +105 public double solve(double min, double max, double initial) +106 throws MaxIterationsExceededException, FunctionEvaluationException { +107 return solve(f, min, max, initial); +108 } +109 +110 /** +111 * Find a zero in the given interval with an initial guess. +112 * <p>Throws <code>IllegalArgumentException</code> if the values of the +113 * function at the three points have the same sign (note that it is +114 * allowed to have endpoints with the same sign if the initial point has +115 * opposite sign function-wise).</p> +116 * +117 * @param f function to solve. +118 * @param min the lower bound for the interval. +119 * @param max the upper bound for the interval. +120 * @param initial the start value to use (must be set to min if no +121 * initial point is known). +122 * @return the value where the function is zero +123 * @throws MaxIterationsExceededException the maximum iteration count +124 * is exceeded +125 * @throws FunctionEvaluationException if an error occurs evaluating +126 * the function +127 * @throws IllegalArgumentException if initial is not between min and max +128 * (even if it <em>is</em> a root) +129 */ +130 public double solve(final UnivariateRealFunction f, +131 final double min, final double max, final double initial) +132 throws MaxIterationsExceededException, FunctionEvaluationException { +133 +134 clearResult(); +135 if ((initial < min) || (initial > max)) { +136 throw MathRuntimeException.createIllegalArgumentException( +137 "invalid interval, initial value parameters: lower={0}, initial={1}, upper={2}", +138 min, initial, max); +139 } +140 +141 // return the initial guess if it is good enough +142 double yInitial = f.value(initial); +143 if (Math.abs(yInitial) <= functionValueAccuracy) { +144 setResult(initial, 0); +145 return result; +146 } +147 +148 // return the first endpoint if it is good enough +149 double yMin = f.value(min); +150 if (Math.abs(yMin) <= functionValueAccuracy) { +151 setResult(min, 0); +152 return result; +153 } +154 +155 // reduce interval if min and initial bracket the root +156 if (yInitial * yMin < 0) { +157 return solve(f, min, yMin, initial, yInitial, min, yMin); +158 } +159 +160 // return the second endpoint if it is good enough +161 double yMax = f.value(max); +162 if (Math.abs(yMax) <= functionValueAccuracy) { +163 setResult(max, 0); +164 return result; +165 } +166 +167 // reduce interval if initial and max bracket the root +168 if (yInitial * yMax < 0) { +169 return solve(f, initial, yInitial, max, yMax, initial, yInitial); +170 } +171 +172 throw MathRuntimeException.createIllegalArgumentException( +173 NON_BRACKETING_MESSAGE, min, max, yMin, yMax); +174 +175 } +176 +177 /** +178 * Find a zero in the given interval. +179 * <p> +180 * Requires that the values of the function at the endpoints have opposite +181 * signs. An <code>IllegalArgumentException</code> is thrown if this is not +182 * the case.</p> +183 * +184 * @param f the function to solve +185 * @param min the lower bound for the interval. +186 * @param max the upper bound for the interval. +187 * @return the value where the function is zero +188 * @throws MaxIterationsExceededException if the maximum iteration count is exceeded +189 * @throws FunctionEvaluationException if an error occurs evaluating the +190 * function +191 * @throws IllegalArgumentException if min is not less than max or the +192 * signs of the values of the function at the endpoints are not opposites +193 */ +194 public double solve(final UnivariateRealFunction f, +195 final double min, final double max) +196 throws MaxIterationsExceededException, +197 FunctionEvaluationException { +198 +199 clearResult(); +200 verifyInterval(min, max); +201 +202 double ret = Double.NaN; +203 +204 double yMin = f.value(min); +205 double yMax = f.value(max); +206 +207 // Verify bracketing +208 double sign = yMin * yMax; +209 if (sign > 0) { +210 // check if either value is close to a zero +211 if (Math.abs(yMin) <= functionValueAccuracy) { +212 setResult(min, 0); +213 ret = min; +214 } else if (Math.abs(yMax) <= functionValueAccuracy) { +215 setResult(max, 0); +216 ret = max; +217 } else { +218 // neither value is close to zero and min and max do not bracket root. +219 throw MathRuntimeException.createIllegalArgumentException( +220 NON_BRACKETING_MESSAGE, min, max, yMin, yMax); +221 } +222 } else if (sign < 0){ +223 // solve using only the first endpoint as initial guess +224 ret = solve(f, min, yMin, max, yMax, min, yMin); +225 } else { +226 // either min or max is a root +227 if (yMin == 0.0) { +228 ret = min; +229 } else { +230 ret = max; +231 } +232 } +233 +234 return ret; +235 } +236 +237 /** +238 * Find a zero starting search according to the three provided points. +239 * @param f the function to solve +240 * @param x0 old approximation for the root +241 * @param y0 function value at the approximation for the root +242 * @param x1 last calculated approximation for the root +243 * @param y1 function value at the last calculated approximation +244 * for the root +245 * @param x2 bracket point (must be set to x0 if no bracket point is +246 * known, this will force starting with linear interpolation) +247 * @param y2 function value at the bracket point. +248 * @return the value where the function is zero +249 * @throws MaxIterationsExceededException if the maximum iteration count +250 * is exceeded +251 * @throws FunctionEvaluationException if an error occurs evaluating +252 * the function +253 */ +254 private double solve(final UnivariateRealFunction f, +255 double x0, double y0, +256 double x1, double y1, +257 double x2, double y2) +258 throws MaxIterationsExceededException, FunctionEvaluationException { +259 +260 double delta = x1 - x0; +261 double oldDelta = delta; +262 +263 int i = 0; +264 while (i < maximalIterationCount) { +265 if (Math.abs(y2) < Math.abs(y1)) { +266 // use the bracket point if is better than last approximation +267 x0 = x1; +268 x1 = x2; +269 x2 = x0; +270 y0 = y1; +271 y1 = y2; +272 y2 = y0; +273 } +274 if (Math.abs(y1) <= functionValueAccuracy) { +275 // Avoid division by very small values. Assume +276 // the iteration has converged (the problem may +277 // still be ill conditioned) +278 setResult(x1, i); +279 return result; +280 } +281 double dx = x2 - x1; +282 double tolerance = +283 Math.max(relativeAccuracy * Math.abs(x1), absoluteAccuracy); +284 if (Math.abs(dx) <= tolerance) { +285 setResult(x1, i); +286 return result; +287 } +288 if ((Math.abs(oldDelta) < tolerance) || +289 (Math.abs(y0) <= Math.abs(y1))) { +290 // Force bisection. +291 delta = 0.5 * dx; +292 oldDelta = delta; +293 } else { +294 double r3 = y1 / y0; +295 double p; +296 double p1; +297 // the equality test (x0 == x2) is intentional, +298 // it is part of the original Brent's method, +299 // it should NOT be replaced by proximity test +300 if (x0 == x2) { +301 // Linear interpolation. +302 p = dx * r3; +303 p1 = 1.0 - r3; +304 } else { +305 // Inverse quadratic interpolation. +306 double r1 = y0 / y2; +307 double r2 = y1 / y2; +308 p = r3 * (dx * r1 * (r1 - r2) - (x1 - x0) * (r2 - 1.0)); +309 p1 = (r1 - 1.0) * (r2 - 1.0) * (r3 - 1.0); +310 } +311 if (p > 0.0) { +312 p1 = -p1; +313 } else { +314 p = -p; +315 } +316 if (2.0 * p >= 1.5 * dx * p1 - Math.abs(tolerance * p1) || +317 p >= Math.abs(0.5 * oldDelta * p1)) { +318 // Inverse quadratic interpolation gives a value +319 // in the wrong direction, or progress is slow. +320 // Fall back to bisection. +321 delta = 0.5 * dx; +322 oldDelta = delta; +323 } else { +324 oldDelta = delta; +325 delta = p / p1; +326 } +327 } +328 // Save old X1, Y1 +329 x0 = x1; +330 y0 = y1; +331 // Compute new X1, Y1 +332 if (Math.abs(delta) > tolerance) { +333 x1 = x1 + delta; +334 } else if (dx > 0.0) { +335 x1 = x1 + 0.5 * tolerance; +336 } else if (dx <= 0.0) { +337 x1 = x1 - 0.5 * tolerance; +338 } +339 y1 = f.value(x1); +340 if ((y1 > 0) == (y2 > 0)) { +341 x2 = x0; +342 y2 = y0; +343 delta = x1 - x0; +344 oldDelta = delta; +345 } +346 i++; +347 } +348 throw new MaxIterationsExceededException(maximalIterationCount); +349 } +350 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/LaguerreSolver.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/LaguerreSolver.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,449 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.solvers; +018 +019 import org.apache.commons.math.ConvergenceException; +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.MaxIterationsExceededException; +023 import org.apache.commons.math.analysis.UnivariateRealFunction; +024 import org.apache.commons.math.analysis.polynomials.PolynomialFunction; +025 import org.apache.commons.math.complex.Complex; +026 +027 /** +028 * Implements the <a href="http://mathworld.wolfram.com/LaguerresMethod.html"> +029 * Laguerre's Method</a> for root finding of real coefficient polynomials. +030 * For reference, see <b>A First Course in Numerical Analysis</b>, +031 * ISBN 048641454X, chapter 8. +032 * <p> +033 * Laguerre's method is global in the sense that it can start with any initial +034 * approximation and be able to solve all roots from that point.</p> +035 * +036 * @version $Revision: 922708 $ $Date: 2010-03-13 20:15:47 -0500 (Sat, 13 Mar 2010) $ +037 * @since 1.2 +038 */ +039 public class LaguerreSolver extends UnivariateRealSolverImpl { +040 +041 /** Message for non-polynomial function. */ +042 private static final String NON_POLYNOMIAL_FUNCTION_MESSAGE = +043 "function is not polynomial"; +044 +045 /** Message for non-positive degree. */ +046 private static final String NON_POSITIVE_DEGREE_MESSAGE = +047 "polynomial degree must be positive: degree={0}"; +048 +049 /** polynomial function to solve. +050 * @deprecated as of 2.0 the function is not stored anymore in the instance +051 */ +052 @Deprecated +053 private final PolynomialFunction p; +054 +055 /** +056 * Construct a solver for the given function. +057 * +058 * @param f function to solve +059 * @throws IllegalArgumentException if function is not polynomial +060 * @deprecated as of 2.0 the function to solve is passed as an argument +061 * to the {@link #solve(UnivariateRealFunction, double, double)} or +062 * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} +063 * method. +064 */ +065 @Deprecated +066 public LaguerreSolver(UnivariateRealFunction f) throws +067 IllegalArgumentException { +068 super(f, 100, 1E-6); +069 if (f instanceof PolynomialFunction) { +070 p = (PolynomialFunction) f; +071 } else { +072 throw MathRuntimeException.createIllegalArgumentException(NON_POLYNOMIAL_FUNCTION_MESSAGE); +073 } +074 } +075 +076 /** +077 * Construct a solver. +078 */ +079 public LaguerreSolver() { +080 super(100, 1E-6); +081 p = null; +082 } +083 +084 /** +085 * Returns a copy of the polynomial function. +086 * +087 * @return a fresh copy of the polynomial function +088 * @deprecated as of 2.0 the function is not stored anymore within the instance. +089 */ +090 @Deprecated +091 public PolynomialFunction getPolynomialFunction() { +092 return new PolynomialFunction(p.getCoefficients()); +093 } +094 +095 /** {@inheritDoc} */ +096 @Deprecated +097 public double solve(final double min, final double max) +098 throws ConvergenceException, FunctionEvaluationException { +099 return solve(p, min, max); +100 } +101 +102 /** {@inheritDoc} */ +103 @Deprecated +104 public double solve(final double min, final double max, final double initial) +105 throws ConvergenceException, FunctionEvaluationException { +106 return solve(p, min, max, initial); +107 } +108 +109 /** +110 * Find a real root in the given interval with initial value. +111 * <p> +112 * Requires bracketing condition.</p> +113 * +114 * @param f function to solve (must be polynomial) +115 * @param min the lower bound for the interval +116 * @param max the upper bound for the interval +117 * @param initial the start value to use +118 * @return the point at which the function value is zero +119 * @throws ConvergenceException if the maximum iteration count is exceeded +120 * or the solver detects convergence problems otherwise +121 * @throws FunctionEvaluationException if an error occurs evaluating the +122 * function +123 * @throws IllegalArgumentException if any parameters are invalid +124 */ +125 public double solve(final UnivariateRealFunction f, +126 final double min, final double max, final double initial) +127 throws ConvergenceException, FunctionEvaluationException { +128 +129 // check for zeros before verifying bracketing +130 if (f.value(min) == 0.0) { +131 return min; +132 } +133 if (f.value(max) == 0.0) { +134 return max; +135 } +136 if (f.value(initial) == 0.0) { +137 return initial; +138 } +139 +140 verifyBracketing(min, max, f); +141 verifySequence(min, initial, max); +142 if (isBracketing(min, initial, f)) { +143 return solve(f, min, initial); +144 } else { +145 return solve(f, initial, max); +146 } +147 +148 } +149 +150 /** +151 * Find a real root in the given interval. +152 * <p> +153 * Despite the bracketing condition, the root returned by solve(Complex[], +154 * Complex) may not be a real zero inside [min, max]. For example, +155 * p(x) = x^3 + 1, min = -2, max = 2, initial = 0. We can either try +156 * another initial value, or, as we did here, call solveAll() to obtain +157 * all roots and pick up the one that we're looking for.</p> +158 * +159 * @param f the function to solve +160 * @param min the lower bound for the interval +161 * @param max the upper bound for the interval +162 * @return the point at which the function value is zero +163 * @throws ConvergenceException if the maximum iteration count is exceeded +164 * or the solver detects convergence problems otherwise +165 * @throws FunctionEvaluationException if an error occurs evaluating the +166 * function +167 * @throws IllegalArgumentException if any parameters are invalid +168 */ +169 public double solve(final UnivariateRealFunction f, +170 final double min, final double max) +171 throws ConvergenceException, FunctionEvaluationException { +172 +173 // check function type +174 if (!(f instanceof PolynomialFunction)) { +175 throw MathRuntimeException.createIllegalArgumentException(NON_POLYNOMIAL_FUNCTION_MESSAGE); +176 } +177 +178 // check for zeros before verifying bracketing +179 if (f.value(min) == 0.0) { return min; } +180 if (f.value(max) == 0.0) { return max; } +181 verifyBracketing(min, max, f); +182 +183 double coefficients[] = ((PolynomialFunction) f).getCoefficients(); +184 Complex c[] = new Complex[coefficients.length]; +185 for (int i = 0; i < coefficients.length; i++) { +186 c[i] = new Complex(coefficients[i], 0.0); +187 } +188 Complex initial = new Complex(0.5 * (min + max), 0.0); +189 Complex z = solve(c, initial); +190 if (isRootOK(min, max, z)) { +191 setResult(z.getReal(), iterationCount); +192 return result; +193 } +194 +195 // solve all roots and select the one we're seeking +196 Complex[] root = solveAll(c, initial); +197 for (int i = 0; i < root.length; i++) { +198 if (isRootOK(min, max, root[i])) { +199 setResult(root[i].getReal(), iterationCount); +200 return result; +201 } +202 } +203 +204 // should never happen +205 throw new ConvergenceException(); +206 } +207 +208 /** +209 * Returns true iff the given complex root is actually a real zero +210 * in the given interval, within the solver tolerance level. +211 * +212 * @param min the lower bound for the interval +213 * @param max the upper bound for the interval +214 * @param z the complex root +215 * @return true iff z is the sought-after real zero +216 */ +217 protected boolean isRootOK(double min, double max, Complex z) { +218 double tolerance = Math.max(relativeAccuracy * z.abs(), absoluteAccuracy); +219 return (isSequence(min, z.getReal(), max)) && +220 (Math.abs(z.getImaginary()) <= tolerance || +221 z.abs() <= functionValueAccuracy); +222 } +223 +224 /** +225 * Find all complex roots for the polynomial with the given coefficients, +226 * starting from the given initial value. +227 * +228 * @param coefficients the polynomial coefficients array +229 * @param initial the start value to use +230 * @return the point at which the function value is zero +231 * @throws ConvergenceException if the maximum iteration count is exceeded +232 * or the solver detects convergence problems otherwise +233 * @throws FunctionEvaluationException if an error occurs evaluating the +234 * function +235 * @throws IllegalArgumentException if any parameters are invalid +236 */ +237 public Complex[] solveAll(double coefficients[], double initial) throws +238 ConvergenceException, FunctionEvaluationException { +239 +240 Complex c[] = new Complex[coefficients.length]; +241 Complex z = new Complex(initial, 0.0); +242 for (int i = 0; i < c.length; i++) { +243 c[i] = new Complex(coefficients[i], 0.0); +244 } +245 return solveAll(c, z); +246 } +247 +248 /** +249 * Find all complex roots for the polynomial with the given coefficients, +250 * starting from the given initial value. +251 * +252 * @param coefficients the polynomial coefficients array +253 * @param initial the start value to use +254 * @return the point at which the function value is zero +255 * @throws MaxIterationsExceededException if the maximum iteration count is exceeded +256 * or the solver detects convergence problems otherwise +257 * @throws FunctionEvaluationException if an error occurs evaluating the +258 * function +259 * @throws IllegalArgumentException if any parameters are invalid +260 */ +261 public Complex[] solveAll(Complex coefficients[], Complex initial) throws +262 MaxIterationsExceededException, FunctionEvaluationException { +263 +264 int n = coefficients.length - 1; +265 int iterationCount = 0; +266 if (n < 1) { +267 throw MathRuntimeException.createIllegalArgumentException( +268 NON_POSITIVE_DEGREE_MESSAGE, n); +269 } +270 Complex c[] = new Complex[n+1]; // coefficients for deflated polynomial +271 for (int i = 0; i <= n; i++) { +272 c[i] = coefficients[i]; +273 } +274 +275 // solve individual root successively +276 Complex root[] = new Complex[n]; +277 for (int i = 0; i < n; i++) { +278 Complex subarray[] = new Complex[n-i+1]; +279 System.arraycopy(c, 0, subarray, 0, subarray.length); +280 root[i] = solve(subarray, initial); +281 // polynomial deflation using synthetic division +282 Complex newc = c[n-i]; +283 Complex oldc = null; +284 for (int j = n-i-1; j >= 0; j--) { +285 oldc = c[j]; +286 c[j] = newc; +287 newc = oldc.add(newc.multiply(root[i])); +288 } +289 iterationCount += this.iterationCount; +290 } +291 +292 resultComputed = true; +293 this.iterationCount = iterationCount; +294 return root; +295 } +296 +297 /** +298 * Find a complex root for the polynomial with the given coefficients, +299 * starting from the given initial value. +300 * +301 * @param coefficients the polynomial coefficients array +302 * @param initial the start value to use +303 * @return the point at which the function value is zero +304 * @throws MaxIterationsExceededException if the maximum iteration count is exceeded +305 * or the solver detects convergence problems otherwise +306 * @throws FunctionEvaluationException if an error occurs evaluating the +307 * function +308 * @throws IllegalArgumentException if any parameters are invalid +309 */ +310 public Complex solve(Complex coefficients[], Complex initial) throws +311 MaxIterationsExceededException, FunctionEvaluationException { +312 +313 int n = coefficients.length - 1; +314 if (n < 1) { +315 throw MathRuntimeException.createIllegalArgumentException( +316 NON_POSITIVE_DEGREE_MESSAGE, n); +317 } +318 Complex N = new Complex(n, 0.0); +319 Complex N1 = new Complex(n - 1, 0.0); +320 +321 int i = 1; +322 Complex pv = null; +323 Complex dv = null; +324 Complex d2v = null; +325 Complex G = null; +326 Complex G2 = null; +327 Complex H = null; +328 Complex delta = null; +329 Complex denominator = null; +330 Complex z = initial; +331 Complex oldz = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); +332 while (i <= maximalIterationCount) { +333 // Compute pv (polynomial value), dv (derivative value), and +334 // d2v (second derivative value) simultaneously. +335 pv = coefficients[n]; +336 dv = Complex.ZERO; +337 d2v = Complex.ZERO; +338 for (int j = n-1; j >= 0; j--) { +339 d2v = dv.add(z.multiply(d2v)); +340 dv = pv.add(z.multiply(dv)); +341 pv = coefficients[j].add(z.multiply(pv)); +342 } +343 d2v = d2v.multiply(new Complex(2.0, 0.0)); +344 +345 // check for convergence +346 double tolerance = Math.max(relativeAccuracy * z.abs(), +347 absoluteAccuracy); +348 if ((z.subtract(oldz)).abs() <= tolerance) { +349 resultComputed = true; +350 iterationCount = i; +351 return z; +352 } +353 if (pv.abs() <= functionValueAccuracy) { +354 resultComputed = true; +355 iterationCount = i; +356 return z; +357 } +358 +359 // now pv != 0, calculate the new approximation +360 G = dv.divide(pv); +361 G2 = G.multiply(G); +362 H = G2.subtract(d2v.divide(pv)); +363 delta = N1.multiply((N.multiply(H)).subtract(G2)); +364 // choose a denominator larger in magnitude +365 Complex deltaSqrt = delta.sqrt(); +366 Complex dplus = G.add(deltaSqrt); +367 Complex dminus = G.subtract(deltaSqrt); +368 denominator = dplus.abs() > dminus.abs() ? dplus : dminus; +369 // Perturb z if denominator is zero, for instance, +370 // p(x) = x^3 + 1, z = 0. +371 if (denominator.equals(new Complex(0.0, 0.0))) { +372 z = z.add(new Complex(absoluteAccuracy, absoluteAccuracy)); +373 oldz = new Complex(Double.POSITIVE_INFINITY, +374 Double.POSITIVE_INFINITY); +375 } else { +376 oldz = z; +377 z = z.subtract(N.divide(denominator)); +378 } +379 i++; +380 } +381 throw new MaxIterationsExceededException(maximalIterationCount); +382 } +383 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/MullerSolver.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/MullerSolver.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,419 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.solvers; +018 +019 import org.apache.commons.math.ConvergenceException; +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.MaxIterationsExceededException; +022 import org.apache.commons.math.analysis.UnivariateRealFunction; +023 import org.apache.commons.math.util.MathUtils; +024 +025 /** +026 * Implements the <a href="http://mathworld.wolfram.com/MullersMethod.html"> +027 * Muller's Method</a> for root finding of real univariate functions. For +028 * reference, see <b>Elementary Numerical Analysis</b>, ISBN 0070124477, +029 * chapter 3. +030 * <p> +031 * Muller's method applies to both real and complex functions, but here we +032 * restrict ourselves to real functions. Methods solve() and solve2() find +033 * real zeros, using different ways to bypass complex arithmetics.</p> +034 * +035 * @version $Revision: 825919 $ $Date: 2009-10-16 10:51:55 -0400 (Fri, 16 Oct 2009) $ +036 * @since 1.2 +037 */ +038 public class MullerSolver extends UnivariateRealSolverImpl { +039 +040 /** +041 * Construct a solver for the given function. +042 * +043 * @param f function to solve +044 * @deprecated as of 2.0 the function to solve is passed as an argument +045 * to the {@link #solve(UnivariateRealFunction, double, double)} or +046 * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} +047 * method. +048 */ +049 @Deprecated +050 public MullerSolver(UnivariateRealFunction f) { +051 super(f, 100, 1E-6); +052 } +053 +054 /** +055 * Construct a solver. +056 */ +057 public MullerSolver() { +058 super(100, 1E-6); +059 } +060 +061 /** {@inheritDoc} */ +062 @Deprecated +063 public double solve(final double min, final double max) +064 throws ConvergenceException, FunctionEvaluationException { +065 return solve(f, min, max); +066 } +067 +068 /** {@inheritDoc} */ +069 @Deprecated +070 public double solve(final double min, final double max, final double initial) +071 throws ConvergenceException, FunctionEvaluationException { +072 return solve(f, min, max, initial); +073 } +074 +075 /** +076 * Find a real root in the given interval with initial value. +077 * <p> +078 * Requires bracketing condition.</p> +079 * +080 * @param f the function to solve +081 * @param min the lower bound for the interval +082 * @param max the upper bound for the interval +083 * @param initial the start value to use +084 * @return the point at which the function value is zero +085 * @throws MaxIterationsExceededException if the maximum iteration count is exceeded +086 * or the solver detects convergence problems otherwise +087 * @throws FunctionEvaluationException if an error occurs evaluating the +088 * function +089 * @throws IllegalArgumentException if any parameters are invalid +090 */ +091 public double solve(final UnivariateRealFunction f, +092 final double min, final double max, final double initial) +093 throws MaxIterationsExceededException, FunctionEvaluationException { +094 +095 // check for zeros before verifying bracketing +096 if (f.value(min) == 0.0) { return min; } +097 if (f.value(max) == 0.0) { return max; } +098 if (f.value(initial) == 0.0) { return initial; } +099 +100 verifyBracketing(min, max, f); +101 verifySequence(min, initial, max); +102 if (isBracketing(min, initial, f)) { +103 return solve(f, min, initial); +104 } else { +105 return solve(f, initial, max); +106 } +107 } +108 +109 /** +110 * Find a real root in the given interval. +111 * <p> +112 * Original Muller's method would have function evaluation at complex point. +113 * Since our f(x) is real, we have to find ways to avoid that. Bracketing +114 * condition is one way to go: by requiring bracketing in every iteration, +115 * the newly computed approximation is guaranteed to be real.</p> +116 * <p> +117 * Normally Muller's method converges quadratically in the vicinity of a +118 * zero, however it may be very slow in regions far away from zeros. For +119 * example, f(x) = exp(x) - 1, min = -50, max = 100. In such case we use +120 * bisection as a safety backup if it performs very poorly.</p> +121 * <p> +122 * The formulas here use divided differences directly.</p> +123 * +124 * @param f the function to solve +125 * @param min the lower bound for the interval +126 * @param max the upper bound for the interval +127 * @return the point at which the function value is zero +128 * @throws MaxIterationsExceededException if the maximum iteration count is exceeded +129 * or the solver detects convergence problems otherwise +130 * @throws FunctionEvaluationException if an error occurs evaluating the +131 * function +132 * @throws IllegalArgumentException if any parameters are invalid +133 */ +134 public double solve(final UnivariateRealFunction f, +135 final double min, final double max) +136 throws MaxIterationsExceededException, FunctionEvaluationException { +137 +138 // [x0, x2] is the bracketing interval in each iteration +139 // x1 is the last approximation and an interpolation point in (x0, x2) +140 // x is the new root approximation and new x1 for next round +141 // d01, d12, d012 are divided differences +142 +143 double x0 = min; +144 double y0 = f.value(x0); +145 double x2 = max; +146 double y2 = f.value(x2); +147 double x1 = 0.5 * (x0 + x2); +148 double y1 = f.value(x1); +149 +150 // check for zeros before verifying bracketing +151 if (y0 == 0.0) { +152 return min; +153 } +154 if (y2 == 0.0) { +155 return max; +156 } +157 verifyBracketing(min, max, f); +158 +159 double oldx = Double.POSITIVE_INFINITY; +160 for (int i = 1; i <= maximalIterationCount; ++i) { +161 // Muller's method employs quadratic interpolation through +162 // x0, x1, x2 and x is the zero of the interpolating parabola. +163 // Due to bracketing condition, this parabola must have two +164 // real roots and we choose one in [x0, x2] to be x. +165 final double d01 = (y1 - y0) / (x1 - x0); +166 final double d12 = (y2 - y1) / (x2 - x1); +167 final double d012 = (d12 - d01) / (x2 - x0); +168 final double c1 = d01 + (x1 - x0) * d012; +169 final double delta = c1 * c1 - 4 * y1 * d012; +170 final double xplus = x1 + (-2.0 * y1) / (c1 + Math.sqrt(delta)); +171 final double xminus = x1 + (-2.0 * y1) / (c1 - Math.sqrt(delta)); +172 // xplus and xminus are two roots of parabola and at least +173 // one of them should lie in (x0, x2) +174 final double x = isSequence(x0, xplus, x2) ? xplus : xminus; +175 final double y = f.value(x); +176 +177 // check for convergence +178 final double tolerance = Math.max(relativeAccuracy * Math.abs(x), absoluteAccuracy); +179 if (Math.abs(x - oldx) <= tolerance) { +180 setResult(x, i); +181 return result; +182 } +183 if (Math.abs(y) <= functionValueAccuracy) { +184 setResult(x, i); +185 return result; +186 } +187 +188 // Bisect if convergence is too slow. Bisection would waste +189 // our calculation of x, hopefully it won't happen often. +190 // the real number equality test x == x1 is intentional and +191 // completes the proximity tests above it +192 boolean bisect = (x < x1 && (x1 - x0) > 0.95 * (x2 - x0)) || +193 (x > x1 && (x2 - x1) > 0.95 * (x2 - x0)) || +194 (x == x1); +195 // prepare the new bracketing interval for next iteration +196 if (!bisect) { +197 x0 = x < x1 ? x0 : x1; +198 y0 = x < x1 ? y0 : y1; +199 x2 = x > x1 ? x2 : x1; +200 y2 = x > x1 ? y2 : y1; +201 x1 = x; y1 = y; +202 oldx = x; +203 } else { +204 double xm = 0.5 * (x0 + x2); +205 double ym = f.value(xm); +206 if (MathUtils.sign(y0) + MathUtils.sign(ym) == 0.0) { +207 x2 = xm; y2 = ym; +208 } else { +209 x0 = xm; y0 = ym; +210 } +211 x1 = 0.5 * (x0 + x2); +212 y1 = f.value(x1); +213 oldx = Double.POSITIVE_INFINITY; +214 } +215 } +216 throw new MaxIterationsExceededException(maximalIterationCount); +217 } +218 +219 /** +220 * Find a real root in the given interval. +221 * <p> +222 * solve2() differs from solve() in the way it avoids complex operations. +223 * Except for the initial [min, max], solve2() does not require bracketing +224 * condition, e.g. f(x0), f(x1), f(x2) can have the same sign. If complex +225 * number arises in the computation, we simply use its modulus as real +226 * approximation.</p> +227 * <p> +228 * Because the interval may not be bracketing, bisection alternative is +229 * not applicable here. However in practice our treatment usually works +230 * well, especially near real zeros where the imaginary part of complex +231 * approximation is often negligible.</p> +232 * <p> +233 * The formulas here do not use divided differences directly.</p> +234 * +235 * @param min the lower bound for the interval +236 * @param max the upper bound for the interval +237 * @return the point at which the function value is zero +238 * @throws MaxIterationsExceededException if the maximum iteration count is exceeded +239 * or the solver detects convergence problems otherwise +240 * @throws FunctionEvaluationException if an error occurs evaluating the +241 * function +242 * @throws IllegalArgumentException if any parameters are invalid +243 * @deprecated replaced by {@link #solve2(UnivariateRealFunction, double, double)} +244 * since 2.0 +245 */ +246 @Deprecated +247 public double solve2(final double min, final double max) +248 throws MaxIterationsExceededException, FunctionEvaluationException { +249 return solve2(f, min, max); +250 } +251 +252 /** +253 * Find a real root in the given interval. +254 * <p> +255 * solve2() differs from solve() in the way it avoids complex operations. +256 * Except for the initial [min, max], solve2() does not require bracketing +257 * condition, e.g. f(x0), f(x1), f(x2) can have the same sign. If complex +258 * number arises in the computation, we simply use its modulus as real +259 * approximation.</p> +260 * <p> +261 * Because the interval may not be bracketing, bisection alternative is +262 * not applicable here. However in practice our treatment usually works +263 * well, especially near real zeros where the imaginary part of complex +264 * approximation is often negligible.</p> +265 * <p> +266 * The formulas here do not use divided differences directly.</p> +267 * +268 * @param f the function to solve +269 * @param min the lower bound for the interval +270 * @param max the upper bound for the interval +271 * @return the point at which the function value is zero +272 * @throws MaxIterationsExceededException if the maximum iteration count is exceeded +273 * or the solver detects convergence problems otherwise +274 * @throws FunctionEvaluationException if an error occurs evaluating the +275 * function +276 * @throws IllegalArgumentException if any parameters are invalid +277 */ +278 public double solve2(final UnivariateRealFunction f, +279 final double min, final double max) +280 throws MaxIterationsExceededException, FunctionEvaluationException { +281 +282 // x2 is the last root approximation +283 // x is the new approximation and new x2 for next round +284 // x0 < x1 < x2 does not hold here +285 +286 double x0 = min; +287 double y0 = f.value(x0); +288 double x1 = max; +289 double y1 = f.value(x1); +290 double x2 = 0.5 * (x0 + x1); +291 double y2 = f.value(x2); +292 +293 // check for zeros before verifying bracketing +294 if (y0 == 0.0) { return min; } +295 if (y1 == 0.0) { return max; } +296 verifyBracketing(min, max, f); +297 +298 double oldx = Double.POSITIVE_INFINITY; +299 for (int i = 1; i <= maximalIterationCount; ++i) { +300 // quadratic interpolation through x0, x1, x2 +301 final double q = (x2 - x1) / (x1 - x0); +302 final double a = q * (y2 - (1 + q) * y1 + q * y0); +303 final double b = (2 * q + 1) * y2 - (1 + q) * (1 + q) * y1 + q * q * y0; +304 final double c = (1 + q) * y2; +305 final double delta = b * b - 4 * a * c; +306 double x; +307 final double denominator; +308 if (delta >= 0.0) { +309 // choose a denominator larger in magnitude +310 double dplus = b + Math.sqrt(delta); +311 double dminus = b - Math.sqrt(delta); +312 denominator = Math.abs(dplus) > Math.abs(dminus) ? dplus : dminus; +313 } else { +314 // take the modulus of (B +/- Math.sqrt(delta)) +315 denominator = Math.sqrt(b * b - delta); +316 } +317 if (denominator != 0) { +318 x = x2 - 2.0 * c * (x2 - x1) / denominator; +319 // perturb x if it exactly coincides with x1 or x2 +320 // the equality tests here are intentional +321 while (x == x1 || x == x2) { +322 x += absoluteAccuracy; +323 } +324 } else { +325 // extremely rare case, get a random number to skip it +326 x = min + Math.random() * (max - min); +327 oldx = Double.POSITIVE_INFINITY; +328 } +329 final double y = f.value(x); +330 +331 // check for convergence +332 final double tolerance = Math.max(relativeAccuracy * Math.abs(x), absoluteAccuracy); +333 if (Math.abs(x - oldx) <= tolerance) { +334 setResult(x, i); +335 return result; +336 } +337 if (Math.abs(y) <= functionValueAccuracy) { +338 setResult(x, i); +339 return result; +340 } +341 +342 // prepare the next iteration +343 x0 = x1; +344 y0 = y1; +345 x1 = x2; +346 y1 = y2; +347 x2 = x; +348 y2 = y; +349 oldx = x; +350 } +351 throw new MaxIterationsExceededException(maximalIterationCount); +352 } +353 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/NewtonSolver.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/NewtonSolver.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,202 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.analysis.solvers; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.MaxIterationsExceededException; +023 import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction; +024 import org.apache.commons.math.analysis.UnivariateRealFunction; +025 +026 /** +027 * Implements <a href="http://mathworld.wolfram.com/NewtonsMethod.html"> +028 * Newton's Method</a> for finding zeros of real univariate functions. +029 * <p> +030 * The function should be continuous but not necessarily smooth.</p> +031 * +032 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +033 */ +034 public class NewtonSolver extends UnivariateRealSolverImpl { +035 +036 /** +037 * Construct a solver for the given function. +038 * @param f function to solve. +039 * @deprecated as of 2.0 the function to solve is passed as an argument +040 * to the {@link #solve(UnivariateRealFunction, double, double)} or +041 * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} +042 * method. +043 */ +044 @Deprecated +045 public NewtonSolver(DifferentiableUnivariateRealFunction f) { +046 super(f, 100, 1E-6); +047 } +048 +049 /** +050 * Construct a solver. +051 */ +052 public NewtonSolver() { +053 super(100, 1E-6); +054 } +055 +056 /** {@inheritDoc} */ +057 @Deprecated +058 public double solve(final double min, final double max) +059 throws MaxIterationsExceededException, +060 FunctionEvaluationException { +061 return solve(f, min, max); +062 } +063 +064 /** {@inheritDoc} */ +065 @Deprecated +066 public double solve(final double min, final double max, final double startValue) +067 throws MaxIterationsExceededException, FunctionEvaluationException { +068 return solve(f, min, max, startValue); +069 } +070 +071 /** +072 * Find a zero near the midpoint of <code>min</code> and <code>max</code>. +073 * +074 * @param f the function to solve +075 * @param min the lower bound for the interval +076 * @param max the upper bound for the interval +077 * @return the value where the function is zero +078 * @throws MaxIterationsExceededException if the maximum iteration count is exceeded +079 * @throws FunctionEvaluationException if an error occurs evaluating the +080 * function or derivative +081 * @throws IllegalArgumentException if min is not less than max +082 */ +083 public double solve(final UnivariateRealFunction f, +084 final double min, final double max) +085 throws MaxIterationsExceededException, FunctionEvaluationException { +086 return solve(f, min, max, UnivariateRealSolverUtils.midpoint(min, max)); +087 } +088 +089 /** +090 * Find a zero near the value <code>startValue</code>. +091 * +092 * @param f the function to solve +093 * @param min the lower bound for the interval (ignored). +094 * @param max the upper bound for the interval (ignored). +095 * @param startValue the start value to use. +096 * @return the value where the function is zero +097 * @throws MaxIterationsExceededException if the maximum iteration count is exceeded +098 * @throws FunctionEvaluationException if an error occurs evaluating the +099 * function or derivative +100 * @throws IllegalArgumentException if startValue is not between min and max or +101 * if function is not a {@link DifferentiableUnivariateRealFunction} instance +102 */ +103 public double solve(final UnivariateRealFunction f, +104 final double min, final double max, final double startValue) +105 throws MaxIterationsExceededException, FunctionEvaluationException { +106 +107 try { +108 +109 final UnivariateRealFunction derivative = +110 ((DifferentiableUnivariateRealFunction) f).derivative(); +111 clearResult(); +112 verifySequence(min, startValue, max); +113 +114 double x0 = startValue; +115 double x1; +116 +117 int i = 0; +118 while (i < maximalIterationCount) { +119 +120 x1 = x0 - (f.value(x0) / derivative.value(x0)); +121 if (Math.abs(x1 - x0) <= absoluteAccuracy) { +122 setResult(x1, i); +123 return x1; +124 } +125 +126 x0 = x1; +127 ++i; +128 } +129 +130 throw new MaxIterationsExceededException(maximalIterationCount); +131 } catch (ClassCastException cce) { +132 throw MathRuntimeException.createIllegalArgumentException("function is not differentiable"); +133 } +134 } +135 +136 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/RiddersSolver.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/RiddersSolver.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,263 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.solvers; +018 +019 import org.apache.commons.math.ConvergenceException; +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.MaxIterationsExceededException; +022 import org.apache.commons.math.analysis.UnivariateRealFunction; +023 import org.apache.commons.math.util.MathUtils; +024 +025 /** +026 * Implements the <a href="http://mathworld.wolfram.com/RiddersMethod.html"> +027 * Ridders' Method</a> for root finding of real univariate functions. For +028 * reference, see C. Ridders, <i>A new algorithm for computing a single root +029 * of a real continuous function </i>, IEEE Transactions on Circuits and +030 * Systems, 26 (1979), 979 - 980. +031 * <p> +032 * The function should be continuous but not necessarily smooth.</p> +033 * +034 * @version $Revision: 825919 $ $Date: 2009-10-16 10:51:55 -0400 (Fri, 16 Oct 2009) $ +035 * @since 1.2 +036 */ +037 public class RiddersSolver extends UnivariateRealSolverImpl { +038 +039 /** +040 * Construct a solver for the given function. +041 * +042 * @param f function to solve +043 * @deprecated as of 2.0 the function to solve is passed as an argument +044 * to the {@link #solve(UnivariateRealFunction, double, double)} or +045 * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} +046 * method. +047 */ +048 @Deprecated +049 public RiddersSolver(UnivariateRealFunction f) { +050 super(f, 100, 1E-6); +051 } +052 +053 /** +054 * Construct a solver. +055 */ +056 public RiddersSolver() { +057 super(100, 1E-6); +058 } +059 +060 /** {@inheritDoc} */ +061 @Deprecated +062 public double solve(final double min, final double max) +063 throws ConvergenceException, FunctionEvaluationException { +064 return solve(f, min, max); +065 } +066 +067 /** {@inheritDoc} */ +068 @Deprecated +069 public double solve(final double min, final double max, final double initial) +070 throws ConvergenceException, FunctionEvaluationException { +071 return solve(f, min, max, initial); +072 } +073 +074 /** +075 * Find a root in the given interval with initial value. +076 * <p> +077 * Requires bracketing condition.</p> +078 * +079 * @param f the function to solve +080 * @param min the lower bound for the interval +081 * @param max the upper bound for the interval +082 * @param initial the start value to use +083 * @return the point at which the function value is zero +084 * @throws MaxIterationsExceededException if the maximum iteration count is exceeded +085 * @throws FunctionEvaluationException if an error occurs evaluating the +086 * function +087 * @throws IllegalArgumentException if any parameters are invalid +088 */ +089 public double solve(final UnivariateRealFunction f, +090 final double min, final double max, final double initial) +091 throws MaxIterationsExceededException, FunctionEvaluationException { +092 +093 // check for zeros before verifying bracketing +094 if (f.value(min) == 0.0) { return min; } +095 if (f.value(max) == 0.0) { return max; } +096 if (f.value(initial) == 0.0) { return initial; } +097 +098 verifyBracketing(min, max, f); +099 verifySequence(min, initial, max); +100 if (isBracketing(min, initial, f)) { +101 return solve(f, min, initial); +102 } else { +103 return solve(f, initial, max); +104 } +105 } +106 +107 /** +108 * Find a root in the given interval. +109 * <p> +110 * Requires bracketing condition.</p> +111 * +112 * @param f the function to solve +113 * @param min the lower bound for the interval +114 * @param max the upper bound for the interval +115 * @return the point at which the function value is zero +116 * @throws MaxIterationsExceededException if the maximum iteration count is exceeded +117 * @throws FunctionEvaluationException if an error occurs evaluating the +118 * function +119 * @throws IllegalArgumentException if any parameters are invalid +120 */ +121 public double solve(final UnivariateRealFunction f, +122 final double min, final double max) +123 throws MaxIterationsExceededException, FunctionEvaluationException { +124 +125 // [x1, x2] is the bracketing interval in each iteration +126 // x3 is the midpoint of [x1, x2] +127 // x is the new root approximation and an endpoint of the new interval +128 double x1 = min; +129 double y1 = f.value(x1); +130 double x2 = max; +131 double y2 = f.value(x2); +132 +133 // check for zeros before verifying bracketing +134 if (y1 == 0.0) { +135 return min; +136 } +137 if (y2 == 0.0) { +138 return max; +139 } +140 verifyBracketing(min, max, f); +141 +142 int i = 1; +143 double oldx = Double.POSITIVE_INFINITY; +144 while (i <= maximalIterationCount) { +145 // calculate the new root approximation +146 final double x3 = 0.5 * (x1 + x2); +147 final double y3 = f.value(x3); +148 if (Math.abs(y3) <= functionValueAccuracy) { +149 setResult(x3, i); +150 return result; +151 } +152 final double delta = 1 - (y1 * y2) / (y3 * y3); // delta > 1 due to bracketing +153 final double correction = (MathUtils.sign(y2) * MathUtils.sign(y3)) * +154 (x3 - x1) / Math.sqrt(delta); +155 final double x = x3 - correction; // correction != 0 +156 final double y = f.value(x); +157 +158 // check for convergence +159 final double tolerance = Math.max(relativeAccuracy * Math.abs(x), absoluteAccuracy); +160 if (Math.abs(x - oldx) <= tolerance) { +161 setResult(x, i); +162 return result; +163 } +164 if (Math.abs(y) <= functionValueAccuracy) { +165 setResult(x, i); +166 return result; +167 } +168 +169 // prepare the new interval for next iteration +170 // Ridders' method guarantees x1 < x < x2 +171 if (correction > 0.0) { // x1 < x < x3 +172 if (MathUtils.sign(y1) + MathUtils.sign(y) == 0.0) { +173 x2 = x; +174 y2 = y; +175 } else { +176 x1 = x; +177 x2 = x3; +178 y1 = y; +179 y2 = y3; +180 } +181 } else { // x3 < x < x2 +182 if (MathUtils.sign(y2) + MathUtils.sign(y) == 0.0) { +183 x1 = x; +184 y1 = y; +185 } else { +186 x1 = x3; +187 x2 = x; +188 y1 = y3; +189 y2 = y; +190 } +191 } +192 oldx = x; +193 i++; +194 } +195 throw new MaxIterationsExceededException(maximalIterationCount); +196 } +197 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/SecantSolver.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/SecantSolver.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,250 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.solvers; +018 +019 import org.apache.commons.math.ConvergenceException; +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.MaxIterationsExceededException; +023 import org.apache.commons.math.analysis.UnivariateRealFunction; +024 +025 +026 /** +027 * Implements a modified version of the +028 * <a href="http://mathworld.wolfram.com/SecantMethod.html">secant method</a> +029 * for approximating a zero of a real univariate function. +030 * <p> +031 * The algorithm is modified to maintain bracketing of a root by successive +032 * approximations. Because of forced bracketing, convergence may be slower than +033 * the unrestricted secant algorithm. However, this implementation should in +034 * general outperform the +035 * <a href="http://mathworld.wolfram.com/MethodofFalsePosition.html"> +036 * regula falsi method.</a></p> +037 * <p> +038 * The function is assumed to be continuous but not necessarily smooth.</p> +039 * +040 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +041 */ +042 public class SecantSolver extends UnivariateRealSolverImpl { +043 +044 /** +045 * Construct a solver for the given function. +046 * @param f function to solve. +047 * @deprecated as of 2.0 the function to solve is passed as an argument +048 * to the {@link #solve(UnivariateRealFunction, double, double)} or +049 * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} +050 * method. +051 */ +052 @Deprecated +053 public SecantSolver(UnivariateRealFunction f) { +054 super(f, 100, 1E-6); +055 } +056 +057 /** +058 * Construct a solver. +059 */ +060 public SecantSolver() { +061 super(100, 1E-6); +062 } +063 +064 /** {@inheritDoc} */ +065 @Deprecated +066 public double solve(final double min, final double max) +067 throws ConvergenceException, FunctionEvaluationException { +068 return solve(f, min, max); +069 } +070 +071 /** {@inheritDoc} */ +072 @Deprecated +073 public double solve(final double min, final double max, final double initial) +074 throws ConvergenceException, FunctionEvaluationException { +075 return solve(f, min, max, initial); +076 } +077 +078 /** +079 * Find a zero in the given interval. +080 * +081 * @param f the function to solve +082 * @param min the lower bound for the interval +083 * @param max the upper bound for the interval +084 * @param initial the start value to use (ignored) +085 * @return the value where the function is zero +086 * @throws MaxIterationsExceededException if the maximum iteration count is exceeded +087 * @throws FunctionEvaluationException if an error occurs evaluating the +088 * function +089 * @throws IllegalArgumentException if min is not less than max or the +090 * signs of the values of the function at the endpoints are not opposites +091 */ +092 public double solve(final UnivariateRealFunction f, +093 final double min, final double max, final double initial) +094 throws MaxIterationsExceededException, FunctionEvaluationException { +095 return solve(f, min, max); +096 } +097 +098 /** +099 * Find a zero in the given interval. +100 * @param f the function to solve +101 * @param min the lower bound for the interval. +102 * @param max the upper bound for the interval. +103 * @return the value where the function is zero +104 * @throws MaxIterationsExceededException if the maximum iteration count is exceeded +105 * @throws FunctionEvaluationException if an error occurs evaluating the +106 * function +107 * @throws IllegalArgumentException if min is not less than max or the +108 * signs of the values of the function at the endpoints are not opposites +109 */ +110 public double solve(final UnivariateRealFunction f, +111 final double min, final double max) +112 throws MaxIterationsExceededException, FunctionEvaluationException { +113 +114 clearResult(); +115 verifyInterval(min, max); +116 +117 // Index 0 is the old approximation for the root. +118 // Index 1 is the last calculated approximation for the root. +119 // Index 2 is a bracket for the root with respect to x0. +120 // OldDelta is the length of the bracketing interval of the last +121 // iteration. +122 double x0 = min; +123 double x1 = max; +124 double y0 = f.value(x0); +125 double y1 = f.value(x1); +126 +127 // Verify bracketing +128 if (y0 * y1 >= 0) { +129 throw MathRuntimeException.createIllegalArgumentException( +130 "function values at endpoints do not have different signs, " + +131 "endpoints: [{0}, {1}], values: [{2}, {3}]", +132 min, max, y0, y1); +133 } +134 +135 double x2 = x0; +136 double y2 = y0; +137 double oldDelta = x2 - x1; +138 int i = 0; +139 while (i < maximalIterationCount) { +140 if (Math.abs(y2) < Math.abs(y1)) { +141 x0 = x1; +142 x1 = x2; +143 x2 = x0; +144 y0 = y1; +145 y1 = y2; +146 y2 = y0; +147 } +148 if (Math.abs(y1) <= functionValueAccuracy) { +149 setResult(x1, i); +150 return result; +151 } +152 if (Math.abs(oldDelta) < +153 Math.max(relativeAccuracy * Math.abs(x1), absoluteAccuracy)) { +154 setResult(x1, i); +155 return result; +156 } +157 double delta; +158 if (Math.abs(y1) > Math.abs(y0)) { +159 // Function value increased in last iteration. Force bisection. +160 delta = 0.5 * oldDelta; +161 } else { +162 delta = (x0 - x1) / (1 - y0 / y1); +163 if (delta / oldDelta > 1) { +164 // New approximation falls outside bracket. +165 // Fall back to bisection. +166 delta = 0.5 * oldDelta; +167 } +168 } +169 x0 = x1; +170 y0 = y1; +171 x1 = x1 + delta; +172 y1 = f.value(x1); +173 if ((y1 > 0) == (y2 > 0)) { +174 // New bracket is (x0,x1). +175 x2 = x0; +176 y2 = y0; +177 } +178 oldDelta = x2 - x1; +179 i++; +180 } +181 throw new MaxIterationsExceededException(maximalIterationCount); +182 } +183 +184 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/UnivariateRealSolver.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,233 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.solvers; +018 +019 import org.apache.commons.math.ConvergenceException; +020 import org.apache.commons.math.ConvergingAlgorithm; +021 import org.apache.commons.math.FunctionEvaluationException; +022 import org.apache.commons.math.analysis.UnivariateRealFunction; +023 +024 +025 /** +026 * Interface for (univariate real) rootfinding algorithms. +027 * <p> +028 * Implementations will search for only one zero in the given interval.</p> +029 * +030 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +031 */ +032 public interface UnivariateRealSolver extends ConvergingAlgorithm { +033 +034 /** +035 * Set the function value accuracy. +036 * <p> +037 * This is used to determine when an evaluated function value or some other +038 * value which is used as divisor is zero.</p> +039 * <p> +040 * This is a safety guard and it shouldn't be necessary to change this in +041 * general.</p> +042 * +043 * @param accuracy the accuracy. +044 * @throws IllegalArgumentException if the accuracy can't be achieved by +045 * the solver or is otherwise deemed unreasonable. +046 */ +047 void setFunctionValueAccuracy(double accuracy); +048 +049 /** +050 * Get the actual function value accuracy. +051 * @return the accuracy +052 */ +053 double getFunctionValueAccuracy(); +054 +055 /** +056 * Reset the actual function accuracy to the default. +057 * The default value is provided by the solver implementation. +058 */ +059 void resetFunctionValueAccuracy(); +060 +061 /** +062 * Solve for a zero root in the given interval. +063 * <p>A solver may require that the interval brackets a single zero root. +064 * Solvers that do require bracketing should be able to handle the case +065 * where one of the endpoints is itself a root.</p> +066 * +067 * @param min the lower bound for the interval. +068 * @param max the upper bound for the interval. +069 * @return a value where the function is zero +070 * @throws ConvergenceException if the maximum iteration count is exceeded +071 * or the solver detects convergence problems otherwise. +072 * @throws FunctionEvaluationException if an error occurs evaluating the +073 * function +074 * @throws IllegalArgumentException if min > max or the endpoints do not +075 * satisfy the requirements specified by the solver +076 * @deprecated replaced by {@link #solve(UnivariateRealFunction, double, double)} +077 * since 2.0 +078 */ +079 @Deprecated +080 double solve(double min, double max) throws ConvergenceException, +081 FunctionEvaluationException; +082 +083 /** +084 * Solve for a zero root in the given interval. +085 * <p>A solver may require that the interval brackets a single zero root. +086 * Solvers that do require bracketing should be able to handle the case +087 * where one of the endpoints is itself a root.</p> +088 * +089 * @param f the function to solve. +090 * @param min the lower bound for the interval. +091 * @param max the upper bound for the interval. +092 * @return a value where the function is zero +093 * @throws ConvergenceException if the maximum iteration count is exceeded +094 * or the solver detects convergence problems otherwise. +095 * @throws FunctionEvaluationException if an error occurs evaluating the +096 * function +097 * @throws IllegalArgumentException if min > max or the endpoints do not +098 * satisfy the requirements specified by the solver +099 * @since 2.0 +100 */ +101 double solve(UnivariateRealFunction f, double min, double max) +102 throws ConvergenceException, +103 FunctionEvaluationException; +104 +105 /** +106 * Solve for a zero in the given interval, start at startValue. +107 * <p>A solver may require that the interval brackets a single zero root. +108 * Solvers that do require bracketing should be able to handle the case +109 * where one of the endpoints is itself a root.</p> +110 * +111 * @param min the lower bound for the interval. +112 * @param max the upper bound for the interval. +113 * @param startValue the start value to use +114 * @return a value where the function is zero +115 * @throws ConvergenceException if the maximum iteration count is exceeded +116 * or the solver detects convergence problems otherwise. +117 * @throws FunctionEvaluationException if an error occurs evaluating the +118 * function +119 * @throws IllegalArgumentException if min > max or the arguments do not +120 * satisfy the requirements specified by the solver +121 * @deprecated replaced by {@link #solve(UnivariateRealFunction, double, double, double)} +122 * since 2.0 +123 */ +124 @Deprecated +125 double solve(double min, double max, double startValue) +126 throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException; +127 +128 /** +129 * Solve for a zero in the given interval, start at startValue. +130 * <p>A solver may require that the interval brackets a single zero root. +131 * Solvers that do require bracketing should be able to handle the case +132 * where one of the endpoints is itself a root.</p> +133 * +134 * @param f the function to solve. +135 * @param min the lower bound for the interval. +136 * @param max the upper bound for the interval. +137 * @param startValue the start value to use +138 * @return a value where the function is zero +139 * @throws ConvergenceException if the maximum iteration count is exceeded +140 * or the solver detects convergence problems otherwise. +141 * @throws FunctionEvaluationException if an error occurs evaluating the +142 * function +143 * @throws IllegalArgumentException if min > max or the arguments do not +144 * satisfy the requirements specified by the solver +145 * @since 2.0 +146 */ +147 double solve(UnivariateRealFunction f, double min, double max, double startValue) +148 throws ConvergenceException, FunctionEvaluationException, IllegalArgumentException; +149 +150 /** +151 * Get the result of the last run of the solver. +152 * +153 * @return the last result. +154 * @throws IllegalStateException if there is no result available, either +155 * because no result was yet computed or the last attempt failed. +156 */ +157 double getResult(); +158 +159 /** +160 * Get the result of the last run of the solver. +161 * +162 * @return the value of the function at the last result. +163 * @throws IllegalStateException if there is no result available, either +164 * because no result was yet computed or the last attempt failed. +165 */ +166 double getFunctionValue(); +167 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFactory.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFactory.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,156 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.solvers; +018 +019 /** +020 * Abstract factory class used to create {@link UnivariateRealSolver} instances. +021 * <p> +022 * Solvers implementing the following algorithms are supported: +023 * <ul> +024 * <li>Bisection</li> +025 * <li>Brent's method</li> +026 * <li>Secant method</li> +027 * </ul> +028 * Concrete factories extending this class also specify a default solver, instances of which +029 * are returned by <code>newDefaultSolver()</code>.</p> +030 * <p> +031 * Common usage:<pre> +032 * SolverFactory factory = UnivariateRealSolverFactory.newInstance();</p> +033 * +034 * // create a Brent solver to use +035 * BrentSolver solver = factory.newBrentSolver(); +036 * </pre> +037 * +038 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +039 */ +040 public abstract class UnivariateRealSolverFactory { +041 /** +042 * Default constructor. +043 */ +044 protected UnivariateRealSolverFactory() { +045 } +046 +047 /** +048 * Create a new factory. +049 * @return a new factory. +050 */ +051 public static UnivariateRealSolverFactory newInstance() { +052 return new UnivariateRealSolverFactoryImpl(); +053 } +054 +055 /** +056 * Create a new {@link UnivariateRealSolver}. The +057 * actual solver returned is determined by the underlying factory. +058 * @return the new solver. +059 */ +060 public abstract UnivariateRealSolver newDefaultSolver(); +061 +062 /** +063 * Create a new {@link UnivariateRealSolver}. The +064 * solver is an implementation of the bisection method. +065 * @return the new solver. +066 */ +067 public abstract UnivariateRealSolver newBisectionSolver(); +068 +069 /** +070 * Create a new {@link UnivariateRealSolver}. The +071 * solver is an implementation of the Brent method. +072 * @return the new solver. +073 */ +074 public abstract UnivariateRealSolver newBrentSolver(); +075 +076 /** +077 * Create a new {@link UnivariateRealSolver}. The +078 * solver is an implementation of Newton's Method. +079 * @return the new solver. +080 */ +081 public abstract UnivariateRealSolver newNewtonSolver(); +082 +083 /** +084 * Create a new {@link UnivariateRealSolver}. The +085 * solver is an implementation of the secant method. +086 * @return the new solver. +087 */ +088 public abstract UnivariateRealSolver newSecantSolver(); +089 +090 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFactoryImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/UnivariateRealSolverFactoryImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,130 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.solvers; +018 +019 /** +020 * A concrete {@link UnivariateRealSolverFactory}. This is the default solver factory +021 * used by commons-math. +022 * <p> +023 * The default solver returned by this factory is a {@link BrentSolver}.</p> +024 * +025 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +026 */ +027 public class UnivariateRealSolverFactoryImpl extends UnivariateRealSolverFactory { +028 +029 /** +030 * Default constructor. +031 */ +032 public UnivariateRealSolverFactoryImpl() { +033 } +034 +035 /** {@inheritDoc} */ +036 @Override +037 public UnivariateRealSolver newDefaultSolver() { +038 return newBrentSolver(); +039 } +040 +041 /** {@inheritDoc} */ +042 @Override +043 public UnivariateRealSolver newBisectionSolver() { +044 return new BisectionSolver(); +045 } +046 +047 /** {@inheritDoc} */ +048 @Override +049 public UnivariateRealSolver newBrentSolver() { +050 return new BrentSolver(); +051 } +052 +053 /** {@inheritDoc} */ +054 @Override +055 public UnivariateRealSolver newNewtonSolver() { +056 return new NewtonSolver(); +057 } +058 +059 /** {@inheritDoc} */ +060 @Override +061 public UnivariateRealSolver newSecantSolver() { +062 return new SecantSolver(); +063 } +064 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,321 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.analysis.solvers; +019 +020 import org.apache.commons.math.ConvergingAlgorithmImpl; +021 import org.apache.commons.math.FunctionEvaluationException; +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.analysis.UnivariateRealFunction; +024 +025 /** +026 * Provide a default implementation for several functions useful to generic +027 * solvers. +028 * +029 * @version $Revision: 811833 $ $Date: 2009-09-06 12:27:50 -0400 (Sun, 06 Sep 2009) $ +030 */ +031 public abstract class UnivariateRealSolverImpl +032 extends ConvergingAlgorithmImpl implements UnivariateRealSolver { +033 +034 /** Maximum error of function. */ +035 protected double functionValueAccuracy; +036 +037 /** Default maximum error of function. */ +038 protected double defaultFunctionValueAccuracy; +039 +040 /** Indicates where a root has been computed. */ +041 protected boolean resultComputed = false; +042 +043 /** The last computed root. */ +044 protected double result; +045 +046 /** Value of the function at the last computed result. */ +047 protected double functionValue; +048 +049 /** The function to solve. +050 * @deprecated as of 2.0 the function to solve is passed as an argument +051 * to the {@link #solve(UnivariateRealFunction, double, double)} or +052 * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} +053 * method. */ +054 @Deprecated +055 protected UnivariateRealFunction f; +056 +057 /** +058 * Construct a solver with given iteration count and accuracy. +059 * +060 * @param f the function to solve. +061 * @param defaultAbsoluteAccuracy maximum absolute error +062 * @param defaultMaximalIterationCount maximum number of iterations +063 * @throws IllegalArgumentException if f is null or the +064 * defaultAbsoluteAccuracy is not valid +065 * @deprecated as of 2.0 the function to solve is passed as an argument +066 * to the {@link #solve(UnivariateRealFunction, double, double)} or +067 * {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)} +068 * method. +069 */ +070 @Deprecated +071 protected UnivariateRealSolverImpl(final UnivariateRealFunction f, +072 final int defaultMaximalIterationCount, +073 final double defaultAbsoluteAccuracy) { +074 super(defaultMaximalIterationCount, defaultAbsoluteAccuracy); +075 if (f == null) { +076 throw MathRuntimeException.createIllegalArgumentException("function to solve cannot be null"); +077 } +078 this.f = f; +079 this.defaultFunctionValueAccuracy = 1.0e-15; +080 this.functionValueAccuracy = defaultFunctionValueAccuracy; +081 } +082 +083 /** +084 * Construct a solver with given iteration count and accuracy. +085 * +086 * @param defaultAbsoluteAccuracy maximum absolute error +087 * @param defaultMaximalIterationCount maximum number of iterations +088 * @throws IllegalArgumentException if f is null or the +089 * defaultAbsoluteAccuracy is not valid +090 */ +091 protected UnivariateRealSolverImpl(final int defaultMaximalIterationCount, +092 final double defaultAbsoluteAccuracy) { +093 super(defaultMaximalIterationCount, defaultAbsoluteAccuracy); +094 this.defaultFunctionValueAccuracy = 1.0e-15; +095 this.functionValueAccuracy = defaultFunctionValueAccuracy; +096 } +097 +098 /** Check if a result has been computed. +099 * @exception IllegalStateException if no result has been computed +100 */ +101 protected void checkResultComputed() throws IllegalStateException { +102 if (!resultComputed) { +103 throw MathRuntimeException.createIllegalStateException("no result available"); +104 } +105 } +106 +107 /** {@inheritDoc} */ +108 public double getResult() { +109 checkResultComputed(); +110 return result; +111 } +112 +113 /** {@inheritDoc} */ +114 public double getFunctionValue() { +115 checkResultComputed(); +116 return functionValue; +117 } +118 +119 /** {@inheritDoc} */ +120 public void setFunctionValueAccuracy(final double accuracy) { +121 functionValueAccuracy = accuracy; +122 } +123 +124 /** {@inheritDoc} */ +125 public double getFunctionValueAccuracy() { +126 return functionValueAccuracy; +127 } +128 +129 /** {@inheritDoc} */ +130 public void resetFunctionValueAccuracy() { +131 functionValueAccuracy = defaultFunctionValueAccuracy; +132 } +133 +134 /** +135 * Convenience function for implementations. +136 * +137 * @param newResult the result to set +138 * @param iterationCount the iteration count to set +139 */ +140 protected final void setResult(final double newResult, final int iterationCount) { +141 this.result = newResult; +142 this.iterationCount = iterationCount; +143 this.resultComputed = true; +144 } +145 +146 /** +147 * Convenience function for implementations. +148 * +149 * @param x the result to set +150 * @param fx the result to set +151 * @param iterationCount the iteration count to set +152 */ +153 protected final void setResult(final double x, final double fx, +154 final int iterationCount) { +155 this.result = x; +156 this.functionValue = fx; +157 this.iterationCount = iterationCount; +158 this.resultComputed = true; +159 } +160 +161 /** +162 * Convenience function for implementations. +163 */ +164 protected final void clearResult() { +165 this.iterationCount = 0; +166 this.resultComputed = false; +167 } +168 +169 /** +170 * Returns true iff the function takes opposite signs at the endpoints. +171 * +172 * @param lower the lower endpoint +173 * @param upper the upper endpoint +174 * @param function the function +175 * @return true if f(lower) * f(upper) < 0 +176 * @throws FunctionEvaluationException if an error occurs evaluating the +177 * function at the endpoints +178 */ +179 protected boolean isBracketing(final double lower, final double upper, +180 final UnivariateRealFunction function) +181 throws FunctionEvaluationException { +182 final double f1 = function.value(lower); +183 final double f2 = function.value(upper); +184 return (f1 > 0 && f2 < 0) || (f1 < 0 && f2 > 0); +185 } +186 +187 /** +188 * Returns true if the arguments form a (strictly) increasing sequence +189 * +190 * @param start first number +191 * @param mid second number +192 * @param end third number +193 * @return true if the arguments form an increasing sequence +194 */ +195 protected boolean isSequence(final double start, final double mid, final double end) { +196 return (start < mid) && (mid < end); +197 } +198 +199 /** +200 * Verifies that the endpoints specify an interval, +201 * throws IllegalArgumentException if not +202 * +203 * @param lower lower endpoint +204 * @param upper upper endpoint +205 * @throws IllegalArgumentException +206 */ +207 protected void verifyInterval(final double lower, final double upper) { +208 if (lower >= upper) { +209 throw MathRuntimeException.createIllegalArgumentException( +210 "endpoints do not specify an interval: [{0}, {1}]", +211 lower, upper); +212 } +213 } +214 +215 /** +216 * Verifies that <code>lower < initial < upper</code> +217 * throws IllegalArgumentException if not +218 * +219 * @param lower lower endpoint +220 * @param initial initial value +221 * @param upper upper endpoint +222 * @throws IllegalArgumentException +223 */ +224 protected void verifySequence(final double lower, final double initial, final double upper) { +225 if (!isSequence(lower, initial, upper)) { +226 throw MathRuntimeException.createIllegalArgumentException( +227 "invalid interval, initial value parameters: lower={0}, initial={1}, upper={2}", +228 lower, initial, upper); +229 } +230 } +231 +232 /** +233 * Verifies that the endpoints specify an interval and the function takes +234 * opposite signs at the enpoints, throws IllegalArgumentException if not +235 * +236 * @param lower lower endpoint +237 * @param upper upper endpoint +238 * @param function function +239 * @throws IllegalArgumentException +240 * @throws FunctionEvaluationException if an error occurs evaluating the +241 * function at the endpoints +242 */ +243 protected void verifyBracketing(final double lower, final double upper, +244 final UnivariateRealFunction function) +245 throws FunctionEvaluationException { +246 +247 verifyInterval(lower, upper); +248 if (!isBracketing(lower, upper, function)) { +249 throw MathRuntimeException.createIllegalArgumentException( +250 "function values at endpoints do not have different signs. " + +251 "Endpoints: [{0}, {1}], Values: [{2}, {3}]", +252 lower, upper, function.value(lower), function.value(upper)); +253 } +254 } +255 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,313 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.analysis.solvers; +018 +019 import org.apache.commons.math.FunctionEvaluationException; +020 import org.apache.commons.math.ConvergenceException; +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.analysis.UnivariateRealFunction; +023 +024 /** +025 * Utility routines for {@link UnivariateRealSolver} objects. +026 * +027 * @version $Revision: 885278 $ $Date: 2009-11-29 16:47:51 -0500 (Sun, 29 Nov 2009) $ +028 */ +029 public class UnivariateRealSolverUtils { +030 +031 /** Message for null function.*/ +032 private static final String NULL_FUNCTION_MESSAGE = +033 "function is null"; +034 +035 /** +036 * Default constructor. +037 */ +038 private UnivariateRealSolverUtils() { +039 super(); +040 } +041 +042 /** +043 * Convenience method to find a zero of a univariate real function. A default +044 * solver is used. +045 * +046 * @param f the function. +047 * @param x0 the lower bound for the interval. +048 * @param x1 the upper bound for the interval. +049 * @return a value where the function is zero. +050 * @throws ConvergenceException if the iteration count was exceeded +051 * @throws FunctionEvaluationException if an error occurs evaluating +052 * the function +053 * @throws IllegalArgumentException if f is null or the endpoints do not +054 * specify a valid interval +055 */ +056 public static double solve(UnivariateRealFunction f, double x0, double x1) +057 throws ConvergenceException, FunctionEvaluationException { +058 setup(f); +059 return LazyHolder.FACTORY.newDefaultSolver().solve(f, x0, x1); +060 } +061 +062 /** +063 * Convenience method to find a zero of a univariate real function. A default +064 * solver is used. +065 * +066 * @param f the function +067 * @param x0 the lower bound for the interval +068 * @param x1 the upper bound for the interval +069 * @param absoluteAccuracy the accuracy to be used by the solver +070 * @return a value where the function is zero +071 * @throws ConvergenceException if the iteration count is exceeded +072 * @throws FunctionEvaluationException if an error occurs evaluating the +073 * function +074 * @throws IllegalArgumentException if f is null, the endpoints do not +075 * specify a valid interval, or the absoluteAccuracy is not valid for the +076 * default solver +077 */ +078 public static double solve(UnivariateRealFunction f, double x0, double x1, +079 double absoluteAccuracy) throws ConvergenceException, +080 FunctionEvaluationException { +081 +082 setup(f); +083 UnivariateRealSolver solver = LazyHolder.FACTORY.newDefaultSolver(); +084 solver.setAbsoluteAccuracy(absoluteAccuracy); +085 return solver.solve(f, x0, x1); +086 } +087 +088 /** +089 * This method attempts to find two values a and b satisfying <ul> +090 * <li> <code> lowerBound <= a < initial < b <= upperBound</code> </li> +091 * <li> <code> f(a) * f(b) < 0 </code></li> +092 * </ul> +093 * If f is continuous on <code>[a,b],</code> this means that <code>a</code> +094 * and <code>b</code> bracket a root of f. +095 * <p> +096 * The algorithm starts by setting +097 * <code>a := initial -1; b := initial +1,</code> examines the value of the +098 * function at <code>a</code> and <code>b</code> and keeps moving +099 * the endpoints out by one unit each time through a loop that terminates +100 * when one of the following happens: <ul> +101 * <li> <code> f(a) * f(b) < 0 </code> -- success!</li> +102 * <li> <code> a = lower </code> and <code> b = upper</code> +103 * -- ConvergenceException </li> +104 * <li> <code> Integer.MAX_VALUE</code> iterations elapse +105 * -- ConvergenceException </li> +106 * </ul></p> +107 * <p> +108 * <strong>Note: </strong> this method can take +109 * <code>Integer.MAX_VALUE</code> iterations to throw a +110 * <code>ConvergenceException.</code> Unless you are confident that there +111 * is a root between <code>lowerBound</code> and <code>upperBound</code> +112 * near <code>initial,</code> it is better to use +113 * {@link #bracket(UnivariateRealFunction, double, double, double, int)}, +114 * explicitly specifying the maximum number of iterations.</p> +115 * +116 * @param function the function +117 * @param initial initial midpoint of interval being expanded to +118 * bracket a root +119 * @param lowerBound lower bound (a is never lower than this value) +120 * @param upperBound upper bound (b never is greater than this +121 * value) +122 * @return a two element array holding {a, b} +123 * @throws ConvergenceException if a root can not be bracketted +124 * @throws FunctionEvaluationException if an error occurs evaluating the +125 * function +126 * @throws IllegalArgumentException if function is null, maximumIterations +127 * is not positive, or initial is not between lowerBound and upperBound +128 */ +129 public static double[] bracket(UnivariateRealFunction function, +130 double initial, double lowerBound, double upperBound) +131 throws ConvergenceException, FunctionEvaluationException { +132 return bracket( function, initial, lowerBound, upperBound, +133 Integer.MAX_VALUE ) ; +134 } +135 +136 /** +137 * This method attempts to find two values a and b satisfying <ul> +138 * <li> <code> lowerBound <= a < initial < b <= upperBound</code> </li> +139 * <li> <code> f(a) * f(b) <= 0 </code> </li> +140 * </ul> +141 * If f is continuous on <code>[a,b],</code> this means that <code>a</code> +142 * and <code>b</code> bracket a root of f. +143 * <p> +144 * The algorithm starts by setting +145 * <code>a := initial -1; b := initial +1,</code> examines the value of the +146 * function at <code>a</code> and <code>b</code> and keeps moving +147 * the endpoints out by one unit each time through a loop that terminates +148 * when one of the following happens: <ul> +149 * <li> <code> f(a) * f(b) <= 0 </code> -- success!</li> +150 * <li> <code> a = lower </code> and <code> b = upper</code> +151 * -- ConvergenceException </li> +152 * <li> <code> maximumIterations</code> iterations elapse +153 * -- ConvergenceException </li></ul></p> +154 * +155 * @param function the function +156 * @param initial initial midpoint of interval being expanded to +157 * bracket a root +158 * @param lowerBound lower bound (a is never lower than this value) +159 * @param upperBound upper bound (b never is greater than this +160 * value) +161 * @param maximumIterations maximum number of iterations to perform +162 * @return a two element array holding {a, b}. +163 * @throws ConvergenceException if the algorithm fails to find a and b +164 * satisfying the desired conditions +165 * @throws FunctionEvaluationException if an error occurs evaluating the +166 * function +167 * @throws IllegalArgumentException if function is null, maximumIterations +168 * is not positive, or initial is not between lowerBound and upperBound +169 */ +170 public static double[] bracket(UnivariateRealFunction function, +171 double initial, double lowerBound, double upperBound, +172 int maximumIterations) throws ConvergenceException, +173 FunctionEvaluationException { +174 +175 if (function == null) { +176 throw MathRuntimeException.createIllegalArgumentException(NULL_FUNCTION_MESSAGE); +177 } +178 if (maximumIterations <= 0) { +179 throw MathRuntimeException.createIllegalArgumentException( +180 "bad value for maximum iterations number: {0}", maximumIterations); +181 } +182 if (initial < lowerBound || initial > upperBound || lowerBound >= upperBound) { +183 throw MathRuntimeException.createIllegalArgumentException( +184 "invalid bracketing parameters: lower bound={0}, initial={1}, upper bound={2}", +185 lowerBound, initial, upperBound); +186 } +187 double a = initial; +188 double b = initial; +189 double fa; +190 double fb; +191 int numIterations = 0 ; +192 +193 do { +194 a = Math.max(a - 1.0, lowerBound); +195 b = Math.min(b + 1.0, upperBound); +196 fa = function.value(a); +197 +198 fb = function.value(b); +199 numIterations++ ; +200 } while ((fa * fb > 0.0) && (numIterations < maximumIterations) && +201 ((a > lowerBound) || (b < upperBound))); +202 +203 if (fa * fb > 0.0 ) { +204 throw new ConvergenceException( +205 "number of iterations={0}, maximum iterations={1}, " + +206 "initial={2}, lower bound={3}, upper bound={4}, final a value={5}, " + +207 "final b value={6}, f(a)={7}, f(b)={8}", +208 numIterations, maximumIterations, initial, +209 lowerBound, upperBound, a, b, fa, fb); +210 } +211 +212 return new double[]{a, b}; +213 } +214 +215 /** +216 * Compute the midpoint of two values. +217 * +218 * @param a first value. +219 * @param b second value. +220 * @return the midpoint. +221 */ +222 public static double midpoint(double a, double b) { +223 return (a + b) * .5; +224 } +225 +226 /** +227 * Checks to see if f is null, throwing IllegalArgumentException if so. +228 * @param f input function +229 * @throws IllegalArgumentException if f is null +230 */ +231 private static void setup(UnivariateRealFunction f) { +232 if (f == null) { +233 throw MathRuntimeException.createIllegalArgumentException(NULL_FUNCTION_MESSAGE); +234 } +235 } +236 +237 // CHECKSTYLE: stop HideUtilityClassConstructor +238 /** Holder for the factory. +239 * <p>We use here the Initialization On Demand Holder Idiom.</p> +240 */ +241 private static class LazyHolder { +242 /** Cached solver factory */ +243 private static final UnivariateRealSolverFactory FACTORY = UnivariateRealSolverFactory.newInstance(); +244 } +245 // CHECKSTYLE: resume HideUtilityClassConstructor +246 +247 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/complex/Complex.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/complex/Complex.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1071 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.complex; +019 +020 import java.io.Serializable; +021 import java.util.ArrayList; +022 import java.util.List; +023 +024 import org.apache.commons.math.FieldElement; +025 import org.apache.commons.math.MathRuntimeException; +026 import org.apache.commons.math.util.MathUtils; +027 +028 /** +029 * Representation of a Complex number - a number which has both a +030 * real and imaginary part. +031 * <p> +032 * Implementations of arithmetic operations handle <code>NaN</code> and +033 * infinite values according to the rules for {@link java.lang.Double} +034 * arithmetic, applying definitional formulas and returning <code>NaN</code> or +035 * infinite values in real or imaginary parts as these arise in computation. +036 * See individual method javadocs for details.</p> +037 * <p> +038 * {@link #equals} identifies all values with <code>NaN</code> in either real +039 * or imaginary part - e.g., <pre> +040 * <code>1 + NaNi == NaN + i == NaN + NaNi.</code></pre></p> +041 * +042 * implements Serializable since 2.0 +043 * +044 * @version $Revision: 922713 $ $Date: 2010-03-13 20:26:13 -0500 (Sat, 13 Mar 2010) $ +045 */ +046 public class Complex implements FieldElement<Complex>, Serializable { +047 +048 /** The square root of -1. A number representing "0.0 + 1.0i" */ +049 public static final Complex I = new Complex(0.0, 1.0); +050 +051 // CHECKSTYLE: stop ConstantName +052 /** A complex number representing "NaN + NaNi" */ +053 public static final Complex NaN = new Complex(Double.NaN, Double.NaN); +054 // CHECKSTYLE: resume ConstantName +055 +056 /** A complex number representing "+INF + INFi" */ +057 public static final Complex INF = new Complex(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); +058 +059 /** A complex number representing "1.0 + 0.0i" */ +060 public static final Complex ONE = new Complex(1.0, 0.0); +061 +062 /** A complex number representing "0.0 + 0.0i" */ +063 public static final Complex ZERO = new Complex(0.0, 0.0); +064 +065 /** Serializable version identifier */ +066 private static final long serialVersionUID = -6195664516687396620L; +067 +068 /** The imaginary part. */ +069 private final double imaginary; +070 +071 /** The real part. */ +072 private final double real; +073 +074 /** Record whether this complex number is equal to NaN. */ +075 private final transient boolean isNaN; +076 +077 /** Record whether this complex number is infinite. */ +078 private final transient boolean isInfinite; +079 +080 /** +081 * Create a complex number given the real and imaginary parts. +082 * +083 * @param real the real part +084 * @param imaginary the imaginary part +085 */ +086 public Complex(double real, double imaginary) { +087 super(); +088 this.real = real; +089 this.imaginary = imaginary; +090 +091 isNaN = Double.isNaN(real) || Double.isNaN(imaginary); +092 isInfinite = !isNaN && +093 (Double.isInfinite(real) || Double.isInfinite(imaginary)); +094 } +095 +096 /** +097 * Return the absolute value of this complex number. +098 * <p> +099 * Returns <code>NaN</code> if either real or imaginary part is +100 * <code>NaN</code> and <code>Double.POSITIVE_INFINITY</code> if +101 * neither part is <code>NaN</code>, but at least one part takes an infinite +102 * value.</p> +103 * +104 * @return the absolute value +105 */ +106 public double abs() { +107 if (isNaN()) { +108 return Double.NaN; +109 } +110 +111 if (isInfinite()) { +112 return Double.POSITIVE_INFINITY; +113 } +114 +115 if (Math.abs(real) < Math.abs(imaginary)) { +116 if (imaginary == 0.0) { +117 return Math.abs(real); +118 } +119 double q = real / imaginary; +120 return Math.abs(imaginary) * Math.sqrt(1 + q * q); +121 } else { +122 if (real == 0.0) { +123 return Math.abs(imaginary); +124 } +125 double q = imaginary / real; +126 return Math.abs(real) * Math.sqrt(1 + q * q); +127 } +128 } +129 +130 /** +131 * Return the sum of this complex number and the given complex number. +132 * <p> +133 * Uses the definitional formula +134 * <pre> +135 * (a + bi) + (c + di) = (a+c) + (b+d)i +136 * </pre></p> +137 * <p> +138 * If either this or <code>rhs</code> has a NaN value in either part, +139 * {@link #NaN} is returned; otherwise Inifinite and NaN values are +140 * returned in the parts of the result according to the rules for +141 * {@link java.lang.Double} arithmetic.</p> +142 * +143 * @param rhs the other complex number +144 * @return the complex number sum +145 * @throws NullPointerException if <code>rhs</code> is null +146 */ +147 public Complex add(Complex rhs) { +148 return createComplex(real + rhs.getReal(), +149 imaginary + rhs.getImaginary()); +150 } +151 +152 /** +153 * Return the conjugate of this complex number. The conjugate of +154 * "A + Bi" is "A - Bi". +155 * <p> +156 * {@link #NaN} is returned if either the real or imaginary +157 * part of this Complex number equals <code>Double.NaN</code>.</p> +158 * <p> +159 * If the imaginary part is infinite, and the real part is not NaN, +160 * the returned value has infinite imaginary part of the opposite +161 * sign - e.g. the conjugate of <code>1 + POSITIVE_INFINITY i</code> +162 * is <code>1 - NEGATIVE_INFINITY i</code></p> +163 * +164 * @return the conjugate of this Complex object +165 */ +166 public Complex conjugate() { +167 if (isNaN()) { +168 return NaN; +169 } +170 return createComplex(real, -imaginary); +171 } +172 +173 /** +174 * Return the quotient of this complex number and the given complex number. +175 * <p> +176 * Implements the definitional formula +177 * <pre><code> +178 * a + bi ac + bd + (bc - ad)i +179 * ----------- = ------------------------- +180 * c + di c<sup>2</sup> + d<sup>2</sup> +181 * </code></pre> +182 * but uses +183 * <a href="http://doi.acm.org/10.1145/1039813.1039814"> +184 * prescaling of operands</a> to limit the effects of overflows and +185 * underflows in the computation.</p> +186 * <p> +187 * Infinite and NaN values are handled / returned according to the +188 * following rules, applied in the order presented: +189 * <ul> +190 * <li>If either this or <code>rhs</code> has a NaN value in either part, +191 * {@link #NaN} is returned.</li> +192 * <li>If <code>rhs</code> equals {@link #ZERO}, {@link #NaN} is returned. +193 * </li> +194 * <li>If this and <code>rhs</code> are both infinite, +195 * {@link #NaN} is returned.</li> +196 * <li>If this is finite (i.e., has no infinite or NaN parts) and +197 * <code>rhs</code> is infinite (one or both parts infinite), +198 * {@link #ZERO} is returned.</li> +199 * <li>If this is infinite and <code>rhs</code> is finite, NaN values are +200 * returned in the parts of the result if the {@link java.lang.Double} +201 * rules applied to the definitional formula force NaN results.</li> +202 * </ul></p> +203 * +204 * @param rhs the other complex number +205 * @return the complex number quotient +206 * @throws NullPointerException if <code>rhs</code> is null +207 */ +208 public Complex divide(Complex rhs) { +209 if (isNaN() || rhs.isNaN()) { +210 return NaN; +211 } +212 +213 double c = rhs.getReal(); +214 double d = rhs.getImaginary(); +215 if (c == 0.0 && d == 0.0) { +216 return NaN; +217 } +218 +219 if (rhs.isInfinite() && !isInfinite()) { +220 return ZERO; +221 } +222 +223 if (Math.abs(c) < Math.abs(d)) { +224 double q = c / d; +225 double denominator = c * q + d; +226 return createComplex((real * q + imaginary) / denominator, +227 (imaginary * q - real) / denominator); +228 } else { +229 double q = d / c; +230 double denominator = d * q + c; +231 return createComplex((imaginary * q + real) / denominator, +232 (imaginary - real * q) / denominator); +233 } +234 } +235 +236 /** +237 * Test for the equality of two Complex objects. +238 * <p> +239 * If both the real and imaginary parts of two Complex numbers +240 * are exactly the same, and neither is <code>Double.NaN</code>, the two +241 * Complex objects are considered to be equal.</p> +242 * <p> +243 * All <code>NaN</code> values are considered to be equal - i.e, if either +244 * (or both) real and imaginary parts of the complex number are equal +245 * to <code>Double.NaN</code>, the complex number is equal to +246 * <code>Complex.NaN</code>.</p> +247 * +248 * @param other Object to test for equality to this +249 * @return true if two Complex objects are equal, false if +250 * object is null, not an instance of Complex, or +251 * not equal to this Complex instance +252 * +253 */ +254 @Override +255 public boolean equals(Object other) { +256 if (this == other) { +257 return true; +258 } +259 if (other instanceof Complex){ +260 Complex rhs = (Complex)other; +261 if (rhs.isNaN()) { +262 return this.isNaN(); +263 } else { +264 return (real == rhs.real) && (imaginary == rhs.imaginary); +265 } +266 } +267 return false; +268 } +269 +270 /** +271 * Get a hashCode for the complex number. +272 * <p> +273 * All NaN values have the same hash code.</p> +274 * +275 * @return a hash code value for this object +276 */ +277 @Override +278 public int hashCode() { +279 if (isNaN()) { +280 return 7; +281 } +282 return 37 * (17 * MathUtils.hash(imaginary) + +283 MathUtils.hash(real)); +284 } +285 +286 /** +287 * Access the imaginary part. +288 * +289 * @return the imaginary part +290 */ +291 public double getImaginary() { +292 return imaginary; +293 } +294 +295 /** +296 * Access the real part. +297 * +298 * @return the real part +299 */ +300 public double getReal() { +301 return real; +302 } +303 +304 /** +305 * Returns true if either or both parts of this complex number is NaN; +306 * false otherwise +307 * +308 * @return true if either or both parts of this complex number is NaN; +309 * false otherwise +310 */ +311 public boolean isNaN() { +312 return isNaN; +313 } +314 +315 /** +316 * Returns true if either the real or imaginary part of this complex number +317 * takes an infinite value (either <code>Double.POSITIVE_INFINITY</code> or +318 * <code>Double.NEGATIVE_INFINITY</code>) and neither part +319 * is <code>NaN</code>. +320 * +321 * @return true if one or both parts of this complex number are infinite +322 * and neither part is <code>NaN</code> +323 */ +324 public boolean isInfinite() { +325 return isInfinite; +326 } +327 +328 /** +329 * Return the product of this complex number and the given complex number. +330 * <p> +331 * Implements preliminary checks for NaN and infinity followed by +332 * the definitional formula: +333 * <pre><code> +334 * (a + bi)(c + di) = (ac - bd) + (ad + bc)i +335 * </code></pre> +336 * </p> +337 * <p> +338 * Returns {@link #NaN} if either this or <code>rhs</code> has one or more +339 * NaN parts. +340 * </p> +341 * Returns {@link #INF} if neither this nor <code>rhs</code> has one or more +342 * NaN parts and if either this or <code>rhs</code> has one or more +343 * infinite parts (same result is returned regardless of the sign of the +344 * components). +345 * </p> +346 * <p> +347 * Returns finite values in components of the result per the +348 * definitional formula in all remaining cases. +349 * </p> +350 * +351 * @param rhs the other complex number +352 * @return the complex number product +353 * @throws NullPointerException if <code>rhs</code> is null +354 */ +355 public Complex multiply(Complex rhs) { +356 if (isNaN() || rhs.isNaN()) { +357 return NaN; +358 } +359 if (Double.isInfinite(real) || Double.isInfinite(imaginary) || +360 Double.isInfinite(rhs.real)|| Double.isInfinite(rhs.imaginary)) { +361 // we don't use Complex.isInfinite() to avoid testing for NaN again +362 return INF; +363 } +364 return createComplex(real * rhs.real - imaginary * rhs.imaginary, +365 real * rhs.imaginary + imaginary * rhs.real); +366 } +367 +368 /** +369 * Return the product of this complex number and the given scalar number. +370 * <p> +371 * Implements preliminary checks for NaN and infinity followed by +372 * the definitional formula: +373 * <pre><code> +374 * c(a + bi) = (ca) + (cb)i +375 * </code></pre> +376 * </p> +377 * <p> +378 * Returns {@link #NaN} if either this or <code>rhs</code> has one or more +379 * NaN parts. +380 * </p> +381 * Returns {@link #INF} if neither this nor <code>rhs</code> has one or more +382 * NaN parts and if either this or <code>rhs</code> has one or more +383 * infinite parts (same result is returned regardless of the sign of the +384 * components). +385 * </p> +386 * <p> +387 * Returns finite values in components of the result per the +388 * definitional formula in all remaining cases. +389 * </p> +390 * +391 * @param rhs the scalar number +392 * @return the complex number product +393 */ +394 public Complex multiply(double rhs) { +395 if (isNaN() || Double.isNaN(rhs)) { +396 return NaN; +397 } +398 if (Double.isInfinite(real) || Double.isInfinite(imaginary) || +399 Double.isInfinite(rhs)) { +400 // we don't use Complex.isInfinite() to avoid testing for NaN again +401 return INF; +402 } +403 return createComplex(real * rhs, imaginary * rhs); +404 } +405 +406 /** +407 * Return the additive inverse of this complex number. +408 * <p> +409 * Returns <code>Complex.NaN</code> if either real or imaginary +410 * part of this Complex number equals <code>Double.NaN</code>.</p> +411 * +412 * @return the negation of this complex number +413 */ +414 public Complex negate() { +415 if (isNaN()) { +416 return NaN; +417 } +418 +419 return createComplex(-real, -imaginary); +420 } +421 +422 /** +423 * Return the difference between this complex number and the given complex +424 * number. +425 * <p> +426 * Uses the definitional formula +427 * <pre> +428 * (a + bi) - (c + di) = (a-c) + (b-d)i +429 * </pre></p> +430 * <p> +431 * If either this or <code>rhs</code> has a NaN value in either part, +432 * {@link #NaN} is returned; otherwise inifinite and NaN values are +433 * returned in the parts of the result according to the rules for +434 * {@link java.lang.Double} arithmetic. </p> +435 * +436 * @param rhs the other complex number +437 * @return the complex number difference +438 * @throws NullPointerException if <code>rhs</code> is null +439 */ +440 public Complex subtract(Complex rhs) { +441 if (isNaN() || rhs.isNaN()) { +442 return NaN; +443 } +444 +445 return createComplex(real - rhs.getReal(), +446 imaginary - rhs.getImaginary()); +447 } +448 +449 /** +450 * Compute the +451 * <a href="http://mathworld.wolfram.com/InverseCosine.html" TARGET="_top"> +452 * inverse cosine</a> of this complex number. +453 * <p> +454 * Implements the formula: <pre> +455 * <code> acos(z) = -i (log(z + i (sqrt(1 - z<sup>2</sup>))))</code></pre></p> +456 * <p> +457 * Returns {@link Complex#NaN} if either real or imaginary part of the +458 * input argument is <code>NaN</code> or infinite.</p> +459 * +460 * @return the inverse cosine of this complex number +461 * @since 1.2 +462 */ +463 public Complex acos() { +464 if (isNaN()) { +465 return Complex.NaN; +466 } +467 +468 return this.add(this.sqrt1z().multiply(Complex.I)).log() +469 .multiply(Complex.I.negate()); +470 } +471 +472 /** +473 * Compute the +474 * <a href="http://mathworld.wolfram.com/InverseSine.html" TARGET="_top"> +475 * inverse sine</a> of this complex number. +476 * <p> +477 * Implements the formula: <pre> +478 * <code> asin(z) = -i (log(sqrt(1 - z<sup>2</sup>) + iz)) </code></pre></p> +479 * <p> +480 * Returns {@link Complex#NaN} if either real or imaginary part of the +481 * input argument is <code>NaN</code> or infinite.</p> +482 * +483 * @return the inverse sine of this complex number. +484 * @since 1.2 +485 */ +486 public Complex asin() { +487 if (isNaN()) { +488 return Complex.NaN; +489 } +490 +491 return sqrt1z().add(this.multiply(Complex.I)).log() +492 .multiply(Complex.I.negate()); +493 } +494 +495 /** +496 * Compute the +497 * <a href="http://mathworld.wolfram.com/InverseTangent.html" TARGET="_top"> +498 * inverse tangent</a> of this complex number. +499 * <p> +500 * Implements the formula: <pre> +501 * <code> atan(z) = (i/2) log((i + z)/(i - z)) </code></pre></p> +502 * <p> +503 * Returns {@link Complex#NaN} if either real or imaginary part of the +504 * input argument is <code>NaN</code> or infinite.</p> +505 * +506 * @return the inverse tangent of this complex number +507 * @since 1.2 +508 */ +509 public Complex atan() { +510 if (isNaN()) { +511 return Complex.NaN; +512 } +513 +514 return this.add(Complex.I).divide(Complex.I.subtract(this)).log() +515 .multiply(Complex.I.divide(createComplex(2.0, 0.0))); +516 } +517 +518 /** +519 * Compute the +520 * <a href="http://mathworld.wolfram.com/Cosine.html" TARGET="_top"> +521 * cosine</a> +522 * of this complex number. +523 * <p> +524 * Implements the formula: <pre> +525 * <code> cos(a + bi) = cos(a)cosh(b) - sin(a)sinh(b)i</code></pre> +526 * where the (real) functions on the right-hand side are +527 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, +528 * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p> +529 * <p> +530 * Returns {@link Complex#NaN} if either real or imaginary part of the +531 * input argument is <code>NaN</code>.</p> +532 * <p> +533 * Infinite values in real or imaginary parts of the input may result in +534 * infinite or NaN values returned in parts of the result.<pre> +535 * Examples: +536 * <code> +537 * cos(1 ± INFINITY i) = 1 ∓ INFINITY i +538 * cos(±INFINITY + i) = NaN + NaN i +539 * cos(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre></p> +540 * +541 * @return the cosine of this complex number +542 * @since 1.2 +543 */ +544 public Complex cos() { +545 if (isNaN()) { +546 return Complex.NaN; +547 } +548 +549 return createComplex(Math.cos(real) * MathUtils.cosh(imaginary), +550 -Math.sin(real) * MathUtils.sinh(imaginary)); +551 } +552 +553 /** +554 * Compute the +555 * <a href="http://mathworld.wolfram.com/HyperbolicCosine.html" TARGET="_top"> +556 * hyperbolic cosine</a> of this complex number. +557 * <p> +558 * Implements the formula: <pre> +559 * <code> cosh(a + bi) = cosh(a)cos(b) + sinh(a)sin(b)i</code></pre> +560 * where the (real) functions on the right-hand side are +561 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, +562 * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p> +563 * <p> +564 * Returns {@link Complex#NaN} if either real or imaginary part of the +565 * input argument is <code>NaN</code>.</p> +566 * <p> +567 * Infinite values in real or imaginary parts of the input may result in +568 * infinite or NaN values returned in parts of the result.<pre> +569 * Examples: +570 * <code> +571 * cosh(1 ± INFINITY i) = NaN + NaN i +572 * cosh(±INFINITY + i) = INFINITY ± INFINITY i +573 * cosh(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre></p> +574 * +575 * @return the hyperbolic cosine of this complex number. +576 * @since 1.2 +577 */ +578 public Complex cosh() { +579 if (isNaN()) { +580 return Complex.NaN; +581 } +582 +583 return createComplex(MathUtils.cosh(real) * Math.cos(imaginary), +584 MathUtils.sinh(real) * Math.sin(imaginary)); +585 } +586 +587 /** +588 * Compute the +589 * <a href="http://mathworld.wolfram.com/ExponentialFunction.html" TARGET="_top"> +590 * exponential function</a> of this complex number. +591 * <p> +592 * Implements the formula: <pre> +593 * <code> exp(a + bi) = exp(a)cos(b) + exp(a)sin(b)i</code></pre> +594 * where the (real) functions on the right-hand side are +595 * {@link java.lang.Math#exp}, {@link java.lang.Math#cos}, and +596 * {@link java.lang.Math#sin}.</p> +597 * <p> +598 * Returns {@link Complex#NaN} if either real or imaginary part of the +599 * input argument is <code>NaN</code>.</p> +600 * <p> +601 * Infinite values in real or imaginary parts of the input may result in +602 * infinite or NaN values returned in parts of the result.<pre> +603 * Examples: +604 * <code> +605 * exp(1 ± INFINITY i) = NaN + NaN i +606 * exp(INFINITY + i) = INFINITY + INFINITY i +607 * exp(-INFINITY + i) = 0 + 0i +608 * exp(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre></p> +609 * +610 * @return <i>e</i><sup><code>this</code></sup> +611 * @since 1.2 +612 */ +613 public Complex exp() { +614 if (isNaN()) { +615 return Complex.NaN; +616 } +617 +618 double expReal = Math.exp(real); +619 return createComplex(expReal * Math.cos(imaginary), expReal * Math.sin(imaginary)); +620 } +621 +622 /** +623 * Compute the +624 * <a href="http://mathworld.wolfram.com/NaturalLogarithm.html" TARGET="_top"> +625 * natural logarithm</a> of this complex number. +626 * <p> +627 * Implements the formula: <pre> +628 * <code> log(a + bi) = ln(|a + bi|) + arg(a + bi)i</code></pre> +629 * where ln on the right hand side is {@link java.lang.Math#log}, +630 * <code>|a + bi|</code> is the modulus, {@link Complex#abs}, and +631 * <code>arg(a + bi) = {@link java.lang.Math#atan2}(b, a)</code></p> +632 * <p> +633 * Returns {@link Complex#NaN} if either real or imaginary part of the +634 * input argument is <code>NaN</code>.</p> +635 * <p> +636 * Infinite (or critical) values in real or imaginary parts of the input may +637 * result in infinite or NaN values returned in parts of the result.<pre> +638 * Examples: +639 * <code> +640 * log(1 ± INFINITY i) = INFINITY ± (π/2)i +641 * log(INFINITY + i) = INFINITY + 0i +642 * log(-INFINITY + i) = INFINITY + πi +643 * log(INFINITY ± INFINITY i) = INFINITY ± (π/4)i +644 * log(-INFINITY ± INFINITY i) = INFINITY ± (3π/4)i +645 * log(0 + 0i) = -INFINITY + 0i +646 * </code></pre></p> +647 * +648 * @return ln of this complex number. +649 * @since 1.2 +650 */ +651 public Complex log() { +652 if (isNaN()) { +653 return Complex.NaN; +654 } +655 +656 return createComplex(Math.log(abs()), +657 Math.atan2(imaginary, real)); +658 } +659 +660 /** +661 * Returns of value of this complex number raised to the power of <code>x</code>. +662 * <p> +663 * Implements the formula: <pre> +664 * <code> y<sup>x</sup> = exp(x·log(y))</code></pre> +665 * where <code>exp</code> and <code>log</code> are {@link #exp} and +666 * {@link #log}, respectively.</p> +667 * <p> +668 * Returns {@link Complex#NaN} if either real or imaginary part of the +669 * input argument is <code>NaN</code> or infinite, or if <code>y</code> +670 * equals {@link Complex#ZERO}.</p> +671 * +672 * @param x the exponent. +673 * @return <code>this</code><sup><code>x</code></sup> +674 * @throws NullPointerException if x is null +675 * @since 1.2 +676 */ +677 public Complex pow(Complex x) { +678 if (x == null) { +679 throw new NullPointerException(); +680 } +681 return this.log().multiply(x).exp(); +682 } +683 +684 /** +685 * Compute the +686 * <a href="http://mathworld.wolfram.com/Sine.html" TARGET="_top"> +687 * sine</a> +688 * of this complex number. +689 * <p> +690 * Implements the formula: <pre> +691 * <code> sin(a + bi) = sin(a)cosh(b) - cos(a)sinh(b)i</code></pre> +692 * where the (real) functions on the right-hand side are +693 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, +694 * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p> +695 * <p> +696 * Returns {@link Complex#NaN} if either real or imaginary part of the +697 * input argument is <code>NaN</code>.</p> +698 * <p> +699 * Infinite values in real or imaginary parts of the input may result in +700 * infinite or NaN values returned in parts of the result.<pre> +701 * Examples: +702 * <code> +703 * sin(1 ± INFINITY i) = 1 ± INFINITY i +704 * sin(±INFINITY + i) = NaN + NaN i +705 * sin(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre></p> +706 * +707 * @return the sine of this complex number. +708 * @since 1.2 +709 */ +710 public Complex sin() { +711 if (isNaN()) { +712 return Complex.NaN; +713 } +714 +715 return createComplex(Math.sin(real) * MathUtils.cosh(imaginary), +716 Math.cos(real) * MathUtils.sinh(imaginary)); +717 } +718 +719 /** +720 * Compute the +721 * <a href="http://mathworld.wolfram.com/HyperbolicSine.html" TARGET="_top"> +722 * hyperbolic sine</a> of this complex number. +723 * <p> +724 * Implements the formula: <pre> +725 * <code> sinh(a + bi) = sinh(a)cos(b)) + cosh(a)sin(b)i</code></pre> +726 * where the (real) functions on the right-hand side are +727 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, +728 * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p> +729 * <p> +730 * Returns {@link Complex#NaN} if either real or imaginary part of the +731 * input argument is <code>NaN</code>.</p> +732 * <p> +733 * Infinite values in real or imaginary parts of the input may result in +734 * infinite or NaN values returned in parts of the result.<pre> +735 * Examples: +736 * <code> +737 * sinh(1 ± INFINITY i) = NaN + NaN i +738 * sinh(±INFINITY + i) = ± INFINITY + INFINITY i +739 * sinh(±INFINITY ± INFINITY i) = NaN + NaN i</code></pre></p> +740 * +741 * @return the hyperbolic sine of this complex number +742 * @since 1.2 +743 */ +744 public Complex sinh() { +745 if (isNaN()) { +746 return Complex.NaN; +747 } +748 +749 return createComplex(MathUtils.sinh(real) * Math.cos(imaginary), +750 MathUtils.cosh(real) * Math.sin(imaginary)); +751 } +752 +753 /** +754 * Compute the +755 * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top"> +756 * square root</a> of this complex number. +757 * <p> +758 * Implements the following algorithm to compute <code>sqrt(a + bi)</code>: +759 * <ol><li>Let <code>t = sqrt((|a| + |a + bi|) / 2)</code></li> +760 * <li><pre>if <code> a ≥ 0</code> return <code>t + (b/2t)i</code> +761 * else return <code>|b|/2t + sign(b)t i </code></pre></li> +762 * </ol> +763 * where <ul> +764 * <li><code>|a| = {@link Math#abs}(a)</code></li> +765 * <li><code>|a + bi| = {@link Complex#abs}(a + bi) </code></li> +766 * <li><code>sign(b) = {@link MathUtils#indicator}(b) </code> +767 * </ul></p> +768 * <p> +769 * Returns {@link Complex#NaN} if either real or imaginary part of the +770 * input argument is <code>NaN</code>.</p> +771 * <p> +772 * Infinite values in real or imaginary parts of the input may result in +773 * infinite or NaN values returned in parts of the result.<pre> +774 * Examples: +775 * <code> +776 * sqrt(1 ± INFINITY i) = INFINITY + NaN i +777 * sqrt(INFINITY + i) = INFINITY + 0i +778 * sqrt(-INFINITY + i) = 0 + INFINITY i +779 * sqrt(INFINITY ± INFINITY i) = INFINITY + NaN i +780 * sqrt(-INFINITY ± INFINITY i) = NaN ± INFINITY i +781 * </code></pre></p> +782 * +783 * @return the square root of this complex number +784 * @since 1.2 +785 */ +786 public Complex sqrt() { +787 if (isNaN()) { +788 return Complex.NaN; +789 } +790 +791 if (real == 0.0 && imaginary == 0.0) { +792 return createComplex(0.0, 0.0); +793 } +794 +795 double t = Math.sqrt((Math.abs(real) + abs()) / 2.0); +796 if (real >= 0.0) { +797 return createComplex(t, imaginary / (2.0 * t)); +798 } else { +799 return createComplex(Math.abs(imaginary) / (2.0 * t), +800 MathUtils.indicator(imaginary) * t); +801 } +802 } +803 +804 /** +805 * Compute the +806 * <a href="http://mathworld.wolfram.com/SquareRoot.html" TARGET="_top"> +807 * square root</a> of 1 - <code>this</code><sup>2</sup> for this complex +808 * number. +809 * <p> +810 * Computes the result directly as +811 * <code>sqrt(Complex.ONE.subtract(z.multiply(z)))</code>.</p> +812 * <p> +813 * Returns {@link Complex#NaN} if either real or imaginary part of the +814 * input argument is <code>NaN</code>.</p> +815 * <p> +816 * Infinite values in real or imaginary parts of the input may result in +817 * infinite or NaN values returned in parts of the result.</p> +818 * +819 * @return the square root of 1 - <code>this</code><sup>2</sup> +820 * @since 1.2 +821 */ +822 public Complex sqrt1z() { +823 return createComplex(1.0, 0.0).subtract(this.multiply(this)).sqrt(); +824 } +825 +826 /** +827 * Compute the +828 * <a href="http://mathworld.wolfram.com/Tangent.html" TARGET="_top"> +829 * tangent</a> of this complex number. +830 * <p> +831 * Implements the formula: <pre> +832 * <code>tan(a + bi) = sin(2a)/(cos(2a)+cosh(2b)) + [sinh(2b)/(cos(2a)+cosh(2b))]i</code></pre> +833 * where the (real) functions on the right-hand side are +834 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, +835 * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p> +836 * <p> +837 * Returns {@link Complex#NaN} if either real or imaginary part of the +838 * input argument is <code>NaN</code>.</p> +839 * <p> +840 * Infinite (or critical) values in real or imaginary parts of the input may +841 * result in infinite or NaN values returned in parts of the result.<pre> +842 * Examples: +843 * <code> +844 * tan(1 ± INFINITY i) = 0 + NaN i +845 * tan(±INFINITY + i) = NaN + NaN i +846 * tan(±INFINITY ± INFINITY i) = NaN + NaN i +847 * tan(±π/2 + 0 i) = ±INFINITY + NaN i</code></pre></p> +848 * +849 * @return the tangent of this complex number +850 * @since 1.2 +851 */ +852 public Complex tan() { +853 if (isNaN()) { +854 return Complex.NaN; +855 } +856 +857 double real2 = 2.0 * real; +858 double imaginary2 = 2.0 * imaginary; +859 double d = Math.cos(real2) + MathUtils.cosh(imaginary2); +860 +861 return createComplex(Math.sin(real2) / d, MathUtils.sinh(imaginary2) / d); +862 } +863 +864 /** +865 * Compute the +866 * <a href="http://mathworld.wolfram.com/HyperbolicTangent.html" TARGET="_top"> +867 * hyperbolic tangent</a> of this complex number. +868 * <p> +869 * Implements the formula: <pre> +870 * <code>tan(a + bi) = sinh(2a)/(cosh(2a)+cos(2b)) + [sin(2b)/(cosh(2a)+cos(2b))]i</code></pre> +871 * where the (real) functions on the right-hand side are +872 * {@link java.lang.Math#sin}, {@link java.lang.Math#cos}, +873 * {@link MathUtils#cosh} and {@link MathUtils#sinh}.</p> +874 * <p> +875 * Returns {@link Complex#NaN} if either real or imaginary part of the +876 * input argument is <code>NaN</code>.</p> +877 * <p> +878 * Infinite values in real or imaginary parts of the input may result in +879 * infinite or NaN values returned in parts of the result.<pre> +880 * Examples: +881 * <code> +882 * tanh(1 ± INFINITY i) = NaN + NaN i +883 * tanh(±INFINITY + i) = NaN + 0 i +884 * tanh(±INFINITY ± INFINITY i) = NaN + NaN i +885 * tanh(0 + (π/2)i) = NaN + INFINITY i</code></pre></p> +886 * +887 * @return the hyperbolic tangent of this complex number +888 * @since 1.2 +889 */ +890 public Complex tanh() { +891 if (isNaN()) { +892 return Complex.NaN; +893 } +894 +895 double real2 = 2.0 * real; +896 double imaginary2 = 2.0 * imaginary; +897 double d = MathUtils.cosh(real2) + Math.cos(imaginary2); +898 +899 return createComplex(MathUtils.sinh(real2) / d, Math.sin(imaginary2) / d); +900 } +901 +902 +903 +904 /** +905 * <p>Compute the argument of this complex number. +906 * </p> +907 * <p>The argument is the angle phi between the positive real axis and the point +908 * representing this number in the complex plane. The value returned is between -PI (not inclusive) +909 * and PI (inclusive), with negative values returned for numbers with negative imaginary parts. +910 * </p> +911 * <p>If either real or imaginary part (or both) is NaN, NaN is returned. Infinite parts are handled +912 * as java.Math.atan2 handles them, essentially treating finite parts as zero in the presence of +913 * an infinite coordinate and returning a multiple of pi/4 depending on the signs of the infinite +914 * parts. See the javadoc for java.Math.atan2 for full details.</p> +915 * +916 * @return the argument of this complex number +917 */ +918 public double getArgument() { +919 return Math.atan2(getImaginary(), getReal()); +920 } +921 +922 /** +923 * <p>Computes the n-th roots of this complex number. +924 * </p> +925 * <p>The nth roots are defined by the formula: <pre> +926 * <code> z<sub>k</sub> = abs<sup> 1/n</sup> (cos(phi + 2πk/n) + i (sin(phi + 2πk/n))</code></pre> +927 * for <i><code>k=0, 1, ..., n-1</code></i>, where <code>abs</code> and <code>phi</code> are +928 * respectively the {@link #abs() modulus} and {@link #getArgument() argument} of this complex number. +929 * </p> +930 * <p>If one or both parts of this complex number is NaN, a list with just one element, +931 * {@link #NaN} is returned.</p> +932 * <p>if neither part is NaN, but at least one part is infinite, the result is a one-element +933 * list containing {@link #INF}.</p> +934 * +935 * @param n degree of root +936 * @return List<Complex> all nth roots of this complex number +937 * @throws IllegalArgumentException if parameter n is less than or equal to 0 +938 * @since 2.0 +939 */ +940 public List<Complex> nthRoot(int n) throws IllegalArgumentException { +941 +942 if (n <= 0) { +943 throw MathRuntimeException.createIllegalArgumentException( +944 "cannot compute nth root for null or negative n: {0}", +945 n); +946 } +947 +948 List<Complex> result = new ArrayList<Complex>(); +949 +950 if (isNaN()) { +951 result.add(Complex.NaN); +952 return result; +953 } +954 +955 if (isInfinite()) { +956 result.add(Complex.INF); +957 return result; +958 } +959 +960 // nth root of abs -- faster / more accurate to use a solver here? +961 final double nthRootOfAbs = Math.pow(abs(), 1.0 / n); +962 +963 // Compute nth roots of complex number with k = 0, 1, ... n-1 +964 final double nthPhi = getArgument()/n; +965 final double slice = 2 * Math.PI / n; +966 double innerPart = nthPhi; +967 for (int k = 0; k < n ; k++) { +968 // inner part +969 final double realPart = nthRootOfAbs * Math.cos(innerPart); +970 final double imaginaryPart = nthRootOfAbs * Math.sin(innerPart); +971 result.add(createComplex(realPart, imaginaryPart)); +972 innerPart += slice; +973 } +974 +975 return result; +976 } +977 +978 /** +979 * Create a complex number given the real and imaginary parts. +980 * +981 * @param realPart the real part +982 * @param imaginaryPart the imaginary part +983 * @return a new complex number instance +984 * @since 1.2 +985 */ +986 protected Complex createComplex(double realPart, double imaginaryPart) { +987 return new Complex(realPart, imaginaryPart); +988 } +989 +990 /** +991 * <p>Resolve the transient fields in a deserialized Complex Object.</p> +992 * <p>Subclasses will need to override {@link #createComplex} to deserialize properly</p> +993 * @return A Complex instance with all fields resolved. +994 * @since 2.0 +995 */ +996 protected final Object readResolve() { +997 return createComplex(real, imaginary); +998 } +999 +1000 /** {@inheritDoc} */ +1001 public ComplexField getField() { +1002 return ComplexField.getInstance(); +1003 } +1004 +1005 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/complex/ComplexField.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/complex/ComplexField.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,144 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.complex; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.Field; +023 +024 /** +025 * Representation of the complex numbers field. +026 * <p> +027 * This class is a singleton. +028 * </p> +029 * @see Complex +030 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +031 * @since 2.0 +032 */ +033 public class ComplexField implements Field<Complex>, Serializable { +034 +035 /** Serializable version identifier. */ +036 private static final long serialVersionUID = -6130362688700788798L; +037 +038 /** Private constructor for the singleton. +039 */ +040 private ComplexField() { +041 } +042 +043 /** Get the unique instance. +044 * @return the unique instance +045 */ +046 public static ComplexField getInstance() { +047 return LazyHolder.INSTANCE; +048 } +049 +050 /** {@inheritDoc} */ +051 public Complex getOne() { +052 return Complex.ONE; +053 } +054 +055 /** {@inheritDoc} */ +056 public Complex getZero() { +057 return Complex.ZERO; +058 } +059 +060 // CHECKSTYLE: stop HideUtilityClassConstructor +061 /** Holder for the instance. +062 * <p>We use here the Initialization On Demand Holder Idiom.</p> +063 */ +064 private static class LazyHolder { +065 /** Cached field instance. */ +066 private static final ComplexField INSTANCE = new ComplexField(); +067 } +068 // CHECKSTYLE: resume HideUtilityClassConstructor +069 +070 /** Handle deserialization of the singleton. +071 * @return the singleton instance +072 */ +073 private Object readResolve() { +074 // return the singleton instance +075 return LazyHolder.INSTANCE; +076 } +077 +078 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/complex/ComplexFormat.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/complex/ComplexFormat.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,451 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.complex; +019 +020 import java.text.FieldPosition; +021 import java.text.NumberFormat; +022 import java.text.ParseException; +023 import java.text.ParsePosition; +024 import java.util.Locale; +025 +026 import org.apache.commons.math.MathRuntimeException; +027 import org.apache.commons.math.util.CompositeFormat; +028 +029 /** +030 * Formats a Complex number in cartesian format "Re(c) + Im(c)i". 'i' can +031 * be replaced with 'j' (or anything else), and the number format for both real +032 * and imaginary parts can be configured. +033 * +034 * @version $Revision: 811783 $ $Date: 2009-09-06 04:56:58 -0400 (Sun, 06 Sep 2009) $ +035 */ +036 public class ComplexFormat extends CompositeFormat { +037 +038 /** Serializable version identifier */ +039 private static final long serialVersionUID = -3343698360149467646L; +040 +041 /** The default imaginary character. */ +042 private static final String DEFAULT_IMAGINARY_CHARACTER = "i"; +043 +044 /** The notation used to signify the imaginary part of the complex number. */ +045 private String imaginaryCharacter; +046 +047 /** The format used for the imaginary part. */ +048 private NumberFormat imaginaryFormat; +049 +050 /** The format used for the real part. */ +051 private NumberFormat realFormat; +052 +053 /** +054 * Create an instance with the default imaginary character, 'i', and the +055 * default number format for both real and imaginary parts. +056 */ +057 public ComplexFormat() { +058 this(DEFAULT_IMAGINARY_CHARACTER, getDefaultNumberFormat()); +059 } +060 +061 /** +062 * Create an instance with a custom number format for both real and +063 * imaginary parts. +064 * @param format the custom format for both real and imaginary parts. +065 */ +066 public ComplexFormat(NumberFormat format) { +067 this(DEFAULT_IMAGINARY_CHARACTER, format); +068 } +069 +070 /** +071 * Create an instance with a custom number format for the real part and a +072 * custom number format for the imaginary part. +073 * @param realFormat the custom format for the real part. +074 * @param imaginaryFormat the custom format for the imaginary part. +075 */ +076 public ComplexFormat(NumberFormat realFormat, NumberFormat imaginaryFormat) { +077 this(DEFAULT_IMAGINARY_CHARACTER, realFormat, imaginaryFormat); +078 } +079 +080 /** +081 * Create an instance with a custom imaginary character, and the default +082 * number format for both real and imaginary parts. +083 * @param imaginaryCharacter The custom imaginary character. +084 */ +085 public ComplexFormat(String imaginaryCharacter) { +086 this(imaginaryCharacter, getDefaultNumberFormat()); +087 } +088 +089 /** +090 * Create an instance with a custom imaginary character, and a custom number +091 * format for both real and imaginary parts. +092 * @param imaginaryCharacter The custom imaginary character. +093 * @param format the custom format for both real and imaginary parts. +094 */ +095 public ComplexFormat(String imaginaryCharacter, NumberFormat format) { +096 this(imaginaryCharacter, format, (NumberFormat)format.clone()); +097 } +098 +099 /** +100 * Create an instance with a custom imaginary character, a custom number +101 * format for the real part, and a custom number format for the imaginary +102 * part. +103 * @param imaginaryCharacter The custom imaginary character. +104 * @param realFormat the custom format for the real part. +105 * @param imaginaryFormat the custom format for the imaginary part. +106 */ +107 public ComplexFormat(String imaginaryCharacter, NumberFormat realFormat, +108 NumberFormat imaginaryFormat) { +109 super(); +110 setImaginaryCharacter(imaginaryCharacter); +111 setImaginaryFormat(imaginaryFormat); +112 setRealFormat(realFormat); +113 } +114 +115 /** +116 * Get the set of locales for which complex formats are available. +117 * <p>This is the same set as the {@link NumberFormat} set.</p> +118 * @return available complex format locales. +119 */ +120 public static Locale[] getAvailableLocales() { +121 return NumberFormat.getAvailableLocales(); +122 } +123 +124 /** +125 * This static method calls {@link #format(Object)} on a default instance of +126 * ComplexFormat. +127 * +128 * @param c Complex object to format +129 * @return A formatted number in the form "Re(c) + Im(c)i" +130 */ +131 public static String formatComplex(Complex c) { +132 return getInstance().format(c); +133 } +134 +135 /** +136 * Formats a {@link Complex} object to produce a string. +137 * +138 * @param complex the object to format. +139 * @param toAppendTo where the text is to be appended +140 * @param pos On input: an alignment field, if desired. On output: the +141 * offsets of the alignment field +142 * @return the value passed in as toAppendTo. +143 */ +144 public StringBuffer format(Complex complex, StringBuffer toAppendTo, +145 FieldPosition pos) { +146 +147 pos.setBeginIndex(0); +148 pos.setEndIndex(0); +149 +150 // format real +151 double re = complex.getReal(); +152 formatDouble(re, getRealFormat(), toAppendTo, pos); +153 +154 // format sign and imaginary +155 double im = complex.getImaginary(); +156 if (im < 0.0) { +157 toAppendTo.append(" - "); +158 formatDouble(-im, getImaginaryFormat(), toAppendTo, pos); +159 toAppendTo.append(getImaginaryCharacter()); +160 } else if (im > 0.0 || Double.isNaN(im)) { +161 toAppendTo.append(" + "); +162 formatDouble(im, getImaginaryFormat(), toAppendTo, pos); +163 toAppendTo.append(getImaginaryCharacter()); +164 } +165 +166 return toAppendTo; +167 } +168 +169 /** +170 * Formats a object to produce a string. <code>obj</code> must be either a +171 * {@link Complex} object or a {@link Number} object. Any other type of +172 * object will result in an {@link IllegalArgumentException} being thrown. +173 * +174 * @param obj the object to format. +175 * @param toAppendTo where the text is to be appended +176 * @param pos On input: an alignment field, if desired. On output: the +177 * offsets of the alignment field +178 * @return the value passed in as toAppendTo. +179 * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) +180 * @throws IllegalArgumentException is <code>obj</code> is not a valid type. +181 */ +182 @Override +183 public StringBuffer format(Object obj, StringBuffer toAppendTo, +184 FieldPosition pos) { +185 +186 StringBuffer ret = null; +187 +188 if (obj instanceof Complex) { +189 ret = format( (Complex)obj, toAppendTo, pos); +190 } else if (obj instanceof Number) { +191 ret = format( new Complex(((Number)obj).doubleValue(), 0.0), +192 toAppendTo, pos); +193 } else { +194 throw MathRuntimeException.createIllegalArgumentException( +195 "cannot format a {0} instance as a complex number", +196 obj.getClass().getName()); +197 } +198 +199 return ret; +200 } +201 +202 /** +203 * Access the imaginaryCharacter. +204 * @return the imaginaryCharacter. +205 */ +206 public String getImaginaryCharacter() { +207 return imaginaryCharacter; +208 } +209 +210 /** +211 * Access the imaginaryFormat. +212 * @return the imaginaryFormat. +213 */ +214 public NumberFormat getImaginaryFormat() { +215 return imaginaryFormat; +216 } +217 +218 /** +219 * Returns the default complex format for the current locale. +220 * @return the default complex format. +221 */ +222 public static ComplexFormat getInstance() { +223 return getInstance(Locale.getDefault()); +224 } +225 +226 /** +227 * Returns the default complex format for the given locale. +228 * @param locale the specific locale used by the format. +229 * @return the complex format specific to the given locale. +230 */ +231 public static ComplexFormat getInstance(Locale locale) { +232 NumberFormat f = getDefaultNumberFormat(locale); +233 return new ComplexFormat(f); +234 } +235 +236 /** +237 * Access the realFormat. +238 * @return the realFormat. +239 */ +240 public NumberFormat getRealFormat() { +241 return realFormat; +242 } +243 +244 /** +245 * Parses a string to produce a {@link Complex} object. +246 * +247 * @param source the string to parse +248 * @return the parsed {@link Complex} object. +249 * @exception ParseException if the beginning of the specified string +250 * cannot be parsed. +251 */ +252 public Complex parse(String source) throws ParseException { +253 ParsePosition parsePosition = new ParsePosition(0); +254 Complex result = parse(source, parsePosition); +255 if (parsePosition.getIndex() == 0) { +256 throw MathRuntimeException.createParseException( +257 parsePosition.getErrorIndex(), +258 "unparseable complex number: \"{0}\"", source); +259 } +260 return result; +261 } +262 +263 /** +264 * Parses a string to produce a {@link Complex} object. +265 * +266 * @param source the string to parse +267 * @param pos input/ouput parsing parameter. +268 * @return the parsed {@link Complex} object. +269 */ +270 public Complex parse(String source, ParsePosition pos) { +271 int initialIndex = pos.getIndex(); +272 +273 // parse whitespace +274 parseAndIgnoreWhitespace(source, pos); +275 +276 // parse real +277 Number re = parseNumber(source, getRealFormat(), pos); +278 if (re == null) { +279 // invalid real number +280 // set index back to initial, error index should already be set +281 pos.setIndex(initialIndex); +282 return null; +283 } +284 +285 // parse sign +286 int startIndex = pos.getIndex(); +287 char c = parseNextCharacter(source, pos); +288 int sign = 0; +289 switch (c) { +290 case 0 : +291 // no sign +292 // return real only complex number +293 return new Complex(re.doubleValue(), 0.0); +294 case '-' : +295 sign = -1; +296 break; +297 case '+' : +298 sign = 1; +299 break; +300 default : +301 // invalid sign +302 // set index back to initial, error index should be the last +303 // character examined. +304 pos.setIndex(initialIndex); +305 pos.setErrorIndex(startIndex); +306 return null; +307 } +308 +309 // parse whitespace +310 parseAndIgnoreWhitespace(source, pos); +311 +312 // parse imaginary +313 Number im = parseNumber(source, getRealFormat(), pos); +314 if (im == null) { +315 // invalid imaginary number +316 // set index back to initial, error index should already be set +317 pos.setIndex(initialIndex); +318 return null; +319 } +320 +321 // parse imaginary character +322 if (!parseFixedstring(source, getImaginaryCharacter(), pos)) { +323 return null; +324 } +325 +326 return new Complex(re.doubleValue(), im.doubleValue() * sign); +327 +328 } +329 +330 /** +331 * Parses a string to produce a object. +332 * +333 * @param source the string to parse +334 * @param pos input/ouput parsing parameter. +335 * @return the parsed object. +336 * @see java.text.Format#parseObject(java.lang.String, java.text.ParsePosition) +337 */ +338 @Override +339 public Object parseObject(String source, ParsePosition pos) { +340 return parse(source, pos); +341 } +342 +343 /** +344 * Modify the imaginaryCharacter. +345 * @param imaginaryCharacter The new imaginaryCharacter value. +346 * @throws IllegalArgumentException if <code>imaginaryCharacter</code> is +347 * <code>null</code> or an empty string. +348 */ +349 public void setImaginaryCharacter(String imaginaryCharacter) { +350 if (imaginaryCharacter == null || imaginaryCharacter.length() == 0) { +351 throw MathRuntimeException.createIllegalArgumentException( +352 "empty string for imaginary character"); +353 } +354 this.imaginaryCharacter = imaginaryCharacter; +355 } +356 +357 /** +358 * Modify the imaginaryFormat. +359 * @param imaginaryFormat The new imaginaryFormat value. +360 * @throws IllegalArgumentException if <code>imaginaryFormat</code> is +361 * <code>null</code>. +362 */ +363 public void setImaginaryFormat(NumberFormat imaginaryFormat) { +364 if (imaginaryFormat == null) { +365 throw MathRuntimeException.createIllegalArgumentException( +366 "null imaginary format"); +367 } +368 this.imaginaryFormat = imaginaryFormat; +369 } +370 +371 /** +372 * Modify the realFormat. +373 * @param realFormat The new realFormat value. +374 * @throws IllegalArgumentException if <code>realFormat</code> is +375 * <code>null</code>. +376 */ +377 public void setRealFormat(NumberFormat realFormat) { +378 if (realFormat == null) { +379 throw MathRuntimeException.createIllegalArgumentException( +380 "null real format"); +381 } +382 this.realFormat = realFormat; +383 } +384 +385 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/complex/ComplexUtils.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/complex/ComplexUtils.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,136 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.complex; +019 +020 import org.apache.commons.math.MathRuntimeException; +021 +022 /** +023 * Static implementations of common +024 * {@link org.apache.commons.math.complex.Complex} utilities functions. +025 * +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 */ +028 public class ComplexUtils { +029 +030 /** +031 * Default constructor. +032 */ +033 private ComplexUtils() { +034 super(); +035 } +036 +037 /** +038 * Creates a complex number from the given polar representation. +039 * <p> +040 * The value returned is <code>r·e<sup>i·theta</sup></code>, +041 * computed as <code>r·cos(theta) + r·sin(theta)i</code></p> +042 * <p> +043 * If either <code>r</code> or <code>theta</code> is NaN, or +044 * <code>theta</code> is infinite, {@link Complex#NaN} is returned.</p> +045 * <p> +046 * If <code>r</code> is infinite and <code>theta</code> is finite, +047 * infinite or NaN values may be returned in parts of the result, following +048 * the rules for double arithmetic.<pre> +049 * Examples: +050 * <code> +051 * polar2Complex(INFINITY, π/4) = INFINITY + INFINITY i +052 * polar2Complex(INFINITY, 0) = INFINITY + NaN i +053 * polar2Complex(INFINITY, -π/4) = INFINITY - INFINITY i +054 * polar2Complex(INFINITY, 5π/4) = -INFINITY - INFINITY i </code></pre></p> +055 * +056 * @param r the modulus of the complex number to create +057 * @param theta the argument of the complex number to create +058 * @return <code>r·e<sup>i·theta</sup></code> +059 * @throws IllegalArgumentException if r is negative +060 * @since 1.1 +061 */ +062 public static Complex polar2Complex(double r, double theta) { +063 if (r < 0) { +064 throw MathRuntimeException.createIllegalArgumentException( +065 "negative complex module {0}", r); +066 } +067 return new Complex(r * Math.cos(theta), r * Math.sin(theta)); +068 } +069 +070 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/AbstractContinuousDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/AbstractContinuousDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,244 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.ConvergenceException; +022 import org.apache.commons.math.FunctionEvaluationException; +023 import org.apache.commons.math.MathException; +024 import org.apache.commons.math.MathRuntimeException; +025 import org.apache.commons.math.analysis.UnivariateRealFunction; +026 import org.apache.commons.math.analysis.solvers.BrentSolver; +027 import org.apache.commons.math.analysis.solvers.UnivariateRealSolverUtils; +028 +029 /** +030 * Base class for continuous distributions. Default implementations are +031 * provided for some of the methods that do not vary from distribution to +032 * distribution. +033 * +034 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +035 */ +036 public abstract class AbstractContinuousDistribution +037 extends AbstractDistribution +038 implements ContinuousDistribution, Serializable { +039 +040 /** Serializable version identifier */ +041 private static final long serialVersionUID = -38038050983108802L; +042 +043 /** +044 * Solver absolute accuracy for inverse cum computation +045 * @since 2.1 +046 */ +047 private double solverAbsoluteAccuracy = BrentSolver.DEFAULT_ABSOLUTE_ACCURACY; +048 +049 /** +050 * Default constructor. +051 */ +052 protected AbstractContinuousDistribution() { +053 super(); +054 } +055 +056 /** +057 * Return the probability density for a particular point. +058 * @param x The point at which the density should be computed. +059 * @return The pdf at point x. +060 * @throws MathRuntimeException if the specialized class hasn't implemented this function +061 * @since 2.1 +062 */ +063 public double density(double x) throws MathRuntimeException { +064 throw new MathRuntimeException(new UnsupportedOperationException(), +065 "This distribution does not have a density function implemented"); +066 } +067 +068 /** +069 * For this distribution, X, this method returns the critical point x, such +070 * that P(X < x) = <code>p</code>. +071 * +072 * @param p the desired probability +073 * @return x, such that P(X < x) = <code>p</code> +074 * @throws MathException if the inverse cumulative probability can not be +075 * computed due to convergence or other numerical errors. +076 * @throws IllegalArgumentException if <code>p</code> is not a valid +077 * probability. +078 */ +079 public double inverseCumulativeProbability(final double p) +080 throws MathException { +081 if (p < 0.0 || p > 1.0) { +082 throw MathRuntimeException.createIllegalArgumentException( +083 "{0} out of [{1}, {2}] range", p, 0.0, 1.0); +084 } +085 +086 // by default, do simple root finding using bracketing and default solver. +087 // subclasses can override if there is a better method. +088 UnivariateRealFunction rootFindingFunction = +089 new UnivariateRealFunction() { +090 public double value(double x) throws FunctionEvaluationException { +091 double ret = Double.NaN; +092 try { +093 ret = cumulativeProbability(x) - p; +094 } catch (MathException ex) { +095 throw new FunctionEvaluationException(ex, x, ex.getPattern(), ex.getArguments()); +096 } +097 if (Double.isNaN(ret)) { +098 throw new FunctionEvaluationException(x, +099 "Cumulative probability function returned NaN for argument {0} p = {1}", x, p); +100 } +101 return ret; +102 } +103 }; +104 +105 // Try to bracket root, test domain endoints if this fails +106 double lowerBound = getDomainLowerBound(p); +107 double upperBound = getDomainUpperBound(p); +108 double[] bracket = null; +109 try { +110 bracket = UnivariateRealSolverUtils.bracket( +111 rootFindingFunction, getInitialDomain(p), +112 lowerBound, upperBound); +113 } catch (ConvergenceException ex) { +114 /* +115 * Check domain endpoints to see if one gives value that is within +116 * the default solver's defaultAbsoluteAccuracy of 0 (will be the +117 * case if density has bounded support and p is 0 or 1). +118 */ +119 if (Math.abs(rootFindingFunction.value(lowerBound)) < getSolverAbsoluteAccuracy()) { +120 return lowerBound; +121 } +122 if (Math.abs(rootFindingFunction.value(upperBound)) < getSolverAbsoluteAccuracy()) { +123 return upperBound; +124 } +125 // Failed bracket convergence was not because of corner solution +126 throw new MathException(ex); +127 } +128 +129 // find root +130 double root = UnivariateRealSolverUtils.solve(rootFindingFunction, +131 // override getSolverAbsoluteAccuracy() to use a Brent solver with +132 // absolute accuracy different from BrentSolver default +133 bracket[0],bracket[1], getSolverAbsoluteAccuracy()); +134 return root; +135 } +136 +137 /** +138 * Access the initial domain value, based on <code>p</code>, used to +139 * bracket a CDF root. This method is used by +140 * {@link #inverseCumulativeProbability(double)} to find critical values. +141 * +142 * @param p the desired probability for the critical value +143 * @return initial domain value +144 */ +145 protected abstract double getInitialDomain(double p); +146 +147 /** +148 * Access the domain value lower bound, based on <code>p</code>, used to +149 * bracket a CDF root. This method is used by +150 * {@link #inverseCumulativeProbability(double)} to find critical values. +151 * +152 * @param p the desired probability for the critical value +153 * @return domain value lower bound, i.e. +154 * P(X < <i>lower bound</i>) < <code>p</code> +155 */ +156 protected abstract double getDomainLowerBound(double p); +157 +158 /** +159 * Access the domain value upper bound, based on <code>p</code>, used to +160 * bracket a CDF root. This method is used by +161 * {@link #inverseCumulativeProbability(double)} to find critical values. +162 * +163 * @param p the desired probability for the critical value +164 * @return domain value upper bound, i.e. +165 * P(X < <i>upper bound</i>) > <code>p</code> +166 */ +167 protected abstract double getDomainUpperBound(double p); +168 +169 /** +170 * Returns the solver absolute accuracy for inverse cum computation. +171 * +172 * @return the maximum absolute error in inverse cumulative probability estimates +173 * @since 2.1 +174 */ +175 protected double getSolverAbsoluteAccuracy() { +176 return solverAbsoluteAccuracy; +177 } +178 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/AbstractDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/AbstractDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,134 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathException; +022 import org.apache.commons.math.MathRuntimeException; +023 +024 /** +025 * Base class for probability distributions. +026 * +027 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +028 */ +029 public abstract class AbstractDistribution +030 implements Distribution, Serializable { +031 +032 /** Serializable version identifier */ +033 private static final long serialVersionUID = -38038050983108802L; +034 +035 /** +036 * Default constructor. +037 */ +038 protected AbstractDistribution() { +039 super(); +040 } +041 +042 /** +043 * For a random variable X whose values are distributed according +044 * to this distribution, this method returns P(x0 ≤ X ≤ x1). +045 * <p> +046 * The default implementation uses the identity</p> +047 * <p> +048 * P(x0 ≤ X ≤ x1) = P(X ≤ x1) - P(X ≤ x0) </p> +049 * +050 * @param x0 the (inclusive) lower bound +051 * @param x1 the (inclusive) upper bound +052 * @return the probability that a random variable with this distribution +053 * will take a value between <code>x0</code> and <code>x1</code>, +054 * including the endpoints. +055 * @throws MathException if the cumulative probability can not be +056 * computed due to convergence or other numerical errors. +057 * @throws IllegalArgumentException if <code>x0 > x1</code> +058 */ +059 public double cumulativeProbability(double x0, double x1) +060 throws MathException { +061 if (x0 > x1) { +062 throw MathRuntimeException.createIllegalArgumentException( +063 "lower endpoint ({0}) must be less than or equal to upper endpoint ({1})", +064 x0, x1); +065 } +066 return cumulativeProbability(x1) - cumulativeProbability(x0); +067 } +068 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/AbstractIntegerDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/AbstractIntegerDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,322 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.FunctionEvaluationException; +022 import org.apache.commons.math.MathException; +023 import org.apache.commons.math.MathRuntimeException; +024 +025 +026 /** +027 * Base class for integer-valued discrete distributions. Default +028 * implementations are provided for some of the methods that do not vary +029 * from distribution to distribution. +030 * +031 * @version $Revision: 920558 $ $Date: 2010-03-08 17:57:32 -0500 (Mon, 08 Mar 2010) $ +032 */ +033 public abstract class AbstractIntegerDistribution extends AbstractDistribution +034 implements IntegerDistribution, Serializable { +035 +036 /** Message for endpoints in wrong order. */ +037 private static final String WRONG_ORDER_ENDPOINTS_MESSAGE = +038 "lower endpoint ({0}) must be less than or equal to upper endpoint ({1})"; +039 +040 /** Message for out of range point. */ +041 private static final String OUT_OF_RANGE_POINT = +042 "{0} out of [{1}, {2}] range"; +043 +044 /** Serializable version identifier */ +045 private static final long serialVersionUID = -1146319659338487221L; +046 +047 /** +048 * Default constructor. +049 */ +050 protected AbstractIntegerDistribution() { +051 super(); +052 } +053 +054 /** +055 * For a random variable X whose values are distributed according +056 * to this distribution, this method returns P(X ≤ x). In other words, +057 * this method represents the (cumulative) distribution function, or +058 * CDF, for this distribution. +059 * <p> +060 * If <code>x</code> does not represent an integer value, the CDF is +061 * evaluated at the greatest integer less than x. +062 * +063 * @param x the value at which the distribution function is evaluated. +064 * @return cumulative probability that a random variable with this +065 * distribution takes a value less than or equal to <code>x</code> +066 * @throws MathException if the cumulative probability can not be +067 * computed due to convergence or other numerical errors. +068 */ +069 public double cumulativeProbability(double x) throws MathException { +070 return cumulativeProbability((int) Math.floor(x)); +071 } +072 +073 /** +074 * For a random variable X whose values are distributed according +075 * to this distribution, this method returns P(x0 ≤ X ≤ x1). +076 * +077 * @param x0 the (inclusive) lower bound +078 * @param x1 the (inclusive) upper bound +079 * @return the probability that a random variable with this distribution +080 * will take a value between <code>x0</code> and <code>x1</code>, +081 * including the endpoints. +082 * @throws MathException if the cumulative probability can not be +083 * computed due to convergence or other numerical errors. +084 * @throws IllegalArgumentException if <code>x0 > x1</code> +085 */ +086 @Override +087 public double cumulativeProbability(double x0, double x1) +088 throws MathException { +089 if (x0 > x1) { +090 throw MathRuntimeException.createIllegalArgumentException( +091 WRONG_ORDER_ENDPOINTS_MESSAGE, x0, x1); +092 } +093 if (Math.floor(x0) < x0) { +094 return cumulativeProbability(((int) Math.floor(x0)) + 1, +095 (int) Math.floor(x1)); // don't want to count mass below x0 +096 } else { // x0 is mathematical integer, so use as is +097 return cumulativeProbability((int) Math.floor(x0), +098 (int) Math.floor(x1)); +099 } +100 } +101 +102 /** +103 * For a random variable X whose values are distributed according +104 * to this distribution, this method returns P(X ≤ x). In other words, +105 * this method represents the probability distribution function, or PDF, +106 * for this distribution. +107 * +108 * @param x the value at which the PDF is evaluated. +109 * @return PDF for this distribution. +110 * @throws MathException if the cumulative probability can not be +111 * computed due to convergence or other numerical errors. +112 */ +113 public abstract double cumulativeProbability(int x) throws MathException; +114 +115 /** +116 * For a random variable X whose values are distributed according +117 * to this distribution, this method returns P(X = x). In other words, this +118 * method represents the probability mass function, or PMF, for the distribution. +119 * <p> +120 * If <code>x</code> does not represent an integer value, 0 is returned. +121 * +122 * @param x the value at which the probability density function is evaluated +123 * @return the value of the probability density function at x +124 */ +125 public double probability(double x) { +126 double fl = Math.floor(x); +127 if (fl == x) { +128 return this.probability((int) x); +129 } else { +130 return 0; +131 } +132 } +133 +134 /** +135 * For a random variable X whose values are distributed according +136 * to this distribution, this method returns P(x0 ≤ X ≤ x1). +137 * +138 * @param x0 the inclusive, lower bound +139 * @param x1 the inclusive, upper bound +140 * @return the cumulative probability. +141 * @throws MathException if the cumulative probability can not be +142 * computed due to convergence or other numerical errors. +143 * @throws IllegalArgumentException if x0 > x1 +144 */ +145 public double cumulativeProbability(int x0, int x1) throws MathException { +146 if (x0 > x1) { +147 throw MathRuntimeException.createIllegalArgumentException( +148 WRONG_ORDER_ENDPOINTS_MESSAGE, x0, x1); +149 } +150 return cumulativeProbability(x1) - cumulativeProbability(x0 - 1); +151 } +152 +153 /** +154 * For a random variable X whose values are distributed according +155 * to this distribution, this method returns the largest x, such +156 * that P(X ≤ x) ≤ <code>p</code>. +157 * +158 * @param p the desired probability +159 * @return the largest x such that P(X ≤ x) <= p +160 * @throws MathException if the inverse cumulative probability can not be +161 * computed due to convergence or other numerical errors. +162 * @throws IllegalArgumentException if p < 0 or p > 1 +163 */ +164 public int inverseCumulativeProbability(final double p) throws MathException{ +165 if (p < 0.0 || p > 1.0) { +166 throw MathRuntimeException.createIllegalArgumentException( +167 OUT_OF_RANGE_POINT, p, 0.0, 1.0); +168 } +169 +170 // by default, do simple bisection. +171 // subclasses can override if there is a better method. +172 int x0 = getDomainLowerBound(p); +173 int x1 = getDomainUpperBound(p); +174 double pm; +175 while (x0 < x1) { +176 int xm = x0 + (x1 - x0) / 2; +177 pm = checkedCumulativeProbability(xm); +178 if (pm > p) { +179 // update x1 +180 if (xm == x1) { +181 // this can happen with integer division +182 // simply decrement x1 +183 --x1; +184 } else { +185 // update x1 normally +186 x1 = xm; +187 } +188 } else { +189 // update x0 +190 if (xm == x0) { +191 // this can happen with integer division +192 // simply increment x0 +193 ++x0; +194 } else { +195 // update x0 normally +196 x0 = xm; +197 } +198 } +199 } +200 +201 // insure x0 is the correct critical point +202 pm = checkedCumulativeProbability(x0); +203 while (pm > p) { +204 --x0; +205 pm = checkedCumulativeProbability(x0); +206 } +207 +208 return x0; +209 } +210 +211 /** +212 * Computes the cumulative probablity function and checks for NaN values returned. +213 * Throws MathException if the value is NaN. Wraps and rethrows any MathException encountered +214 * evaluating the cumulative probability function in a FunctionEvaluationException. Throws +215 * FunctionEvaluationException of the cumulative probability function returns NaN. +216 * +217 * @param argument input value +218 * @return cumulative probability +219 * @throws FunctionEvaluationException if a MathException occurs computing the cumulative probability +220 */ +221 private double checkedCumulativeProbability(int argument) throws FunctionEvaluationException { +222 double result = Double.NaN; +223 try { +224 result = cumulativeProbability(argument); +225 } catch (MathException ex) { +226 throw new FunctionEvaluationException(ex, argument, ex.getPattern(), ex.getArguments()); +227 } +228 if (Double.isNaN(result)) { +229 throw new FunctionEvaluationException(argument, +230 "Discrete cumulative probability function returned NaN for argument {0}", argument); +231 } +232 return result; +233 } +234 +235 /** +236 * Access the domain value lower bound, based on <code>p</code>, used to +237 * bracket a PDF root. This method is used by +238 * {@link #inverseCumulativeProbability(double)} to find critical values. +239 * +240 * @param p the desired probability for the critical value +241 * @return domain value lower bound, i.e. +242 * P(X < <i>lower bound</i>) < <code>p</code> +243 */ +244 protected abstract int getDomainLowerBound(double p); +245 +246 /** +247 * Access the domain value upper bound, based on <code>p</code>, used to +248 * bracket a PDF root. This method is used by +249 * {@link #inverseCumulativeProbability(double)} to find critical values. +250 * +251 * @param p the desired probability for the critical value +252 * @return domain value upper bound, i.e. +253 * P(X < <i>upper bound</i>) > <code>p</code> +254 */ +255 protected abstract int getDomainUpperBound(double p); +256 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/BetaDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/BetaDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,131 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import org.apache.commons.math.MathException; +020 +021 /** +022 * Computes the cumulative, inverse cumulative and density functions for the beta distribuiton. +023 * +024 * @see <a href="http://en.wikipedia.org/wiki/Beta_distribution">Beta_distribution</a> +025 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +026 * @since 2.0 +027 */ +028 public interface BetaDistribution extends ContinuousDistribution, HasDensity<Double> { +029 /** +030 * Modify the shape parameter, alpha. +031 * @param alpha the new shape parameter. +032 * @deprecated as of 2.1 +033 */ +034 @Deprecated +035 void setAlpha(double alpha); +036 +037 /** +038 * Access the shape parameter, alpha +039 * @return alpha. +040 */ +041 double getAlpha(); +042 +043 /** +044 * Modify the shape parameter, beta. +045 * @param beta the new scale parameter. +046 * @deprecated as of 2.1 +047 */ +048 @Deprecated +049 void setBeta(double beta); +050 +051 /** +052 * Access the shape parameter, beta +053 * @return beta. +054 */ +055 double getBeta(); +056 +057 /** +058 * Return the probability density for a particular point. +059 * @param x The point at which the density should be computed. +060 * @return The pdf at point x. +061 * @exception MathException if probability density cannot be computed +062 */ +063 double density(Double x) throws MathException; +064 +065 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/BetaDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/BetaDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,288 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import org.apache.commons.math.MathException; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.special.Gamma; +022 import org.apache.commons.math.special.Beta; +023 +024 /** +025 * Implements the Beta distribution. +026 * <p> +027 * References: +028 * <ul> +029 * <li><a href="http://en.wikipedia.org/wiki/Beta_distribution"> +030 * Beta distribution</a></li> +031 * </ul> +032 * </p> +033 * @version $Revision: 925900 $ $Date: 2010-03-21 17:10:07 -0400 (Sun, 21 Mar 2010) $ +034 * @since 2.0 +035 */ +036 public class BetaDistributionImpl +037 extends AbstractContinuousDistribution implements BetaDistribution { +038 +039 /** +040 * Default inverse cumulative probability accurac +041 * @since 2.1 +042 */ +043 public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; +044 +045 /** Serializable version identifier. */ +046 private static final long serialVersionUID = -1221965979403477668L; +047 +048 /** First shape parameter. */ +049 private double alpha; +050 +051 /** Second shape parameter. */ +052 private double beta; +053 +054 /** Normalizing factor used in density computations. +055 * updated whenever alpha or beta are changed. +056 */ +057 private double z; +058 +059 /** Inverse cumulative probability accuracy */ +060 private final double solverAbsoluteAccuracy; +061 +062 /** +063 * Build a new instance. +064 * @param alpha first shape parameter (must be positive) +065 * @param beta second shape parameter (must be positive) +066 * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates +067 * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) +068 * @since 2.1 +069 */ +070 public BetaDistributionImpl(double alpha, double beta, double inverseCumAccuracy) { +071 this.alpha = alpha; +072 this.beta = beta; +073 z = Double.NaN; +074 solverAbsoluteAccuracy = inverseCumAccuracy; +075 } +076 +077 /** +078 * Build a new instance. +079 * @param alpha first shape parameter (must be positive) +080 * @param beta second shape parameter (must be positive) +081 */ +082 public BetaDistributionImpl(double alpha, double beta) { +083 this(alpha, beta, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); +084 } +085 +086 /** {@inheritDoc} +087 * @deprecated as of 2.1 (class will become immutable in 3.0) +088 */ +089 @Deprecated +090 public void setAlpha(double alpha) { +091 this.alpha = alpha; +092 z = Double.NaN; +093 } +094 +095 /** {@inheritDoc} */ +096 public double getAlpha() { +097 return alpha; +098 } +099 +100 /** {@inheritDoc} +101 * @deprecated as of 2.1 (class will become immutable in 3.0) +102 */ +103 @Deprecated +104 public void setBeta(double beta) { +105 this.beta = beta; +106 z = Double.NaN; +107 } +108 +109 /** {@inheritDoc} */ +110 public double getBeta() { +111 return beta; +112 } +113 +114 /** +115 * Recompute the normalization factor. +116 */ +117 private void recomputeZ() { +118 if (Double.isNaN(z)) { +119 z = Gamma.logGamma(alpha) + Gamma.logGamma(beta) - Gamma.logGamma(alpha + beta); +120 } +121 } +122 +123 /** +124 * Return the probability density for a particular point. +125 * +126 * @param x The point at which the density should be computed. +127 * @return The pdf at point x. +128 * @deprecated +129 */ +130 public double density(Double x) { +131 return density(x.doubleValue()); +132 } +133 +134 /** +135 * Return the probability density for a particular point. +136 * +137 * @param x The point at which the density should be computed. +138 * @return The pdf at point x. +139 * @since 2.1 +140 */ +141 public double density(double x) { +142 recomputeZ(); +143 if (x < 0 || x > 1) { +144 return 0; +145 } else if (x == 0) { +146 if (alpha < 1) { +147 throw MathRuntimeException.createIllegalArgumentException( +148 "Cannot compute beta density at 0 when alpha = {0,number}", alpha); +149 } +150 return 0; +151 } else if (x == 1) { +152 if (beta < 1) { +153 throw MathRuntimeException.createIllegalArgumentException( +154 "Cannot compute beta density at 1 when beta = %.3g", beta); +155 } +156 return 0; +157 } else { +158 double logX = Math.log(x); +159 double log1mX = Math.log1p(-x); +160 return Math.exp((alpha - 1) * logX + (beta - 1) * log1mX - z); +161 } +162 } +163 +164 /** {@inheritDoc} */ +165 @Override +166 public double inverseCumulativeProbability(double p) throws MathException { +167 if (p == 0) { +168 return 0; +169 } else if (p == 1) { +170 return 1; +171 } else { +172 return super.inverseCumulativeProbability(p); +173 } +174 } +175 +176 /** {@inheritDoc} */ +177 @Override +178 protected double getInitialDomain(double p) { +179 return p; +180 } +181 +182 /** {@inheritDoc} */ +183 @Override +184 protected double getDomainLowerBound(double p) { +185 return 0; +186 } +187 +188 /** {@inheritDoc} */ +189 @Override +190 protected double getDomainUpperBound(double p) { +191 return 1; +192 } +193 +194 /** {@inheritDoc} */ +195 public double cumulativeProbability(double x) throws MathException { +196 if (x <= 0) { +197 return 0; +198 } else if (x >= 1) { +199 return 1; +200 } else { +201 return Beta.regularizedBeta(x, alpha, beta); +202 } +203 } +204 +205 /** {@inheritDoc} */ +206 @Override +207 public double cumulativeProbability(double x0, double x1) throws MathException { +208 return cumulativeProbability(x1) - cumulativeProbability(x0); +209 } +210 +211 /** +212 * Return the absolute accuracy setting of the solver used to estimate +213 * inverse cumulative probabilities. +214 * +215 * @return the solver absolute accuracy +216 * @since 2.1 +217 */ +218 @Override +219 protected double getSolverAbsoluteAccuracy() { +220 return solverAbsoluteAccuracy; +221 } +222 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/BinomialDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/BinomialDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,126 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 /** +020 * The Binomial Distribution. +021 * +022 * <p> +023 * References: +024 * <ul> +025 * <li><a href="http://mathworld.wolfram.com/BinomialDistribution.html"> +026 * Binomial Distribution</a></li> +027 * </ul> +028 * </p> +029 * +030 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +031 */ +032 public interface BinomialDistribution extends IntegerDistribution { +033 /** +034 * Access the number of trials for this distribution. +035 * @return the number of trials. +036 */ +037 int getNumberOfTrials(); +038 +039 /** +040 * Access the probability of success for this distribution. +041 * @return the probability of success. +042 */ +043 double getProbabilityOfSuccess(); +044 +045 /** +046 * Change the number of trials for this distribution. +047 * @param trials the new number of trials. +048 * @deprecated as of v2.1 +049 */ +050 @Deprecated +051 void setNumberOfTrials(int trials); +052 +053 /** +054 * Change the probability of success for this distribution. +055 * @param p the new probability of success. +056 * @deprecated as of v2.1 +057 */ +058 @Deprecated +059 void setProbabilityOfSuccess(double p); +060 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/BinomialDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/BinomialDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,287 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathException; +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.special.Beta; +024 +025 /** +026 * The default implementation of {@link BinomialDistribution}. +027 * +028 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +029 */ +030 public class BinomialDistributionImpl extends AbstractIntegerDistribution +031 implements BinomialDistribution, Serializable { +032 +033 /** Serializable version identifier */ +034 private static final long serialVersionUID = 6751309484392813623L; +035 +036 /** The number of trials. */ +037 private int numberOfTrials; +038 +039 /** The probability of success. */ +040 private double probabilityOfSuccess; +041 +042 /** +043 * Create a binomial distribution with the given number of trials and +044 * probability of success. +045 * +046 * @param trials the number of trials. +047 * @param p the probability of success. +048 */ +049 public BinomialDistributionImpl(int trials, double p) { +050 super(); +051 setNumberOfTrialsInternal(trials); +052 setProbabilityOfSuccessInternal(p); +053 } +054 +055 /** +056 * Access the number of trials for this distribution. +057 * +058 * @return the number of trials. +059 */ +060 public int getNumberOfTrials() { +061 return numberOfTrials; +062 } +063 +064 /** +065 * Access the probability of success for this distribution. +066 * +067 * @return the probability of success. +068 */ +069 public double getProbabilityOfSuccess() { +070 return probabilityOfSuccess; +071 } +072 +073 /** +074 * Change the number of trials for this distribution. +075 * +076 * @param trials the new number of trials. +077 * @throws IllegalArgumentException if <code>trials</code> is not a valid +078 * number of trials. +079 * @deprecated as of 2.1 (class will become immutable in 3.0) +080 */ +081 @Deprecated +082 public void setNumberOfTrials(int trials) { +083 setNumberOfTrialsInternal(trials); +084 } +085 /** +086 * Change the number of trials for this distribution. +087 * +088 * @param trials the new number of trials. +089 * @throws IllegalArgumentException if <code>trials</code> is not a valid +090 * number of trials. +091 */ +092 private void setNumberOfTrialsInternal(int trials) { +093 if (trials < 0) { +094 throw MathRuntimeException.createIllegalArgumentException( +095 "number of trials must be non-negative ({0})", trials); +096 } +097 numberOfTrials = trials; +098 } +099 +100 /** +101 * Change the probability of success for this distribution. +102 * +103 * @param p the new probability of success. +104 * @throws IllegalArgumentException if <code>p</code> is not a valid +105 * probability. +106 * @deprecated as of 2.1 (class will become immutable in 3.0) +107 */ +108 @Deprecated +109 public void setProbabilityOfSuccess(double p) { +110 setProbabilityOfSuccessInternal(p); +111 } +112 /** +113 * Change the probability of success for this distribution. +114 * +115 * @param p the new probability of success. +116 * @throws IllegalArgumentException if <code>p</code> is not a valid +117 * probability. +118 */ +119 private void setProbabilityOfSuccessInternal(double p) { +120 if (p < 0.0 || p > 1.0) { +121 throw MathRuntimeException.createIllegalArgumentException( +122 "{0} out of [{1}, {2}] range", p, 0.0, 1.0); +123 } +124 probabilityOfSuccess = p; +125 } +126 +127 /** +128 * Access the domain value lower bound, based on <code>p</code>, used to +129 * bracket a PDF root. +130 * +131 * @param p the desired probability for the critical value +132 * @return domain value lower bound, i.e. P(X < <i>lower bound</i>) < +133 * <code>p</code> +134 */ +135 @Override +136 protected int getDomainLowerBound(double p) { +137 return -1; +138 } +139 +140 /** +141 * Access the domain value upper bound, based on <code>p</code>, used to +142 * bracket a PDF root. +143 * +144 * @param p the desired probability for the critical value +145 * @return domain value upper bound, i.e. P(X < <i>upper bound</i>) > +146 * <code>p</code> +147 */ +148 @Override +149 protected int getDomainUpperBound(double p) { +150 return numberOfTrials; +151 } +152 +153 /** +154 * For this distribution, X, this method returns P(X ≤ x). +155 * +156 * @param x the value at which the PDF is evaluated. +157 * @return PDF for this distribution. +158 * @throws MathException if the cumulative probability can not be computed +159 * due to convergence or other numerical errors. +160 */ +161 @Override +162 public double cumulativeProbability(int x) throws MathException { +163 double ret; +164 if (x < 0) { +165 ret = 0.0; +166 } else if (x >= numberOfTrials) { +167 ret = 1.0; +168 } else { +169 ret = 1.0 - Beta.regularizedBeta(getProbabilityOfSuccess(), +170 x + 1.0, numberOfTrials - x); +171 } +172 return ret; +173 } +174 +175 /** +176 * For this distribution, X, this method returns P(X = x). +177 * +178 * @param x the value at which the PMF is evaluated. +179 * @return PMF for this distribution. +180 */ +181 public double probability(int x) { +182 double ret; +183 if (x < 0 || x > numberOfTrials) { +184 ret = 0.0; +185 } else { +186 ret = Math.exp(SaddlePointExpansion.logBinomialProbability(x, +187 numberOfTrials, probabilityOfSuccess, +188 1.0 - probabilityOfSuccess)); +189 } +190 return ret; +191 } +192 +193 /** +194 * For this distribution, X, this method returns the largest x, such that +195 * P(X ≤ x) ≤ <code>p</code>. +196 * <p> +197 * Returns <code>-1</code> for p=0 and <code>Integer.MAX_VALUE</code> for +198 * p=1. +199 * </p> +200 * +201 * @param p the desired probability +202 * @return the largest x such that P(X ≤ x) <= p +203 * @throws MathException if the inverse cumulative probability can not be +204 * computed due to convergence or other numerical errors. +205 * @throws IllegalArgumentException if p < 0 or p > 1 +206 */ +207 @Override +208 public int inverseCumulativeProbability(final double p) +209 throws MathException { +210 // handle extreme values explicitly +211 if (p == 0) { +212 return -1; +213 } +214 if (p == 1) { +215 return Integer.MAX_VALUE; +216 } +217 +218 // use default bisection impl +219 return super.inverseCumulativeProbability(p); +220 } +221 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/CauchyDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/CauchyDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,129 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.distribution; +019 +020 /** +021 * Cauchy Distribution. +022 * +023 * <p> +024 * References: +025 * <ul> +026 * <li><a href="http://mathworld.wolfram.com/CauchyDistribution.html"> +027 * Cauchy Distribution</a></li> +028 * </ul> +029 * </p> +030 * +031 * @since 1.1 +032 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +033 */ +034 public interface CauchyDistribution extends ContinuousDistribution { +035 +036 /** +037 * Access the median. +038 * @return median for this distribution +039 */ +040 double getMedian(); +041 +042 /** +043 * Access the scale parameter. +044 * @return scale parameter for this distribution +045 */ +046 double getScale(); +047 +048 /** +049 * Modify the median. +050 * @param median for this distribution +051 * @deprecated as of v2.1 +052 */ +053 @Deprecated +054 void setMedian(double median); +055 +056 /** +057 * Modify the scale parameter. +058 * @param s scale parameter for this distribution +059 * @deprecated as of v2.1 +060 */ +061 @Deprecated +062 void setScale(double s); +063 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/CauchyDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/CauchyDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,334 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.distribution; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 +024 /** +025 * Default implementation of +026 * {@link org.apache.commons.math.distribution.CauchyDistribution}. +027 * +028 * @since 1.1 +029 * @version $Revision: 925900 $ $Date: 2010-03-21 17:10:07 -0400 (Sun, 21 Mar 2010) $ +030 */ +031 public class CauchyDistributionImpl extends AbstractContinuousDistribution +032 implements CauchyDistribution, Serializable { +033 +034 /** +035 * Default inverse cumulative probability accuracy +036 * @since 2.1 +037 */ +038 public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; +039 +040 /** Serializable version identifier */ +041 private static final long serialVersionUID = 8589540077390120676L; +042 +043 /** The median of this distribution. */ +044 private double median = 0; +045 +046 /** The scale of this distribution. */ +047 private double scale = 1; +048 +049 /** Inverse cumulative probability accuracy */ +050 private final double solverAbsoluteAccuracy; +051 +052 /** +053 * Creates cauchy distribution with the medain equal to zero and scale +054 * equal to one. +055 */ +056 public CauchyDistributionImpl(){ +057 this(0.0, 1.0); +058 } +059 +060 /** +061 * Create a cauchy distribution using the given median and scale. +062 * @param median median for this distribution +063 * @param s scale parameter for this distribution +064 */ +065 public CauchyDistributionImpl(double median, double s){ +066 this(median, s, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); +067 } +068 +069 /** +070 * Create a cauchy distribution using the given median and scale. +071 * @param median median for this distribution +072 * @param s scale parameter for this distribution +073 * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates +074 * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) +075 * @since 2.1 +076 */ +077 public CauchyDistributionImpl(double median, double s, double inverseCumAccuracy) { +078 super(); +079 setMedianInternal(median); +080 setScaleInternal(s); +081 solverAbsoluteAccuracy = inverseCumAccuracy; +082 } +083 +084 /** +085 * For this distribution, X, this method returns P(X < <code>x</code>). +086 * @param x the value at which the CDF is evaluated. +087 * @return CDF evaluted at <code>x</code>. +088 */ +089 public double cumulativeProbability(double x) { +090 return 0.5 + (Math.atan((x - median) / scale) / Math.PI); +091 } +092 +093 /** +094 * Access the median. +095 * @return median for this distribution +096 */ +097 public double getMedian() { +098 return median; +099 } +100 +101 /** +102 * Access the scale parameter. +103 * @return scale parameter for this distribution +104 */ +105 public double getScale() { +106 return scale; +107 } +108 +109 /** +110 * Returns the probability density for a particular point. +111 * +112 * @param x The point at which the density should be computed. +113 * @return The pdf at point x. +114 * @since 2.1 +115 */ +116 @Override +117 public double density(double x) { +118 final double dev = x - median; +119 return (1 / Math.PI) * (scale / (dev * dev + scale * scale)); +120 } +121 +122 /** +123 * For this distribution, X, this method returns the critical point x, such +124 * that P(X < x) = <code>p</code>. +125 * <p> +126 * Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and +127 * <code>Double.POSITIVE_INFINITY</code> for p=1.</p> +128 * +129 * @param p the desired probability +130 * @return x, such that P(X < x) = <code>p</code> +131 * @throws IllegalArgumentException if <code>p</code> is not a valid +132 * probability. +133 */ +134 @Override +135 public double inverseCumulativeProbability(double p) { +136 double ret; +137 if (p < 0.0 || p > 1.0) { +138 throw MathRuntimeException.createIllegalArgumentException( +139 "{0} out of [{1}, {2}] range", p, 0.0, 1.0); +140 } else if (p == 0) { +141 ret = Double.NEGATIVE_INFINITY; +142 } else if (p == 1) { +143 ret = Double.POSITIVE_INFINITY; +144 } else { +145 ret = median + scale * Math.tan(Math.PI * (p - .5)); +146 } +147 return ret; +148 } +149 +150 /** +151 * Modify the median. +152 * @param median for this distribution +153 * @deprecated as of 2.1 (class will become immutable in 3.0) +154 */ +155 @Deprecated +156 public void setMedian(double median) { +157 setMedianInternal(median); +158 } +159 /** +160 * Modify the median. +161 * @param newMedian for this distribution +162 */ +163 private void setMedianInternal(double newMedian) { +164 this.median = newMedian; +165 } +166 +167 /** +168 * Modify the scale parameter. +169 * @param s scale parameter for this distribution +170 * @throws IllegalArgumentException if <code>sd</code> is not positive. +171 * @deprecated as of 2.1 (class will become immutable in 3.0) +172 */ +173 @Deprecated +174 public void setScale(double s) { +175 setScaleInternal(s); +176 } +177 /** +178 * Modify the scale parameter. +179 * @param s scale parameter for this distribution +180 * @throws IllegalArgumentException if <code>sd</code> is not positive. +181 */ +182 private void setScaleInternal(double s) { +183 if (s <= 0.0) { +184 throw MathRuntimeException.createIllegalArgumentException( +185 "scale must be positive ({0})", s); +186 } +187 scale = s; +188 } +189 +190 /** +191 * Access the domain value lower bound, based on <code>p</code>, used to +192 * bracket a CDF root. This method is used by +193 * {@link #inverseCumulativeProbability(double)} to find critical values. +194 * +195 * @param p the desired probability for the critical value +196 * @return domain value lower bound, i.e. +197 * P(X < <i>lower bound</i>) < <code>p</code> +198 */ +199 @Override +200 protected double getDomainLowerBound(double p) { +201 double ret; +202 +203 if (p < .5) { +204 ret = -Double.MAX_VALUE; +205 } else { +206 ret = median; +207 } +208 +209 return ret; +210 } +211 +212 /** +213 * Access the domain value upper bound, based on <code>p</code>, used to +214 * bracket a CDF root. This method is used by +215 * {@link #inverseCumulativeProbability(double)} to find critical values. +216 * +217 * @param p the desired probability for the critical value +218 * @return domain value upper bound, i.e. +219 * P(X < <i>upper bound</i>) > <code>p</code> +220 */ +221 @Override +222 protected double getDomainUpperBound(double p) { +223 double ret; +224 +225 if (p < .5) { +226 ret = median; +227 } else { +228 ret = Double.MAX_VALUE; +229 } +230 +231 return ret; +232 } +233 +234 /** +235 * Access the initial domain value, based on <code>p</code>, used to +236 * bracket a CDF root. This method is used by +237 * {@link #inverseCumulativeProbability(double)} to find critical values. +238 * +239 * @param p the desired probability for the critical value +240 * @return initial domain value +241 */ +242 @Override +243 protected double getInitialDomain(double p) { +244 double ret; +245 +246 if (p < .5) { +247 ret = median - scale; +248 } else if (p > .5) { +249 ret = median + scale; +250 } else { +251 ret = median; +252 } +253 +254 return ret; +255 } +256 +257 /** +258 * Return the absolute accuracy setting of the solver used to estimate +259 * inverse cumulative probabilities. +260 * +261 * @return the solver absolute accuracy +262 * @since 2.1 +263 */ +264 @Override +265 protected double getSolverAbsoluteAccuracy() { +266 return solverAbsoluteAccuracy; +267 } +268 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/ChiSquaredDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/ChiSquaredDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,119 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 /** +020 * The Chi-Squared Distribution. +021 * +022 * <p> +023 * References: +024 * <ul> +025 * <li><a href="http://mathworld.wolfram.com/Chi-SquaredDistribution.html"> +026 * Chi-Squared Distribution</a></li> +027 * </ul> +028 * </p> +029 * +030 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +031 */ +032 public interface ChiSquaredDistribution extends ContinuousDistribution, HasDensity<Double> { +033 /** +034 * Modify the degrees of freedom. +035 * @param degreesOfFreedom the new degrees of freedom. +036 * @deprecated as of v2.1 +037 */ +038 @Deprecated +039 void setDegreesOfFreedom(double degreesOfFreedom); +040 +041 /** +042 * Access the degrees of freedom. +043 * @return the degrees of freedom. +044 */ +045 double getDegreesOfFreedom(); +046 +047 /** +048 * Return the probability density for a particular point. +049 * @param x The point at which the density should be computed. +050 * @return The pdf at point x. +051 */ +052 double density(Double x); +053 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,337 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathException; +022 +023 /** +024 * The default implementation of {@link ChiSquaredDistribution} +025 * +026 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +027 */ +028 public class ChiSquaredDistributionImpl +029 extends AbstractContinuousDistribution +030 implements ChiSquaredDistribution, Serializable { +031 +032 /** +033 * Default inverse cumulative probability accuracy +034 * @since 2.1 +035 */ +036 public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; +037 +038 /** Serializable version identifier */ +039 private static final long serialVersionUID = -8352658048349159782L; +040 +041 /** Internal Gamma distribution. */ +042 private GammaDistribution gamma; +043 +044 /** Inverse cumulative probability accuracy */ +045 private final double solverAbsoluteAccuracy; +046 +047 /** +048 * Create a Chi-Squared distribution with the given degrees of freedom. +049 * @param df degrees of freedom. +050 */ +051 public ChiSquaredDistributionImpl(double df) { +052 this(df, new GammaDistributionImpl(df / 2.0, 2.0)); +053 } +054 +055 /** +056 * Create a Chi-Squared distribution with the given degrees of freedom. +057 * @param df degrees of freedom. +058 * @param g the underlying gamma distribution used to compute probabilities. +059 * @since 1.2 +060 * @deprecated as of 2.1 (to avoid possibly inconsistent state, the +061 * "GammaDistribution" will be instantiated internally) +062 */ +063 @Deprecated +064 public ChiSquaredDistributionImpl(double df, GammaDistribution g) { +065 super(); +066 setGammaInternal(g); +067 setDegreesOfFreedomInternal(df); +068 solverAbsoluteAccuracy = DEFAULT_INVERSE_ABSOLUTE_ACCURACY; +069 } +070 +071 /** +072 * Create a Chi-Squared distribution with the given degrees of freedom and +073 * inverse cumulative probability accuracy. +074 * @param df degrees of freedom. +075 * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates +076 * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) +077 * @since 2.1 +078 */ +079 public ChiSquaredDistributionImpl(double df, double inverseCumAccuracy) { +080 super(); +081 gamma = new GammaDistributionImpl(df / 2.0, 2.0); +082 setDegreesOfFreedomInternal(df); +083 solverAbsoluteAccuracy = inverseCumAccuracy; +084 } +085 +086 /** +087 * Modify the degrees of freedom. +088 * @param degreesOfFreedom the new degrees of freedom. +089 * @deprecated as of 2.1 (class will become immutable in 3.0) +090 */ +091 @Deprecated +092 public void setDegreesOfFreedom(double degreesOfFreedom) { +093 setDegreesOfFreedomInternal(degreesOfFreedom); +094 } +095 /** +096 * Modify the degrees of freedom. +097 * @param degreesOfFreedom the new degrees of freedom. +098 */ +099 private void setDegreesOfFreedomInternal(double degreesOfFreedom) { +100 gamma.setAlpha(degreesOfFreedom / 2.0); +101 } +102 +103 /** +104 * Access the degrees of freedom. +105 * @return the degrees of freedom. +106 */ +107 public double getDegreesOfFreedom() { +108 return gamma.getAlpha() * 2.0; +109 } +110 +111 /** +112 * Return the probability density for a particular point. +113 * +114 * @param x The point at which the density should be computed. +115 * @return The pdf at point x. +116 * @deprecated +117 */ +118 public double density(Double x) { +119 return density(x.doubleValue()); +120 } +121 +122 /** +123 * Return the probability density for a particular point. +124 * +125 * @param x The point at which the density should be computed. +126 * @return The pdf at point x. +127 * @since 2.1 +128 */ +129 @Override +130 public double density(double x) { +131 return gamma.density(x); +132 } +133 +134 /** +135 * For this distribution, X, this method returns P(X < x). +136 * @param x the value at which the CDF is evaluated. +137 * @return CDF for this distribution. +138 * @throws MathException if the cumulative probability can not be +139 * computed due to convergence or other numerical errors. +140 */ +141 public double cumulativeProbability(double x) throws MathException { +142 return gamma.cumulativeProbability(x); +143 } +144 +145 /** +146 * For this distribution, X, this method returns the critical point x, such +147 * that P(X < x) = <code>p</code>. +148 * <p> +149 * Returns 0 for p=0 and <code>Double.POSITIVE_INFINITY</code> for p=1.</p> +150 * +151 * @param p the desired probability +152 * @return x, such that P(X < x) = <code>p</code> +153 * @throws MathException if the inverse cumulative probability can not be +154 * computed due to convergence or other numerical errors. +155 * @throws IllegalArgumentException if <code>p</code> is not a valid +156 * probability. +157 */ +158 @Override +159 public double inverseCumulativeProbability(final double p) +160 throws MathException { +161 if (p == 0) { +162 return 0d; +163 } +164 if (p == 1) { +165 return Double.POSITIVE_INFINITY; +166 } +167 return super.inverseCumulativeProbability(p); +168 } +169 +170 /** +171 * Access the domain value lower bound, based on <code>p</code>, used to +172 * bracket a CDF root. This method is used by +173 * {@link #inverseCumulativeProbability(double)} to find critical values. +174 * +175 * @param p the desired probability for the critical value +176 * @return domain value lower bound, i.e. +177 * P(X < <i>lower bound</i>) < <code>p</code> +178 */ +179 @Override +180 protected double getDomainLowerBound(double p) { +181 return Double.MIN_VALUE * gamma.getBeta(); +182 } +183 +184 /** +185 * Access the domain value upper bound, based on <code>p</code>, used to +186 * bracket a CDF root. This method is used by +187 * {@link #inverseCumulativeProbability(double)} to find critical values. +188 * +189 * @param p the desired probability for the critical value +190 * @return domain value upper bound, i.e. +191 * P(X < <i>upper bound</i>) > <code>p</code> +192 */ +193 @Override +194 protected double getDomainUpperBound(double p) { +195 // NOTE: chi squared is skewed to the left +196 // NOTE: therefore, P(X < μ) > .5 +197 +198 double ret; +199 +200 if (p < .5) { +201 // use mean +202 ret = getDegreesOfFreedom(); +203 } else { +204 // use max +205 ret = Double.MAX_VALUE; +206 } +207 +208 return ret; +209 } +210 +211 /** +212 * Access the initial domain value, based on <code>p</code>, used to +213 * bracket a CDF root. This method is used by +214 * {@link #inverseCumulativeProbability(double)} to find critical values. +215 * +216 * @param p the desired probability for the critical value +217 * @return initial domain value +218 */ +219 @Override +220 protected double getInitialDomain(double p) { +221 // NOTE: chi squared is skewed to the left +222 // NOTE: therefore, P(X < μ) > .5 +223 +224 double ret; +225 +226 if (p < .5) { +227 // use 1/2 mean +228 ret = getDegreesOfFreedom() * .5; +229 } else { +230 // use mean +231 ret = getDegreesOfFreedom(); +232 } +233 +234 return ret; +235 } +236 +237 /** +238 * Modify the underlying gamma distribution. The caller is responsible for +239 * insuring the gamma distribution has the proper parameter settings. +240 * @param g the new distribution. +241 * @since 1.2 made public +242 * @deprecated as of 2.1 (class will become immutable in 3.0) +243 */ +244 @Deprecated +245 public void setGamma(GammaDistribution g) { +246 setGammaInternal(g); +247 } +248 /** +249 * Modify the underlying gamma distribution. The caller is responsible for +250 * insuring the gamma distribution has the proper parameter settings. +251 * @param g the new distribution. +252 * @since 1.2 made public +253 */ +254 private void setGammaInternal(GammaDistribution g) { +255 this.gamma = g; +256 +257 } +258 +259 +260 /** +261 * Return the absolute accuracy setting of the solver used to estimate +262 * inverse cumulative probabilities. +263 * +264 * @return the solver absolute accuracy +265 * @since 2.1 +266 */ +267 @Override +268 protected double getSolverAbsoluteAccuracy() { +269 return solverAbsoluteAccuracy; +270 } +271 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/ContinuousDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/ContinuousDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,109 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import org.apache.commons.math.MathException; +020 +021 /** +022 * <p>Base interface for continuous distributions.</p> +023 * +024 * <p>Note: this interface will be extended in version 3.0 to include +025 * <br/><code>public double density(double x)</code><br/> +026 * that is, from version 3.0 forward, continuous distributions <strong>must</strong> +027 * include implementations of probability density functions. As of version +028 * 2.1, all continuous distribution implementations included in commons-math +029 * provide implementations of this method.</p> +030 * +031 * @version $Revision: 924362 $ $Date: 2010-03-17 12:45:31 -0400 (Wed, 17 Mar 2010) $ +032 */ +033 public interface ContinuousDistribution extends Distribution { +034 +035 /** +036 * For this distribution, X, this method returns x such that P(X < x) = p. +037 * @param p the cumulative probability. +038 * @return x. +039 * @throws MathException if the inverse cumulative probability can not be +040 * computed due to convergence or other numerical errors. +041 */ +042 double inverseCumulativeProbability(double p) throws MathException; +043 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/DiscreteDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/DiscreteDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,101 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 +020 /** +021 * Base interface for discrete distributions. +022 * +023 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +024 */ +025 public interface DiscreteDistribution extends Distribution { +026 /** +027 * For a random variable X whose values are distributed according +028 * to this distribution, this method returns P(X = x). In other words, this +029 * method represents the probability mass function, or PMF for the distribution. +030 * +031 * @param x the value at which the probability mass function is evaluated. +032 * @return the value of the probability mass function at x +033 */ +034 double probability(double x); +035 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/Distribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/Distribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,121 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import org.apache.commons.math.MathException; +020 +021 /** +022 * Base interface for probability distributions. +023 * +024 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +025 */ +026 public interface Distribution { +027 /** +028 * For a random variable X whose values are distributed according +029 * to this distribution, this method returns P(X ≤ x). In other words, +030 * this method represents the (cumulative) distribution function, or +031 * CDF, for this distribution. +032 * +033 * @param x the value at which the distribution function is evaluated. +034 * @return the probability that a random variable with this +035 * distribution takes a value less than or equal to <code>x</code> +036 * @throws MathException if the cumulative probability can not be +037 * computed due to convergence or other numerical errors. +038 */ +039 double cumulativeProbability(double x) throws MathException; +040 +041 /** +042 * For a random variable X whose values are distributed according +043 * to this distribution, this method returns P(x0 ≤ X ≤ x1). +044 * +045 * @param x0 the (inclusive) lower bound +046 * @param x1 the (inclusive) upper bound +047 * @return the probability that a random variable with this distribution +048 * will take a value between <code>x0</code> and <code>x1</code>, +049 * including the endpoints +050 * @throws MathException if the cumulative probability can not be +051 * computed due to convergence or other numerical errors. +052 * @throws IllegalArgumentException if <code>x0 > x1</code> +053 */ +054 double cumulativeProbability(double x0, double x1) throws MathException; +055 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/ExponentialDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/ExponentialDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,119 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 /** +020 * The Exponential Distribution. +021 * +022 * <p> +023 * References: +024 * <ul> +025 * <li><a href="http://mathworld.wolfram.com/ExponentialDistribution.html"> +026 * Exponential Distribution</a></li> +027 * </ul> +028 * </p> +029 * +030 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +031 */ +032 public interface ExponentialDistribution extends ContinuousDistribution, HasDensity<Double> { +033 /** +034 * Modify the mean. +035 * @param mean the new mean. +036 * @deprecated as of v2.1 +037 */ +038 @Deprecated +039 void setMean(double mean); +040 +041 /** +042 * Access the mean. +043 * @return the mean. +044 */ +045 double getMean(); +046 +047 /** +048 * Return the probability density for a particular point. +049 * @param x The point at which the density should be computed. +050 * @return The pdf at point x. +051 */ +052 double density(Double x); +053 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/ExponentialDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/ExponentialDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,312 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathException; +022 import org.apache.commons.math.MathRuntimeException; +023 +024 /** +025 * The default implementation of {@link ExponentialDistribution}. +026 * +027 * @version $Revision: 925900 $ $Date: 2010-03-21 17:10:07 -0400 (Sun, 21 Mar 2010) $ +028 */ +029 public class ExponentialDistributionImpl extends AbstractContinuousDistribution +030 implements ExponentialDistribution, Serializable { +031 +032 /** +033 * Default inverse cumulative probability accuracy +034 * @since 2.1 +035 */ +036 public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; +037 +038 /** Serializable version identifier */ +039 private static final long serialVersionUID = 2401296428283614780L; +040 +041 /** The mean of this distribution. */ +042 private double mean; +043 +044 /** Inverse cumulative probability accuracy */ +045 private final double solverAbsoluteAccuracy; +046 +047 /** +048 * Create a exponential distribution with the given mean. +049 * @param mean mean of this distribution. +050 */ +051 public ExponentialDistributionImpl(double mean) { +052 this(mean, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); +053 } +054 +055 /** +056 * Create a exponential distribution with the given mean. +057 * @param mean mean of this distribution. +058 * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates +059 * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) +060 * @since 2.1 +061 */ +062 public ExponentialDistributionImpl(double mean, double inverseCumAccuracy) { +063 super(); +064 setMeanInternal(mean); +065 solverAbsoluteAccuracy = inverseCumAccuracy; +066 } +067 +068 /** +069 * Modify the mean. +070 * @param mean the new mean. +071 * @throws IllegalArgumentException if <code>mean</code> is not positive. +072 * @deprecated as of 2.1 (class will become immutable in 3.0) +073 */ +074 @Deprecated +075 public void setMean(double mean) { +076 setMeanInternal(mean); +077 } +078 /** +079 * Modify the mean. +080 * @param newMean the new mean. +081 * @throws IllegalArgumentException if <code>newMean</code> is not positive. +082 */ +083 private void setMeanInternal(double newMean) { +084 if (newMean <= 0.0) { +085 throw MathRuntimeException.createIllegalArgumentException( +086 "mean must be positive ({0})", newMean); +087 } +088 this.mean = newMean; +089 } +090 +091 /** +092 * Access the mean. +093 * @return the mean. +094 */ +095 public double getMean() { +096 return mean; +097 } +098 +099 /** +100 * Return the probability density for a particular point. +101 * +102 * @param x The point at which the density should be computed. +103 * @return The pdf at point x. +104 * @deprecated - use density(double) +105 */ +106 public double density(Double x) { +107 return density(x.doubleValue()); +108 } +109 +110 /** +111 * Return the probability density for a particular point. +112 * +113 * @param x The point at which the density should be computed. +114 * @return The pdf at point x. +115 * @since 2.1 +116 */ +117 @Override +118 public double density(double x) { +119 if (x < 0) { +120 return 0; +121 } +122 return Math.exp(-x / mean) / mean; +123 } +124 +125 /** +126 * For this distribution, X, this method returns P(X < x). +127 * +128 * The implementation of this method is based on: +129 * <ul> +130 * <li> +131 * <a href="http://mathworld.wolfram.com/ExponentialDistribution.html"> +132 * Exponential Distribution</a>, equation (1).</li> +133 * </ul> +134 * +135 * @param x the value at which the CDF is evaluated. +136 * @return CDF for this distribution. +137 * @throws MathException if the cumulative probability can not be +138 * computed due to convergence or other numerical errors. +139 */ +140 public double cumulativeProbability(double x) throws MathException{ +141 double ret; +142 if (x <= 0.0) { +143 ret = 0.0; +144 } else { +145 ret = 1.0 - Math.exp(-x / mean); +146 } +147 return ret; +148 } +149 +150 /** +151 * For this distribution, X, this method returns the critical point x, such +152 * that P(X < x) = <code>p</code>. +153 * <p> +154 * Returns 0 for p=0 and <code>Double.POSITIVE_INFINITY</code> for p=1.</p> +155 * +156 * @param p the desired probability +157 * @return x, such that P(X < x) = <code>p</code> +158 * @throws MathException if the inverse cumulative probability can not be +159 * computed due to convergence or other numerical errors. +160 * @throws IllegalArgumentException if p < 0 or p > 1. +161 */ +162 @Override +163 public double inverseCumulativeProbability(double p) throws MathException { +164 double ret; +165 +166 if (p < 0.0 || p > 1.0) { +167 throw MathRuntimeException.createIllegalArgumentException( +168 "{0} out of [{1}, {2}] range", p, 0.0, 1.0); +169 } else if (p == 1.0) { +170 ret = Double.POSITIVE_INFINITY; +171 } else { +172 ret = -mean * Math.log(1.0 - p); +173 } +174 +175 return ret; +176 } +177 +178 /** +179 * Access the domain value lower bound, based on <code>p</code>, used to +180 * bracket a CDF root. +181 * +182 * @param p the desired probability for the critical value +183 * @return domain value lower bound, i.e. +184 * P(X < <i>lower bound</i>) < <code>p</code> +185 */ +186 @Override +187 protected double getDomainLowerBound(double p) { +188 return 0; +189 } +190 +191 /** +192 * Access the domain value upper bound, based on <code>p</code>, used to +193 * bracket a CDF root. +194 * +195 * @param p the desired probability for the critical value +196 * @return domain value upper bound, i.e. +197 * P(X < <i>upper bound</i>) > <code>p</code> +198 */ +199 @Override +200 protected double getDomainUpperBound(double p) { +201 // NOTE: exponential is skewed to the left +202 // NOTE: therefore, P(X < μ) > .5 +203 +204 if (p < .5) { +205 // use mean +206 return mean; +207 } else { +208 // use max +209 return Double.MAX_VALUE; +210 } +211 } +212 +213 /** +214 * Access the initial domain value, based on <code>p</code>, used to +215 * bracket a CDF root. +216 * +217 * @param p the desired probability for the critical value +218 * @return initial domain value +219 */ +220 @Override +221 protected double getInitialDomain(double p) { +222 // TODO: try to improve on this estimate +223 // TODO: what should really happen here is not derive from AbstractContinuousDistribution +224 // TODO: because the inverse cumulative distribution is simple. +225 // Exponential is skewed to the left, therefore, P(X < μ) > .5 +226 if (p < .5) { +227 // use 1/2 mean +228 return mean * .5; +229 } else { +230 // use mean +231 return mean; +232 } +233 } +234 +235 /** +236 * Return the absolute accuracy setting of the solver used to estimate +237 * inverse cumulative probabilities. +238 * +239 * @return the solver absolute accuracy +240 * @since 2.1 +241 */ +242 @Override +243 protected double getSolverAbsoluteAccuracy() { +244 return solverAbsoluteAccuracy; +245 } +246 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/FDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/FDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,126 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 /** +020 * F-Distribution. +021 * +022 * <p> +023 * References: +024 * <ul> +025 * <li><a href="http://mathworld.wolfram.com/F-Distribution.html"> +026 * F-Distribution</a></li> +027 * </ul> +028 * </p> +029 * +030 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +031 */ +032 public interface FDistribution extends ContinuousDistribution { +033 /** +034 * Modify the numerator degrees of freedom. +035 * @param degreesOfFreedom the new numerator degrees of freedom. +036 * @deprecated as of v2.1 +037 */ +038 @Deprecated +039 void setNumeratorDegreesOfFreedom(double degreesOfFreedom); +040 +041 /** +042 * Access the numerator degrees of freedom. +043 * @return the numerator degrees of freedom. +044 */ +045 double getNumeratorDegreesOfFreedom(); +046 +047 /** +048 * Modify the denominator degrees of freedom. +049 * @param degreesOfFreedom the new denominator degrees of freedom. +050 * @deprecated as of v2.1 +051 */ +052 @Deprecated +053 void setDenominatorDegreesOfFreedom(double degreesOfFreedom); +054 +055 /** +056 * Access the denominator degrees of freedom. +057 * @return the denominator degrees of freedom. +058 */ +059 double getDenominatorDegreesOfFreedom(); +060 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/FDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/FDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,349 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathException; +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.special.Beta; +024 +025 /** +026 * Default implementation of +027 * {@link org.apache.commons.math.distribution.FDistribution}. +028 * +029 * @version $Revision: 925897 $ $Date: 2010-03-21 17:06:46 -0400 (Sun, 21 Mar 2010) $ +030 */ +031 public class FDistributionImpl +032 extends AbstractContinuousDistribution +033 implements FDistribution, Serializable { +034 +035 /** +036 * Default inverse cumulative probability accuracy +037 * @since 2.1 +038 */ +039 public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; +040 +041 /** Message for non positive degrees of freddom. */ +042 private static final String NON_POSITIVE_DEGREES_OF_FREEDOM_MESSAGE = +043 "degrees of freedom must be positive ({0})"; +044 +045 /** Serializable version identifier */ +046 private static final long serialVersionUID = -8516354193418641566L; +047 +048 /** The numerator degrees of freedom*/ +049 private double numeratorDegreesOfFreedom; +050 +051 /** The numerator degrees of freedom*/ +052 private double denominatorDegreesOfFreedom; +053 +054 /** Inverse cumulative probability accuracy */ +055 private final double solverAbsoluteAccuracy; +056 +057 /** +058 * Create a F distribution using the given degrees of freedom. +059 * @param numeratorDegreesOfFreedom the numerator degrees of freedom. +060 * @param denominatorDegreesOfFreedom the denominator degrees of freedom. +061 */ +062 public FDistributionImpl(double numeratorDegreesOfFreedom, +063 double denominatorDegreesOfFreedom) { +064 this(numeratorDegreesOfFreedom, denominatorDegreesOfFreedom, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); +065 } +066 +067 /** +068 * Create a F distribution using the given degrees of freedom and inverse cumulative probability accuracy. +069 * @param numeratorDegreesOfFreedom the numerator degrees of freedom. +070 * @param denominatorDegreesOfFreedom the denominator degrees of freedom. +071 * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates +072 * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) +073 * @since 2.1 +074 */ +075 public FDistributionImpl(double numeratorDegreesOfFreedom, double denominatorDegreesOfFreedom, +076 double inverseCumAccuracy) { +077 super(); +078 setNumeratorDegreesOfFreedomInternal(numeratorDegreesOfFreedom); +079 setDenominatorDegreesOfFreedomInternal(denominatorDegreesOfFreedom); +080 solverAbsoluteAccuracy = inverseCumAccuracy; +081 } +082 +083 /** +084 * Returns the probability density for a particular point. +085 * +086 * @param x The point at which the density should be computed. +087 * @return The pdf at point x. +088 * @since 2.1 +089 */ +090 @Override +091 public double density(double x) { +092 final double nhalf = numeratorDegreesOfFreedom / 2; +093 final double mhalf = denominatorDegreesOfFreedom / 2; +094 final double logx = Math.log(x); +095 final double logn = Math.log(numeratorDegreesOfFreedom); +096 final double logm = Math.log(denominatorDegreesOfFreedom); +097 final double lognxm = Math.log(numeratorDegreesOfFreedom * x + denominatorDegreesOfFreedom); +098 return Math.exp(nhalf*logn + nhalf*logx - logx + mhalf*logm - nhalf*lognxm - +099 mhalf*lognxm - Beta.logBeta(nhalf, mhalf)); +100 } +101 +102 /** +103 * For this distribution, X, this method returns P(X < x). +104 * +105 * The implementation of this method is based on: +106 * <ul> +107 * <li> +108 * <a href="http://mathworld.wolfram.com/F-Distribution.html"> +109 * F-Distribution</a>, equation (4).</li> +110 * </ul> +111 * +112 * @param x the value at which the CDF is evaluated. +113 * @return CDF for this distribution. +114 * @throws MathException if the cumulative probability can not be +115 * computed due to convergence or other numerical errors. +116 */ +117 public double cumulativeProbability(double x) throws MathException { +118 double ret; +119 if (x <= 0.0) { +120 ret = 0.0; +121 } else { +122 double n = numeratorDegreesOfFreedom; +123 double m = denominatorDegreesOfFreedom; +124 +125 ret = Beta.regularizedBeta((n * x) / (m + n * x), +126 0.5 * n, +127 0.5 * m); +128 } +129 return ret; +130 } +131 +132 /** +133 * For this distribution, X, this method returns the critical point x, such +134 * that P(X < x) = <code>p</code>. +135 * <p> +136 * Returns 0 for p=0 and <code>Double.POSITIVE_INFINITY</code> for p=1.</p> +137 * +138 * @param p the desired probability +139 * @return x, such that P(X < x) = <code>p</code> +140 * @throws MathException if the inverse cumulative probability can not be +141 * computed due to convergence or other numerical errors. +142 * @throws IllegalArgumentException if <code>p</code> is not a valid +143 * probability. +144 */ +145 @Override +146 public double inverseCumulativeProbability(final double p) +147 throws MathException { +148 if (p == 0) { +149 return 0d; +150 } +151 if (p == 1) { +152 return Double.POSITIVE_INFINITY; +153 } +154 return super.inverseCumulativeProbability(p); +155 } +156 +157 /** +158 * Access the domain value lower bound, based on <code>p</code>, used to +159 * bracket a CDF root. This method is used by +160 * {@link #inverseCumulativeProbability(double)} to find critical values. +161 * +162 * @param p the desired probability for the critical value +163 * @return domain value lower bound, i.e. +164 * P(X < <i>lower bound</i>) < <code>p</code> +165 */ +166 @Override +167 protected double getDomainLowerBound(double p) { +168 return 0.0; +169 } +170 +171 /** +172 * Access the domain value upper bound, based on <code>p</code>, used to +173 * bracket a CDF root. This method is used by +174 * {@link #inverseCumulativeProbability(double)} to find critical values. +175 * +176 * @param p the desired probability for the critical value +177 * @return domain value upper bound, i.e. +178 * P(X < <i>upper bound</i>) > <code>p</code> +179 */ +180 @Override +181 protected double getDomainUpperBound(double p) { +182 return Double.MAX_VALUE; +183 } +184 +185 /** +186 * Access the initial domain value, based on <code>p</code>, used to +187 * bracket a CDF root. This method is used by +188 * {@link #inverseCumulativeProbability(double)} to find critical values. +189 * +190 * @param p the desired probability for the critical value +191 * @return initial domain value +192 */ +193 @Override +194 protected double getInitialDomain(double p) { +195 double ret = 1.0; +196 double d = denominatorDegreesOfFreedom; +197 if (d > 2.0) { +198 // use mean +199 ret = d / (d - 2.0); +200 } +201 return ret; +202 } +203 +204 /** +205 * Modify the numerator degrees of freedom. +206 * @param degreesOfFreedom the new numerator degrees of freedom. +207 * @throws IllegalArgumentException if <code>degreesOfFreedom</code> is not +208 * positive. +209 * @deprecated as of 2.1 (class will become immutable in 3.0) +210 */ +211 @Deprecated +212 public void setNumeratorDegreesOfFreedom(double degreesOfFreedom) { +213 setNumeratorDegreesOfFreedomInternal(degreesOfFreedom); +214 } +215 +216 /** +217 * Modify the numerator degrees of freedom. +218 * @param degreesOfFreedom the new numerator degrees of freedom. +219 * @throws IllegalArgumentException if <code>degreesOfFreedom</code> is not +220 * positive. +221 */ +222 private void setNumeratorDegreesOfFreedomInternal(double degreesOfFreedom) { +223 if (degreesOfFreedom <= 0.0) { +224 throw MathRuntimeException.createIllegalArgumentException( +225 NON_POSITIVE_DEGREES_OF_FREEDOM_MESSAGE, degreesOfFreedom); +226 } +227 this.numeratorDegreesOfFreedom = degreesOfFreedom; +228 } +229 +230 /** +231 * Access the numerator degrees of freedom. +232 * @return the numerator degrees of freedom. +233 */ +234 public double getNumeratorDegreesOfFreedom() { +235 return numeratorDegreesOfFreedom; +236 } +237 +238 /** +239 * Modify the denominator degrees of freedom. +240 * @param degreesOfFreedom the new denominator degrees of freedom. +241 * @throws IllegalArgumentException if <code>degreesOfFreedom</code> is not +242 * positive. +243 * @deprecated as of 2.1 (class will become immutable in 3.0) +244 */ +245 @Deprecated +246 public void setDenominatorDegreesOfFreedom(double degreesOfFreedom) { +247 setDenominatorDegreesOfFreedomInternal(degreesOfFreedom); +248 } +249 +250 /** +251 * Modify the denominator degrees of freedom. +252 * @param degreesOfFreedom the new denominator degrees of freedom. +253 * @throws IllegalArgumentException if <code>degreesOfFreedom</code> is not +254 * positive. +255 */ +256 private void setDenominatorDegreesOfFreedomInternal(double degreesOfFreedom) { +257 if (degreesOfFreedom <= 0.0) { +258 throw MathRuntimeException.createIllegalArgumentException( +259 NON_POSITIVE_DEGREES_OF_FREEDOM_MESSAGE, degreesOfFreedom); +260 } +261 this.denominatorDegreesOfFreedom = degreesOfFreedom; +262 } +263 +264 /** +265 * Access the denominator degrees of freedom. +266 * @return the denominator degrees of freedom. +267 */ +268 public double getDenominatorDegreesOfFreedom() { +269 return denominatorDegreesOfFreedom; +270 } +271 +272 /** +273 * Return the absolute accuracy setting of the solver used to estimate +274 * inverse cumulative probabilities. +275 * +276 * @return the solver absolute accuracy +277 * @since 2.1 +278 */ +279 @Override +280 protected double getSolverAbsoluteAccuracy() { +281 return solverAbsoluteAccuracy; +282 } +283 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/GammaDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/GammaDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,133 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 /** +020 * The Gamma Distribution. +021 * +022 * <p> +023 * References: +024 * <ul> +025 * <li><a href="http://mathworld.wolfram.com/GammaDistribution.html"> +026 * Gamma Distribution</a></li> +027 * </ul> +028 * </p> +029 * +030 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +031 */ +032 public interface GammaDistribution extends ContinuousDistribution, HasDensity<Double> { +033 /** +034 * Modify the shape parameter, alpha. +035 * @param alpha the new shape parameter. +036 * @deprecated as of v2.1 +037 */ +038 @Deprecated +039 void setAlpha(double alpha); +040 +041 /** +042 * Access the shape parameter, alpha +043 * @return alpha. +044 */ +045 double getAlpha(); +046 +047 /** +048 * Modify the scale parameter, beta. +049 * @param beta the new scale parameter. +050 * @deprecated as of v2.1 +051 */ +052 @Deprecated +053 void setBeta(double beta); +054 +055 /** +056 * Access the scale parameter, beta +057 * @return beta. +058 */ +059 double getBeta(); +060 +061 /** +062 * Return the probability density for a particular point. +063 * @param x The point at which the density should be computed. +064 * @return The pdf at point x. +065 */ +066 double density(Double x); +067 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/GammaDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/GammaDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,364 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathException; +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.special.Gamma; +024 +025 /** +026 * The default implementation of {@link GammaDistribution}. +027 * +028 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +029 */ +030 public class GammaDistributionImpl extends AbstractContinuousDistribution +031 implements GammaDistribution, Serializable { +032 +033 /** +034 * Default inverse cumulative probability accuracy +035 * @since 2.1 +036 */ +037 public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; +038 +039 /** Serializable version identifier */ +040 private static final long serialVersionUID = -3239549463135430361L; +041 +042 /** The shape parameter. */ +043 private double alpha; +044 +045 /** The scale parameter. */ +046 private double beta; +047 +048 /** Inverse cumulative probability accuracy */ +049 private final double solverAbsoluteAccuracy; +050 +051 /** +052 * Create a new gamma distribution with the given alpha and beta values. +053 * @param alpha the shape parameter. +054 * @param beta the scale parameter. +055 */ +056 public GammaDistributionImpl(double alpha, double beta) { +057 this(alpha, beta, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); +058 } +059 +060 /** +061 * Create a new gamma distribution with the given alpha and beta values. +062 * @param alpha the shape parameter. +063 * @param beta the scale parameter. +064 * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates +065 * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) +066 * @since 2.1 +067 */ +068 public GammaDistributionImpl(double alpha, double beta, double inverseCumAccuracy) { +069 super(); +070 setAlphaInternal(alpha); +071 setBetaInternal(beta); +072 solverAbsoluteAccuracy = inverseCumAccuracy; +073 } +074 +075 /** +076 * For this distribution, X, this method returns P(X < x). +077 * +078 * The implementation of this method is based on: +079 * <ul> +080 * <li> +081 * <a href="http://mathworld.wolfram.com/Chi-SquaredDistribution.html"> +082 * Chi-Squared Distribution</a>, equation (9).</li> +083 * <li>Casella, G., & Berger, R. (1990). <i>Statistical Inference</i>. +084 * Belmont, CA: Duxbury Press.</li> +085 * </ul> +086 * +087 * @param x the value at which the CDF is evaluated. +088 * @return CDF for this distribution. +089 * @throws MathException if the cumulative probability can not be +090 * computed due to convergence or other numerical errors. +091 */ +092 public double cumulativeProbability(double x) throws MathException{ +093 double ret; +094 +095 if (x <= 0.0) { +096 ret = 0.0; +097 } else { +098 ret = Gamma.regularizedGammaP(alpha, x / beta); +099 } +100 +101 return ret; +102 } +103 +104 /** +105 * For this distribution, X, this method returns the critical point x, such +106 * that P(X < x) = <code>p</code>. +107 * <p> +108 * Returns 0 for p=0 and <code>Double.POSITIVE_INFINITY</code> for p=1.</p> +109 * +110 * @param p the desired probability +111 * @return x, such that P(X < x) = <code>p</code> +112 * @throws MathException if the inverse cumulative probability can not be +113 * computed due to convergence or other numerical errors. +114 * @throws IllegalArgumentException if <code>p</code> is not a valid +115 * probability. +116 */ +117 @Override +118 public double inverseCumulativeProbability(final double p) +119 throws MathException { +120 if (p == 0) { +121 return 0d; +122 } +123 if (p == 1) { +124 return Double.POSITIVE_INFINITY; +125 } +126 return super.inverseCumulativeProbability(p); +127 } +128 +129 /** +130 * Modify the shape parameter, alpha. +131 * @param alpha the new shape parameter. +132 * @throws IllegalArgumentException if <code>alpha</code> is not positive. +133 * @deprecated as of 2.1 (class will become immutable in 3.0) +134 */ +135 @Deprecated +136 public void setAlpha(double alpha) { +137 setAlphaInternal(alpha); +138 } +139 +140 /** +141 * Modify the shape parameter, alpha. +142 * @param newAlpha the new shape parameter. +143 * @throws IllegalArgumentException if <code>newAlpha</code> is not positive. +144 */ +145 private void setAlphaInternal(double newAlpha) { +146 if (newAlpha <= 0.0) { +147 throw MathRuntimeException.createIllegalArgumentException( +148 "alpha must be positive ({0})", +149 newAlpha); +150 } +151 this.alpha = newAlpha; +152 } +153 +154 /** +155 * Access the shape parameter, alpha +156 * @return alpha. +157 */ +158 public double getAlpha() { +159 return alpha; +160 } +161 +162 /** +163 * Modify the scale parameter, beta. +164 * @param newBeta the new scale parameter. +165 * @throws IllegalArgumentException if <code>newBeta</code> is not positive. +166 * @deprecated as of 2.1 (class will become immutable in 3.0) +167 */ +168 @Deprecated +169 public void setBeta(double newBeta) { +170 setBetaInternal(newBeta); +171 } +172 +173 /** +174 * Modify the scale parameter, beta. +175 * @param newBeta the new scale parameter. +176 * @throws IllegalArgumentException if <code>newBeta</code> is not positive. +177 */ +178 private void setBetaInternal(double newBeta) { +179 if (newBeta <= 0.0) { +180 throw MathRuntimeException.createIllegalArgumentException( +181 "beta must be positive ({0})", +182 newBeta); +183 } +184 this.beta = newBeta; +185 } +186 +187 /** +188 * Access the scale parameter, beta +189 * @return beta. +190 */ +191 public double getBeta() { +192 return beta; +193 } +194 +195 /** +196 * Returns the probability density for a particular point. +197 * +198 * @param x The point at which the density should be computed. +199 * @return The pdf at point x. +200 */ +201 @Override +202 public double density(double x) { +203 if (x < 0) return 0; +204 return Math.pow(x / beta, alpha - 1) / beta * Math.exp(-x / beta) / Math.exp(Gamma.logGamma(alpha)); +205 } +206 +207 /** +208 * Return the probability density for a particular point. +209 * +210 * @param x The point at which the density should be computed. +211 * @return The pdf at point x. +212 * @deprecated +213 */ +214 public double density(Double x) { +215 return density(x.doubleValue()); +216 } +217 +218 /** +219 * Access the domain value lower bound, based on <code>p</code>, used to +220 * bracket a CDF root. This method is used by +221 * {@link #inverseCumulativeProbability(double)} to find critical values. +222 * +223 * @param p the desired probability for the critical value +224 * @return domain value lower bound, i.e. +225 * P(X < <i>lower bound</i>) < <code>p</code> +226 */ +227 @Override +228 protected double getDomainLowerBound(double p) { +229 // TODO: try to improve on this estimate +230 return Double.MIN_VALUE; +231 } +232 +233 /** +234 * Access the domain value upper bound, based on <code>p</code>, used to +235 * bracket a CDF root. This method is used by +236 * {@link #inverseCumulativeProbability(double)} to find critical values. +237 * +238 * @param p the desired probability for the critical value +239 * @return domain value upper bound, i.e. +240 * P(X < <i>upper bound</i>) > <code>p</code> +241 */ +242 @Override +243 protected double getDomainUpperBound(double p) { +244 // TODO: try to improve on this estimate +245 // NOTE: gamma is skewed to the left +246 // NOTE: therefore, P(X < μ) > .5 +247 +248 double ret; +249 +250 if (p < .5) { +251 // use mean +252 ret = alpha * beta; +253 } else { +254 // use max value +255 ret = Double.MAX_VALUE; +256 } +257 +258 return ret; +259 } +260 +261 /** +262 * Access the initial domain value, based on <code>p</code>, used to +263 * bracket a CDF root. This method is used by +264 * {@link #inverseCumulativeProbability(double)} to find critical values. +265 * +266 * @param p the desired probability for the critical value +267 * @return initial domain value +268 */ +269 @Override +270 protected double getInitialDomain(double p) { +271 // TODO: try to improve on this estimate +272 // Gamma is skewed to the left, therefore, P(X < μ) > .5 +273 +274 double ret; +275 +276 if (p < .5) { +277 // use 1/2 mean +278 ret = alpha * beta * .5; +279 } else { +280 // use mean +281 ret = alpha * beta; +282 } +283 +284 return ret; +285 } +286 +287 /** +288 * Return the absolute accuracy setting of the solver used to estimate +289 * inverse cumulative probabilities. +290 * +291 * @return the solver absolute accuracy +292 * @since 2.1 +293 */ +294 @Override +295 protected double getSolverAbsoluteAccuracy() { +296 return solverAbsoluteAccuracy; +297 } +298 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/HasDensity.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/HasDensity.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,110 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.distribution; +019 +020 import org.apache.commons.math.MathException; +021 +022 /** +023 * <p>Interface that signals that a distribution can compute the probability density function +024 * for a particular point. +025 * @param <P> the type of the point at which density is to be computed, this +026 * may be for example <code>Double.</code></p> +027 * +028 * <p>This interface is deprecated. As of version 2.0, the {@link ContinuousDistribution} +029 * interface will be extended to include a <code>density(double)<code> method.</p> +030 * +031 * @deprecated to be removed in math 3.0 +032 * @version $Revision: 924362 $ $Date: 2010-03-17 12:45:31 -0400 (Wed, 17 Mar 2010) $ +033 */ +034 public interface HasDensity<P> { +035 +036 /** +037 * Compute the probability density function. +038 * @param x point for which the probability density is requested +039 * @return probability density at point x +040 * @throws MathException if probability density cannot be computed at specifed point +041 */ +042 double density(P x) throws MathException; +043 +044 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/HypergeometricDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/HypergeometricDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,142 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.distribution; +019 +020 /** +021 * The Hypergeometric Distribution. +022 * +023 * <p> +024 * References: +025 * <ul> +026 * <li><a href="http://mathworld.wolfram.com/HypergeometricDistribution.html"> +027 * Hypergeometric Distribution</a></li> +028 * </ul> +029 * </p> +030 * +031 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +032 */ +033 public interface HypergeometricDistribution extends IntegerDistribution { +034 +035 /** +036 * Access the number of successes. +037 * @return the number of successes. +038 */ +039 int getNumberOfSuccesses(); +040 +041 /** +042 * Access the population size. +043 * @return the population size. +044 */ +045 int getPopulationSize(); +046 +047 /** +048 * Access the sample size. +049 * @return the sample size. +050 */ +051 int getSampleSize(); +052 +053 /** +054 * Modify the number of successes. +055 * @param num the new number of successes. +056 * @deprecated as of v2.1 +057 */ +058 @Deprecated +059 void setNumberOfSuccesses(int num); +060 +061 /** +062 * Modify the population size. +063 * @param size the new population size. +064 * @deprecated as of v2.1 +065 */ +066 @Deprecated +067 void setPopulationSize(int size); +068 +069 /** +070 * Modify the sample size. +071 * @param size the new sample size. +072 * @deprecated as of v2.1 +073 */ +074 @Deprecated +075 void setSampleSize(int size); +076 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/HypergeometricDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/HypergeometricDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,418 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.distribution; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.util.MathUtils; +024 +025 /** +026 * The default implementation of {@link HypergeometricDistribution}. +027 * +028 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +029 */ +030 public class HypergeometricDistributionImpl extends AbstractIntegerDistribution +031 implements HypergeometricDistribution, Serializable { +032 +033 /** Serializable version identifier */ +034 private static final long serialVersionUID = -436928820673516179L; +035 +036 /** The number of successes in the population. */ +037 private int numberOfSuccesses; +038 +039 /** The population size. */ +040 private int populationSize; +041 +042 /** The sample size. */ +043 private int sampleSize; +044 +045 /** +046 * Construct a new hypergeometric distribution with the given the population +047 * size, the number of successes in the population, and the sample size. +048 * +049 * @param populationSize the population size. +050 * @param numberOfSuccesses number of successes in the population. +051 * @param sampleSize the sample size. +052 */ +053 public HypergeometricDistributionImpl(int populationSize, +054 int numberOfSuccesses, int sampleSize) { +055 super(); +056 if (numberOfSuccesses > populationSize) { +057 throw MathRuntimeException +058 .createIllegalArgumentException( +059 "number of successes ({0}) must be less than or equal to population size ({1})", +060 numberOfSuccesses, populationSize); +061 } +062 if (sampleSize > populationSize) { +063 throw MathRuntimeException +064 .createIllegalArgumentException( +065 "sample size ({0}) must be less than or equal to population size ({1})", +066 sampleSize, populationSize); +067 } +068 +069 setPopulationSizeInternal(populationSize); +070 setSampleSizeInternal(sampleSize); +071 setNumberOfSuccessesInternal(numberOfSuccesses); +072 } +073 +074 /** +075 * For this distribution, X, this method returns P(X ≤ x). +076 * +077 * @param x the value at which the PDF is evaluated. +078 * @return PDF for this distribution. +079 */ +080 @Override +081 public double cumulativeProbability(int x) { +082 double ret; +083 +084 int[] domain = getDomain(populationSize, numberOfSuccesses, sampleSize); +085 if (x < domain[0]) { +086 ret = 0.0; +087 } else if (x >= domain[1]) { +088 ret = 1.0; +089 } else { +090 ret = innerCumulativeProbability(domain[0], x, 1, populationSize, +091 numberOfSuccesses, sampleSize); +092 } +093 +094 return ret; +095 } +096 +097 /** +098 * Return the domain for the given hypergeometric distribution parameters. +099 * +100 * @param n the population size. +101 * @param m number of successes in the population. +102 * @param k the sample size. +103 * @return a two element array containing the lower and upper bounds of the +104 * hypergeometric distribution. +105 */ +106 private int[] getDomain(int n, int m, int k) { +107 return new int[] { getLowerDomain(n, m, k), getUpperDomain(m, k) }; +108 } +109 +110 /** +111 * Access the domain value lower bound, based on <code>p</code>, used to +112 * bracket a PDF root. +113 * +114 * @param p the desired probability for the critical value +115 * @return domain value lower bound, i.e. P(X < <i>lower bound</i>) < +116 * <code>p</code> +117 */ +118 @Override +119 protected int getDomainLowerBound(double p) { +120 return getLowerDomain(populationSize, numberOfSuccesses, sampleSize); +121 } +122 +123 /** +124 * Access the domain value upper bound, based on <code>p</code>, used to +125 * bracket a PDF root. +126 * +127 * @param p the desired probability for the critical value +128 * @return domain value upper bound, i.e. P(X < <i>upper bound</i>) > +129 * <code>p</code> +130 */ +131 @Override +132 protected int getDomainUpperBound(double p) { +133 return getUpperDomain(sampleSize, numberOfSuccesses); +134 } +135 +136 /** +137 * Return the lowest domain value for the given hypergeometric distribution +138 * parameters. +139 * +140 * @param n the population size. +141 * @param m number of successes in the population. +142 * @param k the sample size. +143 * @return the lowest domain value of the hypergeometric distribution. +144 */ +145 private int getLowerDomain(int n, int m, int k) { +146 return Math.max(0, m - (n - k)); +147 } +148 +149 /** +150 * Access the number of successes. +151 * +152 * @return the number of successes. +153 */ +154 public int getNumberOfSuccesses() { +155 return numberOfSuccesses; +156 } +157 +158 /** +159 * Access the population size. +160 * +161 * @return the population size. +162 */ +163 public int getPopulationSize() { +164 return populationSize; +165 } +166 +167 /** +168 * Access the sample size. +169 * +170 * @return the sample size. +171 */ +172 public int getSampleSize() { +173 return sampleSize; +174 } +175 +176 /** +177 * Return the highest domain value for the given hypergeometric distribution +178 * parameters. +179 * +180 * @param m number of successes in the population. +181 * @param k the sample size. +182 * @return the highest domain value of the hypergeometric distribution. +183 */ +184 private int getUpperDomain(int m, int k) { +185 return Math.min(k, m); +186 } +187 +188 /** +189 * For this distribution, X, this method returns P(X = x). +190 * +191 * @param x the value at which the PMF is evaluated. +192 * @return PMF for this distribution. +193 */ +194 public double probability(int x) { +195 double ret; +196 +197 int[] domain = getDomain(populationSize, numberOfSuccesses, sampleSize); +198 if (x < domain[0] || x > domain[1]) { +199 ret = 0.0; +200 } else { +201 double p = (double) sampleSize / (double) populationSize; +202 double q = (double) (populationSize - sampleSize) / (double) populationSize; +203 double p1 = SaddlePointExpansion.logBinomialProbability(x, +204 numberOfSuccesses, p, q); +205 double p2 = +206 SaddlePointExpansion.logBinomialProbability(sampleSize - x, +207 populationSize - numberOfSuccesses, p, q); +208 double p3 = +209 SaddlePointExpansion.logBinomialProbability(sampleSize, populationSize, p, q); +210 ret = Math.exp(p1 + p2 - p3); +211 } +212 +213 return ret; +214 } +215 +216 /** +217 * For the distribution, X, defined by the given hypergeometric distribution +218 * parameters, this method returns P(X = x). +219 * +220 * @param n the population size. +221 * @param m number of successes in the population. +222 * @param k the sample size. +223 * @param x the value at which the PMF is evaluated. +224 * @return PMF for the distribution. +225 */ +226 private double probability(int n, int m, int k, int x) { +227 return Math.exp(MathUtils.binomialCoefficientLog(m, x) + +228 MathUtils.binomialCoefficientLog(n - m, k - x) - +229 MathUtils.binomialCoefficientLog(n, k)); +230 } +231 +232 /** +233 * Modify the number of successes. +234 * +235 * @param num the new number of successes. +236 * @throws IllegalArgumentException if <code>num</code> is negative. +237 * @deprecated as of 2.1 (class will become immutable in 3.0) +238 */ +239 @Deprecated +240 public void setNumberOfSuccesses(int num) { +241 setNumberOfSuccessesInternal(num); +242 } +243 /** +244 * Modify the number of successes. +245 * +246 * @param num the new number of successes. +247 * @throws IllegalArgumentException if <code>num</code> is negative. +248 */ +249 private void setNumberOfSuccessesInternal(int num) { +250 if (num < 0) { +251 throw MathRuntimeException.createIllegalArgumentException( +252 "number of successes must be non-negative ({0})", num); +253 } +254 numberOfSuccesses = num; +255 } +256 +257 /** +258 * Modify the population size. +259 * +260 * @param size the new population size. +261 * @throws IllegalArgumentException if <code>size</code> is not positive. +262 * @deprecated as of 2.1 (class will become immutable in 3.0) +263 */ +264 @Deprecated +265 public void setPopulationSize(int size) { +266 setPopulationSizeInternal(size); +267 } +268 /** +269 * Modify the population size. +270 * +271 * @param size the new population size. +272 * @throws IllegalArgumentException if <code>size</code> is not positive. +273 */ +274 private void setPopulationSizeInternal(int size) { +275 if (size <= 0) { +276 throw MathRuntimeException.createIllegalArgumentException( +277 "population size must be positive ({0})", size); +278 } +279 populationSize = size; +280 } +281 +282 /** +283 * Modify the sample size. +284 * +285 * @param size the new sample size. +286 * @throws IllegalArgumentException if <code>size</code> is negative. +287 * @deprecated as of 2.1 (class will become immutable in 3.0) +288 */ +289 @Deprecated +290 public void setSampleSize(int size) { +291 setSampleSizeInternal(size); +292 } +293 /** +294 * Modify the sample size. +295 * +296 * @param size the new sample size. +297 * @throws IllegalArgumentException if <code>size</code> is negative. +298 */ +299 private void setSampleSizeInternal(int size) { +300 if (size < 0) { +301 throw MathRuntimeException.createIllegalArgumentException( +302 "sample size must be positive ({0})", size); +303 } +304 sampleSize = size; +305 } +306 +307 /** +308 * For this distribution, X, this method returns P(X ≥ x). +309 * +310 * @param x the value at which the CDF is evaluated. +311 * @return upper tail CDF for this distribution. +312 * @since 1.1 +313 */ +314 public double upperCumulativeProbability(int x) { +315 double ret; +316 +317 final int[] domain = getDomain(populationSize, numberOfSuccesses, sampleSize); +318 if (x < domain[0]) { +319 ret = 1.0; +320 } else if (x > domain[1]) { +321 ret = 0.0; +322 } else { +323 ret = innerCumulativeProbability(domain[1], x, -1, populationSize, numberOfSuccesses, sampleSize); +324 } +325 +326 return ret; +327 } +328 +329 /** +330 * For this distribution, X, this method returns P(x0 ≤ X ≤ x1). This +331 * probability is computed by summing the point probabilities for the values +332 * x0, x0 + 1, x0 + 2, ..., x1, in the order directed by dx. +333 * +334 * @param x0 the inclusive, lower bound +335 * @param x1 the inclusive, upper bound +336 * @param dx the direction of summation. 1 indicates summing from x0 to x1. +337 * 0 indicates summing from x1 to x0. +338 * @param n the population size. +339 * @param m number of successes in the population. +340 * @param k the sample size. +341 * @return P(x0 ≤ X ≤ x1). +342 */ +343 private double innerCumulativeProbability(int x0, int x1, int dx, int n, +344 int m, int k) { +345 double ret = probability(n, m, k, x0); +346 while (x0 != x1) { +347 x0 += dx; +348 ret += probability(n, m, k, x0); +349 } +350 return ret; +351 } +352 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/IntegerDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/IntegerDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,150 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import org.apache.commons.math.MathException; +020 +021 /** +022 * Interface for discrete distributions of integer-valued random variables. +023 * +024 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +025 */ +026 public interface IntegerDistribution extends DiscreteDistribution { +027 /** +028 * For a random variable X whose values are distributed according +029 * to this distribution, this method returns P(X = x). In other words, this +030 * method represents the probability mass function for the distribution. +031 * +032 * @param x the value at which the probability density function is evaluated. +033 * @return the value of the probability density function at x +034 */ +035 double probability(int x); +036 +037 /** +038 * For a random variable X whose values are distributed according +039 * to this distribution, this method returns P(X ≤ x). In other words, +040 * this method represents the probability distribution function, or PDF +041 * for the distribution. +042 * +043 * @param x the value at which the PDF is evaluated. +044 * @return PDF for this distribution. +045 * @throws MathException if the cumulative probability can not be +046 * computed due to convergence or other numerical errors. +047 */ +048 double cumulativeProbability(int x) throws MathException; +049 +050 /** +051 * For this distribution, X, this method returns P(x0 ≤ X ≤ x1). +052 * @param x0 the inclusive, lower bound +053 * @param x1 the inclusive, upper bound +054 * @return the cumulative probability. +055 * @throws MathException if the cumulative probability can not be +056 * computed due to convergence or other numerical errors. +057 * @throws IllegalArgumentException if x0 > x1 +058 */ +059 double cumulativeProbability(int x0, int x1) throws MathException; +060 +061 /** +062 * For this distribution, X, this method returns the largest x such that +063 * P(X ≤ x) <= p. +064 * <p> +065 * Note that this definition implies: <ul> +066 * <li> If there is a minimum value, <code>m</code>, with postive +067 * probablility under (the density of) X, then <code>m - 1</code> is +068 * returned by <code>inverseCumulativeProbability(0).</code> If there is +069 * no such value <code>m, Integer.MIN_VALUE</code> is +070 * returned.</li> +071 * <li> If there is a maximum value, <code>M</code>, such that +072 * P(X ≤ M) =1, then <code>M</code> is returned by +073 * <code>inverseCumulativeProbability(1).</code> +074 * If there is no such value, <code>M, Integer.MAX_VALUE</code> is +075 * returned.</li></ul></p> +076 * +077 * @param p the cumulative probability. +078 * @return the largest x such that P(X ≤ x) <= p +079 * @throws MathException if the inverse cumulative probability can not be +080 * computed due to convergence or other numerical errors. +081 * @throws IllegalArgumentException if p is not between 0 and 1 (inclusive) +082 */ +083 int inverseCumulativeProbability(double p) throws MathException; +084 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/NormalDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/NormalDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,131 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.distribution; +019 +020 /** +021 * Normal (Gauss) Distribution. +022 * +023 * <p> +024 * References:</p><p> +025 * <ul> +026 * <li><a href="http://mathworld.wolfram.com/NormalDistribution.html"> +027 * Normal Distribution</a></li> +028 * </ul> +029 * </p> +030 * +031 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +032 */ +033 public interface NormalDistribution extends ContinuousDistribution, HasDensity<Double> { +034 /** +035 * Access the mean. +036 * @return mean for this distribution +037 */ +038 double getMean(); +039 /** +040 * Modify the mean. +041 * @param mean for this distribution +042 * @deprecated as of v2.1 +043 */ +044 @Deprecated +045 void setMean(double mean); +046 /** +047 * Access the standard deviation. +048 * @return standard deviation for this distribution +049 */ +050 double getStandardDeviation(); +051 /** +052 * Modify the standard deviation. +053 * @param sd standard deviation for this distribution +054 * @deprecated as of v2.1 +055 */ +056 @Deprecated +057 void setStandardDeviation(double sd); +058 +059 /** +060 * Return the probability density for a particular point. +061 * @param x The point at which the density should be computed. +062 * @return The pdf at point x. +063 */ +064 double density(Double x); +065 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/NormalDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/NormalDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,363 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.distribution; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.MathException; +023 import org.apache.commons.math.MathRuntimeException; +024 import org.apache.commons.math.MaxIterationsExceededException; +025 import org.apache.commons.math.special.Erf; +026 +027 /** +028 * Default implementation of +029 * {@link org.apache.commons.math.distribution.NormalDistribution}. +030 * +031 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +032 */ +033 public class NormalDistributionImpl extends AbstractContinuousDistribution +034 implements NormalDistribution, Serializable { +035 +036 /** +037 * Default inverse cumulative probability accuracy +038 * @since 2.1 +039 */ +040 public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; +041 +042 /** Serializable version identifier */ +043 private static final long serialVersionUID = 8589540077390120676L; +044 +045 /** &sqrt;(2 π) */ +046 private static final double SQRT2PI = Math.sqrt(2 * Math.PI); +047 +048 /** The mean of this distribution. */ +049 private double mean = 0; +050 +051 /** The standard deviation of this distribution. */ +052 private double standardDeviation = 1; +053 +054 /** Inverse cumulative probability accuracy */ +055 private final double solverAbsoluteAccuracy; +056 +057 /** +058 * Create a normal distribution using the given mean and standard deviation. +059 * @param mean mean for this distribution +060 * @param sd standard deviation for this distribution +061 */ +062 public NormalDistributionImpl(double mean, double sd){ +063 this(mean, sd, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); +064 } +065 +066 /** +067 * Create a normal distribution using the given mean, standard deviation and +068 * inverse cumulative distribution accuracy. +069 * +070 * @param mean mean for this distribution +071 * @param sd standard deviation for this distribution +072 * @param inverseCumAccuracy inverse cumulative probability accuracy +073 * @since 2.1 +074 */ +075 public NormalDistributionImpl(double mean, double sd, double inverseCumAccuracy) { +076 super(); +077 setMeanInternal(mean); +078 setStandardDeviationInternal(sd); +079 solverAbsoluteAccuracy = inverseCumAccuracy; +080 } +081 +082 /** +083 * Creates normal distribution with the mean equal to zero and standard +084 * deviation equal to one. +085 */ +086 public NormalDistributionImpl(){ +087 this(0.0, 1.0); +088 } +089 +090 /** +091 * Access the mean. +092 * @return mean for this distribution +093 */ +094 public double getMean() { +095 return mean; +096 } +097 +098 /** +099 * Modify the mean. +100 * @param mean for this distribution +101 * @deprecated as of 2.1 (class will become immutable in 3.0) +102 */ +103 @Deprecated +104 public void setMean(double mean) { +105 setMeanInternal(mean); +106 } +107 /** +108 * Modify the mean. +109 * @param newMean for this distribution +110 */ +111 private void setMeanInternal(double newMean) { +112 this.mean = newMean; +113 } +114 +115 /** +116 * Access the standard deviation. +117 * @return standard deviation for this distribution +118 */ +119 public double getStandardDeviation() { +120 return standardDeviation; +121 } +122 +123 /** +124 * Modify the standard deviation. +125 * @param sd standard deviation for this distribution +126 * @throws IllegalArgumentException if <code>sd</code> is not positive. +127 * @deprecated as of 2.1 (class will become immutable in 3.0) +128 */ +129 @Deprecated +130 public void setStandardDeviation(double sd) { +131 setStandardDeviationInternal(sd); +132 } +133 /** +134 * Modify the standard deviation. +135 * @param sd standard deviation for this distribution +136 * @throws IllegalArgumentException if <code>sd</code> is not positive. +137 */ +138 private void setStandardDeviationInternal(double sd) { +139 if (sd <= 0.0) { +140 throw MathRuntimeException.createIllegalArgumentException( +141 "standard deviation must be positive ({0})", +142 sd); +143 } +144 standardDeviation = sd; +145 } +146 +147 /** +148 * Return the probability density for a particular point. +149 * +150 * @param x The point at which the density should be computed. +151 * @return The pdf at point x. +152 * @deprecated +153 */ +154 public double density(Double x) { +155 return density(x.doubleValue()); +156 } +157 +158 /** +159 * Returns the probability density for a particular point. +160 * +161 * @param x The point at which the density should be computed. +162 * @return The pdf at point x. +163 * @since 2.1 +164 */ +165 public double density(double x) { +166 double x0 = x - mean; +167 return Math.exp(-x0 * x0 / (2 * standardDeviation * standardDeviation)) / (standardDeviation * SQRT2PI); +168 } +169 +170 /** +171 * For this distribution, X, this method returns P(X < <code>x</code>). +172 * @param x the value at which the CDF is evaluated. +173 * @return CDF evaluted at <code>x</code>. +174 * @throws MathException if the algorithm fails to converge; unless +175 * x is more than 20 standard deviations from the mean, in which case the +176 * convergence exception is caught and 0 or 1 is returned. +177 */ +178 public double cumulativeProbability(double x) throws MathException { +179 try { +180 return 0.5 * (1.0 + Erf.erf((x - mean) / +181 (standardDeviation * Math.sqrt(2.0)))); +182 } catch (MaxIterationsExceededException ex) { +183 if (x < (mean - 20 * standardDeviation)) { // JDK 1.5 blows at 38 +184 return 0.0d; +185 } else if (x > (mean + 20 * standardDeviation)) { +186 return 1.0d; +187 } else { +188 throw ex; +189 } +190 } +191 } +192 +193 /** +194 * Return the absolute accuracy setting of the solver used to estimate +195 * inverse cumulative probabilities. +196 * +197 * @return the solver absolute accuracy +198 * @since 2.1 +199 */ +200 @Override +201 protected double getSolverAbsoluteAccuracy() { +202 return solverAbsoluteAccuracy; +203 } +204 +205 /** +206 * For this distribution, X, this method returns the critical point x, such +207 * that P(X < x) = <code>p</code>. +208 * <p> +209 * Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and +210 * <code>Double.POSITIVE_INFINITY</code> for p=1.</p> +211 * +212 * @param p the desired probability +213 * @return x, such that P(X < x) = <code>p</code> +214 * @throws MathException if the inverse cumulative probability can not be +215 * computed due to convergence or other numerical errors. +216 * @throws IllegalArgumentException if <code>p</code> is not a valid +217 * probability. +218 */ +219 @Override +220 public double inverseCumulativeProbability(final double p) +221 throws MathException { +222 if (p == 0) { +223 return Double.NEGATIVE_INFINITY; +224 } +225 if (p == 1) { +226 return Double.POSITIVE_INFINITY; +227 } +228 return super.inverseCumulativeProbability(p); +229 } +230 +231 /** +232 * Access the domain value lower bound, based on <code>p</code>, used to +233 * bracket a CDF root. This method is used by +234 * {@link #inverseCumulativeProbability(double)} to find critical values. +235 * +236 * @param p the desired probability for the critical value +237 * @return domain value lower bound, i.e. +238 * P(X < <i>lower bound</i>) < <code>p</code> +239 */ +240 @Override +241 protected double getDomainLowerBound(double p) { +242 double ret; +243 +244 if (p < .5) { +245 ret = -Double.MAX_VALUE; +246 } else { +247 ret = mean; +248 } +249 +250 return ret; +251 } +252 +253 /** +254 * Access the domain value upper bound, based on <code>p</code>, used to +255 * bracket a CDF root. This method is used by +256 * {@link #inverseCumulativeProbability(double)} to find critical values. +257 * +258 * @param p the desired probability for the critical value +259 * @return domain value upper bound, i.e. +260 * P(X < <i>upper bound</i>) > <code>p</code> +261 */ +262 @Override +263 protected double getDomainUpperBound(double p) { +264 double ret; +265 +266 if (p < .5) { +267 ret = mean; +268 } else { +269 ret = Double.MAX_VALUE; +270 } +271 +272 return ret; +273 } +274 +275 /** +276 * Access the initial domain value, based on <code>p</code>, used to +277 * bracket a CDF root. This method is used by +278 * {@link #inverseCumulativeProbability(double)} to find critical values. +279 * +280 * @param p the desired probability for the critical value +281 * @return initial domain value +282 */ +283 @Override +284 protected double getInitialDomain(double p) { +285 double ret; +286 +287 if (p < .5) { +288 ret = mean - standardDeviation; +289 } else if (p > .5) { +290 ret = mean + standardDeviation; +291 } else { +292 ret = mean; +293 } +294 +295 return ret; +296 } +297 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/PascalDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/PascalDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,139 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 /** +020 * The Pascal distribution. The Pascal distribution is a special case of the +021 * Negative Binomial distribution where the number of successes parameter is an +022 * integer. +023 * +024 * There are various ways to express the probability mass and distribution +025 * functions for the Pascal distribution. The convention employed by the +026 * library is to express these functions in terms of the number of failures in +027 * a Bernoulli experiment [2]. +028 * +029 * <p> +030 * References: +031 * <ol> +032 * <li><a href="http://mathworld.wolfram.com/NegativeBinomialDistribution.html"> +033 * Negative Binomial Distribution</a></li> +034 * <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> +035 * </ul> +036 * </p> +037 * +038 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +039 * @since 1.2 +040 */ +041 public interface PascalDistribution extends IntegerDistribution { +042 /** +043 * Access the number of successes for this distribution. +044 * +045 * @return the number of successes +046 */ +047 int getNumberOfSuccesses(); +048 +049 /** +050 * Access the probability of success for this distribution. +051 * +052 * @return the probability of success +053 */ +054 double getProbabilityOfSuccess(); +055 +056 /** +057 * Change the number of successes for this distribution. +058 * +059 * @param successes the new number of successes +060 * @deprecated as of v2.1 +061 */ +062 @Deprecated +063 void setNumberOfSuccesses(int successes); +064 +065 /** +066 * Change the probability of success for this distribution. +067 * +068 * @param p the new probability of success +069 * @deprecated as of v2.1 +070 */ +071 @Deprecated +072 void setProbabilityOfSuccess(double p); +073 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/PascalDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/PascalDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,278 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathException; +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.special.Beta; +024 import org.apache.commons.math.util.MathUtils; +025 +026 /** +027 * The default implementation of {@link PascalDistribution}. +028 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +029 * @since 1.2 +030 */ +031 public class PascalDistributionImpl extends AbstractIntegerDistribution +032 implements PascalDistribution, Serializable { +033 +034 /** Serializable version identifier */ +035 private static final long serialVersionUID = 6751309484392813623L; +036 +037 /** The number of successes */ +038 private int numberOfSuccesses; +039 +040 /** The probability of success */ +041 private double probabilityOfSuccess; +042 +043 /** +044 * Create a binomial distribution with the given number of trials and +045 * probability of success. +046 * @param r the number of successes +047 * @param p the probability of success +048 */ +049 public PascalDistributionImpl(int r, double p) { +050 super(); +051 setNumberOfSuccessesInternal(r); +052 setProbabilityOfSuccessInternal(p); +053 } +054 +055 /** +056 * Access the number of successes for this distribution. +057 * @return the number of successes +058 */ +059 public int getNumberOfSuccesses() { +060 return numberOfSuccesses; +061 } +062 +063 /** +064 * Access the probability of success for this distribution. +065 * @return the probability of success +066 */ +067 public double getProbabilityOfSuccess() { +068 return probabilityOfSuccess; +069 } +070 +071 /** +072 * Change the number of successes for this distribution. +073 * @param successes the new number of successes +074 * @throws IllegalArgumentException if <code>successes</code> is not +075 * positive. +076 * @deprecated as of 2.1 (class will become immutable in 3.0) +077 */ +078 @Deprecated +079 public void setNumberOfSuccesses(int successes) { +080 setNumberOfSuccessesInternal(successes); +081 } +082 /** +083 * Change the number of successes for this distribution. +084 * @param successes the new number of successes +085 * @throws IllegalArgumentException if <code>successes</code> is not +086 * positive. +087 */ +088 private void setNumberOfSuccessesInternal(int successes) { +089 if (successes < 0) { +090 throw MathRuntimeException.createIllegalArgumentException( +091 "number of successes must be non-negative ({0})", +092 successes); +093 } +094 numberOfSuccesses = successes; +095 } +096 +097 /** +098 * Change the probability of success for this distribution. +099 * @param p the new probability of success +100 * @throws IllegalArgumentException if <code>p</code> is not a valid +101 * probability. +102 * @deprecated as of 2.1 (class will become immutable in 3.0) +103 */ +104 @Deprecated +105 public void setProbabilityOfSuccess(double p) { +106 setProbabilityOfSuccessInternal(p); +107 } +108 /** +109 * Change the probability of success for this distribution. +110 * @param p the new probability of success +111 * @throws IllegalArgumentException if <code>p</code> is not a valid +112 * probability. +113 */ +114 private void setProbabilityOfSuccessInternal(double p) { +115 if (p < 0.0 || p > 1.0) { +116 throw MathRuntimeException.createIllegalArgumentException( +117 "{0} out of [{1}, {2}] range", p, 0.0, 1.0); +118 } +119 probabilityOfSuccess = p; +120 } +121 +122 /** +123 * Access the domain value lower bound, based on <code>p</code>, used to +124 * bracket a PDF root. +125 * @param p the desired probability for the critical value +126 * @return domain value lower bound, i.e. P(X < <i>lower bound</i>) < +127 * <code>p</code> +128 */ +129 @Override +130 protected int getDomainLowerBound(double p) { +131 return -1; +132 } +133 +134 /** +135 * Access the domain value upper bound, based on <code>p</code>, used to +136 * bracket a PDF root. +137 * @param p the desired probability for the critical value +138 * @return domain value upper bound, i.e. P(X < <i>upper bound</i>) > +139 * <code>p</code> +140 */ +141 @Override +142 protected int getDomainUpperBound(double p) { +143 // use MAX - 1 because MAX causes loop +144 return Integer.MAX_VALUE - 1; +145 } +146 +147 /** +148 * For this distribution, X, this method returns P(X ≤ x). +149 * @param x the value at which the PDF is evaluated +150 * @return PDF for this distribution +151 * @throws MathException if the cumulative probability can not be computed +152 * due to convergence or other numerical errors +153 */ +154 @Override +155 public double cumulativeProbability(int x) throws MathException { +156 double ret; +157 if (x < 0) { +158 ret = 0.0; +159 } else { +160 ret = Beta.regularizedBeta(probabilityOfSuccess, +161 numberOfSuccesses, x + 1); +162 } +163 return ret; +164 } +165 +166 /** +167 * For this distribution, X, this method returns P(X = x). +168 * @param x the value at which the PMF is evaluated +169 * @return PMF for this distribution +170 */ +171 public double probability(int x) { +172 double ret; +173 if (x < 0) { +174 ret = 0.0; +175 } else { +176 ret = MathUtils.binomialCoefficientDouble(x + +177 numberOfSuccesses - 1, numberOfSuccesses - 1) * +178 Math.pow(probabilityOfSuccess, numberOfSuccesses) * +179 Math.pow(1.0 - probabilityOfSuccess, x); +180 } +181 return ret; +182 } +183 +184 /** +185 * For this distribution, X, this method returns the largest x, such that +186 * P(X ≤ x) ≤ <code>p</code>. +187 * <p> +188 * Returns <code>-1</code> for p=0 and <code>Integer.MAX_VALUE</code> +189 * for p=1.</p> +190 * @param p the desired probability +191 * @return the largest x such that P(X ≤ x) <= p +192 * @throws MathException if the inverse cumulative probability can not be +193 * computed due to convergence or other numerical errors. +194 * @throws IllegalArgumentException if p < 0 or p > 1 +195 */ +196 @Override +197 public int inverseCumulativeProbability(final double p) +198 throws MathException { +199 int ret; +200 +201 // handle extreme values explicitly +202 if (p == 0) { +203 ret = -1; +204 } else if (p == 1) { +205 ret = Integer.MAX_VALUE; +206 } else { +207 ret = super.inverseCumulativeProbability(p); +208 } +209 +210 return ret; +211 } +212 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/PoissonDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/PoissonDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,130 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import org.apache.commons.math.MathException; +020 +021 /** +022 * Interface representing the Poisson Distribution. +023 * +024 * <p> +025 * References: +026 * <ul> +027 * <li><a href="http://mathworld.wolfram.com/PoissonDistribution.html"> +028 * Poisson distribution</a></li> +029 * </ul> +030 * </p> +031 * +032 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +033 */ +034 public interface PoissonDistribution extends IntegerDistribution { +035 +036 /** +037 * Get the mean for the distribution. +038 * +039 * @return the mean for the distribution. +040 */ +041 double getMean(); +042 +043 /** +044 * Set the mean for the distribution. +045 * The parameter value must be positive; otherwise an +046 * <code>IllegalArgument</code> is thrown. +047 * +048 * @param p the mean +049 * @throws IllegalArgumentException if p ≤ 0 +050 * @deprecated as of v2.1 +051 */ +052 @Deprecated +053 void setMean(double p); +054 +055 /** +056 * Calculates the Poisson distribution function using a normal approximation. +057 * +058 * @param x the upper bound, inclusive +059 * @return the distribution function value calculated using a normal approximation +060 * @throws MathException if an error occurs computing the normal approximation +061 */ +062 double normalApproximateProbability(int x) throws MathException; +063 +064 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/PoissonDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/PoissonDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,345 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathException; +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.special.Gamma; +024 import org.apache.commons.math.util.MathUtils; +025 +026 /** +027 * Implementation for the {@link PoissonDistribution}. +028 * +029 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +030 */ +031 public class PoissonDistributionImpl extends AbstractIntegerDistribution +032 implements PoissonDistribution, Serializable { +033 +034 /** +035 * Default maximum number of iterations for cumulative probability calculations. +036 * @since 2.1 +037 */ +038 public static final int DEFAULT_MAX_ITERATIONS = 10000000; +039 +040 /** +041 * Default convergence criterion. +042 * @since 2.1 +043 */ +044 public static final double DEFAULT_EPSILON = 1E-12; +045 +046 /** Serializable version identifier */ +047 private static final long serialVersionUID = -3349935121172596109L; +048 +049 /** Distribution used to compute normal approximation. */ +050 private NormalDistribution normal; +051 +052 /** +053 * Holds the Poisson mean for the distribution. +054 */ +055 private double mean; +056 +057 /** +058 * Maximum number of iterations for cumulative probability. +059 * +060 * Cumulative probabilities are estimated using either Lanczos series approximation of +061 * Gamma#regularizedGammaP or continued fraction approximation of Gamma#regularizedGammaQ. +062 */ +063 private int maxIterations = DEFAULT_MAX_ITERATIONS; +064 +065 /** +066 * Convergence criterion for cumulative probability. +067 */ +068 private double epsilon = DEFAULT_EPSILON; +069 +070 /** +071 * Create a new Poisson distribution with the given the mean. The mean value +072 * must be positive; otherwise an <code>IllegalArgument</code> is thrown. +073 * +074 * @param p the Poisson mean +075 * @throws IllegalArgumentException if p ≤ 0 +076 */ +077 public PoissonDistributionImpl(double p) { +078 this(p, new NormalDistributionImpl()); +079 } +080 +081 /** +082 * Create a new Poisson distribution with the given mean, convergence criterion +083 * and maximum number of iterations. +084 * +085 * @param p the Poisson mean +086 * @param epsilon the convergence criteria for cumulative probabilites +087 * @param maxIterations the maximum number of iterations for cumulative probabilites +088 * @since 2.1 +089 */ +090 public PoissonDistributionImpl(double p, double epsilon, int maxIterations) { +091 setMean(p); +092 this.epsilon = epsilon; +093 this.maxIterations = maxIterations; +094 } +095 +096 /** +097 * Create a new Poisson distribution with the given mean and convergence criterion. +098 * +099 * @param p the Poisson mean +100 * @param epsilon the convergence criteria for cumulative probabilites +101 * @since 2.1 +102 */ +103 public PoissonDistributionImpl(double p, double epsilon) { +104 setMean(p); +105 this.epsilon = epsilon; +106 } +107 +108 /** +109 * Create a new Poisson distribution with the given mean and maximum number of iterations. +110 * +111 * @param p the Poisson mean +112 * @param maxIterations the maximum number of iterations for cumulative probabilites +113 * @since 2.1 +114 */ +115 public PoissonDistributionImpl(double p, int maxIterations) { +116 setMean(p); +117 this.maxIterations = maxIterations; +118 } +119 +120 +121 /** +122 * Create a new Poisson distribution with the given the mean. The mean value +123 * must be positive; otherwise an <code>IllegalArgument</code> is thrown. +124 * +125 * @param p the Poisson mean +126 * @param z a normal distribution used to compute normal approximations. +127 * @throws IllegalArgumentException if p ≤ 0 +128 * @since 1.2 +129 * @deprecated as of 2.1 (to avoid possibly inconsistent state, the +130 * "NormalDistribution" will be instantiated internally) +131 */ +132 @Deprecated +133 public PoissonDistributionImpl(double p, NormalDistribution z) { +134 super(); +135 setNormalAndMeanInternal(z, p); +136 } +137 +138 /** +139 * Get the Poisson mean for the distribution. +140 * +141 * @return the Poisson mean for the distribution. +142 */ +143 public double getMean() { +144 return mean; +145 } +146 +147 /** +148 * Set the Poisson mean for the distribution. The mean value must be +149 * positive; otherwise an <code>IllegalArgument</code> is thrown. +150 * +151 * @param p the Poisson mean value +152 * @throws IllegalArgumentException if p ≤ 0 +153 * @deprecated as of 2.1 (class will become immutable in 3.0) +154 */ +155 @Deprecated +156 public void setMean(double p) { +157 setNormalAndMeanInternal(normal, p); +158 } +159 /** +160 * Set the Poisson mean for the distribution. The mean value must be +161 * positive; otherwise an <code>IllegalArgument</code> is thrown. +162 * +163 * @param z the new distribution +164 * @param p the Poisson mean value +165 * @throws IllegalArgumentException if p ≤ 0 +166 */ +167 private void setNormalAndMeanInternal(NormalDistribution z, +168 double p) { +169 if (p <= 0) { +170 throw MathRuntimeException.createIllegalArgumentException( +171 "the Poisson mean must be positive ({0})", p); +172 } +173 mean = p; +174 normal = z; +175 normal.setMean(p); +176 normal.setStandardDeviation(Math.sqrt(p)); +177 } +178 +179 /** +180 * The probability mass function P(X = x) for a Poisson distribution. +181 * +182 * @param x the value at which the probability density function is +183 * evaluated. +184 * @return the value of the probability mass function at x +185 */ +186 public double probability(int x) { +187 double ret; +188 if (x < 0 || x == Integer.MAX_VALUE) { +189 ret = 0.0; +190 } else if (x == 0) { +191 ret = Math.exp(-mean); +192 } else { +193 ret = Math.exp(-SaddlePointExpansion.getStirlingError(x) - +194 SaddlePointExpansion.getDeviancePart(x, mean)) / +195 Math.sqrt(MathUtils.TWO_PI * x); +196 } +197 return ret; +198 } +199 +200 /** +201 * The probability distribution function P(X <= x) for a Poisson +202 * distribution. +203 * +204 * @param x the value at which the PDF is evaluated. +205 * @return Poisson distribution function evaluated at x +206 * @throws MathException if the cumulative probability can not be computed +207 * due to convergence or other numerical errors. +208 */ +209 @Override +210 public double cumulativeProbability(int x) throws MathException { +211 if (x < 0) { +212 return 0; +213 } +214 if (x == Integer.MAX_VALUE) { +215 return 1; +216 } +217 return Gamma.regularizedGammaQ((double) x + 1, mean, epsilon, maxIterations); +218 } +219 +220 /** +221 * Calculates the Poisson distribution function using a normal +222 * approximation. The <code>N(mean, sqrt(mean))</code> distribution is used +223 * to approximate the Poisson distribution. +224 * <p> +225 * The computation uses "half-correction" -- evaluating the normal +226 * distribution function at <code>x + 0.5</code> +227 * </p> +228 * +229 * @param x the upper bound, inclusive +230 * @return the distribution function value calculated using a normal +231 * approximation +232 * @throws MathException if an error occurs computing the normal +233 * approximation +234 */ +235 public double normalApproximateProbability(int x) throws MathException { +236 // calculate the probability using half-correction +237 return normal.cumulativeProbability(x + 0.5); +238 } +239 +240 /** +241 * Access the domain value lower bound, based on <code>p</code>, used to +242 * bracket a CDF root. This method is used by +243 * {@link #inverseCumulativeProbability(double)} to find critical values. +244 * +245 * @param p the desired probability for the critical value +246 * @return domain lower bound +247 */ +248 @Override +249 protected int getDomainLowerBound(double p) { +250 return 0; +251 } +252 +253 /** +254 * Access the domain value upper bound, based on <code>p</code>, used to +255 * bracket a CDF root. This method is used by +256 * {@link #inverseCumulativeProbability(double)} to find critical values. +257 * +258 * @param p the desired probability for the critical value +259 * @return domain upper bound +260 */ +261 @Override +262 protected int getDomainUpperBound(double p) { +263 return Integer.MAX_VALUE; +264 } +265 +266 /** +267 * Modify the normal distribution used to compute normal approximations. The +268 * caller is responsible for insuring the normal distribution has the proper +269 * parameter settings. +270 * +271 * @param value the new distribution +272 * @since 1.2 +273 * @deprecated as of 2.1 (class will become immutable in 3.0) +274 */ +275 @Deprecated +276 public void setNormal(NormalDistribution value) { +277 setNormalAndMeanInternal(value, mean); +278 } +279 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/TDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/TDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,112 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 /** +020 * Student's t-Distribution. +021 * +022 * <p> +023 * References: +024 * <ul> +025 * <li><a href="http://mathworld.wolfram.com/Studentst-Distribution.html"> +026 * Student's t-Distribution</a></li> +027 * </ul> +028 * </p> +029 * +030 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +031 */ +032 public interface TDistribution extends ContinuousDistribution { +033 /** +034 * Modify the degrees of freedom. +035 * @param degreesOfFreedom the new degrees of freedom. +036 * @deprecated as of v2.1 +037 */ +038 @Deprecated +039 void setDegreesOfFreedom(double degreesOfFreedom); +040 +041 /** +042 * Access the degrees of freedom. +043 * @return the degrees of freedom. +044 */ +045 double getDegreesOfFreedom(); +046 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/TDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/TDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,290 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.distribution; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathException; +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.special.Beta; +024 import org.apache.commons.math.special.Gamma; +025 +026 /** +027 * Default implementation of +028 * {@link org.apache.commons.math.distribution.TDistribution}. +029 * +030 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +031 */ +032 public class TDistributionImpl +033 extends AbstractContinuousDistribution +034 implements TDistribution, Serializable { +035 +036 /** +037 * Default inverse cumulative probability accuracy +038 * @since 2.1 +039 */ +040 public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; +041 +042 /** Serializable version identifier */ +043 private static final long serialVersionUID = -5852615386664158222L; +044 +045 /** The degrees of freedom*/ +046 private double degreesOfFreedom; +047 +048 /** Inverse cumulative probability accuracy */ +049 private final double solverAbsoluteAccuracy; +050 +051 /** +052 * Create a t distribution using the given degrees of freedom and the +053 * specified inverse cumulative probability absolute accuracy. +054 * +055 * @param degreesOfFreedom the degrees of freedom. +056 * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates +057 * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) +058 * @since 2.1 +059 */ +060 public TDistributionImpl(double degreesOfFreedom, double inverseCumAccuracy) { +061 super(); +062 setDegreesOfFreedomInternal(degreesOfFreedom); +063 solverAbsoluteAccuracy = inverseCumAccuracy; +064 } +065 +066 /** +067 * Create a t distribution using the given degrees of freedom. +068 * @param degreesOfFreedom the degrees of freedom. +069 */ +070 public TDistributionImpl(double degreesOfFreedom) { +071 this(degreesOfFreedom, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); +072 } +073 +074 /** +075 * Modify the degrees of freedom. +076 * @param degreesOfFreedom the new degrees of freedom. +077 * @deprecated as of 2.1 (class will become immutable in 3.0) +078 */ +079 @Deprecated +080 public void setDegreesOfFreedom(double degreesOfFreedom) { +081 setDegreesOfFreedomInternal(degreesOfFreedom); +082 } +083 /** +084 * Modify the degrees of freedom. +085 * @param newDegreesOfFreedom the new degrees of freedom. +086 */ +087 private void setDegreesOfFreedomInternal(double newDegreesOfFreedom) { +088 if (newDegreesOfFreedom <= 0.0) { +089 throw MathRuntimeException.createIllegalArgumentException( +090 "degrees of freedom must be positive ({0})", +091 newDegreesOfFreedom); +092 } +093 this.degreesOfFreedom = newDegreesOfFreedom; +094 } +095 +096 /** +097 * Access the degrees of freedom. +098 * @return the degrees of freedom. +099 */ +100 public double getDegreesOfFreedom() { +101 return degreesOfFreedom; +102 } +103 +104 /** +105 * Returns the probability density for a particular point. +106 * +107 * @param x The point at which the density should be computed. +108 * @return The pdf at point x. +109 * @since 2.1 +110 */ +111 @Override +112 public double density(double x) { +113 final double n = degreesOfFreedom; +114 final double nPlus1Over2 = (n + 1) / 2; +115 return Math.exp(Gamma.logGamma(nPlus1Over2) - 0.5 * (Math.log(Math.PI) + Math.log(n)) - +116 Gamma.logGamma(n/2) - nPlus1Over2 * Math.log(1 + x * x /n)); +117 } +118 +119 /** +120 * For this distribution, X, this method returns P(X < <code>x</code>). +121 * @param x the value at which the CDF is evaluated. +122 * @return CDF evaluted at <code>x</code>. +123 * @throws MathException if the cumulative probability can not be +124 * computed due to convergence or other numerical errors. +125 */ +126 public double cumulativeProbability(double x) throws MathException{ +127 double ret; +128 if (x == 0.0) { +129 ret = 0.5; +130 } else { +131 double t = +132 Beta.regularizedBeta( +133 degreesOfFreedom / (degreesOfFreedom + (x * x)), +134 0.5 * degreesOfFreedom, +135 0.5); +136 if (x < 0.0) { +137 ret = 0.5 * t; +138 } else { +139 ret = 1.0 - 0.5 * t; +140 } +141 } +142 +143 return ret; +144 } +145 +146 /** +147 * For this distribution, X, this method returns the critical point x, such +148 * that P(X < x) = <code>p</code>. +149 * <p> +150 * Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and +151 * <code>Double.POSITIVE_INFINITY</code> for p=1.</p> +152 * +153 * @param p the desired probability +154 * @return x, such that P(X < x) = <code>p</code> +155 * @throws MathException if the inverse cumulative probability can not be +156 * computed due to convergence or other numerical errors. +157 * @throws IllegalArgumentException if <code>p</code> is not a valid +158 * probability. +159 */ +160 @Override +161 public double inverseCumulativeProbability(final double p) +162 throws MathException { +163 if (p == 0) { +164 return Double.NEGATIVE_INFINITY; +165 } +166 if (p == 1) { +167 return Double.POSITIVE_INFINITY; +168 } +169 return super.inverseCumulativeProbability(p); +170 } +171 +172 /** +173 * Access the domain value lower bound, based on <code>p</code>, used to +174 * bracket a CDF root. This method is used by +175 * {@link #inverseCumulativeProbability(double)} to find critical values. +176 * +177 * @param p the desired probability for the critical value +178 * @return domain value lower bound, i.e. +179 * P(X < <i>lower bound</i>) < <code>p</code> +180 */ +181 @Override +182 protected double getDomainLowerBound(double p) { +183 return -Double.MAX_VALUE; +184 } +185 +186 /** +187 * Access the domain value upper bound, based on <code>p</code>, used to +188 * bracket a CDF root. This method is used by +189 * {@link #inverseCumulativeProbability(double)} to find critical values. +190 * +191 * @param p the desired probability for the critical value +192 * @return domain value upper bound, i.e. +193 * P(X < <i>upper bound</i>) > <code>p</code> +194 */ +195 @Override +196 protected double getDomainUpperBound(double p) { +197 return Double.MAX_VALUE; +198 } +199 +200 /** +201 * Access the initial domain value, based on <code>p</code>, used to +202 * bracket a CDF root. This method is used by +203 * {@link #inverseCumulativeProbability(double)} to find critical values. +204 * +205 * @param p the desired probability for the critical value +206 * @return initial domain value +207 */ +208 @Override +209 protected double getInitialDomain(double p) { +210 return 0.0; +211 } +212 +213 /** +214 * Return the absolute accuracy setting of the solver used to estimate +215 * inverse cumulative probabilities. +216 * +217 * @return the solver absolute accuracy +218 * @since 2.1 +219 */ +220 @Override +221 protected double getSolverAbsoluteAccuracy() { +222 return solverAbsoluteAccuracy; +223 } +224 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/WeibullDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/WeibullDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,132 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.distribution; +019 +020 /** +021 * Weibull Distribution. This interface defines the two parameter form of the +022 * distribution as defined by +023 * <a href="http://mathworld.wolfram.com/WeibullDistribution.html"> +024 * Weibull Distribution</a>, equations (1) and (2). +025 * +026 * <p> +027 * References: +028 * <ul> +029 * <li><a href="http://mathworld.wolfram.com/WeibullDistribution.html"> +030 * Weibull Distribution</a></li> +031 * </ul> +032 * </p> +033 * +034 * @since 1.1 +035 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +036 */ +037 public interface WeibullDistribution extends ContinuousDistribution { +038 +039 /** +040 * Access the shape parameter. +041 * @return the shape parameter. +042 */ +043 double getShape(); +044 +045 /** +046 * Access the scale parameter. +047 * @return the scale parameter. +048 */ +049 double getScale(); +050 +051 /** +052 * Modify the shape parameter. +053 * @param alpha The new shape parameter value. +054 * @deprecated as of v2.1 +055 */ +056 @Deprecated +057 void setShape(double alpha); +058 +059 /** +060 * Modify the scale parameter. +061 * @param beta The new scale parameter value. +062 * @deprecated as of v2.1 +063 */ +064 @Deprecated +065 void setScale(double beta); +066 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/WeibullDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/WeibullDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,326 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.distribution; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 +024 /** +025 * Default implementation of +026 * {@link org.apache.commons.math.distribution.WeibullDistribution}. +027 * +028 * @since 1.1 +029 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +030 */ +031 public class WeibullDistributionImpl extends AbstractContinuousDistribution +032 implements WeibullDistribution, Serializable { +033 +034 /** +035 * Default inverse cumulative probability accuracy +036 * @since 2.1 +037 */ +038 public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; +039 +040 /** Serializable version identifier */ +041 private static final long serialVersionUID = 8589540077390120676L; +042 +043 /** The shape parameter. */ +044 private double shape; +045 +046 /** The scale parameter. */ +047 private double scale; +048 +049 /** Inverse cumulative probability accuracy */ +050 private final double solverAbsoluteAccuracy; +051 +052 /** +053 * Creates weibull distribution with the given shape and scale and a +054 * location equal to zero. +055 * @param alpha the shape parameter. +056 * @param beta the scale parameter. +057 */ +058 public WeibullDistributionImpl(double alpha, double beta){ +059 this(alpha, beta, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); +060 } +061 +062 /** +063 * Creates weibull distribution with the given shape, scale and inverse +064 * cumulative probability accuracy and a location equal to zero. +065 * @param alpha the shape parameter. +066 * @param beta the scale parameter. +067 * @param inverseCumAccuracy the maximum absolute error in inverse cumulative probability estimates +068 * (defaults to {@link #DEFAULT_INVERSE_ABSOLUTE_ACCURACY}) +069 * @since 2.1 +070 */ +071 public WeibullDistributionImpl(double alpha, double beta, double inverseCumAccuracy){ +072 super(); +073 setShapeInternal(alpha); +074 setScaleInternal(beta); +075 solverAbsoluteAccuracy = inverseCumAccuracy; +076 } +077 +078 /** +079 * For this distribution, X, this method returns P(X < <code>x</code>). +080 * @param x the value at which the CDF is evaluated. +081 * @return CDF evaluted at <code>x</code>. +082 */ +083 public double cumulativeProbability(double x) { +084 double ret; +085 if (x <= 0.0) { +086 ret = 0.0; +087 } else { +088 ret = 1.0 - Math.exp(-Math.pow(x / scale, shape)); +089 } +090 return ret; +091 } +092 +093 /** +094 * Access the shape parameter. +095 * @return the shape parameter. +096 */ +097 public double getShape() { +098 return shape; +099 } +100 +101 /** +102 * Access the scale parameter. +103 * @return the scale parameter. +104 */ +105 public double getScale() { +106 return scale; +107 } +108 +109 /** +110 * Returns the probability density for a particular point. +111 * +112 * @param x The point at which the density should be computed. +113 * @return The pdf at point x. +114 * @since 2.1 +115 */ +116 @Override +117 public double density(double x) { +118 if (x < 0) { +119 return 0; +120 } +121 +122 final double xscale = x / scale; +123 final double xscalepow = Math.pow(xscale, shape - 1); +124 +125 /* +126 * Math.pow(x / scale, shape) = +127 * Math.pow(xscale, shape) = +128 * Math.pow(xscale, shape - 1) * xscale +129 */ +130 final double xscalepowshape = xscalepow * xscale; +131 +132 return (shape / scale) * xscalepow * Math.exp(-xscalepowshape); +133 } +134 +135 /** +136 * For this distribution, X, this method returns the critical point x, such +137 * that P(X < x) = <code>p</code>. +138 * <p> +139 * Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and +140 * <code>Double.POSITIVE_INFINITY</code> for p=1.</p> +141 * +142 * @param p the desired probability +143 * @return x, such that P(X < x) = <code>p</code> +144 * @throws IllegalArgumentException if <code>p</code> is not a valid +145 * probability. +146 */ +147 @Override +148 public double inverseCumulativeProbability(double p) { +149 double ret; +150 if (p < 0.0 || p > 1.0) { +151 throw MathRuntimeException.createIllegalArgumentException( +152 "{0} out of [{1}, {2}] range", p, 0.0, 1.0); +153 } else if (p == 0) { +154 ret = 0.0; +155 } else if (p == 1) { +156 ret = Double.POSITIVE_INFINITY; +157 } else { +158 ret = scale * Math.pow(-Math.log(1.0 - p), 1.0 / shape); +159 } +160 return ret; +161 } +162 +163 /** +164 * Modify the shape parameter. +165 * @param alpha the new shape parameter value. +166 * @deprecated as of 2.1 (class will become immutable in 3.0) +167 */ +168 @Deprecated +169 public void setShape(double alpha) { +170 setShapeInternal(alpha); +171 } +172 /** +173 * Modify the shape parameter. +174 * @param alpha the new shape parameter value. +175 */ +176 private void setShapeInternal(double alpha) { +177 if (alpha <= 0.0) { +178 throw MathRuntimeException.createIllegalArgumentException( +179 "shape must be positive ({0})", +180 alpha); +181 } +182 this.shape = alpha; +183 } +184 +185 /** +186 * Modify the scale parameter. +187 * @param beta the new scale parameter value. +188 * @deprecated as of 2.1 (class will become immutable in 3.0) +189 */ +190 @Deprecated +191 public void setScale(double beta) { +192 setScaleInternal(beta); +193 } +194 /** +195 * Modify the scale parameter. +196 * @param beta the new scale parameter value. +197 */ +198 private void setScaleInternal(double beta) { +199 if (beta <= 0.0) { +200 throw MathRuntimeException.createIllegalArgumentException( +201 "scale must be positive ({0})", +202 beta); +203 } +204 this.scale = beta; +205 } +206 +207 /** +208 * Access the domain value lower bound, based on <code>p</code>, used to +209 * bracket a CDF root. This method is used by +210 * {@link #inverseCumulativeProbability(double)} to find critical values. +211 * +212 * @param p the desired probability for the critical value +213 * @return domain value lower bound, i.e. +214 * P(X < <i>lower bound</i>) < <code>p</code> +215 */ +216 @Override +217 protected double getDomainLowerBound(double p) { +218 return 0.0; +219 } +220 +221 /** +222 * Access the domain value upper bound, based on <code>p</code>, used to +223 * bracket a CDF root. This method is used by +224 * {@link #inverseCumulativeProbability(double)} to find critical values. +225 * +226 * @param p the desired probability for the critical value +227 * @return domain value upper bound, i.e. +228 * P(X < <i>upper bound</i>) > <code>p</code> +229 */ +230 @Override +231 protected double getDomainUpperBound(double p) { +232 return Double.MAX_VALUE; +233 } +234 +235 /** +236 * Access the initial domain value, based on <code>p</code>, used to +237 * bracket a CDF root. This method is used by +238 * {@link #inverseCumulativeProbability(double)} to find critical values. +239 * +240 * @param p the desired probability for the critical value +241 * @return initial domain value +242 */ +243 @Override +244 protected double getInitialDomain(double p) { +245 // use median +246 return Math.pow(scale * Math.log(2.0), 1.0 / shape); +247 } +248 +249 /** +250 * Return the absolute accuracy setting of the solver used to estimate +251 * inverse cumulative probabilities. +252 * +253 * @return the solver absolute accuracy +254 * @since 2.1 +255 */ +256 @Override +257 protected double getSolverAbsoluteAccuracy() { +258 return solverAbsoluteAccuracy; +259 } +260 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/ZipfDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/ZipfDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,137 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.distribution; +019 +020 /** +021 * The Zipf (or zeta) Distribution. +022 * <p> +023 * References: +024 * <ul> +025 * <li><a href="http://mathworld.wolfram.com/ZipfDistribution.html">Zipf +026 * Distribution</a></li> +027 * </ul> +028 * </p> +029 * +030 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +031 */ +032 public interface ZipfDistribution extends IntegerDistribution { +033 +034 /** +035 * Get the number of elements (e.g. corpus size) for the distribution. +036 * +037 * @return the number of elements +038 */ +039 int getNumberOfElements(); +040 +041 /** +042 * Set the number of elements (e.g. corpus size) for the distribution. +043 * The parameter value must be positive; otherwise an +044 * <code>IllegalArgumentException</code> is thrown. +045 * +046 * @param n the number of elements +047 * @throws IllegalArgumentException if n ≤ 0 +048 * @deprecated as of v2.1 +049 */ +050 @Deprecated +051 void setNumberOfElements(int n); +052 +053 /** +054 * Get the exponent characterising the distribution. +055 * +056 * @return the exponent +057 */ +058 double getExponent(); +059 +060 /** +061 * Set the exponent characterising the distribution. +062 * The parameter value must be positive; otherwise an +063 * <code>IllegalArgumentException</code> is thrown. +064 * +065 * @param s the exponent +066 * @throws IllegalArgumentException if s ≤ 0.0 +067 * @deprecated as of v2.1 +068 */ +069 @Deprecated +070 void setExponent(double s); +071 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/ZipfDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/distribution/ZipfDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,279 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.distribution; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 +024 /** +025 * Implementation for the {@link ZipfDistribution}. +026 * +027 * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $ +028 */ +029 public class ZipfDistributionImpl extends AbstractIntegerDistribution +030 implements ZipfDistribution, Serializable { +031 +032 /** Serializable version identifier. */ +033 private static final long serialVersionUID = -140627372283420404L; +034 +035 /** Number of elements. */ +036 private int numberOfElements; +037 +038 /** Exponent parameter of the distribution. */ +039 private double exponent; +040 +041 /** +042 * Create a new Zipf distribution with the given number of elements and +043 * exponent. Both values must be positive; otherwise an +044 * <code>IllegalArgumentException</code> is thrown. +045 * +046 * @param numberOfElements the number of elements +047 * @param exponent the exponent +048 * @exception IllegalArgumentException if n ≤ 0 or s ≤ 0.0 +049 */ +050 public ZipfDistributionImpl(final int numberOfElements, final double exponent) +051 throws IllegalArgumentException { +052 setNumberOfElementsInternal(numberOfElements); +053 setExponentInternal(exponent); +054 } +055 +056 /** +057 * Get the number of elements (e.g. corpus size) for the distribution. +058 * +059 * @return the number of elements +060 */ +061 public int getNumberOfElements() { +062 return numberOfElements; +063 } +064 +065 /** +066 * Set the number of elements (e.g. corpus size) for the distribution. +067 * The parameter value must be positive; otherwise an +068 * <code>IllegalArgumentException</code> is thrown. +069 * +070 * @param n the number of elements +071 * @exception IllegalArgumentException if n ≤ 0 +072 * @deprecated as of 2.1 (class will become immutable in 3.0) +073 */ +074 @Deprecated +075 public void setNumberOfElements(final int n) { +076 setNumberOfElementsInternal(n); +077 } +078 /** +079 * Set the number of elements (e.g. corpus size) for the distribution. +080 * The parameter value must be positive; otherwise an +081 * <code>IllegalArgumentException</code> is thrown. +082 * +083 * @param n the number of elements +084 * @exception IllegalArgumentException if n ≤ 0 +085 */ +086 private void setNumberOfElementsInternal(final int n) +087 throws IllegalArgumentException { +088 if (n <= 0) { +089 throw MathRuntimeException.createIllegalArgumentException( +090 "invalid number of elements {0} (must be positive)", +091 n); +092 } +093 this.numberOfElements = n; +094 } +095 +096 /** +097 * Get the exponent characterising the distribution. +098 * +099 * @return the exponent +100 */ +101 public double getExponent() { +102 return exponent; +103 } +104 +105 /** +106 * Set the exponent characterising the distribution. +107 * The parameter value must be positive; otherwise an +108 * <code>IllegalArgumentException</code> is thrown. +109 * +110 * @param s the exponent +111 * @exception IllegalArgumentException if s ≤ 0.0 +112 * @deprecated as of 2.1 (class will become immutable in 3.0) +113 */ +114 @Deprecated +115 public void setExponent(final double s) { +116 setExponentInternal(s); +117 } +118 /** +119 * Set the exponent characterising the distribution. +120 * The parameter value must be positive; otherwise an +121 * <code>IllegalArgumentException</code> is thrown. +122 * +123 * @param s the exponent +124 * @exception IllegalArgumentException if s ≤ 0.0 +125 */ +126 private void setExponentInternal(final double s) +127 throws IllegalArgumentException { +128 if (s <= 0.0) { +129 throw MathRuntimeException.createIllegalArgumentException( +130 "invalid exponent {0} (must be positive)", +131 s); +132 } +133 this.exponent = s; +134 } +135 +136 /** +137 * The probability mass function P(X = x) for a Zipf distribution. +138 * +139 * @param x the value at which the probability density function is evaluated. +140 * @return the value of the probability mass function at x +141 */ +142 public double probability(final int x) { +143 if (x <= 0 || x > numberOfElements) { +144 return 0.0; +145 } +146 +147 return (1.0 / Math.pow(x, exponent)) / generalizedHarmonic(numberOfElements, exponent); +148 +149 } +150 +151 /** +152 * The probability distribution function P(X <= x) for a Zipf distribution. +153 * +154 * @param x the value at which the PDF is evaluated. +155 * @return Zipf distribution function evaluated at x +156 */ +157 @Override +158 public double cumulativeProbability(final int x) { +159 if (x <= 0) { +160 return 0.0; +161 } else if (x >= numberOfElements) { +162 return 1.0; +163 } +164 +165 return generalizedHarmonic(x, exponent) / generalizedHarmonic(numberOfElements, exponent); +166 +167 } +168 +169 /** +170 * Access the domain value lower bound, based on <code>p</code>, used to +171 * bracket a PDF root. +172 * +173 * @param p the desired probability for the critical value +174 * @return domain value lower bound, i.e. +175 * P(X < <i>lower bound</i>) < <code>p</code> +176 */ +177 @Override +178 protected int getDomainLowerBound(final double p) { +179 return 0; +180 } +181 +182 /** +183 * Access the domain value upper bound, based on <code>p</code>, used to +184 * bracket a PDF root. +185 * +186 * @param p the desired probability for the critical value +187 * @return domain value upper bound, i.e. +188 * P(X < <i>upper bound</i>) > <code>p</code> +189 */ +190 @Override +191 protected int getDomainUpperBound(final double p) { +192 return numberOfElements; +193 } +194 +195 +196 /** +197 * Calculates the Nth generalized harmonic number. See +198 * <a href="http://mathworld.wolfram.com/HarmonicSeries.html">Harmonic +199 * Series</a>. +200 * +201 * @param n the term in the series to calculate (must be ≥ 1) +202 * @param m the exponent; special case m == 1.0 is the harmonic series +203 * @return the nth generalized harmonic number +204 */ +205 private double generalizedHarmonic(final int n, final double m) { +206 double value = 0; +207 for (int k = n; k > 0; --k) { +208 value += 1.0 / Math.pow(k, m); +209 } +210 return value; +211 } +212 +213 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/AbstractEstimator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/AbstractEstimator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,382 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.estimation; +019 +020 import java.util.Arrays; +021 +022 import org.apache.commons.math.linear.InvalidMatrixException; +023 import org.apache.commons.math.linear.LUDecompositionImpl; +024 import org.apache.commons.math.linear.MatrixUtils; +025 import org.apache.commons.math.linear.RealMatrix; +026 +027 /** +028 * Base class for implementing estimators. +029 * <p>This base class handles the boilerplates methods associated to thresholds +030 * settings, jacobian and error estimation.</p> +031 * @version $Revision: 825919 $ $Date: 2009-10-16 10:51:55 -0400 (Fri, 16 Oct 2009) $ +032 * @since 1.2 +033 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has +034 * been deprecated and replaced by package org.apache.commons.math.optimization.general +035 * +036 */ +037 @Deprecated +038 public abstract class AbstractEstimator implements Estimator { +039 +040 /** Default maximal number of cost evaluations allowed. */ +041 public static final int DEFAULT_MAX_COST_EVALUATIONS = 100; +042 +043 /** Array of measurements. */ +044 protected WeightedMeasurement[] measurements; +045 +046 /** Array of parameters. */ +047 protected EstimatedParameter[] parameters; +048 +049 /** +050 * Jacobian matrix. +051 * <p>This matrix is in canonical form just after the calls to +052 * {@link #updateJacobian()}, but may be modified by the solver +053 * in the derived class (the {@link LevenbergMarquardtEstimator +054 * Levenberg-Marquardt estimator} does this).</p> +055 */ +056 protected double[] jacobian; +057 +058 /** Number of columns of the jacobian matrix. */ +059 protected int cols; +060 +061 /** Number of rows of the jacobian matrix. */ +062 protected int rows; +063 +064 /** Residuals array. +065 * <p>This array is in canonical form just after the calls to +066 * {@link #updateJacobian()}, but may be modified by the solver +067 * in the derived class (the {@link LevenbergMarquardtEstimator +068 * Levenberg-Marquardt estimator} does this).</p> +069 */ +070 protected double[] residuals; +071 +072 /** Cost value (square root of the sum of the residuals). */ +073 protected double cost; +074 +075 /** Maximal allowed number of cost evaluations. */ +076 private int maxCostEval; +077 +078 /** Number of cost evaluations. */ +079 private int costEvaluations; +080 +081 /** Number of jacobian evaluations. */ +082 private int jacobianEvaluations; +083 +084 /** +085 * Build an abstract estimator for least squares problems. +086 * <p>The maximal number of cost evaluations allowed is set +087 * to its default value {@link #DEFAULT_MAX_COST_EVALUATIONS}.</p> +088 */ +089 protected AbstractEstimator() { +090 setMaxCostEval(DEFAULT_MAX_COST_EVALUATIONS); +091 } +092 +093 /** +094 * Set the maximal number of cost evaluations allowed. +095 * +096 * @param maxCostEval maximal number of cost evaluations allowed +097 * @see #estimate +098 */ +099 public final void setMaxCostEval(int maxCostEval) { +100 this.maxCostEval = maxCostEval; +101 } +102 +103 /** +104 * Get the number of cost evaluations. +105 * +106 * @return number of cost evaluations +107 * */ +108 public final int getCostEvaluations() { +109 return costEvaluations; +110 } +111 +112 /** +113 * Get the number of jacobian evaluations. +114 * +115 * @return number of jacobian evaluations +116 * */ +117 public final int getJacobianEvaluations() { +118 return jacobianEvaluations; +119 } +120 +121 /** +122 * Update the jacobian matrix. +123 */ +124 protected void updateJacobian() { +125 incrementJacobianEvaluationsCounter(); +126 Arrays.fill(jacobian, 0); +127 int index = 0; +128 for (int i = 0; i < rows; i++) { +129 WeightedMeasurement wm = measurements[i]; +130 double factor = -Math.sqrt(wm.getWeight()); +131 for (int j = 0; j < cols; ++j) { +132 jacobian[index++] = factor * wm.getPartial(parameters[j]); +133 } +134 } +135 } +136 +137 /** +138 * Increment the jacobian evaluations counter. +139 */ +140 protected final void incrementJacobianEvaluationsCounter() { +141 ++jacobianEvaluations; +142 } +143 +144 /** +145 * Update the residuals array and cost function value. +146 * @exception EstimationException if the number of cost evaluations +147 * exceeds the maximum allowed +148 */ +149 protected void updateResidualsAndCost() +150 throws EstimationException { +151 +152 if (++costEvaluations > maxCostEval) { +153 throw new EstimationException("maximal number of evaluations exceeded ({0})", +154 maxCostEval); +155 } +156 +157 cost = 0; +158 int index = 0; +159 for (int i = 0; i < rows; i++, index += cols) { +160 WeightedMeasurement wm = measurements[i]; +161 double residual = wm.getResidual(); +162 residuals[i] = Math.sqrt(wm.getWeight()) * residual; +163 cost += wm.getWeight() * residual * residual; +164 } +165 cost = Math.sqrt(cost); +166 +167 } +168 +169 /** +170 * Get the Root Mean Square value. +171 * Get the Root Mean Square value, i.e. the root of the arithmetic +172 * mean of the square of all weighted residuals. This is related to the +173 * criterion that is minimized by the estimator as follows: if +174 * <em>c</em> if the criterion, and <em>n</em> is the number of +175 * measurements, then the RMS is <em>sqrt (c/n)</em>. +176 * +177 * @param problem estimation problem +178 * @return RMS value +179 */ +180 public double getRMS(EstimationProblem problem) { +181 WeightedMeasurement[] wm = problem.getMeasurements(); +182 double criterion = 0; +183 for (int i = 0; i < wm.length; ++i) { +184 double residual = wm[i].getResidual(); +185 criterion += wm[i].getWeight() * residual * residual; +186 } +187 return Math.sqrt(criterion / wm.length); +188 } +189 +190 /** +191 * Get the Chi-Square value. +192 * @param problem estimation problem +193 * @return chi-square value +194 */ +195 public double getChiSquare(EstimationProblem problem) { +196 WeightedMeasurement[] wm = problem.getMeasurements(); +197 double chiSquare = 0; +198 for (int i = 0; i < wm.length; ++i) { +199 double residual = wm[i].getResidual(); +200 chiSquare += residual * residual / wm[i].getWeight(); +201 } +202 return chiSquare; +203 } +204 +205 /** +206 * Get the covariance matrix of unbound estimated parameters. +207 * @param problem estimation problem +208 * @return covariance matrix +209 * @exception EstimationException if the covariance matrix +210 * cannot be computed (singular problem) +211 */ +212 public double[][] getCovariances(EstimationProblem problem) +213 throws EstimationException { +214 +215 // set up the jacobian +216 updateJacobian(); +217 +218 // compute transpose(J).J, avoiding building big intermediate matrices +219 final int n = problem.getMeasurements().length; +220 final int m = problem.getUnboundParameters().length; +221 final int max = m * n; +222 double[][] jTj = new double[m][m]; +223 for (int i = 0; i < m; ++i) { +224 for (int j = i; j < m; ++j) { +225 double sum = 0; +226 for (int k = 0; k < max; k += m) { +227 sum += jacobian[k + i] * jacobian[k + j]; +228 } +229 jTj[i][j] = sum; +230 jTj[j][i] = sum; +231 } +232 } +233 +234 try { +235 // compute the covariances matrix +236 RealMatrix inverse = +237 new LUDecompositionImpl(MatrixUtils.createRealMatrix(jTj)).getSolver().getInverse(); +238 return inverse.getData(); +239 } catch (InvalidMatrixException ime) { +240 throw new EstimationException("unable to compute covariances: singular problem"); +241 } +242 +243 } +244 +245 /** +246 * Guess the errors in unbound estimated parameters. +247 * <p>Guessing is covariance-based, it only gives rough order of magnitude.</p> +248 * @param problem estimation problem +249 * @return errors in estimated parameters +250 * @exception EstimationException if the covariances matrix cannot be computed +251 * or the number of degrees of freedom is not positive (number of measurements +252 * lesser or equal to number of parameters) +253 */ +254 public double[] guessParametersErrors(EstimationProblem problem) +255 throws EstimationException { +256 int m = problem.getMeasurements().length; +257 int p = problem.getUnboundParameters().length; +258 if (m <= p) { +259 throw new EstimationException( +260 "no degrees of freedom ({0} measurements, {1} parameters)", +261 m, p); +262 } +263 double[] errors = new double[problem.getUnboundParameters().length]; +264 final double c = Math.sqrt(getChiSquare(problem) / (m - p)); +265 double[][] covar = getCovariances(problem); +266 for (int i = 0; i < errors.length; ++i) { +267 errors[i] = Math.sqrt(covar[i][i]) * c; +268 } +269 return errors; +270 } +271 +272 /** +273 * Initialization of the common parts of the estimation. +274 * <p>This method <em>must</em> be called at the start +275 * of the {@link #estimate(EstimationProblem) estimate} +276 * method.</p> +277 * @param problem estimation problem to solve +278 */ +279 protected void initializeEstimate(EstimationProblem problem) { +280 +281 // reset counters +282 costEvaluations = 0; +283 jacobianEvaluations = 0; +284 +285 // retrieve the equations and the parameters +286 measurements = problem.getMeasurements(); +287 parameters = problem.getUnboundParameters(); +288 +289 // arrays shared with the other private methods +290 rows = measurements.length; +291 cols = parameters.length; +292 jacobian = new double[rows * cols]; +293 residuals = new double[rows]; +294 +295 cost = Double.POSITIVE_INFINITY; +296 +297 } +298 +299 /** +300 * Solve an estimation problem. +301 * +302 * <p>The method should set the parameters of the problem to several +303 * trial values until it reaches convergence. If this method returns +304 * normally (i.e. without throwing an exception), then the best +305 * estimate of the parameters can be retrieved from the problem +306 * itself, through the {@link EstimationProblem#getAllParameters +307 * EstimationProblem.getAllParameters} method.</p> +308 * +309 * @param problem estimation problem to solve +310 * @exception EstimationException if the problem cannot be solved +311 * +312 */ +313 public abstract void estimate(EstimationProblem problem) +314 throws EstimationException; +315 +316 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/EstimatedParameter.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/EstimatedParameter.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,192 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.estimation; +019 +020 import java.io.Serializable; +021 +022 /** This class represents the estimated parameters of an estimation problem. +023 * +024 * <p>The parameters of an estimation problem have a name, a value and +025 * a bound flag. The value of bound parameters is considered trusted +026 * and the solvers should not adjust them. On the other hand, the +027 * solvers should adjust the value of unbounds parameters until they +028 * satisfy convergence criterions specific to each solver.</p> +029 * +030 * @version $Revision: 922710 $ $Date: 2010-03-13 20:20:56 -0500 (Sat, 13 Mar 2010) $ +031 * @since 1.2 +032 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has +033 * been deprecated and replaced by package org.apache.commons.math.optimization.general +034 * +035 */ +036 @Deprecated +037 public class EstimatedParameter +038 implements Serializable { +039 +040 /** Serializable version identifier */ +041 private static final long serialVersionUID = -555440800213416949L; +042 +043 /** Current value of the parameter */ +044 protected double estimate; +045 +046 /** Name of the parameter */ +047 private final String name; +048 +049 /** Indicator for bound parameters +050 * (ie parameters that should not be estimated) +051 */ +052 private boolean bound; +053 +054 /** Simple constructor. +055 * Build an instance from a first estimate of the parameter, +056 * initially considered unbound. +057 * @param name name of the parameter +058 * @param firstEstimate first estimate of the parameter +059 */ +060 public EstimatedParameter(String name, double firstEstimate) { +061 this.name = name; +062 estimate = firstEstimate; +063 bound = false; +064 } +065 +066 /** Simple constructor. +067 * Build an instance from a first estimate of the parameter and a +068 * bound flag +069 * @param name name of the parameter +070 * @param firstEstimate first estimate of the parameter +071 * @param bound flag, should be true if the parameter is bound +072 */ +073 public EstimatedParameter(String name, +074 double firstEstimate, +075 boolean bound) { +076 this.name = name; +077 estimate = firstEstimate; +078 this.bound = bound; +079 } +080 +081 /** Copy constructor. +082 * Build a copy of a parameter +083 * @param parameter instance to copy +084 */ +085 public EstimatedParameter(EstimatedParameter parameter) { +086 name = parameter.name; +087 estimate = parameter.estimate; +088 bound = parameter.bound; +089 } +090 +091 /** Set a new estimated value for the parameter. +092 * @param estimate new estimate for the parameter +093 */ +094 public void setEstimate(double estimate) { +095 this.estimate = estimate; +096 } +097 +098 /** Get the current estimate of the parameter +099 * @return current estimate +100 */ +101 public double getEstimate() { +102 return estimate; +103 } +104 +105 /** get the name of the parameter +106 * @return parameter name +107 */ +108 public String getName() { +109 return name; +110 } +111 +112 /** Set the bound flag of the parameter +113 * @param bound this flag should be set to true if the parameter is +114 * bound (i.e. if it should not be adjusted by the solver). +115 */ +116 public void setBound(boolean bound) { +117 this.bound = bound; +118 } +119 +120 /** Check if the parameter is bound +121 * @return true if the parameter is bound */ +122 public boolean isBound() { +123 return bound; +124 } +125 +126 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/EstimationException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/EstimationException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,114 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.estimation; +019 +020 import org.apache.commons.math.MathException; +021 +022 /** +023 * This class represents exceptions thrown by the estimation solvers. +024 * +025 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +026 * @since 1.2 +027 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has +028 * been deprecated and replaced by package org.apache.commons.math.optimization.general +029 * +030 */ +031 @Deprecated +032 public class EstimationException +033 extends MathException { +034 +035 /** Serializable version identifier. */ +036 private static final long serialVersionUID = -573038581493881337L; +037 +038 /** +039 * Simple constructor. +040 * Build an exception by translating and formating a message +041 * @param specifier format specifier (to be translated) +042 * @param parts to insert in the format (no translation) +043 */ +044 public EstimationException(String specifier, Object ... parts) { +045 super(specifier, parts); +046 } +047 +048 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/EstimationProblem.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/EstimationProblem.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,134 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.estimation; +019 +020 /** +021 * This interface represents an estimation problem. +022 * +023 * <p>This interface should be implemented by all real estimation +024 * problems before they can be handled by the estimators through the +025 * {@link Estimator#estimate Estimator.estimate} method.</p> +026 * +027 * <p>An estimation problem, as seen by a solver is a set of +028 * parameters and a set of measurements. The parameters are adjusted +029 * during the estimation through the {@link #getUnboundParameters +030 * getUnboundParameters} and {@link EstimatedParameter#setEstimate +031 * EstimatedParameter.setEstimate} methods. The measurements both have +032 * a measured value which is generally fixed at construction and a +033 * theoretical value which depends on the model and hence varies as +034 * the parameters are adjusted. The purpose of the solver is to reduce +035 * the residual between these values, it can retrieve the measurements +036 * through the {@link #getMeasurements getMeasurements} method.</p> +037 * +038 * @see Estimator +039 * @see WeightedMeasurement +040 * +041 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +042 * @since 1.2 +043 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has +044 * been deprecated and replaced by package org.apache.commons.math.optimization.general +045 * +046 */ +047 @Deprecated +048 public interface EstimationProblem { +049 +050 /** +051 * Get the measurements of an estimation problem. +052 * @return measurements +053 */ +054 WeightedMeasurement[] getMeasurements(); +055 +056 /** +057 * Get the unbound parameters of the problem. +058 * @return unbound parameters +059 */ +060 EstimatedParameter[] getUnboundParameters(); +061 +062 /** +063 * Get all the parameters of the problem. +064 * @return parameters +065 */ +066 EstimatedParameter[] getAllParameters(); +067 +068 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/Estimator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/Estimator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,156 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.estimation; +019 +020 /** +021 * This interface represents solvers for estimation problems. +022 * +023 * <p>The classes which are devoted to solve estimation problems +024 * should implement this interface. The problems which can be handled +025 * should implement the {@link EstimationProblem} interface which +026 * gather all the information needed by the solver.</p> +027 * +028 * <p>The interface is composed only of the {@link #estimate estimate} +029 * method.</p> +030 * +031 * @see EstimationProblem +032 * +033 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +034 * @since 1.2 +035 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has +036 * been deprecated and replaced by package org.apache.commons.math.optimization.general +037 * +038 */ +039 @Deprecated +040 public interface Estimator { +041 +042 /** +043 * Solve an estimation problem. +044 * +045 * <p>The method should set the parameters of the problem to several +046 * trial values until it reaches convergence. If this method returns +047 * normally (i.e. without throwing an exception), then the best +048 * estimate of the parameters can be retrieved from the problem +049 * itself, through the {@link EstimationProblem#getAllParameters +050 * EstimationProblem.getAllParameters} method.</p> +051 * +052 * @param problem estimation problem to solve +053 * @exception EstimationException if the problem cannot be solved +054 * +055 */ +056 void estimate(EstimationProblem problem) throws EstimationException; +057 +058 /** +059 * Get the Root Mean Square value. +060 * Get the Root Mean Square value, i.e. the root of the arithmetic +061 * mean of the square of all weighted residuals. This is related to the +062 * criterion that is minimized by the estimator as follows: if +063 * <em>c</em> is the criterion, and <em>n</em> is the number of +064 * measurements, then the RMS is <em>sqrt (c/n)</em>. +065 * @see #guessParametersErrors(EstimationProblem) +066 * +067 * @param problem estimation problem +068 * @return RMS value +069 */ +070 double getRMS(EstimationProblem problem); +071 +072 /** +073 * Get the covariance matrix of estimated parameters. +074 * @param problem estimation problem +075 * @return covariance matrix +076 * @exception EstimationException if the covariance matrix +077 * cannot be computed (singular problem) +078 */ +079 double[][] getCovariances(EstimationProblem problem) throws EstimationException; +080 +081 /** +082 * Guess the errors in estimated parameters. +083 * @see #getRMS(EstimationProblem) +084 * @param problem estimation problem +085 * @return errors in estimated parameters +086 * @exception EstimationException if the error cannot be guessed +087 */ +088 double[] guessParametersErrors(EstimationProblem problem) throws EstimationException; +089 +090 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/GaussNewtonEstimator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/GaussNewtonEstimator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,295 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.estimation; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.linear.InvalidMatrixException; +023 import org.apache.commons.math.linear.LUDecompositionImpl; +024 import org.apache.commons.math.linear.MatrixUtils; +025 import org.apache.commons.math.linear.RealMatrix; +026 import org.apache.commons.math.linear.RealVector; +027 import org.apache.commons.math.linear.ArrayRealVector; +028 +029 /** +030 * This class implements a solver for estimation problems. +031 * +032 * <p>This class solves estimation problems using a weighted least +033 * squares criterion on the measurement residuals. It uses a +034 * Gauss-Newton algorithm.</p> +035 * +036 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +037 * @since 1.2 +038 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has +039 * been deprecated and replaced by package org.apache.commons.math.optimization.general +040 * +041 */ +042 @Deprecated +043 public class GaussNewtonEstimator extends AbstractEstimator implements Serializable { +044 +045 /** Serializable version identifier */ +046 private static final long serialVersionUID = 5485001826076289109L; +047 +048 /** Default threshold for cost steady state detection. */ +049 private static final double DEFAULT_STEADY_STATE_THRESHOLD = 1.0e-6; +050 +051 /** Default threshold for cost convergence. */ +052 private static final double DEFAULT_CONVERGENCE = 1.0e-6; +053 +054 /** Threshold for cost steady state detection. */ +055 private double steadyStateThreshold; +056 +057 /** Threshold for cost convergence. */ +058 private double convergence; +059 +060 /** Simple constructor with default settings. +061 * <p> +062 * The estimator is built with default values for all settings. +063 * </p> +064 * @see #DEFAULT_STEADY_STATE_THRESHOLD +065 * @see #DEFAULT_CONVERGENCE +066 * @see AbstractEstimator#DEFAULT_MAX_COST_EVALUATIONS +067 */ +068 public GaussNewtonEstimator() { +069 this.steadyStateThreshold = DEFAULT_STEADY_STATE_THRESHOLD; +070 this.convergence = DEFAULT_CONVERGENCE; +071 } +072 +073 /** +074 * Simple constructor. +075 * +076 * <p>This constructor builds an estimator and stores its convergence +077 * characteristics.</p> +078 * +079 * <p>An estimator is considered to have converged whenever either +080 * the criterion goes below a physical threshold under which +081 * improvements are considered useless or when the algorithm is +082 * unable to improve it (even if it is still high). The first +083 * condition that is met stops the iterations.</p> +084 * +085 * <p>The fact an estimator has converged does not mean that the +086 * model accurately fits the measurements. It only means no better +087 * solution can be found, it does not mean this one is good. Such an +088 * analysis is left to the caller.</p> +089 * +090 * <p>If neither conditions are fulfilled before a given number of +091 * iterations, the algorithm is considered to have failed and an +092 * {@link EstimationException} is thrown.</p> +093 * +094 * @param maxCostEval maximal number of cost evaluations allowed +095 * @param convergence criterion threshold below which we do not need +096 * to improve the criterion anymore +097 * @param steadyStateThreshold steady state detection threshold, the +098 * problem has converged has reached a steady state if +099 * <code>Math.abs(J<sub>n</sub> - J<sub>n-1</sub>) < +100 * J<sub>n</sub> × convergence</code>, where <code>J<sub>n</sub></code> +101 * and <code>J<sub>n-1</sub></code> are the current and preceding criterion +102 * values (square sum of the weighted residuals of considered measurements). +103 */ +104 public GaussNewtonEstimator(final int maxCostEval, final double convergence, +105 final double steadyStateThreshold) { +106 setMaxCostEval(maxCostEval); +107 this.steadyStateThreshold = steadyStateThreshold; +108 this.convergence = convergence; +109 } +110 +111 /** +112 * Set the convergence criterion threshold. +113 * @param convergence criterion threshold below which we do not need +114 * to improve the criterion anymore +115 */ +116 public void setConvergence(final double convergence) { +117 this.convergence = convergence; +118 } +119 +120 /** +121 * Set the steady state detection threshold. +122 * <p> +123 * The problem has converged has reached a steady state if +124 * <code>Math.abs(J<sub>n</sub> - J<sub>n-1</sub>) < +125 * J<sub>n</sub> × convergence</code>, where <code>J<sub>n</sub></code> +126 * and <code>J<sub>n-1</sub></code> are the current and preceding criterion +127 * values (square sum of the weighted residuals of considered measurements). +128 * </p> +129 * @param steadyStateThreshold steady state detection threshold +130 */ +131 public void setSteadyStateThreshold(final double steadyStateThreshold) { +132 this.steadyStateThreshold = steadyStateThreshold; +133 } +134 +135 /** +136 * Solve an estimation problem using a least squares criterion. +137 * +138 * <p>This method set the unbound parameters of the given problem +139 * starting from their current values through several iterations. At +140 * each step, the unbound parameters are changed in order to +141 * minimize a weighted least square criterion based on the +142 * measurements of the problem.</p> +143 * +144 * <p>The iterations are stopped either when the criterion goes +145 * below a physical threshold under which improvement are considered +146 * useless or when the algorithm is unable to improve it (even if it +147 * is still high). The first condition that is met stops the +148 * iterations. If the convergence it not reached before the maximum +149 * number of iterations, an {@link EstimationException} is +150 * thrown.</p> +151 * +152 * @param problem estimation problem to solve +153 * @exception EstimationException if the problem cannot be solved +154 * +155 * @see EstimationProblem +156 * +157 */ +158 @Override +159 public void estimate(EstimationProblem problem) +160 throws EstimationException { +161 +162 initializeEstimate(problem); +163 +164 // work matrices +165 double[] grad = new double[parameters.length]; +166 ArrayRealVector bDecrement = new ArrayRealVector(parameters.length); +167 double[] bDecrementData = bDecrement.getDataRef(); +168 RealMatrix wGradGradT = MatrixUtils.createRealMatrix(parameters.length, parameters.length); +169 +170 // iterate until convergence is reached +171 double previous = Double.POSITIVE_INFINITY; +172 do { +173 +174 // build the linear problem +175 incrementJacobianEvaluationsCounter(); +176 RealVector b = new ArrayRealVector(parameters.length); +177 RealMatrix a = MatrixUtils.createRealMatrix(parameters.length, parameters.length); +178 for (int i = 0; i < measurements.length; ++i) { +179 if (! measurements [i].isIgnored()) { +180 +181 double weight = measurements[i].getWeight(); +182 double residual = measurements[i].getResidual(); +183 +184 // compute the normal equation +185 for (int j = 0; j < parameters.length; ++j) { +186 grad[j] = measurements[i].getPartial(parameters[j]); +187 bDecrementData[j] = weight * residual * grad[j]; +188 } +189 +190 // build the contribution matrix for measurement i +191 for (int k = 0; k < parameters.length; ++k) { +192 double gk = grad[k]; +193 for (int l = 0; l < parameters.length; ++l) { +194 wGradGradT.setEntry(k, l, weight * gk * grad[l]); +195 } +196 } +197 +198 // update the matrices +199 a = a.add(wGradGradT); +200 b = b.add(bDecrement); +201 +202 } +203 } +204 +205 try { +206 +207 // solve the linearized least squares problem +208 RealVector dX = new LUDecompositionImpl(a).getSolver().solve(b); +209 +210 // update the estimated parameters +211 for (int i = 0; i < parameters.length; ++i) { +212 parameters[i].setEstimate(parameters[i].getEstimate() + dX.getEntry(i)); +213 } +214 +215 } catch(InvalidMatrixException e) { +216 throw new EstimationException("unable to solve: singular problem"); +217 } +218 +219 +220 previous = cost; +221 updateResidualsAndCost(); +222 +223 } while ((getCostEvaluations() < 2) || +224 (Math.abs(previous - cost) > (cost * steadyStateThreshold) && +225 (Math.abs(cost) > convergence))); +226 +227 } +228 +229 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/LevenbergMarquardtEstimator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/LevenbergMarquardtEstimator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,960 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.estimation; +018 +019 import java.io.Serializable; +020 import java.util.Arrays; +021 +022 +023 /** +024 * This class solves a least squares problem. +025 * +026 * <p>This implementation <em>should</em> work even for over-determined systems +027 * (i.e. systems having more variables than equations). Over-determined systems +028 * are solved by ignoring the variables which have the smallest impact according +029 * to their jacobian column norm. Only the rank of the matrix and some loop bounds +030 * are changed to implement this.</p> +031 * +032 * <p>The resolution engine is a simple translation of the MINPACK <a +033 * href="http://www.netlib.org/minpack/lmder.f">lmder</a> routine with minor +034 * changes. The changes include the over-determined resolution and the Q.R. +035 * decomposition which has been rewritten following the algorithm described in the +036 * P. Lascaux and R. Theodor book <i>Analyse numérique matricielle +037 * appliquée à l'art de l'ingénieur</i>, Masson 1986.</p> +038 * <p>The authors of the original fortran version are: +039 * <ul> +040 * <li>Argonne National Laboratory. MINPACK project. March 1980</li> +041 * <li>Burton S. Garbow</li> +042 * <li>Kenneth E. Hillstrom</li> +043 * <li>Jorge J. More</li> +044 * </ul> +045 * The redistribution policy for MINPACK is available <a +046 * href="http://www.netlib.org/minpack/disclaimer">here</a>, for convenience, it +047 * is reproduced below.</p> +048 * +049 * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0"> +050 * <tr><td> +051 * Minpack Copyright Notice (1999) University of Chicago. +052 * All rights reserved +053 * </td></tr> +054 * <tr><td> +055 * Redistribution and use in source and binary forms, with or without +056 * modification, are permitted provided that the following conditions +057 * are met: +058 * <ol> +059 * <li>Redistributions of source code must retain the above copyright +060 * notice, this list of conditions and the following disclaimer.</li> +061 * <li>Redistributions in binary form must reproduce the above +062 * copyright notice, this list of conditions and the following +063 * disclaimer in the documentation and/or other materials provided +064 * with the distribution.</li> +065 * <li>The end-user documentation included with the redistribution, if any, +066 * must include the following acknowledgment: +067 * <code>This product includes software developed by the University of +068 * Chicago, as Operator of Argonne National Laboratory.</code> +069 * Alternately, this acknowledgment may appear in the software itself, +070 * if and wherever such third-party acknowledgments normally appear.</li> +071 * <li><strong>WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" +072 * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE +073 * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND +074 * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR +075 * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES +076 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE +077 * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY +078 * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR +079 * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF +080 * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) +081 * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION +082 * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL +083 * BE CORRECTED.</strong></li> +084 * <li><strong>LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT +085 * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF +086 * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, +087 * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF +088 * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF +089 * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER +090 * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT +091 * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, +092 * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE +093 * POSSIBILITY OF SUCH LOSS OR DAMAGES.</strong></li> +094 * <ol></td></tr> +095 * </table> +096 +097 * @version $Revision: 825919 $ $Date: 2009-10-16 10:51:55 -0400 (Fri, 16 Oct 2009) $ +098 * @since 1.2 +099 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has +100 * been deprecated and replaced by package org.apache.commons.math.optimization.general +101 * +102 */ +103 @Deprecated +104 public class LevenbergMarquardtEstimator extends AbstractEstimator implements Serializable { +105 +106 /** Serializable version identifier */ +107 private static final long serialVersionUID = -5705952631533171019L; +108 +109 /** Number of solved variables. */ +110 private int solvedCols; +111 +112 /** Diagonal elements of the R matrix in the Q.R. decomposition. */ +113 private double[] diagR; +114 +115 /** Norms of the columns of the jacobian matrix. */ +116 private double[] jacNorm; +117 +118 /** Coefficients of the Householder transforms vectors. */ +119 private double[] beta; +120 +121 /** Columns permutation array. */ +122 private int[] permutation; +123 +124 /** Rank of the jacobian matrix. */ +125 private int rank; +126 +127 /** Levenberg-Marquardt parameter. */ +128 private double lmPar; +129 +130 /** Parameters evolution direction associated with lmPar. */ +131 private double[] lmDir; +132 +133 /** Positive input variable used in determining the initial step bound. */ +134 private double initialStepBoundFactor; +135 +136 /** Desired relative error in the sum of squares. */ +137 private double costRelativeTolerance; +138 +139 /** Desired relative error in the approximate solution parameters. */ +140 private double parRelativeTolerance; +141 +142 /** Desired max cosine on the orthogonality between the function vector +143 * and the columns of the jacobian. */ +144 private double orthoTolerance; +145 +146 /** +147 * Build an estimator for least squares problems. +148 * <p>The default values for the algorithm settings are: +149 * <ul> +150 * <li>{@link #setInitialStepBoundFactor initial step bound factor}: 100.0</li> +151 * <li>{@link #setMaxCostEval maximal cost evaluations}: 1000</li> +152 * <li>{@link #setCostRelativeTolerance cost relative tolerance}: 1.0e-10</li> +153 * <li>{@link #setParRelativeTolerance parameters relative tolerance}: 1.0e-10</li> +154 * <li>{@link #setOrthoTolerance orthogonality tolerance}: 1.0e-10</li> +155 * </ul> +156 * </p> +157 */ +158 public LevenbergMarquardtEstimator() { +159 +160 // set up the superclass with a default max cost evaluations setting +161 setMaxCostEval(1000); +162 +163 // default values for the tuning parameters +164 setInitialStepBoundFactor(100.0); +165 setCostRelativeTolerance(1.0e-10); +166 setParRelativeTolerance(1.0e-10); +167 setOrthoTolerance(1.0e-10); +168 +169 } +170 +171 /** +172 * Set the positive input variable used in determining the initial step bound. +173 * This bound is set to the product of initialStepBoundFactor and the euclidean norm of diag*x if nonzero, +174 * or else to initialStepBoundFactor itself. In most cases factor should lie +175 * in the interval (0.1, 100.0). 100.0 is a generally recommended value +176 * +177 * @param initialStepBoundFactor initial step bound factor +178 * @see #estimate +179 */ +180 public void setInitialStepBoundFactor(double initialStepBoundFactor) { +181 this.initialStepBoundFactor = initialStepBoundFactor; +182 } +183 +184 /** +185 * Set the desired relative error in the sum of squares. +186 * +187 * @param costRelativeTolerance desired relative error in the sum of squares +188 * @see #estimate +189 */ +190 public void setCostRelativeTolerance(double costRelativeTolerance) { +191 this.costRelativeTolerance = costRelativeTolerance; +192 } +193 +194 /** +195 * Set the desired relative error in the approximate solution parameters. +196 * +197 * @param parRelativeTolerance desired relative error +198 * in the approximate solution parameters +199 * @see #estimate +200 */ +201 public void setParRelativeTolerance(double parRelativeTolerance) { +202 this.parRelativeTolerance = parRelativeTolerance; +203 } +204 +205 /** +206 * Set the desired max cosine on the orthogonality. +207 * +208 * @param orthoTolerance desired max cosine on the orthogonality +209 * between the function vector and the columns of the jacobian +210 * @see #estimate +211 */ +212 public void setOrthoTolerance(double orthoTolerance) { +213 this.orthoTolerance = orthoTolerance; +214 } +215 +216 /** +217 * Solve an estimation problem using the Levenberg-Marquardt algorithm. +218 * <p>The algorithm used is a modified Levenberg-Marquardt one, based +219 * on the MINPACK <a href="http://www.netlib.org/minpack/lmder.f">lmder</a> +220 * routine. The algorithm settings must have been set up before this method +221 * is called with the {@link #setInitialStepBoundFactor}, +222 * {@link #setMaxCostEval}, {@link #setCostRelativeTolerance}, +223 * {@link #setParRelativeTolerance} and {@link #setOrthoTolerance} methods. +224 * If these methods have not been called, the default values set up by the +225 * {@link #LevenbergMarquardtEstimator() constructor} will be used.</p> +226 * <p>The authors of the original fortran function are:</p> +227 * <ul> +228 * <li>Argonne National Laboratory. MINPACK project. March 1980</li> +229 * <li>Burton S. Garbow</li> +230 * <li>Kenneth E. Hillstrom</li> +231 * <li>Jorge J. More</li> +232 * </ul> +233 * <p>Luc Maisonobe did the Java translation.</p> +234 * +235 * @param problem estimation problem to solve +236 * @exception EstimationException if convergence cannot be +237 * reached with the specified algorithm settings or if there are more variables +238 * than equations +239 * @see #setInitialStepBoundFactor +240 * @see #setCostRelativeTolerance +241 * @see #setParRelativeTolerance +242 * @see #setOrthoTolerance +243 */ +244 @Override +245 public void estimate(EstimationProblem problem) +246 throws EstimationException { +247 +248 initializeEstimate(problem); +249 +250 // arrays shared with the other private methods +251 solvedCols = Math.min(rows, cols); +252 diagR = new double[cols]; +253 jacNorm = new double[cols]; +254 beta = new double[cols]; +255 permutation = new int[cols]; +256 lmDir = new double[cols]; +257 +258 // local variables +259 double delta = 0; +260 double xNorm = 0; +261 double[] diag = new double[cols]; +262 double[] oldX = new double[cols]; +263 double[] oldRes = new double[rows]; +264 double[] work1 = new double[cols]; +265 double[] work2 = new double[cols]; +266 double[] work3 = new double[cols]; +267 +268 // evaluate the function at the starting point and calculate its norm +269 updateResidualsAndCost(); +270 +271 // outer loop +272 lmPar = 0; +273 boolean firstIteration = true; +274 while (true) { +275 +276 // compute the Q.R. decomposition of the jacobian matrix +277 updateJacobian(); +278 qrDecomposition(); +279 +280 // compute Qt.res +281 qTy(residuals); +282 +283 // now we don't need Q anymore, +284 // so let jacobian contain the R matrix with its diagonal elements +285 for (int k = 0; k < solvedCols; ++k) { +286 int pk = permutation[k]; +287 jacobian[k * cols + pk] = diagR[pk]; +288 } +289 +290 if (firstIteration) { +291 +292 // scale the variables according to the norms of the columns +293 // of the initial jacobian +294 xNorm = 0; +295 for (int k = 0; k < cols; ++k) { +296 double dk = jacNorm[k]; +297 if (dk == 0) { +298 dk = 1.0; +299 } +300 double xk = dk * parameters[k].getEstimate(); +301 xNorm += xk * xk; +302 diag[k] = dk; +303 } +304 xNorm = Math.sqrt(xNorm); +305 +306 // initialize the step bound delta +307 delta = (xNorm == 0) ? initialStepBoundFactor : (initialStepBoundFactor * xNorm); +308 +309 } +310 +311 // check orthogonality between function vector and jacobian columns +312 double maxCosine = 0; +313 if (cost != 0) { +314 for (int j = 0; j < solvedCols; ++j) { +315 int pj = permutation[j]; +316 double s = jacNorm[pj]; +317 if (s != 0) { +318 double sum = 0; +319 int index = pj; +320 for (int i = 0; i <= j; ++i) { +321 sum += jacobian[index] * residuals[i]; +322 index += cols; +323 } +324 maxCosine = Math.max(maxCosine, Math.abs(sum) / (s * cost)); +325 } +326 } +327 } +328 if (maxCosine <= orthoTolerance) { +329 return; +330 } +331 +332 // rescale if necessary +333 for (int j = 0; j < cols; ++j) { +334 diag[j] = Math.max(diag[j], jacNorm[j]); +335 } +336 +337 // inner loop +338 for (double ratio = 0; ratio < 1.0e-4;) { +339 +340 // save the state +341 for (int j = 0; j < solvedCols; ++j) { +342 int pj = permutation[j]; +343 oldX[pj] = parameters[pj].getEstimate(); +344 } +345 double previousCost = cost; +346 double[] tmpVec = residuals; +347 residuals = oldRes; +348 oldRes = tmpVec; +349 +350 // determine the Levenberg-Marquardt parameter +351 determineLMParameter(oldRes, delta, diag, work1, work2, work3); +352 +353 // compute the new point and the norm of the evolution direction +354 double lmNorm = 0; +355 for (int j = 0; j < solvedCols; ++j) { +356 int pj = permutation[j]; +357 lmDir[pj] = -lmDir[pj]; +358 parameters[pj].setEstimate(oldX[pj] + lmDir[pj]); +359 double s = diag[pj] * lmDir[pj]; +360 lmNorm += s * s; +361 } +362 lmNorm = Math.sqrt(lmNorm); +363 +364 // on the first iteration, adjust the initial step bound. +365 if (firstIteration) { +366 delta = Math.min(delta, lmNorm); +367 } +368 +369 // evaluate the function at x + p and calculate its norm +370 updateResidualsAndCost(); +371 +372 // compute the scaled actual reduction +373 double actRed = -1.0; +374 if (0.1 * cost < previousCost) { +375 double r = cost / previousCost; +376 actRed = 1.0 - r * r; +377 } +378 +379 // compute the scaled predicted reduction +380 // and the scaled directional derivative +381 for (int j = 0; j < solvedCols; ++j) { +382 int pj = permutation[j]; +383 double dirJ = lmDir[pj]; +384 work1[j] = 0; +385 int index = pj; +386 for (int i = 0; i <= j; ++i) { +387 work1[i] += jacobian[index] * dirJ; +388 index += cols; +389 } +390 } +391 double coeff1 = 0; +392 for (int j = 0; j < solvedCols; ++j) { +393 coeff1 += work1[j] * work1[j]; +394 } +395 double pc2 = previousCost * previousCost; +396 coeff1 = coeff1 / pc2; +397 double coeff2 = lmPar * lmNorm * lmNorm / pc2; +398 double preRed = coeff1 + 2 * coeff2; +399 double dirDer = -(coeff1 + coeff2); +400 +401 // ratio of the actual to the predicted reduction +402 ratio = (preRed == 0) ? 0 : (actRed / preRed); +403 +404 // update the step bound +405 if (ratio <= 0.25) { +406 double tmp = +407 (actRed < 0) ? (0.5 * dirDer / (dirDer + 0.5 * actRed)) : 0.5; +408 if ((0.1 * cost >= previousCost) || (tmp < 0.1)) { +409 tmp = 0.1; +410 } +411 delta = tmp * Math.min(delta, 10.0 * lmNorm); +412 lmPar /= tmp; +413 } else if ((lmPar == 0) || (ratio >= 0.75)) { +414 delta = 2 * lmNorm; +415 lmPar *= 0.5; +416 } +417 +418 // test for successful iteration. +419 if (ratio >= 1.0e-4) { +420 // successful iteration, update the norm +421 firstIteration = false; +422 xNorm = 0; +423 for (int k = 0; k < cols; ++k) { +424 double xK = diag[k] * parameters[k].getEstimate(); +425 xNorm += xK * xK; +426 } +427 xNorm = Math.sqrt(xNorm); +428 } else { +429 // failed iteration, reset the previous values +430 cost = previousCost; +431 for (int j = 0; j < solvedCols; ++j) { +432 int pj = permutation[j]; +433 parameters[pj].setEstimate(oldX[pj]); +434 } +435 tmpVec = residuals; +436 residuals = oldRes; +437 oldRes = tmpVec; +438 } +439 +440 // tests for convergence. +441 if (((Math.abs(actRed) <= costRelativeTolerance) && +442 (preRed <= costRelativeTolerance) && +443 (ratio <= 2.0)) || +444 (delta <= parRelativeTolerance * xNorm)) { +445 return; +446 } +447 +448 // tests for termination and stringent tolerances +449 // (2.2204e-16 is the machine epsilon for IEEE754) +450 if ((Math.abs(actRed) <= 2.2204e-16) && (preRed <= 2.2204e-16) && (ratio <= 2.0)) { +451 throw new EstimationException("cost relative tolerance is too small ({0})," + +452 " no further reduction in the" + +453 " sum of squares is possible", +454 costRelativeTolerance); +455 } else if (delta <= 2.2204e-16 * xNorm) { +456 throw new EstimationException("parameters relative tolerance is too small" + +457 " ({0}), no further improvement in" + +458 " the approximate solution is possible", +459 parRelativeTolerance); +460 } else if (maxCosine <= 2.2204e-16) { +461 throw new EstimationException("orthogonality tolerance is too small ({0})," + +462 " solution is orthogonal to the jacobian", +463 orthoTolerance); +464 } +465 +466 } +467 +468 } +469 +470 } +471 +472 /** +473 * Determine the Levenberg-Marquardt parameter. +474 * <p>This implementation is a translation in Java of the MINPACK +475 * <a href="http://www.netlib.org/minpack/lmpar.f">lmpar</a> +476 * routine.</p> +477 * <p>This method sets the lmPar and lmDir attributes.</p> +478 * <p>The authors of the original fortran function are:</p> +479 * <ul> +480 * <li>Argonne National Laboratory. MINPACK project. March 1980</li> +481 * <li>Burton S. Garbow</li> +482 * <li>Kenneth E. Hillstrom</li> +483 * <li>Jorge J. More</li> +484 * </ul> +485 * <p>Luc Maisonobe did the Java translation.</p> +486 * +487 * @param qy array containing qTy +488 * @param delta upper bound on the euclidean norm of diagR * lmDir +489 * @param diag diagonal matrix +490 * @param work1 work array +491 * @param work2 work array +492 * @param work3 work array +493 */ +494 private void determineLMParameter(double[] qy, double delta, double[] diag, +495 double[] work1, double[] work2, double[] work3) { +496 +497 // compute and store in x the gauss-newton direction, if the +498 // jacobian is rank-deficient, obtain a least squares solution +499 for (int j = 0; j < rank; ++j) { +500 lmDir[permutation[j]] = qy[j]; +501 } +502 for (int j = rank; j < cols; ++j) { +503 lmDir[permutation[j]] = 0; +504 } +505 for (int k = rank - 1; k >= 0; --k) { +506 int pk = permutation[k]; +507 double ypk = lmDir[pk] / diagR[pk]; +508 int index = pk; +509 for (int i = 0; i < k; ++i) { +510 lmDir[permutation[i]] -= ypk * jacobian[index]; +511 index += cols; +512 } +513 lmDir[pk] = ypk; +514 } +515 +516 // evaluate the function at the origin, and test +517 // for acceptance of the Gauss-Newton direction +518 double dxNorm = 0; +519 for (int j = 0; j < solvedCols; ++j) { +520 int pj = permutation[j]; +521 double s = diag[pj] * lmDir[pj]; +522 work1[pj] = s; +523 dxNorm += s * s; +524 } +525 dxNorm = Math.sqrt(dxNorm); +526 double fp = dxNorm - delta; +527 if (fp <= 0.1 * delta) { +528 lmPar = 0; +529 return; +530 } +531 +532 // if the jacobian is not rank deficient, the Newton step provides +533 // a lower bound, parl, for the zero of the function, +534 // otherwise set this bound to zero +535 double sum2; +536 double parl = 0; +537 if (rank == solvedCols) { +538 for (int j = 0; j < solvedCols; ++j) { +539 int pj = permutation[j]; +540 work1[pj] *= diag[pj] / dxNorm; +541 } +542 sum2 = 0; +543 for (int j = 0; j < solvedCols; ++j) { +544 int pj = permutation[j]; +545 double sum = 0; +546 int index = pj; +547 for (int i = 0; i < j; ++i) { +548 sum += jacobian[index] * work1[permutation[i]]; +549 index += cols; +550 } +551 double s = (work1[pj] - sum) / diagR[pj]; +552 work1[pj] = s; +553 sum2 += s * s; +554 } +555 parl = fp / (delta * sum2); +556 } +557 +558 // calculate an upper bound, paru, for the zero of the function +559 sum2 = 0; +560 for (int j = 0; j < solvedCols; ++j) { +561 int pj = permutation[j]; +562 double sum = 0; +563 int index = pj; +564 for (int i = 0; i <= j; ++i) { +565 sum += jacobian[index] * qy[i]; +566 index += cols; +567 } +568 sum /= diag[pj]; +569 sum2 += sum * sum; +570 } +571 double gNorm = Math.sqrt(sum2); +572 double paru = gNorm / delta; +573 if (paru == 0) { +574 // 2.2251e-308 is the smallest positive real for IEE754 +575 paru = 2.2251e-308 / Math.min(delta, 0.1); +576 } +577 +578 // if the input par lies outside of the interval (parl,paru), +579 // set par to the closer endpoint +580 lmPar = Math.min(paru, Math.max(lmPar, parl)); +581 if (lmPar == 0) { +582 lmPar = gNorm / dxNorm; +583 } +584 +585 for (int countdown = 10; countdown >= 0; --countdown) { +586 +587 // evaluate the function at the current value of lmPar +588 if (lmPar == 0) { +589 lmPar = Math.max(2.2251e-308, 0.001 * paru); +590 } +591 double sPar = Math.sqrt(lmPar); +592 for (int j = 0; j < solvedCols; ++j) { +593 int pj = permutation[j]; +594 work1[pj] = sPar * diag[pj]; +595 } +596 determineLMDirection(qy, work1, work2, work3); +597 +598 dxNorm = 0; +599 for (int j = 0; j < solvedCols; ++j) { +600 int pj = permutation[j]; +601 double s = diag[pj] * lmDir[pj]; +602 work3[pj] = s; +603 dxNorm += s * s; +604 } +605 dxNorm = Math.sqrt(dxNorm); +606 double previousFP = fp; +607 fp = dxNorm - delta; +608 +609 // if the function is small enough, accept the current value +610 // of lmPar, also test for the exceptional cases where parl is zero +611 if ((Math.abs(fp) <= 0.1 * delta) || +612 ((parl == 0) && (fp <= previousFP) && (previousFP < 0))) { +613 return; +614 } +615 +616 // compute the Newton correction +617 for (int j = 0; j < solvedCols; ++j) { +618 int pj = permutation[j]; +619 work1[pj] = work3[pj] * diag[pj] / dxNorm; +620 } +621 for (int j = 0; j < solvedCols; ++j) { +622 int pj = permutation[j]; +623 work1[pj] /= work2[j]; +624 double tmp = work1[pj]; +625 for (int i = j + 1; i < solvedCols; ++i) { +626 work1[permutation[i]] -= jacobian[i * cols + pj] * tmp; +627 } +628 } +629 sum2 = 0; +630 for (int j = 0; j < solvedCols; ++j) { +631 double s = work1[permutation[j]]; +632 sum2 += s * s; +633 } +634 double correction = fp / (delta * sum2); +635 +636 // depending on the sign of the function, update parl or paru. +637 if (fp > 0) { +638 parl = Math.max(parl, lmPar); +639 } else if (fp < 0) { +640 paru = Math.min(paru, lmPar); +641 } +642 +643 // compute an improved estimate for lmPar +644 lmPar = Math.max(parl, lmPar + correction); +645 +646 } +647 } +648 +649 /** +650 * Solve a*x = b and d*x = 0 in the least squares sense. +651 * <p>This implementation is a translation in Java of the MINPACK +652 * <a href="http://www.netlib.org/minpack/qrsolv.f">qrsolv</a> +653 * routine.</p> +654 * <p>This method sets the lmDir and lmDiag attributes.</p> +655 * <p>The authors of the original fortran function are:</p> +656 * <ul> +657 * <li>Argonne National Laboratory. MINPACK project. March 1980</li> +658 * <li>Burton S. Garbow</li> +659 * <li>Kenneth E. Hillstrom</li> +660 * <li>Jorge J. More</li> +661 * </ul> +662 * <p>Luc Maisonobe did the Java translation.</p> +663 * +664 * @param qy array containing qTy +665 * @param diag diagonal matrix +666 * @param lmDiag diagonal elements associated with lmDir +667 * @param work work array +668 */ +669 private void determineLMDirection(double[] qy, double[] diag, +670 double[] lmDiag, double[] work) { +671 +672 // copy R and Qty to preserve input and initialize s +673 // in particular, save the diagonal elements of R in lmDir +674 for (int j = 0; j < solvedCols; ++j) { +675 int pj = permutation[j]; +676 for (int i = j + 1; i < solvedCols; ++i) { +677 jacobian[i * cols + pj] = jacobian[j * cols + permutation[i]]; +678 } +679 lmDir[j] = diagR[pj]; +680 work[j] = qy[j]; +681 } +682 +683 // eliminate the diagonal matrix d using a Givens rotation +684 for (int j = 0; j < solvedCols; ++j) { +685 +686 // prepare the row of d to be eliminated, locating the +687 // diagonal element using p from the Q.R. factorization +688 int pj = permutation[j]; +689 double dpj = diag[pj]; +690 if (dpj != 0) { +691 Arrays.fill(lmDiag, j + 1, lmDiag.length, 0); +692 } +693 lmDiag[j] = dpj; +694 +695 // the transformations to eliminate the row of d +696 // modify only a single element of Qty +697 // beyond the first n, which is initially zero. +698 double qtbpj = 0; +699 for (int k = j; k < solvedCols; ++k) { +700 int pk = permutation[k]; +701 +702 // determine a Givens rotation which eliminates the +703 // appropriate element in the current row of d +704 if (lmDiag[k] != 0) { +705 +706 final double sin; +707 final double cos; +708 double rkk = jacobian[k * cols + pk]; +709 if (Math.abs(rkk) < Math.abs(lmDiag[k])) { +710 final double cotan = rkk / lmDiag[k]; +711 sin = 1.0 / Math.sqrt(1.0 + cotan * cotan); +712 cos = sin * cotan; +713 } else { +714 final double tan = lmDiag[k] / rkk; +715 cos = 1.0 / Math.sqrt(1.0 + tan * tan); +716 sin = cos * tan; +717 } +718 +719 // compute the modified diagonal element of R and +720 // the modified element of (Qty,0) +721 jacobian[k * cols + pk] = cos * rkk + sin * lmDiag[k]; +722 final double temp = cos * work[k] + sin * qtbpj; +723 qtbpj = -sin * work[k] + cos * qtbpj; +724 work[k] = temp; +725 +726 // accumulate the tranformation in the row of s +727 for (int i = k + 1; i < solvedCols; ++i) { +728 double rik = jacobian[i * cols + pk]; +729 final double temp2 = cos * rik + sin * lmDiag[i]; +730 lmDiag[i] = -sin * rik + cos * lmDiag[i]; +731 jacobian[i * cols + pk] = temp2; +732 } +733 +734 } +735 } +736 +737 // store the diagonal element of s and restore +738 // the corresponding diagonal element of R +739 int index = j * cols + permutation[j]; +740 lmDiag[j] = jacobian[index]; +741 jacobian[index] = lmDir[j]; +742 +743 } +744 +745 // solve the triangular system for z, if the system is +746 // singular, then obtain a least squares solution +747 int nSing = solvedCols; +748 for (int j = 0; j < solvedCols; ++j) { +749 if ((lmDiag[j] == 0) && (nSing == solvedCols)) { +750 nSing = j; +751 } +752 if (nSing < solvedCols) { +753 work[j] = 0; +754 } +755 } +756 if (nSing > 0) { +757 for (int j = nSing - 1; j >= 0; --j) { +758 int pj = permutation[j]; +759 double sum = 0; +760 for (int i = j + 1; i < nSing; ++i) { +761 sum += jacobian[i * cols + pj] * work[i]; +762 } +763 work[j] = (work[j] - sum) / lmDiag[j]; +764 } +765 } +766 +767 // permute the components of z back to components of lmDir +768 for (int j = 0; j < lmDir.length; ++j) { +769 lmDir[permutation[j]] = work[j]; +770 } +771 +772 } +773 +774 /** +775 * Decompose a matrix A as A.P = Q.R using Householder transforms. +776 * <p>As suggested in the P. Lascaux and R. Theodor book +777 * <i>Analyse numérique matricielle appliquée à +778 * l'art de l'ingénieur</i> (Masson, 1986), instead of representing +779 * the Householder transforms with u<sub>k</sub> unit vectors such that: +780 * <pre> +781 * H<sub>k</sub> = I - 2u<sub>k</sub>.u<sub>k</sub><sup>t</sup> +782 * </pre> +783 * we use <sub>k</sub> non-unit vectors such that: +784 * <pre> +785 * H<sub>k</sub> = I - beta<sub>k</sub>v<sub>k</sub>.v<sub>k</sub><sup>t</sup> +786 * </pre> +787 * where v<sub>k</sub> = a<sub>k</sub> - alpha<sub>k</sub> e<sub>k</sub>. +788 * The beta<sub>k</sub> coefficients are provided upon exit as recomputing +789 * them from the v<sub>k</sub> vectors would be costly.</p> +790 * <p>This decomposition handles rank deficient cases since the tranformations +791 * are performed in non-increasing columns norms order thanks to columns +792 * pivoting. The diagonal elements of the R matrix are therefore also in +793 * non-increasing absolute values order.</p> +794 * @exception EstimationException if the decomposition cannot be performed +795 */ +796 private void qrDecomposition() throws EstimationException { +797 +798 // initializations +799 for (int k = 0; k < cols; ++k) { +800 permutation[k] = k; +801 double norm2 = 0; +802 for (int index = k; index < jacobian.length; index += cols) { +803 double akk = jacobian[index]; +804 norm2 += akk * akk; +805 } +806 jacNorm[k] = Math.sqrt(norm2); +807 } +808 +809 // transform the matrix column after column +810 for (int k = 0; k < cols; ++k) { +811 +812 // select the column with the greatest norm on active components +813 int nextColumn = -1; +814 double ak2 = Double.NEGATIVE_INFINITY; +815 for (int i = k; i < cols; ++i) { +816 double norm2 = 0; +817 int iDiag = k * cols + permutation[i]; +818 for (int index = iDiag; index < jacobian.length; index += cols) { +819 double aki = jacobian[index]; +820 norm2 += aki * aki; +821 } +822 if (Double.isInfinite(norm2) || Double.isNaN(norm2)) { +823 throw new EstimationException( +824 "unable to perform Q.R decomposition on the {0}x{1} jacobian matrix", +825 rows, cols); +826 } +827 if (norm2 > ak2) { +828 nextColumn = i; +829 ak2 = norm2; +830 } +831 } +832 if (ak2 == 0) { +833 rank = k; +834 return; +835 } +836 int pk = permutation[nextColumn]; +837 permutation[nextColumn] = permutation[k]; +838 permutation[k] = pk; +839 +840 // choose alpha such that Hk.u = alpha ek +841 int kDiag = k * cols + pk; +842 double akk = jacobian[kDiag]; +843 double alpha = (akk > 0) ? -Math.sqrt(ak2) : Math.sqrt(ak2); +844 double betak = 1.0 / (ak2 - akk * alpha); +845 beta[pk] = betak; +846 +847 // transform the current column +848 diagR[pk] = alpha; +849 jacobian[kDiag] -= alpha; +850 +851 // transform the remaining columns +852 for (int dk = cols - 1 - k; dk > 0; --dk) { +853 int dkp = permutation[k + dk] - pk; +854 double gamma = 0; +855 for (int index = kDiag; index < jacobian.length; index += cols) { +856 gamma += jacobian[index] * jacobian[index + dkp]; +857 } +858 gamma *= betak; +859 for (int index = kDiag; index < jacobian.length; index += cols) { +860 jacobian[index + dkp] -= gamma * jacobian[index]; +861 } +862 } +863 +864 } +865 +866 rank = solvedCols; +867 +868 } +869 +870 /** +871 * Compute the product Qt.y for some Q.R. decomposition. +872 * +873 * @param y vector to multiply (will be overwritten with the result) +874 */ +875 private void qTy(double[] y) { +876 for (int k = 0; k < cols; ++k) { +877 int pk = permutation[k]; +878 int kDiag = k * cols + pk; +879 double gamma = 0; +880 int index = kDiag; +881 for (int i = k; i < rows; ++i) { +882 gamma += jacobian[index] * y[i]; +883 index += cols; +884 } +885 gamma *= beta[pk]; +886 index = kDiag; +887 for (int i = k; i < rows; ++i) { +888 y[i] -= gamma * jacobian[index]; +889 index += cols; +890 } +891 } +892 } +893 +894 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/SimpleEstimationProblem.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/SimpleEstimationProblem.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,177 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.estimation; +019 +020 import java.util.ArrayList; +021 import java.util.List; +022 +023 /** +024 * Simple implementation of the {@link EstimationProblem +025 * EstimationProblem} interface for boilerplate data handling. +026 * <p>This class <em>only</em> handles parameters and measurements +027 * storage and unbound parameters filtering. It does not compute +028 * anything by itself. It should either be used with measurements +029 * implementation that are smart enough to know about the +030 * various parameters in order to compute the partial derivatives +031 * appropriately. Since the problem-specific logic is mainly related to +032 * the various measurements models, the simplest way to use this class +033 * is by extending it and using one internal class extending +034 * {@link WeightedMeasurement WeightedMeasurement} for each measurement +035 * type. The instances of the internal classes would have access to the +036 * various parameters and their current estimate.</p> +037 +038 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +039 * @since 1.2 +040 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has +041 * been deprecated and replaced by package org.apache.commons.math.optimization.general +042 +043 */ +044 @Deprecated +045 public class SimpleEstimationProblem implements EstimationProblem { +046 +047 /** Estimated parameters. */ +048 private final List<EstimatedParameter> parameters; +049 +050 /** Measurements. */ +051 private final List<WeightedMeasurement> measurements; +052 +053 /** +054 * Build an empty instance without parameters nor measurements. +055 */ +056 public SimpleEstimationProblem() { +057 parameters = new ArrayList<EstimatedParameter>(); +058 measurements = new ArrayList<WeightedMeasurement>(); +059 } +060 +061 /** +062 * Get all the parameters of the problem. +063 * @return parameters +064 */ +065 public EstimatedParameter[] getAllParameters() { +066 return parameters.toArray(new EstimatedParameter[parameters.size()]); +067 } +068 +069 /** +070 * Get the unbound parameters of the problem. +071 * @return unbound parameters +072 */ +073 public EstimatedParameter[] getUnboundParameters() { +074 +075 // filter the unbound parameters +076 List<EstimatedParameter> unbound = new ArrayList<EstimatedParameter>(parameters.size()); +077 for (EstimatedParameter p : parameters) { +078 if (! p.isBound()) { +079 unbound.add(p); +080 } +081 } +082 +083 // convert to an array +084 return unbound.toArray(new EstimatedParameter[unbound.size()]); +085 +086 } +087 +088 /** +089 * Get the measurements of an estimation problem. +090 * @return measurements +091 */ +092 public WeightedMeasurement[] getMeasurements() { +093 return measurements.toArray(new WeightedMeasurement[measurements.size()]); +094 } +095 +096 /** Add a parameter to the problem. +097 * @param p parameter to add +098 */ +099 protected void addParameter(EstimatedParameter p) { +100 parameters.add(p); +101 } +102 +103 /** +104 * Add a new measurement to the set. +105 * @param m measurement to add +106 */ +107 protected void addMeasurement(WeightedMeasurement m) { +108 measurements.add(m); +109 } +110 +111 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/WeightedMeasurement.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/WeightedMeasurement.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,238 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.estimation; +019 +020 import java.io.Serializable; +021 +022 /** +023 * This class represents measurements in estimation problems. +024 * +025 * <p>This abstract class implements all the methods needed to handle +026 * measurements in a general way. It defines neither the {@link +027 * #getTheoreticalValue getTheoreticalValue} nor the {@link +028 * #getPartial getPartial} methods, which should be defined by +029 * sub-classes according to the specific problem.</p> +030 * +031 * <p>The {@link #getTheoreticalValue getTheoreticalValue} and {@link +032 * #getPartial getPartial} methods must always use the current +033 * estimate of the parameters set by the solver in the problem. These +034 * parameters can be retrieved through the {@link +035 * EstimationProblem#getAllParameters +036 * EstimationProblem.getAllParameters} method if the measurements are +037 * independent of the problem, or directly if they are implemented as +038 * inner classes of the problem.</p> +039 * +040 * <p>The instances for which the <code>ignored</code> flag is set +041 * through the {@link #setIgnored setIgnored} method are ignored by the +042 * solvers. This can be used to reject wrong measurements at some +043 * steps of the estimation.</p> +044 * +045 * @see EstimationProblem +046 * +047 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +048 * @since 1.2 +049 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has +050 * been deprecated and replaced by package org.apache.commons.math.optimization.general +051 */ +052 +053 @Deprecated +054 public abstract class WeightedMeasurement implements Serializable { +055 +056 /** Serializable version identifier. */ +057 private static final long serialVersionUID = 4360046376796901941L; +058 +059 /** Measurement weight. */ +060 private final double weight; +061 +062 /** Value of the measurements. */ +063 private final double measuredValue; +064 +065 /** Ignore measurement indicator. */ +066 private boolean ignored; +067 +068 /** +069 * Simple constructor. +070 * Build a measurement with the given parameters, and set its ignore +071 * flag to false. +072 * @param weight weight of the measurement in the least squares problem +073 * (two common choices are either to use 1.0 for all measurements, or to +074 * use a value proportional to the inverse of the variance of the measurement +075 * type) +076 * +077 * @param measuredValue measured value +078 */ +079 public WeightedMeasurement(double weight, double measuredValue) { +080 this.weight = weight; +081 this.measuredValue = measuredValue; +082 ignored = false; +083 } +084 +085 /** Simple constructor. +086 * +087 * Build a measurement with the given parameters +088 * +089 * @param weight weight of the measurement in the least squares problem +090 * @param measuredValue measured value +091 * @param ignored true if the measurement should be ignored +092 */ +093 public WeightedMeasurement(double weight, double measuredValue, +094 boolean ignored) { +095 this.weight = weight; +096 this.measuredValue = measuredValue; +097 this.ignored = ignored; +098 } +099 +100 /** +101 * Get the weight of the measurement in the least squares problem +102 * +103 * @return weight +104 */ +105 public double getWeight() { +106 return weight; +107 } +108 +109 /** +110 * Get the measured value +111 * +112 * @return measured value +113 */ +114 public double getMeasuredValue() { +115 return measuredValue; +116 } +117 +118 /** +119 * Get the residual for this measurement +120 * The residual is the measured value minus the theoretical value. +121 * +122 * @return residual +123 */ +124 public double getResidual() { +125 return measuredValue - getTheoreticalValue(); +126 } +127 +128 /** +129 * Get the theoretical value expected for this measurement +130 * <p>The theoretical value is the value expected for this measurement +131 * if the model and its parameter were all perfectly known.</p> +132 * <p>The value must be computed using the current estimate of the parameters +133 * set by the solver in the problem.</p> +134 * +135 * @return theoretical value +136 */ +137 public abstract double getTheoreticalValue(); +138 +139 /** +140 * Get the partial derivative of the {@link #getTheoreticalValue +141 * theoretical value} according to the parameter. +142 * <p>The value must be computed using the current estimate of the parameters +143 * set by the solver in the problem.</p> +144 * +145 * @param parameter parameter against which the partial derivative +146 * should be computed +147 * @return partial derivative of the {@link #getTheoreticalValue +148 * theoretical value} +149 */ +150 public abstract double getPartial(EstimatedParameter parameter); +151 +152 /** +153 * Set the ignore flag to the specified value +154 * Setting the ignore flag to true allow to reject wrong +155 * measurements, which sometimes can be detected only rather late. +156 * +157 * @param ignored value for the ignore flag +158 */ +159 public void setIgnored(boolean ignored) { +160 this.ignored = ignored; +161 } +162 +163 /** +164 * Check if this measurement should be ignored +165 * +166 * @return true if the measurement should be ignored +167 */ +168 public boolean isIgnored() { +169 return ignored; +170 } +171 +172 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/AbstractFormat.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/AbstractFormat.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,279 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.fraction; +019 +020 import java.io.Serializable; +021 import java.text.FieldPosition; +022 import java.text.NumberFormat; +023 import java.text.ParsePosition; +024 import java.util.Locale; +025 +026 import org.apache.commons.math.MathRuntimeException; +027 +028 /** +029 * Common part shared by both {@link FractionFormat} and {@link BigFractionFormat}. +030 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +031 * @since 2.0 +032 */ +033 public abstract class AbstractFormat extends NumberFormat implements Serializable { +034 +035 /** Serializable version identifier. */ +036 private static final long serialVersionUID = -6981118387974191891L; +037 +038 /** The format used for the denominator. */ +039 protected NumberFormat denominatorFormat; +040 +041 /** The format used for the numerator. */ +042 protected NumberFormat numeratorFormat; +043 +044 /** +045 * Create an improper formatting instance with the default number format +046 * for the numerator and denominator. +047 */ +048 protected AbstractFormat() { +049 this(getDefaultNumberFormat()); +050 } +051 +052 /** +053 * Create an improper formatting instance with a custom number format for +054 * both the numerator and denominator. +055 * @param format the custom format for both the numerator and denominator. +056 */ +057 protected AbstractFormat(final NumberFormat format) { +058 this(format, (NumberFormat) format.clone()); +059 } +060 +061 /** +062 * Create an improper formatting instance with a custom number format for +063 * the numerator and a custom number format for the denominator. +064 * @param numeratorFormat the custom format for the numerator. +065 * @param denominatorFormat the custom format for the denominator. +066 */ +067 protected AbstractFormat(final NumberFormat numeratorFormat, +068 final NumberFormat denominatorFormat) { +069 this.numeratorFormat = numeratorFormat; +070 this.denominatorFormat = denominatorFormat; +071 } +072 +073 /** +074 * Create a default number format. The default number format is based on +075 * {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only +076 * customizing is the maximum number of BigFraction digits, which is set to 0. +077 * @return the default number format. +078 */ +079 protected static NumberFormat getDefaultNumberFormat() { +080 return getDefaultNumberFormat(Locale.getDefault()); +081 } +082 +083 /** +084 * Create a default number format. The default number format is based on +085 * {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only +086 * customizing is the maximum number of BigFraction digits, which is set to 0. +087 * @param locale the specific locale used by the format. +088 * @return the default number format specific to the given locale. +089 */ +090 protected static NumberFormat getDefaultNumberFormat(final Locale locale) { +091 final NumberFormat nf = NumberFormat.getNumberInstance(locale); +092 nf.setMaximumFractionDigits(0); +093 nf.setParseIntegerOnly(true); +094 return nf; +095 } +096 +097 /** +098 * Access the denominator format. +099 * @return the denominator format. +100 */ +101 public NumberFormat getDenominatorFormat() { +102 return denominatorFormat; +103 } +104 +105 /** +106 * Access the numerator format. +107 * @return the numerator format. +108 */ +109 public NumberFormat getNumeratorFormat() { +110 return numeratorFormat; +111 } +112 +113 /** +114 * Modify the denominator format. +115 * @param format the new denominator format value. +116 * @throws IllegalArgumentException if <code>format</code> is +117 * <code>null</code>. +118 */ +119 public void setDenominatorFormat(final NumberFormat format) { +120 if (format == null) { +121 throw MathRuntimeException.createIllegalArgumentException( +122 "denominator format can not be null"); +123 } +124 this.denominatorFormat = format; +125 } +126 +127 /** +128 * Modify the numerator format. +129 * @param format the new numerator format value. +130 * @throws IllegalArgumentException if <code>format</code> is +131 * <code>null</code>. +132 */ +133 public void setNumeratorFormat(final NumberFormat format) { +134 if (format == null) { +135 throw MathRuntimeException.createIllegalArgumentException( +136 "numerator format can not be null"); +137 } +138 this.numeratorFormat = format; +139 } +140 +141 /** +142 * Parses <code>source</code> until a non-whitespace character is found. +143 * @param source the string to parse +144 * @param pos input/ouput parsing parameter. On output, <code>pos</code> +145 * holds the index of the next non-whitespace character. +146 */ +147 protected static void parseAndIgnoreWhitespace(final String source, +148 final ParsePosition pos) { +149 parseNextCharacter(source, pos); +150 pos.setIndex(pos.getIndex() - 1); +151 } +152 +153 /** +154 * Parses <code>source</code> until a non-whitespace character is found. +155 * @param source the string to parse +156 * @param pos input/ouput parsing parameter. +157 * @return the first non-whitespace character. +158 */ +159 protected static char parseNextCharacter(final String source, +160 final ParsePosition pos) { +161 int index = pos.getIndex(); +162 final int n = source.length(); +163 char ret = 0; +164 +165 if (index < n) { +166 char c; +167 do { +168 c = source.charAt(index++); +169 } while (Character.isWhitespace(c) && index < n); +170 pos.setIndex(index); +171 +172 if (index < n) { +173 ret = c; +174 } +175 } +176 +177 return ret; +178 } +179 +180 /** +181 * Formats a double value as a fraction and appends the result to a StringBuffer. +182 * +183 * @param value the double value to format +184 * @param buffer StringBuffer to append to +185 * @param position On input: an alignment field, if desired. On output: the +186 * offsets of the alignment field +187 * @return a reference to the appended buffer +188 * @see #format(Object, StringBuffer, FieldPosition) +189 */ +190 @Override +191 public StringBuffer format(final double value, +192 final StringBuffer buffer, final FieldPosition position) { +193 return format(Double.valueOf(value), buffer, position); +194 } +195 +196 +197 /** +198 * Formats a long value as a fraction and appends the result to a StringBuffer. +199 * +200 * @param value the long value to format +201 * @param buffer StringBuffer to append to +202 * @param position On input: an alignment field, if desired. On output: the +203 * offsets of the alignment field +204 * @return a reference to the appended buffer +205 * @see #format(Object, StringBuffer, FieldPosition) +206 */ +207 @Override +208 public StringBuffer format(final long value, +209 final StringBuffer buffer, final FieldPosition position) { +210 return format(Long.valueOf(value), buffer, position); +211 } +212 +213 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/BigFraction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/BigFraction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1201 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.fraction; +018 +019 import java.io.Serializable; +020 import java.math.BigDecimal; +021 import java.math.BigInteger; +022 +023 import org.apache.commons.math.FieldElement; +024 import org.apache.commons.math.MathRuntimeException; +025 import org.apache.commons.math.util.MathUtils; +026 +027 /** +028 * Representation of a rational number without any overflow. This class is +029 * immutable. +030 * +031 * @version $Revision: 906251 $ $Date: 2010-02-03 16:19:54 -0500 (Wed, 03 Feb 2010) $ +032 * @since 2.0 +033 */ +034 public class BigFraction +035 extends Number +036 implements FieldElement<BigFraction>, Comparable<BigFraction>, Serializable { +037 +038 /** A fraction representing "2 / 1". */ +039 public static final BigFraction TWO = new BigFraction(2); +040 +041 /** A fraction representing "1". */ +042 public static final BigFraction ONE = new BigFraction(1); +043 +044 /** A fraction representing "0". */ +045 public static final BigFraction ZERO = new BigFraction(0); +046 +047 /** A fraction representing "-1 / 1". */ +048 public static final BigFraction MINUS_ONE = new BigFraction(-1); +049 +050 /** A fraction representing "4/5". */ +051 public static final BigFraction FOUR_FIFTHS = new BigFraction(4, 5); +052 +053 /** A fraction representing "1/5". */ +054 public static final BigFraction ONE_FIFTH = new BigFraction(1, 5); +055 +056 /** A fraction representing "1/2". */ +057 public static final BigFraction ONE_HALF = new BigFraction(1, 2); +058 +059 /** A fraction representing "1/4". */ +060 public static final BigFraction ONE_QUARTER = new BigFraction(1, 4); +061 +062 /** A fraction representing "1/3". */ +063 public static final BigFraction ONE_THIRD = new BigFraction(1, 3); +064 +065 /** A fraction representing "3/5". */ +066 public static final BigFraction THREE_FIFTHS = new BigFraction(3, 5); +067 +068 /** A fraction representing "3/4". */ +069 public static final BigFraction THREE_QUARTERS = new BigFraction(3, 4); +070 +071 /** A fraction representing "2/5". */ +072 public static final BigFraction TWO_FIFTHS = new BigFraction(2, 5); +073 +074 /** A fraction representing "2/4". */ +075 public static final BigFraction TWO_QUARTERS = new BigFraction(2, 4); +076 +077 /** A fraction representing "2/3". */ +078 public static final BigFraction TWO_THIRDS = new BigFraction(2, 3); +079 +080 /** Serializable version identifier. */ +081 private static final long serialVersionUID = -5630213147331578515L; +082 +083 /** Message for zero denominator. */ +084 private static final String FORBIDDEN_ZERO_DENOMINATOR = +085 "denominator must be different from 0"; +086 +087 /** <code>BigInteger</code> representation of 100. */ +088 private static final BigInteger ONE_HUNDRED_DOUBLE = BigInteger.valueOf(100); +089 +090 /** The numerator. */ +091 private final BigInteger numerator; +092 +093 /** The denominator. */ +094 private final BigInteger denominator; +095 +096 /** +097 * <p> +098 * Create a {@link BigFraction} equivalent to the passed <tt>BigInteger</tt>, ie +099 * "num / 1". +100 * </p> +101 * +102 * @param num +103 * the numerator. +104 */ +105 public BigFraction(final BigInteger num) { +106 this(num, BigInteger.ONE); +107 } +108 +109 /** +110 * <p> +111 * Create a {@link BigFraction} given the numerator and denominator as +112 * <code>BigInteger</code>. The {@link BigFraction} is reduced to lowest terms. +113 * </p> +114 * +115 * @param num +116 * the numerator, must not be <code>null</code>. +117 * @param den +118 * the denominator, must not be <code>null</code>. +119 * @throws ArithmeticException +120 * if the denominator is <code>zero</code>. +121 * @throws NullPointerException +122 * if the numerator or the denominator is <code>zero</code>. +123 */ +124 public BigFraction(BigInteger num, BigInteger den) { +125 if (num == null) { +126 throw MathRuntimeException.createNullPointerException("numerator is null"); +127 } +128 if (den == null) { +129 throw MathRuntimeException.createNullPointerException("denominator is null"); +130 } +131 if (BigInteger.ZERO.equals(den)) { +132 throw MathRuntimeException.createArithmeticException(FORBIDDEN_ZERO_DENOMINATOR); +133 } +134 if (BigInteger.ZERO.equals(num)) { +135 numerator = BigInteger.ZERO; +136 denominator = BigInteger.ONE; +137 } else { +138 +139 // reduce numerator and denominator by greatest common denominator +140 final BigInteger gcd = num.gcd(den); +141 if (BigInteger.ONE.compareTo(gcd) < 0) { +142 num = num.divide(gcd); +143 den = den.divide(gcd); +144 } +145 +146 // move sign to numerator +147 if (BigInteger.ZERO.compareTo(den) > 0) { +148 num = num.negate(); +149 den = den.negate(); +150 } +151 +152 // store the values in the final fields +153 numerator = num; +154 denominator = den; +155 +156 } +157 } +158 +159 /** +160 * Create a fraction given the double value. +161 * <p> +162 * This constructor behaves <em>differently</em> from +163 * {@link #BigFraction(double, double, int)}. It converts the +164 * double value exactly, considering its internal bits representation. +165 * This does work for all values except NaN and infinities and does +166 * not requires any loop or convergence threshold. +167 * </p> +168 * <p> +169 * Since this conversion is exact and since double numbers are sometimes +170 * approximated, the fraction created may seem strange in some cases. For example +171 * calling <code>new BigFraction(1.0 / 3.0)</code> does <em>not</em> create +172 * the fraction 1/3 but the fraction 6004799503160661 / 18014398509481984 +173 * because the double number passed to the constructor is not exactly 1/3 +174 * (this number cannot be stored exactly in IEEE754). +175 * </p> +176 * @see #BigFraction(double, double, int) +177 * @param value the double value to convert to a fraction. +178 * @exception IllegalArgumentException if value is NaN or infinite +179 */ +180 public BigFraction(final double value) throws IllegalArgumentException { +181 if (Double.isNaN(value)) { +182 throw MathRuntimeException.createIllegalArgumentException("cannot convert NaN value"); +183 } +184 if (Double.isInfinite(value)) { +185 throw MathRuntimeException.createIllegalArgumentException("cannot convert infinite value"); +186 } +187 +188 // compute m and k such that value = m * 2^k +189 final long bits = Double.doubleToLongBits(value); +190 final long sign = bits & 0x8000000000000000L; +191 final long exponent = bits & 0x7ff0000000000000L; +192 long m = bits & 0x000fffffffffffffL; +193 if (exponent != 0) { +194 // this was a normalized number, add the implicit most significant bit +195 m |= 0x0010000000000000L; +196 } +197 if (sign != 0) { +198 m = -m; +199 } +200 int k = ((int) (exponent >> 52)) - 1075; +201 while (((m & 0x001ffffffffffffeL) != 0) && ((m & 0x1) == 0)) { +202 m = m >> 1; +203 ++k; +204 } +205 +206 if (k < 0) { +207 numerator = BigInteger.valueOf(m); +208 denominator = BigInteger.ZERO.flipBit(-k); +209 } else { +210 numerator = BigInteger.valueOf(m).multiply(BigInteger.ZERO.flipBit(k)); +211 denominator = BigInteger.ONE; +212 } +213 +214 } +215 +216 /** +217 * Create a fraction given the double value and maximum error allowed. +218 * <p> +219 * References: +220 * <ul> +221 * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html"> +222 * Continued Fraction</a> equations (11) and (22)-(26)</li> +223 * </ul> +224 * </p> +225 * +226 * @param value +227 * the double value to convert to a fraction. +228 * @param epsilon +229 * maximum error allowed. The resulting fraction is within +230 * <code>epsilon</code> of <code>value</code>, in absolute terms. +231 * @param maxIterations +232 * maximum number of convergents. +233 * @throws FractionConversionException +234 * if the continued fraction failed to converge. +235 * @see #BigFraction(double) +236 */ +237 public BigFraction(final double value, final double epsilon, +238 final int maxIterations) +239 throws FractionConversionException { +240 this(value, epsilon, Integer.MAX_VALUE, maxIterations); +241 } +242 +243 /** +244 * Create a fraction given the double value and either the maximum error +245 * allowed or the maximum number of denominator digits. +246 * <p> +247 * +248 * NOTE: This constructor is called with EITHER - a valid epsilon value and +249 * the maxDenominator set to Integer.MAX_VALUE (that way the maxDenominator +250 * has no effect). OR - a valid maxDenominator value and the epsilon value +251 * set to zero (that way epsilon only has effect if there is an exact match +252 * before the maxDenominator value is reached). +253 * </p> +254 * <p> +255 * +256 * It has been done this way so that the same code can be (re)used for both +257 * scenarios. However this could be confusing to users if it were part of +258 * the public API and this constructor should therefore remain PRIVATE. +259 * </p> +260 * +261 * See JIRA issue ticket MATH-181 for more details: +262 * +263 * https://issues.apache.org/jira/browse/MATH-181 +264 * +265 * @param value +266 * the double value to convert to a fraction. +267 * @param epsilon +268 * maximum error allowed. The resulting fraction is within +269 * <code>epsilon</code> of <code>value</code>, in absolute terms. +270 * @param maxDenominator +271 * maximum denominator value allowed. +272 * @param maxIterations +273 * maximum number of convergents. +274 * @throws FractionConversionException +275 * if the continued fraction failed to converge. +276 */ +277 private BigFraction(final double value, final double epsilon, +278 final int maxDenominator, int maxIterations) +279 throws FractionConversionException { +280 long overflow = Integer.MAX_VALUE; +281 double r0 = value; +282 long a0 = (long) Math.floor(r0); +283 if (a0 > overflow) { +284 throw new FractionConversionException(value, a0, 1l); +285 } +286 +287 // check for (almost) integer arguments, which should not go +288 // to iterations. +289 if (Math.abs(a0 - value) < epsilon) { +290 numerator = BigInteger.valueOf(a0); +291 denominator = BigInteger.ONE; +292 return; +293 } +294 +295 long p0 = 1; +296 long q0 = 0; +297 long p1 = a0; +298 long q1 = 1; +299 +300 long p2 = 0; +301 long q2 = 1; +302 +303 int n = 0; +304 boolean stop = false; +305 do { +306 ++n; +307 final double r1 = 1.0 / (r0 - a0); +308 final long a1 = (long) Math.floor(r1); +309 p2 = (a1 * p1) + p0; +310 q2 = (a1 * q1) + q0; +311 if ((p2 > overflow) || (q2 > overflow)) { +312 throw new FractionConversionException(value, p2, q2); +313 } +314 +315 final double convergent = (double) p2 / (double) q2; +316 if ((n < maxIterations) && +317 (Math.abs(convergent - value) > epsilon) && +318 (q2 < maxDenominator)) { +319 p0 = p1; +320 p1 = p2; +321 q0 = q1; +322 q1 = q2; +323 a0 = a1; +324 r0 = r1; +325 } else { +326 stop = true; +327 } +328 } while (!stop); +329 +330 if (n >= maxIterations) { +331 throw new FractionConversionException(value, maxIterations); +332 } +333 +334 if (q2 < maxDenominator) { +335 numerator = BigInteger.valueOf(p2); +336 denominator = BigInteger.valueOf(q2); +337 } else { +338 numerator = BigInteger.valueOf(p1); +339 denominator = BigInteger.valueOf(q1); +340 } +341 } +342 +343 /** +344 * Create a fraction given the double value and maximum denominator. +345 * <p> +346 * References: +347 * <ul> +348 * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html"> +349 * Continued Fraction</a> equations (11) and (22)-(26)</li> +350 * </ul> +351 * </p> +352 * +353 * @param value +354 * the double value to convert to a fraction. +355 * @param maxDenominator +356 * The maximum allowed value for denominator. +357 * @throws FractionConversionException +358 * if the continued fraction failed to converge. +359 */ +360 public BigFraction(final double value, final int maxDenominator) +361 throws FractionConversionException { +362 this(value, 0, maxDenominator, 100); +363 } +364 +365 /** +366 * <p> +367 * Create a {@link BigFraction} equivalent to the passed <tt>int</tt>, ie +368 * "num / 1". +369 * </p> +370 * +371 * @param num +372 * the numerator. +373 */ +374 public BigFraction(final int num) { +375 this(BigInteger.valueOf(num), BigInteger.ONE); +376 } +377 +378 /** +379 * <p> +380 * Create a {@link BigFraction} given the numerator and denominator as simple +381 * <tt>int</tt>. The {@link BigFraction} is reduced to lowest terms. +382 * </p> +383 * +384 * @param num +385 * the numerator. +386 * @param den +387 * the denominator. +388 */ +389 public BigFraction(final int num, final int den) { +390 this(BigInteger.valueOf(num), BigInteger.valueOf(den)); +391 } +392 +393 /** +394 * <p> +395 * Create a {@link BigFraction} equivalent to the passed long, ie "num / 1". +396 * </p> +397 * +398 * @param num +399 * the numerator. +400 */ +401 public BigFraction(final long num) { +402 this(BigInteger.valueOf(num), BigInteger.ONE); +403 } +404 +405 /** +406 * <p> +407 * Create a {@link BigFraction} given the numerator and denominator as simple +408 * <tt>long</tt>. The {@link BigFraction} is reduced to lowest terms. +409 * </p> +410 * +411 * @param num +412 * the numerator. +413 * @param den +414 * the denominator. +415 */ +416 public BigFraction(final long num, final long den) { +417 this(BigInteger.valueOf(num), BigInteger.valueOf(den)); +418 } +419 +420 /** +421 * <p> +422 * Creates a <code>BigFraction</code> instance with the 2 parts of a fraction +423 * Y/Z. +424 * </p> +425 * +426 * <p> +427 * Any negative signs are resolved to be on the numerator. +428 * </p> +429 * +430 * @param numerator +431 * the numerator, for example the three in 'three sevenths'. +432 * @param denominator +433 * the denominator, for example the seven in 'three sevenths'. +434 * @return a new fraction instance, with the numerator and denominator +435 * reduced. +436 * @throws ArithmeticException +437 * if the denominator is <code>zero</code>. +438 */ +439 public static BigFraction getReducedFraction(final int numerator, +440 final int denominator) { +441 if (numerator == 0) { +442 return ZERO; // normalize zero. +443 } +444 +445 return new BigFraction(numerator, denominator); +446 } +447 +448 /** +449 * <p> +450 * Returns the absolute value of this {@link BigFraction}. +451 * </p> +452 * +453 * @return the absolute value as a {@link BigFraction}. +454 */ +455 public BigFraction abs() { +456 return (BigInteger.ZERO.compareTo(numerator) <= 0) ? this : negate(); +457 } +458 +459 /** +460 * <p> +461 * Adds the value of this fraction to the passed {@link BigInteger}, +462 * returning the result in reduced form. +463 * </p> +464 * +465 * @param bg +466 * the {@link BigInteger} to add, must'nt be <code>null</code>. +467 * @return a <code>BigFraction</code> instance with the resulting values. +468 * @throws NullPointerException +469 * if the {@link BigInteger} is <code>null</code>. +470 */ +471 public BigFraction add(final BigInteger bg) { +472 return new BigFraction(numerator.add(denominator.multiply(bg)), denominator); +473 } +474 +475 /** +476 * <p> +477 * Adds the value of this fraction to the passed <tt>integer</tt>, returning +478 * the result in reduced form. +479 * </p> +480 * +481 * @param i +482 * the <tt>integer</tt> to add. +483 * @return a <code>BigFraction</code> instance with the resulting values. +484 */ +485 public BigFraction add(final int i) { +486 return add(BigInteger.valueOf(i)); +487 } +488 +489 /** +490 * <p> +491 * Adds the value of this fraction to the passed <tt>long</tt>, returning +492 * the result in reduced form. +493 * </p> +494 * +495 * @param l +496 * the <tt>long</tt> to add. +497 * @return a <code>BigFraction</code> instance with the resulting values. +498 */ +499 public BigFraction add(final long l) { +500 return add(BigInteger.valueOf(l)); +501 } +502 +503 /** +504 * <p> +505 * Adds the value of this fraction to another, returning the result in +506 * reduced form. +507 * </p> +508 * +509 * @param fraction +510 * the {@link BigFraction} to add, must not be <code>null</code>. +511 * @return a {@link BigFraction} instance with the resulting values. +512 * @throws NullPointerException +513 * if the {@link BigFraction} is <code>null</code>. +514 */ +515 public BigFraction add(final BigFraction fraction) { +516 if (ZERO.equals(fraction)) { +517 return this; +518 } +519 +520 BigInteger num = null; +521 BigInteger den = null; +522 +523 if (denominator.equals(fraction.denominator)) { +524 num = numerator.add(fraction.numerator); +525 den = denominator; +526 } else { +527 num = (numerator.multiply(fraction.denominator)).add((fraction.numerator).multiply(denominator)); +528 den = denominator.multiply(fraction.denominator); +529 } +530 return new BigFraction(num, den); +531 +532 } +533 +534 /** +535 * <p> +536 * Gets the fraction as a <code>BigDecimal</code>. This calculates the +537 * fraction as the numerator divided by denominator. +538 * </p> +539 * +540 * @return the fraction as a <code>BigDecimal</code>. +541 * @throws ArithmeticException +542 * if the exact quotient does not have a terminating decimal +543 * expansion. +544 * @see BigDecimal +545 */ +546 public BigDecimal bigDecimalValue() { +547 return new BigDecimal(numerator).divide(new BigDecimal(denominator)); +548 } +549 +550 /** +551 * <p> +552 * Gets the fraction as a <code>BigDecimal</code> following the passed +553 * rounding mode. This calculates the fraction as the numerator divided by +554 * denominator. +555 * </p> +556 * +557 * @param roundingMode +558 * rounding mode to apply. see {@link BigDecimal} constants. +559 * @return the fraction as a <code>BigDecimal</code>. +560 * @throws IllegalArgumentException +561 * if <tt>roundingMode</tt> does not represent a valid rounding +562 * mode. +563 * @see BigDecimal +564 */ +565 public BigDecimal bigDecimalValue(final int roundingMode) { +566 return new BigDecimal(numerator).divide(new BigDecimal(denominator), roundingMode); +567 } +568 +569 /** +570 * <p> +571 * Gets the fraction as a <code>BigDecimal</code> following the passed scale +572 * and rounding mode. This calculates the fraction as the numerator divided +573 * by denominator. +574 * </p> +575 * +576 * @param scale +577 * scale of the <code>BigDecimal</code> quotient to be returned. +578 * see {@link BigDecimal} for more information. +579 * @param roundingMode +580 * rounding mode to apply. see {@link BigDecimal} constants. +581 * @return the fraction as a <code>BigDecimal</code>. +582 * @see BigDecimal +583 */ +584 public BigDecimal bigDecimalValue(final int scale, final int roundingMode) { +585 return new BigDecimal(numerator).divide(new BigDecimal(denominator), scale, roundingMode); +586 } +587 +588 /** +589 * <p> +590 * Compares this object to another based on size. +591 * </p> +592 * +593 * @param object +594 * the object to compare to, must not be <code>null</code>. +595 * @return -1 if this is less than <tt>object</tt>, +1 if this is greater +596 * than <tt>object</tt>, 0 if they are equal. +597 * @see java.lang.Comparable#compareTo(java.lang.Object) +598 */ +599 public int compareTo(final BigFraction object) { +600 BigInteger nOd = numerator.multiply(object.denominator); +601 BigInteger dOn = denominator.multiply(object.numerator); +602 return nOd.compareTo(dOn); +603 } +604 +605 /** +606 * <p> +607 * Divide the value of this fraction by the passed <code>BigInteger</code>, +608 * ie "this * 1 / bg", returning the result in reduced form. +609 * </p> +610 * +611 * @param bg +612 * the <code>BigInteger</code> to divide by, must not be +613 * <code>null</code>. +614 * @return a {@link BigFraction} instance with the resulting values. +615 * @throws NullPointerException +616 * if the <code>BigInteger</code> is <code>null</code>. +617 * @throws ArithmeticException +618 * if the fraction to divide by is zero. +619 */ +620 public BigFraction divide(final BigInteger bg) { +621 if (BigInteger.ZERO.equals(bg)) { +622 throw MathRuntimeException.createArithmeticException(FORBIDDEN_ZERO_DENOMINATOR); +623 } +624 return new BigFraction(numerator, denominator.multiply(bg)); +625 } +626 +627 /** +628 * <p> +629 * Divide the value of this fraction by the passed <tt>int</tt>, ie +630 * "this * 1 / i", returning the result in reduced form. +631 * </p> +632 * +633 * @param i +634 * the <tt>int</tt> to divide by. +635 * @return a {@link BigFraction} instance with the resulting values. +636 * @throws ArithmeticException +637 * if the fraction to divide by is zero. +638 */ +639 public BigFraction divide(final int i) { +640 return divide(BigInteger.valueOf(i)); +641 } +642 +643 /** +644 * <p> +645 * Divide the value of this fraction by the passed <tt>long</tt>, ie +646 * "this * 1 / l", returning the result in reduced form. +647 * </p> +648 * +649 * @param l +650 * the <tt>long</tt> to divide by. +651 * @return a {@link BigFraction} instance with the resulting values. +652 * @throws ArithmeticException +653 * if the fraction to divide by is zero. +654 */ +655 public BigFraction divide(final long l) { +656 return divide(BigInteger.valueOf(l)); +657 } +658 +659 /** +660 * <p> +661 * Divide the value of this fraction by another, returning the result in +662 * reduced form. +663 * </p> +664 * +665 * @param fraction +666 * the fraction to divide by, must not be <code>null</code>. +667 * @return a {@link BigFraction} instance with the resulting values. +668 * @throws NullPointerException +669 * if the fraction is <code>null</code>. +670 * @throws ArithmeticException +671 * if the fraction to divide by is zero. +672 */ +673 public BigFraction divide(final BigFraction fraction) { +674 if (BigInteger.ZERO.equals(fraction.numerator)) { +675 throw MathRuntimeException.createArithmeticException(FORBIDDEN_ZERO_DENOMINATOR); +676 } +677 +678 return multiply(fraction.reciprocal()); +679 } +680 +681 /** +682 * <p> +683 * Gets the fraction as a <tt>double</tt>. This calculates the fraction as +684 * the numerator divided by denominator. +685 * </p> +686 * +687 * @return the fraction as a <tt>double</tt> +688 * @see java.lang.Number#doubleValue() +689 */ +690 @Override +691 public double doubleValue() { +692 return numerator.doubleValue() / denominator.doubleValue(); +693 } +694 +695 /** +696 * <p> +697 * Test for the equality of two fractions. If the lowest term numerator and +698 * denominators are the same for both fractions, the two fractions are +699 * considered to be equal. +700 * </p> +701 * +702 * @param other +703 * fraction to test for equality to this fraction, can be +704 * <code>null</code>. +705 * @return true if two fractions are equal, false if object is +706 * <code>null</code>, not an instance of {@link BigFraction}, or not +707 * equal to this fraction instance. +708 * @see java.lang.Object#equals(java.lang.Object) +709 */ +710 @Override +711 public boolean equals(final Object other) { +712 boolean ret = false; +713 +714 if (this == other) { +715 ret = true; +716 } else if (other instanceof BigFraction) { +717 BigFraction rhs = ((BigFraction) other).reduce(); +718 BigFraction thisOne = this.reduce(); +719 ret = thisOne.numerator.equals(rhs.numerator) && thisOne.denominator.equals(rhs.denominator); +720 } +721 +722 return ret; +723 } +724 +725 /** +726 * <p> +727 * Gets the fraction as a <tt>float</tt>. This calculates the fraction as +728 * the numerator divided by denominator. +729 * </p> +730 * +731 * @return the fraction as a <tt>float</tt>. +732 * @see java.lang.Number#floatValue() +733 */ +734 @Override +735 public float floatValue() { +736 return numerator.floatValue() / denominator.floatValue(); +737 } +738 +739 /** +740 * <p> +741 * Access the denominator as a <code>BigInteger</code>. +742 * </p> +743 * +744 * @return the denominator as a <code>BigInteger</code>. +745 */ +746 public BigInteger getDenominator() { +747 return denominator; +748 } +749 +750 /** +751 * <p> +752 * Access the denominator as a <tt>int</tt>. +753 * </p> +754 * +755 * @return the denominator as a <tt>int</tt>. +756 */ +757 public int getDenominatorAsInt() { +758 return denominator.intValue(); +759 } +760 +761 /** +762 * <p> +763 * Access the denominator as a <tt>long</tt>. +764 * </p> +765 * +766 * @return the denominator as a <tt>long</tt>. +767 */ +768 public long getDenominatorAsLong() { +769 return denominator.longValue(); +770 } +771 +772 /** +773 * <p> +774 * Access the numerator as a <code>BigInteger</code>. +775 * </p> +776 * +777 * @return the numerator as a <code>BigInteger</code>. +778 */ +779 public BigInteger getNumerator() { +780 return numerator; +781 } +782 +783 /** +784 * <p> +785 * Access the numerator as a <tt>int</tt>. +786 * </p> +787 * +788 * @return the numerator as a <tt>int</tt>. +789 */ +790 public int getNumeratorAsInt() { +791 return numerator.intValue(); +792 } +793 +794 /** +795 * <p> +796 * Access the numerator as a <tt>long</tt>. +797 * </p> +798 * +799 * @return the numerator as a <tt>long</tt>. +800 */ +801 public long getNumeratorAsLong() { +802 return numerator.longValue(); +803 } +804 +805 /** +806 * <p> +807 * Gets a hashCode for the fraction. +808 * </p> +809 * +810 * @return a hash code value for this object. +811 * @see java.lang.Object#hashCode() +812 */ +813 @Override +814 public int hashCode() { +815 return 37 * (37 * 17 + numerator.hashCode()) + denominator.hashCode(); +816 } +817 +818 /** +819 * <p> +820 * Gets the fraction as an <tt>int</tt>. This returns the whole number part +821 * of the fraction. +822 * </p> +823 * +824 * @return the whole number fraction part. +825 * @see java.lang.Number#intValue() +826 */ +827 @Override +828 public int intValue() { +829 return numerator.divide(denominator).intValue(); +830 } +831 +832 /** +833 * <p> +834 * Gets the fraction as a <tt>long</tt>. This returns the whole number part +835 * of the fraction. +836 * </p> +837 * +838 * @return the whole number fraction part. +839 * @see java.lang.Number#longValue() +840 */ +841 @Override +842 public long longValue() { +843 return numerator.divide(denominator).longValue(); +844 } +845 +846 /** +847 * <p> +848 * Multiplies the value of this fraction by the passed +849 * <code>BigInteger</code>, returning the result in reduced form. +850 * </p> +851 * +852 * @param bg +853 * the <code>BigInteger</code> to multiply by. +854 * @return a <code>BigFraction</code> instance with the resulting values. +855 * @throws NullPointerException +856 * if the bg is <code>null</code>. +857 */ +858 public BigFraction multiply(final BigInteger bg) { +859 return new BigFraction(bg.multiply(numerator), denominator); +860 } +861 +862 /** +863 * <p> +864 * Multiply the value of this fraction by the passed <tt>int</tt>, returning +865 * the result in reduced form. +866 * </p> +867 * +868 * @param i +869 * the <tt>int</tt> to multiply by. +870 * @return a {@link BigFraction} instance with the resulting values. +871 */ +872 public BigFraction multiply(final int i) { +873 return multiply(BigInteger.valueOf(i)); +874 } +875 +876 /** +877 * <p> +878 * Multiply the value of this fraction by the passed <tt>long</tt>, +879 * returning the result in reduced form. +880 * </p> +881 * +882 * @param l +883 * the <tt>long</tt> to multiply by. +884 * @return a {@link BigFraction} instance with the resulting values. +885 */ +886 public BigFraction multiply(final long l) { +887 return multiply(BigInteger.valueOf(l)); +888 } +889 +890 /** +891 * <p> +892 * Multiplies the value of this fraction by another, returning the result in +893 * reduced form. +894 * </p> +895 * +896 * @param fraction +897 * the fraction to multiply by, must not be <code>null</code>. +898 * @return a {@link BigFraction} instance with the resulting values. +899 * @throws NullPointerException +900 * if the fraction is <code>null</code>. +901 */ +902 public BigFraction multiply(final BigFraction fraction) { +903 if (numerator.equals(BigInteger.ZERO) || +904 fraction.numerator.equals(BigInteger.ZERO)) { +905 return ZERO; +906 } +907 return new BigFraction(numerator.multiply(fraction.numerator), +908 denominator.multiply(fraction.denominator)); +909 } +910 +911 /** +912 * <p> +913 * Return the additive inverse of this fraction, returning the result in +914 * reduced form. +915 * </p> +916 * +917 * @return the negation of this fraction. +918 */ +919 public BigFraction negate() { +920 return new BigFraction(numerator.negate(), denominator); +921 } +922 +923 /** +924 * <p> +925 * Gets the fraction percentage as a <tt>double</tt>. This calculates the +926 * fraction as the numerator divided by denominator multiplied by 100. +927 * </p> +928 * +929 * @return the fraction percentage as a <tt>double</tt>. +930 */ +931 public double percentageValue() { +932 return (numerator.divide(denominator)).multiply(ONE_HUNDRED_DOUBLE).doubleValue(); +933 } +934 +935 /** +936 * <p> +937 * Returns a <tt>integer</tt> whose value is +938 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form. +939 * </p> +940 * +941 * @param exponent +942 * exponent to which this <code>BigInteger</code> is to be +943 * raised. +944 * @return <tt>this<sup>exponent</sup></tt>. +945 */ +946 public BigFraction pow(final int exponent) { +947 if (exponent < 0) { +948 return new BigFraction(denominator.pow(-exponent), numerator.pow(-exponent)); +949 } +950 return new BigFraction(numerator.pow(exponent), denominator.pow(exponent)); +951 } +952 +953 /** +954 * <p> +955 * Returns a <code>BigFraction</code> whose value is +956 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form. +957 * </p> +958 * +959 * @param exponent +960 * exponent to which this <code>BigFraction</code> is to be raised. +961 * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>. +962 */ +963 public BigFraction pow(final long exponent) { +964 if (exponent < 0) { +965 return new BigFraction(MathUtils.pow(denominator, -exponent), +966 MathUtils.pow(numerator, -exponent)); +967 } +968 return new BigFraction(MathUtils.pow(numerator, exponent), +969 MathUtils.pow(denominator, exponent)); +970 } +971 +972 /** +973 * <p> +974 * Returns a <code>BigFraction</code> whose value is +975 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form. +976 * </p> +977 * +978 * @param exponent +979 * exponent to which this <code>BigFraction</code> is to be raised. +980 * @return <tt>this<sup>exponent</sup></tt> as a <code>BigFraction</code>. +981 */ +982 public BigFraction pow(final BigInteger exponent) { +983 if (exponent.compareTo(BigInteger.ZERO) < 0) { +984 final BigInteger eNeg = exponent.negate(); +985 return new BigFraction(MathUtils.pow(denominator, eNeg), +986 MathUtils.pow(numerator, eNeg)); +987 } +988 return new BigFraction(MathUtils.pow(numerator, exponent), +989 MathUtils.pow(denominator, exponent)); +990 } +991 +992 /** +993 * <p> +994 * Returns a <code>double</code> whose value is +995 * <tt>(this<sup>exponent</sup>)</tt>, returning the result in reduced form. +996 * </p> +997 * +998 * @param exponent +999 * exponent to which this <code>BigFraction</code> is to be raised. +1000 * @return <tt>this<sup>exponent</sup></tt>. +1001 */ +1002 public double pow(final double exponent) { +1003 return Math.pow(numerator.doubleValue(), exponent) / +1004 Math.pow(denominator.doubleValue(), exponent); +1005 } +1006 +1007 /** +1008 * <p> +1009 * Return the multiplicative inverse of this fraction. +1010 * </p> +1011 * +1012 * @return the reciprocal fraction. +1013 */ +1014 public BigFraction reciprocal() { +1015 return new BigFraction(denominator, numerator); +1016 } +1017 +1018 /** +1019 * <p> +1020 * Reduce this <code>BigFraction</code> to its lowest terms. +1021 * </p> +1022 * +1023 * @return the reduced <code>BigFraction</code>. It doesn't change anything if +1024 * the fraction can be reduced. +1025 */ +1026 public BigFraction reduce() { +1027 final BigInteger gcd = numerator.gcd(denominator); +1028 return new BigFraction(numerator.divide(gcd), denominator.divide(gcd)); +1029 } +1030 +1031 /** +1032 * <p> +1033 * Subtracts the value of an {@link BigInteger} from the value of this one, +1034 * returning the result in reduced form. +1035 * </p> +1036 * +1037 * @param bg +1038 * the {@link BigInteger} to subtract, must'nt be +1039 * <code>null</code>. +1040 * @return a <code>BigFraction</code> instance with the resulting values. +1041 * @throws NullPointerException +1042 * if the {@link BigInteger} is <code>null</code>. +1043 */ +1044 public BigFraction subtract(final BigInteger bg) { +1045 return new BigFraction(numerator.subtract(denominator.multiply(bg)), denominator); +1046 } +1047 +1048 /** +1049 * <p> +1050 * Subtracts the value of an <tt>integer</tt> from the value of this one, +1051 * returning the result in reduced form. +1052 * </p> +1053 * +1054 * @param i +1055 * the <tt>integer</tt> to subtract. +1056 * @return a <code>BigFraction</code> instance with the resulting values. +1057 */ +1058 public BigFraction subtract(final int i) { +1059 return subtract(BigInteger.valueOf(i)); +1060 } +1061 +1062 /** +1063 * <p> +1064 * Subtracts the value of an <tt>integer</tt> from the value of this one, +1065 * returning the result in reduced form. +1066 * </p> +1067 * +1068 * @param l +1069 * the <tt>long</tt> to subtract. +1070 * @return a <code>BigFraction</code> instance with the resulting values, or +1071 * this object if the <tt>long</tt> is zero. +1072 */ +1073 public BigFraction subtract(final long l) { +1074 return subtract(BigInteger.valueOf(l)); +1075 } +1076 +1077 /** +1078 * <p> +1079 * Subtracts the value of another fraction from the value of this one, +1080 * returning the result in reduced form. +1081 * </p> +1082 * +1083 * @param fraction +1084 * the {@link BigFraction} to subtract, must not be +1085 * <code>null</code>. +1086 * @return a {@link BigFraction} instance with the resulting values +1087 * @throws NullPointerException +1088 * if the fraction is <code>null</code>. +1089 */ +1090 public BigFraction subtract(final BigFraction fraction) { +1091 if (ZERO.equals(fraction)) { +1092 return this; +1093 } +1094 +1095 BigInteger num = null; +1096 BigInteger den = null; +1097 if (denominator.equals(fraction.denominator)) { +1098 num = numerator.subtract(fraction.numerator); +1099 den = denominator; +1100 } else { +1101 num = (numerator.multiply(fraction.denominator)).subtract((fraction.numerator).multiply(denominator)); +1102 den = denominator.multiply(fraction.denominator); +1103 } +1104 return new BigFraction(num, den); +1105 +1106 } +1107 +1108 /** +1109 * <p> +1110 * Returns the <code>String</code> representing this fraction, ie +1111 * "num / dem" or just "num" if the denominator is one. +1112 * </p> +1113 * +1114 * @return a string representation of the fraction. +1115 * @see java.lang.Object#toString() +1116 */ +1117 @Override +1118 public String toString() { +1119 String str = null; +1120 if (BigInteger.ONE.equals(denominator)) { +1121 str = numerator.toString(); +1122 } else if (BigInteger.ZERO.equals(numerator)) { +1123 str = "0"; +1124 } else { +1125 str = numerator + " / " + denominator; +1126 } +1127 return str; +1128 } +1129 +1130 /** {@inheritDoc} */ +1131 public BigFractionField getField() { +1132 return BigFractionField.getInstance(); +1133 } +1134 +1135 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/BigFractionField.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/BigFractionField.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,144 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.fraction; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.Field; +023 +024 /** +025 * Representation of the fractional numbers without any overflow field. +026 * <p> +027 * This class is a singleton. +028 * </p> +029 * @see Fraction +030 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +031 * @since 2.0 +032 */ +033 public class BigFractionField implements Field<BigFraction>, Serializable { +034 +035 /** Serializable version identifier */ +036 private static final long serialVersionUID = -1699294557189741703L; +037 +038 /** Private constructor for the singleton. +039 */ +040 private BigFractionField() { +041 } +042 +043 /** Get the unique instance. +044 * @return the unique instance +045 */ +046 public static BigFractionField getInstance() { +047 return LazyHolder.INSTANCE; +048 } +049 +050 /** {@inheritDoc} */ +051 public BigFraction getOne() { +052 return BigFraction.ONE; +053 } +054 +055 /** {@inheritDoc} */ +056 public BigFraction getZero() { +057 return BigFraction.ZERO; +058 } +059 +060 // CHECKSTYLE: stop HideUtilityClassConstructor +061 /** Holder for the instance. +062 * <p>We use here the Initialization On Demand Holder Idiom.</p> +063 */ +064 private static class LazyHolder { +065 /** Cached field instance. */ +066 private static final BigFractionField INSTANCE = new BigFractionField(); +067 } +068 // CHECKSTYLE: resume HideUtilityClassConstructor +069 +070 /** Handle deserialization of the singleton. +071 * @return the singleton instance +072 */ +073 private Object readResolve() { +074 // return the singleton instance +075 return LazyHolder.INSTANCE; +076 } +077 +078 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/BigFractionFormat.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/BigFractionFormat.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,356 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.fraction; +019 +020 import java.io.Serializable; +021 import java.math.BigInteger; +022 import java.text.FieldPosition; +023 import java.text.NumberFormat; +024 import java.text.ParseException; +025 import java.text.ParsePosition; +026 import java.util.Locale; +027 +028 import org.apache.commons.math.MathRuntimeException; +029 +030 /** +031 * Formats a BigFraction number in proper format or improper format. +032 * <p> +033 * The number format for each of the whole number, numerator and, +034 * denominator can be configured. +035 * </p> +036 * +037 * @since 2.0 +038 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +039 */ +040 public class BigFractionFormat extends AbstractFormat implements Serializable { +041 +042 /** Serializable version identifier */ +043 private static final long serialVersionUID = -2932167925527338976L; +044 +045 /** +046 * Create an improper formatting instance with the default number format +047 * for the numerator and denominator. +048 */ +049 public BigFractionFormat() { +050 } +051 +052 /** +053 * Create an improper formatting instance with a custom number format for +054 * both the numerator and denominator. +055 * @param format the custom format for both the numerator and denominator. +056 */ +057 public BigFractionFormat(final NumberFormat format) { +058 super(format); +059 } +060 +061 /** +062 * Create an improper formatting instance with a custom number format for +063 * the numerator and a custom number format for the denominator. +064 * @param numeratorFormat the custom format for the numerator. +065 * @param denominatorFormat the custom format for the denominator. +066 */ +067 public BigFractionFormat(final NumberFormat numeratorFormat, +068 final NumberFormat denominatorFormat) { +069 super(numeratorFormat, denominatorFormat); +070 } +071 +072 /** +073 * Get the set of locales for which complex formats are available. This +074 * is the same set as the {@link NumberFormat} set. +075 * @return available complex format locales. +076 */ +077 public static Locale[] getAvailableLocales() { +078 return NumberFormat.getAvailableLocales(); +079 } +080 +081 /** +082 * This static method calls formatBigFraction() on a default instance of +083 * BigFractionFormat. +084 * +085 * @param f BigFraction object to format +086 * @return A formatted BigFraction in proper form. +087 */ +088 public static String formatBigFraction(final BigFraction f) { +089 return getImproperInstance().format(f); +090 } +091 +092 /** +093 * Returns the default complex format for the current locale. +094 * @return the default complex format. +095 */ +096 public static BigFractionFormat getImproperInstance() { +097 return getImproperInstance(Locale.getDefault()); +098 } +099 +100 /** +101 * Returns the default complex format for the given locale. +102 * @param locale the specific locale used by the format. +103 * @return the complex format specific to the given locale. +104 */ +105 public static BigFractionFormat getImproperInstance(final Locale locale) { +106 return new BigFractionFormat(getDefaultNumberFormat(locale)); +107 } +108 +109 /** +110 * Returns the default complex format for the current locale. +111 * @return the default complex format. +112 */ +113 public static BigFractionFormat getProperInstance() { +114 return getProperInstance(Locale.getDefault()); +115 } +116 +117 /** +118 * Returns the default complex format for the given locale. +119 * @param locale the specific locale used by the format. +120 * @return the complex format specific to the given locale. +121 */ +122 public static BigFractionFormat getProperInstance(final Locale locale) { +123 return new ProperBigFractionFormat(getDefaultNumberFormat(locale)); +124 } +125 +126 /** +127 * Formats a {@link BigFraction} object to produce a string. The BigFraction is +128 * output in improper format. +129 * +130 * @param BigFraction the object to format. +131 * @param toAppendTo where the text is to be appended +132 * @param pos On input: an alignment field, if desired. On output: the +133 * offsets of the alignment field +134 * @return the value passed in as toAppendTo. +135 */ +136 public StringBuffer format(final BigFraction BigFraction, +137 final StringBuffer toAppendTo, final FieldPosition pos) { +138 +139 pos.setBeginIndex(0); +140 pos.setEndIndex(0); +141 +142 getNumeratorFormat().format(BigFraction.getNumerator(), toAppendTo, pos); +143 toAppendTo.append(" / "); +144 getDenominatorFormat().format(BigFraction.getDenominator(), toAppendTo, pos); +145 +146 return toAppendTo; +147 } +148 +149 /** +150 * Formats an object and appends the result to a StringBuffer. +151 * <code>obj</code> must be either a {@link BigFraction} object or a +152 * {@link BigInteger} object or a {@link Number} object. Any other type of +153 * object will result in an {@link IllegalArgumentException} being thrown. +154 * +155 * @param obj the object to format. +156 * @param toAppendTo where the text is to be appended +157 * @param pos On input: an alignment field, if desired. On output: the +158 * offsets of the alignment field +159 * @return the value passed in as toAppendTo. +160 * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) +161 * @throws IllegalArgumentException is <code>obj</code> is not a valid type. +162 */ +163 @Override +164 public StringBuffer format(final Object obj, +165 final StringBuffer toAppendTo, final FieldPosition pos) { +166 +167 final StringBuffer ret; +168 if (obj instanceof BigFraction) { +169 ret = format((BigFraction) obj, toAppendTo, pos); +170 } else if (obj instanceof BigInteger) { +171 ret = format(new BigFraction((BigInteger) obj), toAppendTo, pos); +172 } else if (obj instanceof Number) { +173 ret = format(new BigFraction(((Number) obj).doubleValue()), +174 toAppendTo, pos); +175 } else { +176 throw MathRuntimeException.createIllegalArgumentException( +177 "cannot format given object as a fraction number"); +178 } +179 +180 return ret; +181 } +182 +183 /** +184 * Parses a string to produce a {@link BigFraction} object. +185 * @param source the string to parse +186 * @return the parsed {@link BigFraction} object. +187 * @exception ParseException if the beginning of the specified string +188 * cannot be parsed. +189 */ +190 @Override +191 public BigFraction parse(final String source) throws ParseException { +192 final ParsePosition parsePosition = new ParsePosition(0); +193 final BigFraction result = parse(source, parsePosition); +194 if (parsePosition.getIndex() == 0) { +195 throw MathRuntimeException.createParseException( +196 parsePosition.getErrorIndex(), +197 "unparseable fraction number: \"{0}\"", source); +198 } +199 return result; +200 } +201 +202 /** +203 * Parses a string to produce a {@link BigFraction} object. +204 * This method expects the string to be formatted as an improper BigFraction. +205 * @param source the string to parse +206 * @param pos input/ouput parsing parameter. +207 * @return the parsed {@link BigFraction} object. +208 */ +209 @Override +210 public BigFraction parse(final String source, final ParsePosition pos) { +211 final int initialIndex = pos.getIndex(); +212 +213 // parse whitespace +214 parseAndIgnoreWhitespace(source, pos); +215 +216 // parse numerator +217 final BigInteger num = parseNextBigInteger(source, pos); +218 if (num == null) { +219 // invalid integer number +220 // set index back to initial, error index should already be set +221 // character examined. +222 pos.setIndex(initialIndex); +223 return null; +224 } +225 +226 // parse '/' +227 final int startIndex = pos.getIndex(); +228 final char c = parseNextCharacter(source, pos); +229 switch (c) { +230 case 0 : +231 // no '/' +232 // return num as a BigFraction +233 return new BigFraction(num); +234 case '/' : +235 // found '/', continue parsing denominator +236 break; +237 default : +238 // invalid '/' +239 // set index back to initial, error index should be the last +240 // character examined. +241 pos.setIndex(initialIndex); +242 pos.setErrorIndex(startIndex); +243 return null; +244 } +245 +246 // parse whitespace +247 parseAndIgnoreWhitespace(source, pos); +248 +249 // parse denominator +250 final BigInteger den = parseNextBigInteger(source, pos); +251 if (den == null) { +252 // invalid integer number +253 // set index back to initial, error index should already be set +254 // character examined. +255 pos.setIndex(initialIndex); +256 return null; +257 } +258 +259 return new BigFraction(num, den); +260 } +261 +262 /** +263 * Parses a string to produce a <code>BigInteger</code>. +264 * @param source the string to parse +265 * @param pos input/ouput parsing parameter. +266 * @return a parsed <code>BigInteger</code> or null if string does not +267 * contain a BigInteger at the specified position +268 */ +269 protected BigInteger parseNextBigInteger(final String source, +270 final ParsePosition pos) { +271 +272 final int start = pos.getIndex(); +273 int end = (source.charAt(start) == '-') ? (start + 1) : start; +274 while((end < source.length()) && +275 Character.isDigit(source.charAt(end))) { +276 ++end; +277 } +278 +279 try { +280 BigInteger n = new BigInteger(source.substring(start, end)); +281 pos.setIndex(end); +282 return n; +283 } catch (NumberFormatException nfe) { +284 pos.setErrorIndex(start); +285 return null; +286 } +287 +288 } +289 +290 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/Fraction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/Fraction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,730 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.fraction; +018 +019 import java.io.Serializable; +020 import java.math.BigInteger; +021 +022 import org.apache.commons.math.FieldElement; +023 import org.apache.commons.math.MathRuntimeException; +024 import org.apache.commons.math.util.MathUtils; +025 +026 /** +027 * Representation of a rational number. +028 * +029 * implements Serializable since 2.0 +030 * +031 * @since 1.1 +032 * @version $Revision: 922715 $ $Date: 2010-03-13 20:38:14 -0500 (Sat, 13 Mar 2010) $ +033 */ +034 public class Fraction +035 extends Number +036 implements FieldElement<Fraction>, Comparable<Fraction>, Serializable { +037 +038 /** A fraction representing "2 / 1". */ +039 public static final Fraction TWO = new Fraction(2, 1); +040 +041 /** A fraction representing "1". */ +042 public static final Fraction ONE = new Fraction(1, 1); +043 +044 /** A fraction representing "0". */ +045 public static final Fraction ZERO = new Fraction(0, 1); +046 +047 /** A fraction representing "4/5". */ +048 public static final Fraction FOUR_FIFTHS = new Fraction(4, 5); +049 +050 /** A fraction representing "1/5". */ +051 public static final Fraction ONE_FIFTH = new Fraction(1, 5); +052 +053 /** A fraction representing "1/2". */ +054 public static final Fraction ONE_HALF = new Fraction(1, 2); +055 +056 /** A fraction representing "1/4". */ +057 public static final Fraction ONE_QUARTER = new Fraction(1, 4); +058 +059 /** A fraction representing "1/3". */ +060 public static final Fraction ONE_THIRD = new Fraction(1, 3); +061 +062 /** A fraction representing "3/5". */ +063 public static final Fraction THREE_FIFTHS = new Fraction(3, 5); +064 +065 /** A fraction representing "3/4". */ +066 public static final Fraction THREE_QUARTERS = new Fraction(3, 4); +067 +068 /** A fraction representing "2/5". */ +069 public static final Fraction TWO_FIFTHS = new Fraction(2, 5); +070 +071 /** A fraction representing "2/4". */ +072 public static final Fraction TWO_QUARTERS = new Fraction(2, 4); +073 +074 /** A fraction representing "2/3". */ +075 public static final Fraction TWO_THIRDS = new Fraction(2, 3); +076 +077 /** A fraction representing "-1 / 1". */ +078 public static final Fraction MINUS_ONE = new Fraction(-1, 1); +079 +080 /** Message for zero denominator. */ +081 private static final String ZERO_DENOMINATOR_MESSAGE = +082 "zero denominator in fraction {0}/{1}"; +083 +084 /** Message for overflow. */ +085 private static final String OVERFLOW_MESSAGE = +086 "overflow in fraction {0}/{1}, cannot negate"; +087 +088 /** Message for null fraction. */ +089 private static final String NULL_FRACTION = +090 "null fraction"; +091 +092 /** Serializable version identifier */ +093 private static final long serialVersionUID = 3698073679419233275L; +094 +095 /** The denominator. */ +096 private final int denominator; +097 +098 /** The numerator. */ +099 private final int numerator; +100 +101 /** +102 * Create a fraction given the double value. +103 * @param value the double value to convert to a fraction. +104 * @throws FractionConversionException if the continued fraction failed to +105 * converge. +106 */ +107 public Fraction(double value) throws FractionConversionException { +108 this(value, 1.0e-5, 100); +109 } +110 +111 /** +112 * Create a fraction given the double value and maximum error allowed. +113 * <p> +114 * References: +115 * <ul> +116 * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html"> +117 * Continued Fraction</a> equations (11) and (22)-(26)</li> +118 * </ul> +119 * </p> +120 * @param value the double value to convert to a fraction. +121 * @param epsilon maximum error allowed. The resulting fraction is within +122 * <code>epsilon</code> of <code>value</code>, in absolute terms. +123 * @param maxIterations maximum number of convergents +124 * @throws FractionConversionException if the continued fraction failed to +125 * converge. +126 */ +127 public Fraction(double value, double epsilon, int maxIterations) +128 throws FractionConversionException +129 { +130 this(value, epsilon, Integer.MAX_VALUE, maxIterations); +131 } +132 +133 /** +134 * Create a fraction given the double value and maximum denominator. +135 * <p> +136 * References: +137 * <ul> +138 * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html"> +139 * Continued Fraction</a> equations (11) and (22)-(26)</li> +140 * </ul> +141 * </p> +142 * @param value the double value to convert to a fraction. +143 * @param maxDenominator The maximum allowed value for denominator +144 * @throws FractionConversionException if the continued fraction failed to +145 * converge +146 */ +147 public Fraction(double value, int maxDenominator) +148 throws FractionConversionException +149 { +150 this(value, 0, maxDenominator, 100); +151 } +152 +153 /** +154 * Create a fraction given the double value and either the maximum error +155 * allowed or the maximum number of denominator digits. +156 * <p> +157 * +158 * NOTE: This constructor is called with EITHER +159 * - a valid epsilon value and the maxDenominator set to Integer.MAX_VALUE +160 * (that way the maxDenominator has no effect). +161 * OR +162 * - a valid maxDenominator value and the epsilon value set to zero +163 * (that way epsilon only has effect if there is an exact match before +164 * the maxDenominator value is reached). +165 * </p><p> +166 * +167 * It has been done this way so that the same code can be (re)used for both +168 * scenarios. However this could be confusing to users if it were part of +169 * the public API and this constructor should therefore remain PRIVATE. +170 * </p> +171 * +172 * See JIRA issue ticket MATH-181 for more details: +173 * +174 * https://issues.apache.org/jira/browse/MATH-181 +175 * +176 * @param value the double value to convert to a fraction. +177 * @param epsilon maximum error allowed. The resulting fraction is within +178 * <code>epsilon</code> of <code>value</code>, in absolute terms. +179 * @param maxDenominator maximum denominator value allowed. +180 * @param maxIterations maximum number of convergents +181 * @throws FractionConversionException if the continued fraction failed to +182 * converge. +183 */ +184 private Fraction(double value, double epsilon, int maxDenominator, int maxIterations) +185 throws FractionConversionException +186 { +187 long overflow = Integer.MAX_VALUE; +188 double r0 = value; +189 long a0 = (long)Math.floor(r0); +190 if (a0 > overflow) { +191 throw new FractionConversionException(value, a0, 1l); +192 } +193 +194 // check for (almost) integer arguments, which should not go +195 // to iterations. +196 if (Math.abs(a0 - value) < epsilon) { +197 this.numerator = (int) a0; +198 this.denominator = 1; +199 return; +200 } +201 +202 long p0 = 1; +203 long q0 = 0; +204 long p1 = a0; +205 long q1 = 1; +206 +207 long p2 = 0; +208 long q2 = 1; +209 +210 int n = 0; +211 boolean stop = false; +212 do { +213 ++n; +214 double r1 = 1.0 / (r0 - a0); +215 long a1 = (long)Math.floor(r1); +216 p2 = (a1 * p1) + p0; +217 q2 = (a1 * q1) + q0; +218 if ((p2 > overflow) || (q2 > overflow)) { +219 throw new FractionConversionException(value, p2, q2); +220 } +221 +222 double convergent = (double)p2 / (double)q2; +223 if (n < maxIterations && Math.abs(convergent - value) > epsilon && q2 < maxDenominator) { +224 p0 = p1; +225 p1 = p2; +226 q0 = q1; +227 q1 = q2; +228 a0 = a1; +229 r0 = r1; +230 } else { +231 stop = true; +232 } +233 } while (!stop); +234 +235 if (n >= maxIterations) { +236 throw new FractionConversionException(value, maxIterations); +237 } +238 +239 if (q2 < maxDenominator) { +240 this.numerator = (int) p2; +241 this.denominator = (int) q2; +242 } else { +243 this.numerator = (int) p1; +244 this.denominator = (int) q1; +245 } +246 +247 } +248 +249 /** +250 * Create a fraction from an int. +251 * The fraction is num / 1. +252 * @param num the numerator. +253 */ +254 public Fraction(int num) { +255 this(num, 1); +256 } +257 +258 /** +259 * Create a fraction given the numerator and denominator. The fraction is +260 * reduced to lowest terms. +261 * @param num the numerator. +262 * @param den the denominator. +263 * @throws ArithmeticException if the denominator is <code>zero</code> +264 */ +265 public Fraction(int num, int den) { +266 if (den == 0) { +267 throw MathRuntimeException.createArithmeticException( +268 ZERO_DENOMINATOR_MESSAGE, num, den); +269 } +270 if (den < 0) { +271 if (num == Integer.MIN_VALUE || den == Integer.MIN_VALUE) { +272 throw MathRuntimeException.createArithmeticException( +273 OVERFLOW_MESSAGE, num, den); +274 } +275 num = -num; +276 den = -den; +277 } +278 // reduce numerator and denominator by greatest common denominator. +279 final int d = MathUtils.gcd(num, den); +280 if (d > 1) { +281 num /= d; +282 den /= d; +283 } +284 +285 // move sign to numerator. +286 if (den < 0) { +287 num = -num; +288 den = -den; +289 } +290 this.numerator = num; +291 this.denominator = den; +292 } +293 +294 /** +295 * Returns the absolute value of this fraction. +296 * @return the absolute value. +297 */ +298 public Fraction abs() { +299 Fraction ret; +300 if (numerator >= 0) { +301 ret = this; +302 } else { +303 ret = negate(); +304 } +305 return ret; +306 } +307 +308 /** +309 * Compares this object to another based on size. +310 * @param object the object to compare to +311 * @return -1 if this is less than <tt>object</tt>, +1 if this is greater +312 * than <tt>object</tt>, 0 if they are equal. +313 */ +314 public int compareTo(Fraction object) { +315 long nOd = ((long) numerator) * object.denominator; +316 long dOn = ((long) denominator) * object.numerator; +317 return (nOd < dOn) ? -1 : ((nOd > dOn) ? +1 : 0); +318 } +319 +320 /** +321 * Gets the fraction as a <tt>double</tt>. This calculates the fraction as +322 * the numerator divided by denominator. +323 * @return the fraction as a <tt>double</tt> +324 */ +325 @Override +326 public double doubleValue() { +327 return (double)numerator / (double)denominator; +328 } +329 +330 /** +331 * Test for the equality of two fractions. If the lowest term +332 * numerator and denominators are the same for both fractions, the two +333 * fractions are considered to be equal. +334 * @param other fraction to test for equality to this fraction +335 * @return true if two fractions are equal, false if object is +336 * <tt>null</tt>, not an instance of {@link Fraction}, or not equal +337 * to this fraction instance. +338 */ +339 @Override +340 public boolean equals(Object other) { +341 if (this == other) { +342 return true; +343 } +344 if (other instanceof Fraction) { +345 // since fractions are always in lowest terms, numerators and +346 // denominators can be compared directly for equality. +347 Fraction rhs = (Fraction)other; +348 return (numerator == rhs.numerator) && +349 (denominator == rhs.denominator); +350 } +351 return false; +352 } +353 +354 /** +355 * Gets the fraction as a <tt>float</tt>. This calculates the fraction as +356 * the numerator divided by denominator. +357 * @return the fraction as a <tt>float</tt> +358 */ +359 @Override +360 public float floatValue() { +361 return (float)doubleValue(); +362 } +363 +364 /** +365 * Access the denominator. +366 * @return the denominator. +367 */ +368 public int getDenominator() { +369 return denominator; +370 } +371 +372 /** +373 * Access the numerator. +374 * @return the numerator. +375 */ +376 public int getNumerator() { +377 return numerator; +378 } +379 +380 /** +381 * Gets a hashCode for the fraction. +382 * @return a hash code value for this object +383 */ +384 @Override +385 public int hashCode() { +386 return 37 * (37 * 17 + numerator) + denominator; +387 } +388 +389 /** +390 * Gets the fraction as an <tt>int</tt>. This returns the whole number part +391 * of the fraction. +392 * @return the whole number fraction part +393 */ +394 @Override +395 public int intValue() { +396 return (int)doubleValue(); +397 } +398 +399 /** +400 * Gets the fraction as a <tt>long</tt>. This returns the whole number part +401 * of the fraction. +402 * @return the whole number fraction part +403 */ +404 @Override +405 public long longValue() { +406 return (long)doubleValue(); +407 } +408 +409 /** +410 * Return the additive inverse of this fraction. +411 * @return the negation of this fraction. +412 */ +413 public Fraction negate() { +414 if (numerator==Integer.MIN_VALUE) { +415 throw MathRuntimeException.createArithmeticException( +416 OVERFLOW_MESSAGE, numerator, denominator); +417 } +418 return new Fraction(-numerator, denominator); +419 } +420 +421 /** +422 * Return the multiplicative inverse of this fraction. +423 * @return the reciprocal fraction +424 */ +425 public Fraction reciprocal() { +426 return new Fraction(denominator, numerator); +427 } +428 +429 /** +430 * <p>Adds the value of this fraction to another, returning the result in reduced form. +431 * The algorithm follows Knuth, 4.5.1.</p> +432 * +433 * @param fraction the fraction to add, must not be <code>null</code> +434 * @return a <code>Fraction</code> instance with the resulting values +435 * @throws IllegalArgumentException if the fraction is <code>null</code> +436 * @throws ArithmeticException if the resulting numerator or denominator exceeds +437 * <code>Integer.MAX_VALUE</code> +438 */ +439 public Fraction add(Fraction fraction) { +440 return addSub(fraction, true /* add */); +441 } +442 +443 /** +444 * Add an integer to the fraction. +445 * @param i the <tt>integer</tt> to add. +446 * @return this + i +447 */ +448 public Fraction add(final int i) { +449 return new Fraction(numerator + i * denominator, denominator); +450 } +451 +452 /** +453 * <p>Subtracts the value of another fraction from the value of this one, +454 * returning the result in reduced form.</p> +455 * +456 * @param fraction the fraction to subtract, must not be <code>null</code> +457 * @return a <code>Fraction</code> instance with the resulting values +458 * @throws IllegalArgumentException if the fraction is <code>null</code> +459 * @throws ArithmeticException if the resulting numerator or denominator +460 * cannot be represented in an <code>int</code>. +461 */ +462 public Fraction subtract(Fraction fraction) { +463 return addSub(fraction, false /* subtract */); +464 } +465 +466 /** +467 * Subtract an integer from the fraction. +468 * @param i the <tt>integer</tt> to subtract. +469 * @return this - i +470 */ +471 public Fraction subtract(final int i) { +472 return new Fraction(numerator - i * denominator, denominator); +473 } +474 +475 /** +476 * Implement add and subtract using algorithm described in Knuth 4.5.1. +477 * +478 * @param fraction the fraction to subtract, must not be <code>null</code> +479 * @param isAdd true to add, false to subtract +480 * @return a <code>Fraction</code> instance with the resulting values +481 * @throws IllegalArgumentException if the fraction is <code>null</code> +482 * @throws ArithmeticException if the resulting numerator or denominator +483 * cannot be represented in an <code>int</code>. +484 */ +485 private Fraction addSub(Fraction fraction, boolean isAdd) { +486 if (fraction == null) { +487 throw MathRuntimeException.createIllegalArgumentException(NULL_FRACTION); +488 } +489 // zero is identity for addition. +490 if (numerator == 0) { +491 return isAdd ? fraction : fraction.negate(); +492 } +493 if (fraction.numerator == 0) { +494 return this; +495 } +496 // if denominators are randomly distributed, d1 will be 1 about 61% +497 // of the time. +498 int d1 = MathUtils.gcd(denominator, fraction.denominator); +499 if (d1==1) { +500 // result is ( (u*v' +/- u'v) / u'v') +501 int uvp = MathUtils.mulAndCheck(numerator, fraction.denominator); +502 int upv = MathUtils.mulAndCheck(fraction.numerator, denominator); +503 return new Fraction +504 (isAdd ? MathUtils.addAndCheck(uvp, upv) : +505 MathUtils.subAndCheck(uvp, upv), +506 MathUtils.mulAndCheck(denominator, fraction.denominator)); +507 } +508 // the quantity 't' requires 65 bits of precision; see knuth 4.5.1 +509 // exercise 7. we're going to use a BigInteger. +510 // t = u(v'/d1) +/- v(u'/d1) +511 BigInteger uvp = BigInteger.valueOf(numerator) +512 .multiply(BigInteger.valueOf(fraction.denominator/d1)); +513 BigInteger upv = BigInteger.valueOf(fraction.numerator) +514 .multiply(BigInteger.valueOf(denominator/d1)); +515 BigInteger t = isAdd ? uvp.add(upv) : uvp.subtract(upv); +516 // but d2 doesn't need extra precision because +517 // d2 = gcd(t,d1) = gcd(t mod d1, d1) +518 int tmodd1 = t.mod(BigInteger.valueOf(d1)).intValue(); +519 int d2 = (tmodd1==0)?d1:MathUtils.gcd(tmodd1, d1); +520 +521 // result is (t/d2) / (u'/d1)(v'/d2) +522 BigInteger w = t.divide(BigInteger.valueOf(d2)); +523 if (w.bitLength() > 31) { +524 throw MathRuntimeException.createArithmeticException("overflow, numerator too large after multiply: {0}", +525 w); +526 } +527 return new Fraction (w.intValue(), +528 MathUtils.mulAndCheck(denominator/d1, +529 fraction.denominator/d2)); +530 } +531 +532 /** +533 * <p>Multiplies the value of this fraction by another, returning the +534 * result in reduced form.</p> +535 * +536 * @param fraction the fraction to multiply by, must not be <code>null</code> +537 * @return a <code>Fraction</code> instance with the resulting values +538 * @throws IllegalArgumentException if the fraction is <code>null</code> +539 * @throws ArithmeticException if the resulting numerator or denominator exceeds +540 * <code>Integer.MAX_VALUE</code> +541 */ +542 public Fraction multiply(Fraction fraction) { +543 if (fraction == null) { +544 throw MathRuntimeException.createIllegalArgumentException(NULL_FRACTION); +545 } +546 if (numerator == 0 || fraction.numerator == 0) { +547 return ZERO; +548 } +549 // knuth 4.5.1 +550 // make sure we don't overflow unless the result *must* overflow. +551 int d1 = MathUtils.gcd(numerator, fraction.denominator); +552 int d2 = MathUtils.gcd(fraction.numerator, denominator); +553 return getReducedFraction +554 (MathUtils.mulAndCheck(numerator/d1, fraction.numerator/d2), +555 MathUtils.mulAndCheck(denominator/d2, fraction.denominator/d1)); +556 } +557 +558 /** +559 * Multiply the fraction by an integer. +560 * @param i the <tt>integer</tt> to multiply by. +561 * @return this * i +562 */ +563 public Fraction multiply(final int i) { +564 return new Fraction(numerator * i, denominator); +565 } +566 +567 /** +568 * <p>Divide the value of this fraction by another.</p> +569 * +570 * @param fraction the fraction to divide by, must not be <code>null</code> +571 * @return a <code>Fraction</code> instance with the resulting values +572 * @throws IllegalArgumentException if the fraction is <code>null</code> +573 * @throws ArithmeticException if the fraction to divide by is zero +574 * @throws ArithmeticException if the resulting numerator or denominator exceeds +575 * <code>Integer.MAX_VALUE</code> +576 */ +577 public Fraction divide(Fraction fraction) { +578 if (fraction == null) { +579 throw MathRuntimeException.createIllegalArgumentException(NULL_FRACTION); +580 } +581 if (fraction.numerator == 0) { +582 throw MathRuntimeException.createArithmeticException( +583 "the fraction to divide by must not be zero: {0}/{1}", +584 fraction.numerator, fraction.denominator); +585 } +586 return multiply(fraction.reciprocal()); +587 } +588 +589 /** +590 * Divide the fraction by an integer. +591 * @param i the <tt>integer</tt> to divide by. +592 * @return this * i +593 */ +594 public Fraction divide(final int i) { +595 return new Fraction(numerator, denominator * i); +596 } +597 +598 /** +599 * <p>Creates a <code>Fraction</code> instance with the 2 parts +600 * of a fraction Y/Z.</p> +601 * +602 * <p>Any negative signs are resolved to be on the numerator.</p> +603 * +604 * @param numerator the numerator, for example the three in 'three sevenths' +605 * @param denominator the denominator, for example the seven in 'three sevenths' +606 * @return a new fraction instance, with the numerator and denominator reduced +607 * @throws ArithmeticException if the denominator is <code>zero</code> +608 */ +609 public static Fraction getReducedFraction(int numerator, int denominator) { +610 if (denominator == 0) { +611 throw MathRuntimeException.createArithmeticException( +612 ZERO_DENOMINATOR_MESSAGE, numerator, denominator); +613 } +614 if (numerator==0) { +615 return ZERO; // normalize zero. +616 } +617 // allow 2^k/-2^31 as a valid fraction (where k>0) +618 if (denominator==Integer.MIN_VALUE && (numerator&1)==0) { +619 numerator/=2; denominator/=2; +620 } +621 if (denominator < 0) { +622 if (numerator==Integer.MIN_VALUE || +623 denominator==Integer.MIN_VALUE) { +624 throw MathRuntimeException.createArithmeticException( +625 OVERFLOW_MESSAGE, numerator, denominator); +626 } +627 numerator = -numerator; +628 denominator = -denominator; +629 } +630 // simplify fraction. +631 int gcd = MathUtils.gcd(numerator, denominator); +632 numerator /= gcd; +633 denominator /= gcd; +634 return new Fraction(numerator, denominator); +635 } +636 +637 /** +638 * <p> +639 * Returns the <code>String</code> representing this fraction, ie +640 * "num / dem" or just "num" if the denominator is one. +641 * </p> +642 * +643 * @return a string representation of the fraction. +644 * @see java.lang.Object#toString() +645 */ +646 @Override +647 public String toString() { +648 String str = null; +649 if (denominator == 1) { +650 str = Integer.toString(numerator); +651 } else if (numerator == 0) { +652 str = "0"; +653 } else { +654 str = numerator + " / " + denominator; +655 } +656 return str; +657 } +658 +659 /** {@inheritDoc} */ +660 public FractionField getField() { +661 return FractionField.getInstance(); +662 } +663 +664 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/FractionConversionException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/FractionConversionException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,121 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.fraction; +019 +020 import org.apache.commons.math.ConvergenceException; +021 +022 /** +023 * Error thrown when a double value cannot be converted to a fraction +024 * in the allowed number of iterations. +025 * +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 * @since 1.2 +028 */ +029 public class FractionConversionException extends ConvergenceException { +030 +031 /** Serializable version identifier. */ +032 private static final long serialVersionUID = -4661812640132576263L; +033 +034 /** +035 * Constructs an exception with specified formatted detail message. +036 * Message formatting is delegated to {@link java.text.MessageFormat}. +037 * @param value double value to convert +038 * @param maxIterations maximal number of iterations allowed +039 */ +040 public FractionConversionException(double value, int maxIterations) { +041 super("Unable to convert {0} to fraction after {1} iterations", value, maxIterations); +042 } +043 +044 /** +045 * Constructs an exception with specified formatted detail message. +046 * Message formatting is delegated to {@link java.text.MessageFormat}. +047 * @param value double value to convert +048 * @param p current numerator +049 * @param q current denominator +050 */ +051 public FractionConversionException(double value, long p, long q) { +052 super("Overflow trying to convert {0} to fraction ({1}/{2})", value, p, q); +053 } +054 +055 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/FractionField.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/FractionField.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,144 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.fraction; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.Field; +023 +024 /** +025 * Representation of the fractional numbers field. +026 * <p> +027 * This class is a singleton. +028 * </p> +029 * @see Fraction +030 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +031 * @since 2.0 +032 */ +033 public class FractionField implements Field<Fraction>, Serializable { +034 +035 /** Serializable version identifier */ +036 private static final long serialVersionUID = -1257768487499119313L; +037 +038 /** Private constructor for the singleton. +039 */ +040 private FractionField() { +041 } +042 +043 /** Get the unique instance. +044 * @return the unique instance +045 */ +046 public static FractionField getInstance() { +047 return LazyHolder.INSTANCE; +048 } +049 +050 /** {@inheritDoc} */ +051 public Fraction getOne() { +052 return Fraction.ONE; +053 } +054 +055 /** {@inheritDoc} */ +056 public Fraction getZero() { +057 return Fraction.ZERO; +058 } +059 +060 // CHECKSTYLE: stop HideUtilityClassConstructor +061 /** Holder for the instance. +062 * <p>We use here the Initialization On Demand Holder Idiom.</p> +063 */ +064 private static class LazyHolder { +065 /** Cached field instance. */ +066 private static final FractionField INSTANCE = new FractionField(); +067 } +068 // CHECKSTYLE: resume HideUtilityClassConstructor +069 +070 /** Handle deserialization of the singleton. +071 * @return the singleton instance +072 */ +073 private Object readResolve() { +074 // return the singleton instance +075 return LazyHolder.INSTANCE; +076 } +077 +078 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/FractionFormat.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/FractionFormat.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,339 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.fraction; +019 +020 import java.text.FieldPosition; +021 import java.text.NumberFormat; +022 import java.text.ParseException; +023 import java.text.ParsePosition; +024 import java.util.Locale; +025 +026 import org.apache.commons.math.ConvergenceException; +027 import org.apache.commons.math.MathRuntimeException; +028 +029 /** +030 * Formats a Fraction number in proper format or improper format. The number +031 * format for each of the whole number, numerator and, denominator can be +032 * configured. +033 * +034 * @since 1.1 +035 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +036 */ +037 public class FractionFormat extends AbstractFormat { +038 +039 /** Serializable version identifier */ +040 private static final long serialVersionUID = 3008655719530972611L; +041 +042 /** +043 * Create an improper formatting instance with the default number format +044 * for the numerator and denominator. +045 */ +046 public FractionFormat() { +047 } +048 +049 /** +050 * Create an improper formatting instance with a custom number format for +051 * both the numerator and denominator. +052 * @param format the custom format for both the numerator and denominator. +053 */ +054 public FractionFormat(final NumberFormat format) { +055 super(format); +056 } +057 +058 /** +059 * Create an improper formatting instance with a custom number format for +060 * the numerator and a custom number format for the denominator. +061 * @param numeratorFormat the custom format for the numerator. +062 * @param denominatorFormat the custom format for the denominator. +063 */ +064 public FractionFormat(final NumberFormat numeratorFormat, +065 final NumberFormat denominatorFormat) { +066 super(numeratorFormat, denominatorFormat); +067 } +068 +069 /** +070 * Get the set of locales for which complex formats are available. This +071 * is the same set as the {@link NumberFormat} set. +072 * @return available complex format locales. +073 */ +074 public static Locale[] getAvailableLocales() { +075 return NumberFormat.getAvailableLocales(); +076 } +077 +078 /** +079 * This static method calls formatFraction() on a default instance of +080 * FractionFormat. +081 * +082 * @param f Fraction object to format +083 * @return A formatted fraction in proper form. +084 */ +085 public static String formatFraction(Fraction f) { +086 return getImproperInstance().format(f); +087 } +088 +089 /** +090 * Returns the default complex format for the current locale. +091 * @return the default complex format. +092 */ +093 public static FractionFormat getImproperInstance() { +094 return getImproperInstance(Locale.getDefault()); +095 } +096 +097 /** +098 * Returns the default complex format for the given locale. +099 * @param locale the specific locale used by the format. +100 * @return the complex format specific to the given locale. +101 */ +102 public static FractionFormat getImproperInstance(final Locale locale) { +103 return new FractionFormat(getDefaultNumberFormat(locale)); +104 } +105 +106 /** +107 * Returns the default complex format for the current locale. +108 * @return the default complex format. +109 */ +110 public static FractionFormat getProperInstance() { +111 return getProperInstance(Locale.getDefault()); +112 } +113 +114 /** +115 * Returns the default complex format for the given locale. +116 * @param locale the specific locale used by the format. +117 * @return the complex format specific to the given locale. +118 */ +119 public static FractionFormat getProperInstance(final Locale locale) { +120 return new ProperFractionFormat(getDefaultNumberFormat(locale)); +121 } +122 +123 /** +124 * Create a default number format. The default number format is based on +125 * {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only +126 * customizing is the maximum number of fraction digits, which is set to 0. +127 * @return the default number format. +128 */ +129 protected static NumberFormat getDefaultNumberFormat() { +130 return getDefaultNumberFormat(Locale.getDefault()); +131 } +132 +133 /** +134 * Formats a {@link Fraction} object to produce a string. The fraction is +135 * output in improper format. +136 * +137 * @param fraction the object to format. +138 * @param toAppendTo where the text is to be appended +139 * @param pos On input: an alignment field, if desired. On output: the +140 * offsets of the alignment field +141 * @return the value passed in as toAppendTo. +142 */ +143 public StringBuffer format(final Fraction fraction, +144 final StringBuffer toAppendTo, final FieldPosition pos) { +145 +146 pos.setBeginIndex(0); +147 pos.setEndIndex(0); +148 +149 getNumeratorFormat().format(fraction.getNumerator(), toAppendTo, pos); +150 toAppendTo.append(" / "); +151 getDenominatorFormat().format(fraction.getDenominator(), toAppendTo, +152 pos); +153 +154 return toAppendTo; +155 } +156 +157 /** +158 * Formats an object and appends the result to a StringBuffer. <code>obj</code> must be either a +159 * {@link Fraction} object or a {@link Number} object. Any other type of +160 * object will result in an {@link IllegalArgumentException} being thrown. +161 * +162 * @param obj the object to format. +163 * @param toAppendTo where the text is to be appended +164 * @param pos On input: an alignment field, if desired. On output: the +165 * offsets of the alignment field +166 * @return the value passed in as toAppendTo. +167 * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) +168 * @throws IllegalArgumentException is <code>obj</code> is not a valid type. +169 */ +170 @Override +171 public StringBuffer format(final Object obj, +172 final StringBuffer toAppendTo, final FieldPosition pos) { +173 StringBuffer ret = null; +174 +175 if (obj instanceof Fraction) { +176 ret = format((Fraction) obj, toAppendTo, pos); +177 } else if (obj instanceof Number) { +178 try { +179 ret = format(new Fraction(((Number) obj).doubleValue()), +180 toAppendTo, pos); +181 } catch (ConvergenceException ex) { +182 throw MathRuntimeException.createIllegalArgumentException( +183 "cannot convert given object to a fraction number: {0}", +184 ex.getLocalizedMessage()); +185 } +186 } else { +187 throw MathRuntimeException.createIllegalArgumentException( +188 "cannot format given object as a fraction number"); +189 } +190 +191 return ret; +192 } +193 +194 /** +195 * Parses a string to produce a {@link Fraction} object. +196 * @param source the string to parse +197 * @return the parsed {@link Fraction} object. +198 * @exception ParseException if the beginning of the specified string +199 * cannot be parsed. +200 */ +201 @Override +202 public Fraction parse(final String source) throws ParseException { +203 final ParsePosition parsePosition = new ParsePosition(0); +204 final Fraction result = parse(source, parsePosition); +205 if (parsePosition.getIndex() == 0) { +206 throw MathRuntimeException.createParseException( +207 parsePosition.getErrorIndex(), +208 "unparseable fraction number: \"{0}\"", source); +209 } +210 return result; +211 } +212 +213 /** +214 * Parses a string to produce a {@link Fraction} object. This method +215 * expects the string to be formatted as an improper fraction. +216 * @param source the string to parse +217 * @param pos input/ouput parsing parameter. +218 * @return the parsed {@link Fraction} object. +219 */ +220 @Override +221 public Fraction parse(final String source, final ParsePosition pos) { +222 final int initialIndex = pos.getIndex(); +223 +224 // parse whitespace +225 parseAndIgnoreWhitespace(source, pos); +226 +227 // parse numerator +228 final Number num = getNumeratorFormat().parse(source, pos); +229 if (num == null) { +230 // invalid integer number +231 // set index back to initial, error index should already be set +232 // character examined. +233 pos.setIndex(initialIndex); +234 return null; +235 } +236 +237 // parse '/' +238 final int startIndex = pos.getIndex(); +239 final char c = parseNextCharacter(source, pos); +240 switch (c) { +241 case 0 : +242 // no '/' +243 // return num as a fraction +244 return new Fraction(num.intValue(), 1); +245 case '/' : +246 // found '/', continue parsing denominator +247 break; +248 default : +249 // invalid '/' +250 // set index back to initial, error index should be the last +251 // character examined. +252 pos.setIndex(initialIndex); +253 pos.setErrorIndex(startIndex); +254 return null; +255 } +256 +257 // parse whitespace +258 parseAndIgnoreWhitespace(source, pos); +259 +260 // parse denominator +261 final Number den = getDenominatorFormat().parse(source, pos); +262 if (den == null) { +263 // invalid integer number +264 // set index back to initial, error index should already be set +265 // character examined. +266 pos.setIndex(initialIndex); +267 return null; +268 } +269 +270 return new Fraction(num.intValue(), den.intValue()); +271 } +272 +273 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/ProperBigFractionFormat.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/ProperBigFractionFormat.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,307 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.fraction; +018 +019 import java.math.BigInteger; +020 import java.text.FieldPosition; +021 import java.text.NumberFormat; +022 import java.text.ParsePosition; +023 +024 import org.apache.commons.math.MathRuntimeException; +025 +026 /** +027 * Formats a BigFraction number in proper format. The number format for each of +028 * the whole number, numerator and, denominator can be configured. +029 * <p> +030 * Minus signs are only allowed in the whole number part - i.e., +031 * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and +032 * will result in a <code>ParseException</code>.</p> +033 * +034 * @since 1.1 +035 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +036 */ +037 public class ProperBigFractionFormat extends BigFractionFormat { +038 +039 /** Serializable version identifier */ +040 private static final long serialVersionUID = -6337346779577272307L; +041 +042 /** The format used for the whole number. */ +043 private NumberFormat wholeFormat; +044 +045 /** +046 * Create a proper formatting instance with the default number format for +047 * the whole, numerator, and denominator. +048 */ +049 public ProperBigFractionFormat() { +050 this(getDefaultNumberFormat()); +051 } +052 +053 /** +054 * Create a proper formatting instance with a custom number format for the +055 * whole, numerator, and denominator. +056 * @param format the custom format for the whole, numerator, and +057 * denominator. +058 */ +059 public ProperBigFractionFormat(final NumberFormat format) { +060 this(format, (NumberFormat)format.clone(), (NumberFormat)format.clone()); +061 } +062 +063 /** +064 * Create a proper formatting instance with a custom number format for each +065 * of the whole, numerator, and denominator. +066 * @param wholeFormat the custom format for the whole. +067 * @param numeratorFormat the custom format for the numerator. +068 * @param denominatorFormat the custom format for the denominator. +069 */ +070 public ProperBigFractionFormat(final NumberFormat wholeFormat, +071 final NumberFormat numeratorFormat, +072 final NumberFormat denominatorFormat) { +073 super(numeratorFormat, denominatorFormat); +074 setWholeFormat(wholeFormat); +075 } +076 +077 /** +078 * Formats a {@link BigFraction} object to produce a string. The BigFraction +079 * is output in proper format. +080 * +081 * @param fraction the object to format. +082 * @param toAppendTo where the text is to be appended +083 * @param pos On input: an alignment field, if desired. On output: the +084 * offsets of the alignment field +085 * @return the value passed in as toAppendTo. +086 */ +087 @Override +088 public StringBuffer format(final BigFraction fraction, +089 final StringBuffer toAppendTo, final FieldPosition pos) { +090 +091 pos.setBeginIndex(0); +092 pos.setEndIndex(0); +093 +094 BigInteger num = fraction.getNumerator(); +095 BigInteger den = fraction.getDenominator(); +096 BigInteger whole = num.divide(den); +097 num = num.remainder(den); +098 +099 if (!BigInteger.ZERO.equals(whole)) { +100 getWholeFormat().format(whole, toAppendTo, pos); +101 toAppendTo.append(' '); +102 if (num.compareTo(BigInteger.ZERO) < 0) { +103 num = num.negate(); +104 } +105 } +106 getNumeratorFormat().format(num, toAppendTo, pos); +107 toAppendTo.append(" / "); +108 getDenominatorFormat().format(den, toAppendTo, pos); +109 +110 return toAppendTo; +111 } +112 +113 /** +114 * Access the whole format. +115 * @return the whole format. +116 */ +117 public NumberFormat getWholeFormat() { +118 return wholeFormat; +119 } +120 +121 /** +122 * Parses a string to produce a {@link BigFraction} object. This method +123 * expects the string to be formatted as a proper BigFraction. +124 * <p> +125 * Minus signs are only allowed in the whole number part - i.e., +126 * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and +127 * will result in a <code>ParseException</code>.</p> +128 * +129 * @param source the string to parse +130 * @param pos input/ouput parsing parameter. +131 * @return the parsed {@link BigFraction} object. +132 */ +133 @Override +134 public BigFraction parse(final String source, final ParsePosition pos) { +135 // try to parse improper BigFraction +136 BigFraction ret = super.parse(source, pos); +137 if (ret != null) { +138 return ret; +139 } +140 +141 final int initialIndex = pos.getIndex(); +142 +143 // parse whitespace +144 parseAndIgnoreWhitespace(source, pos); +145 +146 // parse whole +147 BigInteger whole = parseNextBigInteger(source, pos); +148 if (whole == null) { +149 // invalid integer number +150 // set index back to initial, error index should already be set +151 // character examined. +152 pos.setIndex(initialIndex); +153 return null; +154 } +155 +156 // parse whitespace +157 parseAndIgnoreWhitespace(source, pos); +158 +159 // parse numerator +160 BigInteger num = parseNextBigInteger(source, pos); +161 if (num == null) { +162 // invalid integer number +163 // set index back to initial, error index should already be set +164 // character examined. +165 pos.setIndex(initialIndex); +166 return null; +167 } +168 +169 if (num.compareTo(BigInteger.ZERO) < 0) { +170 // minus signs should be leading, invalid expression +171 pos.setIndex(initialIndex); +172 return null; +173 } +174 +175 // parse '/' +176 final int startIndex = pos.getIndex(); +177 final char c = parseNextCharacter(source, pos); +178 switch (c) { +179 case 0 : +180 // no '/' +181 // return num as a BigFraction +182 return new BigFraction(num); +183 case '/' : +184 // found '/', continue parsing denominator +185 break; +186 default : +187 // invalid '/' +188 // set index back to initial, error index should be the last +189 // character examined. +190 pos.setIndex(initialIndex); +191 pos.setErrorIndex(startIndex); +192 return null; +193 } +194 +195 // parse whitespace +196 parseAndIgnoreWhitespace(source, pos); +197 +198 // parse denominator +199 final BigInteger den = parseNextBigInteger(source, pos); +200 if (den == null) { +201 // invalid integer number +202 // set index back to initial, error index should already be set +203 // character examined. +204 pos.setIndex(initialIndex); +205 return null; +206 } +207 +208 if (den.compareTo(BigInteger.ZERO) < 0) { +209 // minus signs must be leading, invalid +210 pos.setIndex(initialIndex); +211 return null; +212 } +213 +214 boolean wholeIsNeg = whole.compareTo(BigInteger.ZERO) < 0; +215 if (wholeIsNeg) { +216 whole = whole.negate(); +217 } +218 num = whole.multiply(den).add(num); +219 if (wholeIsNeg) { +220 num = num.negate(); +221 } +222 +223 return new BigFraction(num, den); +224 +225 } +226 +227 /** +228 * Modify the whole format. +229 * @param format The new whole format value. +230 * @throws IllegalArgumentException if <code>format</code> is +231 * <code>null</code>. +232 */ +233 public void setWholeFormat(final NumberFormat format) { +234 if (format == null) { +235 throw MathRuntimeException.createIllegalArgumentException( +236 "whole format can not be null"); +237 } +238 this.wholeFormat = format; +239 } +240 +241 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/ProperFractionFormat.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/fraction/ProperFractionFormat.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,299 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.fraction; +018 +019 import java.text.FieldPosition; +020 import java.text.NumberFormat; +021 import java.text.ParsePosition; +022 +023 import org.apache.commons.math.MathRuntimeException; +024 import org.apache.commons.math.util.MathUtils; +025 +026 /** +027 * Formats a Fraction number in proper format. The number format for each of +028 * the whole number, numerator and, denominator can be configured. +029 * <p> +030 * Minus signs are only allowed in the whole number part - i.e., +031 * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and +032 * will result in a <code>ParseException</code>.</p> +033 * +034 * @since 1.1 +035 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +036 */ +037 public class ProperFractionFormat extends FractionFormat { +038 +039 /** Serializable version identifier */ +040 private static final long serialVersionUID = 760934726031766749L; +041 +042 /** The format used for the whole number. */ +043 private NumberFormat wholeFormat; +044 +045 /** +046 * Create a proper formatting instance with the default number format for +047 * the whole, numerator, and denominator. +048 */ +049 public ProperFractionFormat() { +050 this(getDefaultNumberFormat()); +051 } +052 +053 /** +054 * Create a proper formatting instance with a custom number format for the +055 * whole, numerator, and denominator. +056 * @param format the custom format for the whole, numerator, and +057 * denominator. +058 */ +059 public ProperFractionFormat(NumberFormat format) { +060 this(format, (NumberFormat)format.clone(), (NumberFormat)format.clone()); +061 } +062 +063 /** +064 * Create a proper formatting instance with a custom number format for each +065 * of the whole, numerator, and denominator. +066 * @param wholeFormat the custom format for the whole. +067 * @param numeratorFormat the custom format for the numerator. +068 * @param denominatorFormat the custom format for the denominator. +069 */ +070 public ProperFractionFormat(NumberFormat wholeFormat, +071 NumberFormat numeratorFormat, +072 NumberFormat denominatorFormat) +073 { +074 super(numeratorFormat, denominatorFormat); +075 setWholeFormat(wholeFormat); +076 } +077 +078 /** +079 * Formats a {@link Fraction} object to produce a string. The fraction +080 * is output in proper format. +081 * +082 * @param fraction the object to format. +083 * @param toAppendTo where the text is to be appended +084 * @param pos On input: an alignment field, if desired. On output: the +085 * offsets of the alignment field +086 * @return the value passed in as toAppendTo. +087 */ +088 @Override +089 public StringBuffer format(Fraction fraction, StringBuffer toAppendTo, +090 FieldPosition pos) { +091 +092 pos.setBeginIndex(0); +093 pos.setEndIndex(0); +094 +095 int num = fraction.getNumerator(); +096 int den = fraction.getDenominator(); +097 int whole = num / den; +098 num = num % den; +099 +100 if (whole != 0) { +101 getWholeFormat().format(whole, toAppendTo, pos); +102 toAppendTo.append(' '); +103 num = Math.abs(num); +104 } +105 getNumeratorFormat().format(num, toAppendTo, pos); +106 toAppendTo.append(" / "); +107 getDenominatorFormat().format(den, toAppendTo, +108 pos); +109 +110 return toAppendTo; +111 } +112 +113 /** +114 * Access the whole format. +115 * @return the whole format. +116 */ +117 public NumberFormat getWholeFormat() { +118 return wholeFormat; +119 } +120 +121 /** +122 * Parses a string to produce a {@link Fraction} object. This method +123 * expects the string to be formatted as a proper fraction. +124 * <p> +125 * Minus signs are only allowed in the whole number part - i.e., +126 * "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and +127 * will result in a <code>ParseException</code>.</p> +128 * +129 * @param source the string to parse +130 * @param pos input/ouput parsing parameter. +131 * @return the parsed {@link Fraction} object. +132 */ +133 @Override +134 public Fraction parse(String source, ParsePosition pos) { +135 // try to parse improper fraction +136 Fraction ret = super.parse(source, pos); +137 if (ret != null) { +138 return ret; +139 } +140 +141 int initialIndex = pos.getIndex(); +142 +143 // parse whitespace +144 parseAndIgnoreWhitespace(source, pos); +145 +146 // parse whole +147 Number whole = getWholeFormat().parse(source, pos); +148 if (whole == null) { +149 // invalid integer number +150 // set index back to initial, error index should already be set +151 // character examined. +152 pos.setIndex(initialIndex); +153 return null; +154 } +155 +156 // parse whitespace +157 parseAndIgnoreWhitespace(source, pos); +158 +159 // parse numerator +160 Number num = getNumeratorFormat().parse(source, pos); +161 if (num == null) { +162 // invalid integer number +163 // set index back to initial, error index should already be set +164 // character examined. +165 pos.setIndex(initialIndex); +166 return null; +167 } +168 +169 if (num.intValue() < 0) { +170 // minus signs should be leading, invalid expression +171 pos.setIndex(initialIndex); +172 return null; +173 } +174 +175 // parse '/' +176 int startIndex = pos.getIndex(); +177 char c = parseNextCharacter(source, pos); +178 switch (c) { +179 case 0 : +180 // no '/' +181 // return num as a fraction +182 return new Fraction(num.intValue(), 1); +183 case '/' : +184 // found '/', continue parsing denominator +185 break; +186 default : +187 // invalid '/' +188 // set index back to initial, error index should be the last +189 // character examined. +190 pos.setIndex(initialIndex); +191 pos.setErrorIndex(startIndex); +192 return null; +193 } +194 +195 // parse whitespace +196 parseAndIgnoreWhitespace(source, pos); +197 +198 // parse denominator +199 Number den = getDenominatorFormat().parse(source, pos); +200 if (den == null) { +201 // invalid integer number +202 // set index back to initial, error index should already be set +203 // character examined. +204 pos.setIndex(initialIndex); +205 return null; +206 } +207 +208 if (den.intValue() < 0) { +209 // minus signs must be leading, invalid +210 pos.setIndex(initialIndex); +211 return null; +212 } +213 +214 int w = whole.intValue(); +215 int n = num.intValue(); +216 int d = den.intValue(); +217 return new Fraction(((Math.abs(w) * d) + n) * MathUtils.sign(w), d); +218 } +219 +220 /** +221 * Modify the whole format. +222 * @param format The new whole format value. +223 * @throws IllegalArgumentException if <code>format</code> is +224 * <code>null</code>. +225 */ +226 public void setWholeFormat(NumberFormat format) { +227 if (format == null) { +228 throw MathRuntimeException.createIllegalArgumentException( +229 "whole format can not be null"); +230 } +231 this.wholeFormat = format; +232 } +233 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/AbstractListChromosome.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/AbstractListChromosome.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,170 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 import java.util.ArrayList; +020 import java.util.Arrays; +021 import java.util.Collections; +022 import java.util.List; +023 +024 /** +025 * Chromosome represented by an immutable list of a fixed length. +026 * +027 * @param <T> type of the representation list +028 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +029 * @since 2.0 +030 */ +031 public abstract class AbstractListChromosome<T> extends Chromosome { +032 +033 /** List representing the chromosome */ +034 private final List<T> representation; +035 +036 /** +037 * Constructor. +038 * @param representation inner representation of the chromosome +039 */ +040 public AbstractListChromosome(final List<T> representation) { +041 try { +042 checkValidity(representation); +043 } catch (InvalidRepresentationException e) { +044 throw new IllegalArgumentException(String.format("Invalid representation for %s", getClass().getSimpleName()), e); +045 } +046 this.representation = Collections.unmodifiableList(new ArrayList<T> (representation)); +047 } +048 +049 /** +050 * Constructor. +051 * @param representation inner representation of the chromosome +052 */ +053 public AbstractListChromosome(final T[] representation) { +054 this(Arrays.asList(representation)); +055 } +056 +057 /** +058 * +059 * Asserts that <code>representation</code> can represent a valid chromosome. +060 * @param chromosomeRepresentation representation of the chromosome +061 * @throws InvalidRepresentationException iff the <code>representation</code> can not represent +062 * a valid chromosome +063 */ +064 protected abstract void checkValidity(List<T> chromosomeRepresentation) throws InvalidRepresentationException; +065 +066 /** +067 * Returns the (immutable) inner representation of the chromosome. +068 * @return the representation of the chromosome +069 */ +070 protected List<T> getRepresentation() { +071 return representation; +072 } +073 +074 /** +075 * Returns the length of the chromosome. +076 * @return the length of the chromosome +077 */ +078 public int getLength() { +079 return getRepresentation().size(); +080 } +081 +082 /** +083 * Creates a new instance of the same class as <code>this</code> is, with a +084 * given <code>arrayRepresentation</code>. This is needed in crossover and +085 * mutation operators, where we need a new instance of the same class, but +086 * with different array representation. +087 * +088 * Usually, this method just calls a constructor of the class. +089 * +090 * @param chromosomeRepresentation +091 * the inner array representation of the new chromosome. +092 * @return new instance extended from FixedLengthChromosome with the given +093 * arrayRepresentation +094 */ +095 public abstract AbstractListChromosome<T> newFixedLengthChromosome(final List<T> chromosomeRepresentation); +096 +097 /** +098 * {@inheritDoc} +099 */ +100 @Override +101 public String toString() { +102 return String.format("(f=%s %s)", getFitness(), getRepresentation()); +103 } +104 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/BinaryChromosome.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/BinaryChromosome.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,158 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 import java.util.ArrayList; +020 import java.util.List; +021 +022 +023 /** +024 * Chromosome represented by a vector of 0s and 1s. +025 * +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 * @since 2.0 +028 */ +029 public abstract class BinaryChromosome extends AbstractListChromosome<Integer> { +030 +031 /** +032 * Constructor. +033 * @param representation list of {0,1} values representing the chromosome +034 */ +035 public BinaryChromosome(List<Integer> representation) { +036 super(representation); +037 } +038 +039 /** +040 * Constructor. +041 * @param representation array of {0,1} values representing the chromosome +042 */ +043 public BinaryChromosome(Integer[] representation) { +044 super(representation); +045 } +046 +047 /** +048 * {@inheritDoc} +049 */ +050 @Override +051 protected void checkValidity(List<Integer> chromosomeRepresentation) throws InvalidRepresentationException { +052 for (int i : chromosomeRepresentation) { +053 if (i < 0 || i >1) +054 throw new InvalidRepresentationException("Elements can be only 0 or 1."); +055 } +056 } +057 +058 /** +059 * Returns a representation of a random binary array of length <code>length</code>. +060 * @param length length of the array +061 * @return a random binary array of length <code>length</code> +062 */ +063 public static List<Integer> randomBinaryRepresentation(int length) { +064 // random binary list +065 List<Integer> rList= new ArrayList<Integer> (length); +066 for (int j=0; j<length; j++) { +067 rList.add(GeneticAlgorithm.getRandomGenerator().nextInt(2)); +068 } +069 return rList; +070 } +071 +072 /** +073 * {@inheritDoc} +074 */ +075 @Override +076 protected boolean isSame(Chromosome another) { +077 // type check +078 if (! (another instanceof BinaryChromosome)) +079 return false; +080 BinaryChromosome anotherBc = (BinaryChromosome) another; +081 // size check +082 if (getLength() != anotherBc.getLength()) +083 return false; +084 +085 for (int i=0; i< getRepresentation().size(); i++) { +086 if (!(getRepresentation().get(i).equals(anotherBc.getRepresentation().get(i)))) +087 return false; +088 } +089 // all is ok +090 return true; +091 } +092 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/BinaryMutation.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/BinaryMutation.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,118 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 import java.util.ArrayList; +020 import java.util.List; +021 +022 /** +023 * Mutation for {@link BinaryChromosome}s. Randomly changes one gene. +024 * +025 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +026 * @since 2.0 +027 */ +028 public class BinaryMutation implements MutationPolicy { +029 +030 /** +031 * Mutate the given chromosome. Randomly changes one gene. +032 * @param original the original chromosome. +033 * @return the mutated chromomsome. +034 */ +035 public Chromosome mutate(Chromosome original) { +036 if (!(original instanceof BinaryChromosome)) { +037 throw new IllegalArgumentException("Binary mutation works on BinaryChromosome only."); +038 } +039 +040 BinaryChromosome origChrom = (BinaryChromosome) original; +041 List<Integer> newRepr = new ArrayList<Integer>(origChrom.getRepresentation()); +042 +043 // randomly select a gene +044 int geneIndex = GeneticAlgorithm.getRandomGenerator().nextInt(origChrom.getLength()); +045 // and change it +046 newRepr.set(geneIndex, origChrom.getRepresentation().get(geneIndex) == 0 ? 1 : 0); +047 +048 Chromosome newChrom = origChrom.newFixedLengthChromosome(newRepr); +049 return newChrom; +050 } +051 +052 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/Chromosome.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/Chromosome.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,177 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 /** +020 * Individual in a population. Chromosomes are compared based on their fitness. +021 * +022 * The chromosomes are IMMUTABLE, and so their fitness is also immutable and +023 * therefore it can be cached. +024 * +025 * @since 2.0 +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 */ +028 public abstract class Chromosome implements Comparable<Chromosome>,Fitness { +029 +030 /** +031 * Cached value of the fitness of this chromosome. +032 */ +033 private double fitness = Double.MIN_VALUE; +034 +035 /** +036 * Access the fitness of this chromosome. The bigger the fitness, the better +037 * the chromosome. +038 * +039 * Computation of fitness is usually very time-consuming task, therefore the +040 * fitness is cached. +041 * +042 * @return the fitness. +043 */ +044 public double getFitness() { +045 if (this.fitness == Double.MIN_VALUE) { +046 // no cache - compute the fitness +047 this.fitness = fitness(); +048 } +049 return this.fitness; +050 } +051 +052 /** +053 * Compares two chromosomes based on their fitness. The bigger the fitness, +054 * the better the chromosome. +055 * +056 * @param another another chromosome to compare +057 * @return +058 * <ul> +059 * <li>-1 if <code>another</code> is better than <code>this</code></li> +060 * <li>1 if <code>another</code> is worse than <code>this</code></li> +061 * <li>0 if the two chromosomes have the same fitness</li> +062 * </ul> +063 */ +064 public int compareTo(Chromosome another) { +065 return ((Double)this.getFitness()).compareTo(another.getFitness()); +066 } +067 +068 /** +069 * Returns <code>true<code> iff <code>another</code> has the same +070 * representation and therefore the same fitness. By default, it returns +071 * false -- override it in your implementation if you need it. +072 * @param another chromosome to compare +073 * @return true if <code>another</code> is equivalent to this chromosome +074 */ +075 protected boolean isSame(Chromosome another) { +076 return false; +077 } +078 +079 /** +080 * Searches the <code>population</code> for another chromosome with the same +081 * representation. If such chromosome is found, it is returned, if no such +082 * chromosome exists, returns <code>null</code>. +083 * +084 * @param population +085 * Population to search +086 * @return Chromosome with the same representation, or <code>null</code> if +087 * no such chromosome exists. +088 */ +089 protected Chromosome findSameChromosome(Population population) { +090 for (Chromosome anotherChr : population) { +091 if (this.isSame(anotherChr)) +092 return anotherChr; +093 } +094 return null; +095 } +096 +097 /** +098 * Searches the population for a chromosome representing the same solution, +099 * and if it finds one, updates the fitness to its value. +100 * +101 * @param population +102 * Population to search +103 */ +104 public void searchForFitnessUpdate(Population population) { +105 Chromosome sameChromosome = findSameChromosome(population); +106 if (sameChromosome != null) { +107 fitness = sameChromosome.getFitness(); +108 } +109 } +110 +111 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/ChromosomePair.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/ChromosomePair.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,135 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 /** +020 * A pair of {@link Chromosome} objects. +021 * @since 2.0 +022 * +023 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +024 */ +025 public class ChromosomePair { +026 /** the first chromosome in the pair. */ +027 private final Chromosome first; +028 +029 /** the second chromosome in the pair. */ +030 private final Chromosome second; +031 +032 /** +033 * Create a chromosome pair. +034 * +035 * @param c1 the first chromosome. +036 * @param c2 the second chromosome. +037 */ +038 public ChromosomePair(final Chromosome c1, final Chromosome c2) { +039 super(); +040 first = c1; +041 second = c2; +042 } +043 +044 /** +045 * Access the first chromosome. +046 * +047 * @return the first chromosome. +048 */ +049 public Chromosome getFirst() { +050 return first; +051 } +052 +053 /** +054 * Access the second chromosome. +055 * +056 * @return the second chromosome. +057 */ +058 public Chromosome getSecond() { +059 return second; +060 } +061 +062 /** +063 * {@inheritDoc} +064 */ +065 @Override +066 public String toString() { +067 return String.format("(%s,%s)", getFirst(), getSecond()); +068 } +069 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/CrossoverPolicy.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/CrossoverPolicy.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,101 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 /** +020 * Policy used to create a pair of new chromosomes by performing a crossover +021 * operation on a source pair of chromosomes. +022 * +023 * @since 2.0 +024 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +025 */ +026 public interface CrossoverPolicy { +027 /** +028 * Perform a crossover operation on the given chromosomes. +029 * +030 * @param first the first chromosome. +031 * @param second the second chromosome. +032 * @return the pair of new chromosomes that resulted from the crossover. +033 */ +034 ChromosomePair crossover(Chromosome first, Chromosome second); +035 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/ElitisticListPopulation.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/ElitisticListPopulation.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,174 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 import java.util.Collections; +020 import java.util.List; +021 +022 /** +023 * Population of chromosomes which uses elitism (certain percentace of the best +024 * chromosomes is directly copied to the next generation). +025 * +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 * @since 2.0 +028 */ +029 public class ElitisticListPopulation extends ListPopulation { +030 +031 /** percentage of chromosomes copied to the next generation */ +032 private double elitismRate = 0.9; +033 +034 /** +035 * Creates a new ElitisticListPopulation instance. +036 * +037 * @param chromosomes +038 * list of chromosomes in the population +039 * @param populationLimit +040 * maximal size of the population +041 * @param elitismRate +042 * how many best chromosomes will be directly transferred to the +043 * next generation [in %] +044 */ +045 public ElitisticListPopulation(List<Chromosome> chromosomes, int populationLimit, double elitismRate) { +046 super(chromosomes, populationLimit); +047 this.elitismRate = elitismRate; +048 } +049 +050 /** +051 * Creates a new ListPopulation instance and initializes its inner +052 * chromosome list. +053 * +054 * @param populationLimit maximal size of the population +055 * @param elitismRate +056 * how many best chromosomes will be directly transferred to the +057 * next generation [in %] +058 */ +059 public ElitisticListPopulation(int populationLimit, double elitismRate) { +060 super(populationLimit); +061 this.elitismRate = elitismRate; +062 } +063 +064 /** +065 * Start the population for the next generation. The +066 * <code>{@link #elitismRate}<code> percents of the best +067 * chromosomes are directly copied to the next generation. +068 * +069 * @return the beginnings of the next generation. +070 */ +071 public Population nextGeneration() { +072 // initialize a new generation with the same parameters +073 ElitisticListPopulation nextGeneration = new ElitisticListPopulation(this.getPopulationLimit(), this.getElitismRate()); +074 +075 List<Chromosome> oldChromosomes = this.getChromosomes(); +076 Collections.sort(oldChromosomes); +077 +078 // index of the last "not good enough" chromosome +079 int boundIndex = (int) Math.ceil((1.0 - this.getElitismRate()) * oldChromosomes.size()); +080 for (int i=boundIndex; i<oldChromosomes.size(); i++) { +081 nextGeneration.addChromosome(oldChromosomes.get(i)); +082 } +083 return nextGeneration; +084 } +085 +086 /** +087 * Sets the elitism rate, i.e. how many best chromosomes will be directly +088 * transferred to the next generation [in %]. +089 * +090 * @param elitismRate +091 * how many best chromosomes will be directly transferred to the +092 * next generation [in %] +093 */ +094 public void setElitismRate(double elitismRate) { +095 if (elitismRate < 0 || elitismRate > 1) +096 throw new IllegalArgumentException("Elitism rate has to be in [0,1]"); +097 this.elitismRate = elitismRate; +098 } +099 +100 /** +101 * Access the elitism rate. +102 * @return the elitism rate +103 */ +104 public double getElitismRate() { +105 return this.elitismRate; +106 } +107 +108 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/Fitness.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/Fitness.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,101 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 /** +020 * Fitness of a chromosome. +021 * +022 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +023 * @since 2.0 +024 */ +025 public interface Fitness { +026 +027 /** +028 * Compute the fitness. This is usually very time-consuming, so the value +029 * should be cached. +030 * +031 * @return fitness +032 */ +033 double fitness(); +034 +035 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/FixedGenerationCount.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/FixedGenerationCount.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,136 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 /** +020 * Stops after a fixed number of generations. Each time +021 * {@link #isSatisfied(Population)} is invoked, a generation counter is +022 * incremented. Once the counter reaches the configured +023 * <code>maxGenerations</code> value, {@link #isSatisfied(Population)} returns +024 * true. +025 * +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 * @since 2.0 +028 */ +029 public class FixedGenerationCount implements StoppingCondition { +030 /** Number of generations that have passed */ +031 private int numGenerations = 0; +032 +033 /** Maximum number of generations (stopping criteria) */ +034 private final int maxGenerations; +035 +036 /** +037 * Create a new FixedGenerationCount instance. +038 * +039 * @param maxGenerations number of generations to evolve +040 */ +041 public FixedGenerationCount(int maxGenerations) { +042 if (maxGenerations <= 0) +043 throw new IllegalArgumentException("The number of generations has to be >= 0"); +044 this.maxGenerations = maxGenerations; +045 } +046 +047 /** +048 * Determine whether or not the given number of generations have passed. +049 * Increments the number of generations counter if the maximum has not +050 * been reached. +051 * +052 * @param population ignored (no impact on result) +053 * @return <code>true</code> IFF the maximum number of generations has been exceeded +054 */ +055 public boolean isSatisfied(Population population) { +056 if (this.numGenerations < this.maxGenerations) { +057 numGenerations++; +058 return false; +059 } +060 return true; +061 } +062 +063 /** +064 * @return the number of generations that have passed +065 */ +066 public int getNumGenerations() { +067 return numGenerations; +068 } +069 +070 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/GeneticAlgorithm.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/GeneticAlgorithm.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,294 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 import org.apache.commons.math.random.RandomGenerator; +020 import org.apache.commons.math.random.JDKRandomGenerator; +021 +022 /** +023 * Implementation of a genetic algorithm. All factors that govern the operation +024 * of the algorithm can be configured for a specific problem. +025 * +026 * @since 2.0 +027 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +028 */ +029 public class GeneticAlgorithm { +030 +031 /** +032 * Static random number generator shared by GA implementation classes. +033 * Set the randomGenerator seed to get reproducible results. +034 * Use {@link #setRandomGenerator(RandomGenerator)} to supply an alternative +035 * to the default JDK-provided PRNG. +036 */ +037 //@GuardedBy("this") +038 private static RandomGenerator randomGenerator = new JDKRandomGenerator(); +039 +040 /** the crossover policy used by the algorithm. */ +041 private final CrossoverPolicy crossoverPolicy; +042 +043 /** the rate of crossover for the algorithm. */ +044 private final double crossoverRate; +045 +046 /** the mutation policy used by the algorithm. */ +047 private final MutationPolicy mutationPolicy; +048 +049 /** the rate of mutation for the algorithm. */ +050 private final double mutationRate; +051 +052 /** the selection policy used by the algorithm. */ +053 private final SelectionPolicy selectionPolicy; +054 +055 /** the number of generations evolved to reach {@link StoppingCondition} in the last run. */ +056 private int generationsEvolved = 0; +057 +058 /** +059 * @param crossoverPolicy The {@link CrossoverPolicy} +060 * @param crossoverRate The crossover rate as a percentage (0-1 inclusive) +061 * @param mutationPolicy The {@link MutationPolicy} +062 * @param mutationRate The mutation rate as a percentage (0-1 inclusive) +063 * @param selectionPolicy The {@link SelectionPolicy} +064 */ +065 public GeneticAlgorithm( +066 CrossoverPolicy crossoverPolicy, double crossoverRate, +067 MutationPolicy mutationPolicy, double mutationRate, +068 SelectionPolicy selectionPolicy) { +069 if (crossoverRate < 0 || crossoverRate > 1) { +070 throw new IllegalArgumentException("crossoverRate must be between 0 and 1"); +071 } +072 if (mutationRate < 0 || mutationRate > 1) { +073 throw new IllegalArgumentException("mutationRate must be between 0 and 1"); +074 } +075 this.crossoverPolicy = crossoverPolicy; +076 this.crossoverRate = crossoverRate; +077 this.mutationPolicy = mutationPolicy; +078 this.mutationRate = mutationRate; +079 this.selectionPolicy = selectionPolicy; +080 } +081 +082 /** +083 * Set the (static) random generator. +084 * +085 * @param random random generator +086 */ +087 public static synchronized void setRandomGenerator(RandomGenerator random) { +088 randomGenerator = random; +089 } +090 +091 /** +092 * Returns the (static) random generator. +093 * +094 * @return the static random generator shared by GA implementation classes +095 */ +096 public static synchronized RandomGenerator getRandomGenerator() { +097 return randomGenerator; +098 } +099 +100 /** +101 * Evolve the given population. Evolution stops when the stopping condition +102 * is satisfied. Updates the {@link #getGenerationsEvolved() generationsEvolved} +103 * property with the number of generations evolved before the StoppingCondition +104 * is satisfied. +105 * +106 * @param initial the initial, seed population. +107 * @param condition the stopping condition used to stop evolution. +108 * @return the population that satisfies the stopping condition. +109 */ +110 public Population evolve(Population initial, StoppingCondition condition) { +111 Population current = initial; +112 generationsEvolved = 0; +113 while (!condition.isSatisfied(current)) { +114 current = nextGeneration(current); +115 generationsEvolved++; +116 } +117 return current; +118 } +119 +120 /** +121 * <p>Evolve the given population into the next generation.</p> +122 * <p><ol> +123 * <li>Get nextGeneration population to fill from <code>current</code> +124 * generation, using its nextGeneration method</li> +125 * <li>Loop until new generation is filled:</li> +126 * <ul><li>Apply configured SelectionPolicy to select a pair of parents +127 * from <code>current</code></li> +128 * <li>With probability = {@link #getCrossoverRate()}, apply +129 * configured {@link CrossoverPolicy} to parents</li> +130 * <li>With probability = {@link #getMutationRate()}, apply +131 * configured {@link MutationPolicy} to each of the offspring</li> +132 * <li>Add offspring individually to nextGeneration, +133 * space permitting</li> +134 * </ul> +135 * <li>Return nextGeneration</li> +136 * </ol> +137 * </p> +138 * +139 * @param current the current population. +140 * @return the population for the next generation. +141 */ +142 public Population nextGeneration(Population current) { +143 Population nextGeneration = current.nextGeneration(); +144 +145 RandomGenerator randGen = getRandomGenerator(); +146 +147 while (nextGeneration.getPopulationSize() < nextGeneration.getPopulationLimit()) { +148 // select parent chromosomes +149 ChromosomePair pair = getSelectionPolicy().select(current); +150 +151 // crossover? +152 if (randGen.nextDouble() < getCrossoverRate()) { +153 // apply crossover policy to create two offspring +154 pair = getCrossoverPolicy().crossover(pair.getFirst(), pair.getSecond()); +155 } +156 +157 // mutation? +158 if (randGen.nextDouble() < getMutationRate()) { +159 // apply mutation policy to the chromosomes +160 pair = new ChromosomePair( +161 getMutationPolicy().mutate(pair.getFirst()), +162 getMutationPolicy().mutate(pair.getSecond())); +163 } +164 +165 // add the first chromosome to the population +166 nextGeneration.addChromosome(pair.getFirst()); +167 // is there still a place for the second chromosome? +168 if (nextGeneration.getPopulationSize() < nextGeneration.getPopulationLimit()) { +169 // add the second chromosome to the population +170 nextGeneration.addChromosome(pair.getSecond()); +171 } +172 } +173 +174 return nextGeneration; +175 } +176 +177 /** +178 * Returns the crossover policy. +179 * @return crossover policy +180 */ +181 public CrossoverPolicy getCrossoverPolicy() { +182 return crossoverPolicy; +183 } +184 +185 /** +186 * Returns the crossover rate. +187 * @return crossover rate +188 */ +189 public double getCrossoverRate() { +190 return crossoverRate; +191 } +192 +193 /** +194 * Returns the mutation policy. +195 * @return mutation policy +196 */ +197 public MutationPolicy getMutationPolicy() { +198 return mutationPolicy; +199 } +200 +201 /** +202 * Returns the mutation rate. +203 * @return mutation rate +204 */ +205 public double getMutationRate() { +206 return mutationRate; +207 } +208 +209 /** +210 * Returns the selection policy. +211 * @return selection policy +212 */ +213 public SelectionPolicy getSelectionPolicy() { +214 return selectionPolicy; +215 } +216 +217 /** +218 * Returns the number of generations evolved to +219 * reach {@link StoppingCondition} in the last run. +220 * +221 * @return number of generations evolved +222 * @since 2.1 +223 */ +224 public int getGenerationsEvolved() { +225 return generationsEvolved; +226 } +227 +228 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/InvalidRepresentationException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/InvalidRepresentationException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,129 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 /** +020 * Exception indicating that the representation of a chromosome is not valid. +021 * +022 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +023 * @since 2.0 +024 */ +025 public class InvalidRepresentationException extends Exception { +026 +027 /** Serialization version id */ +028 private static final long serialVersionUID = 1L; +029 +030 /** +031 * Constructor +032 */ +033 public InvalidRepresentationException() { +034 super(); +035 } +036 +037 /** +038 * Construct an InvalidRepresentationException +039 * @param arg0 exception message +040 */ +041 public InvalidRepresentationException(String arg0) { +042 super(arg0); +043 } +044 +045 /** +046 * Construct an InvalidRepresentationException +047 * @param arg0 cause +048 */ +049 public InvalidRepresentationException(Throwable arg0) { +050 super(arg0); +051 } +052 +053 /** +054 * Construct an InvalidRepresentationException +055 * +056 * @param arg0 exception message +057 * @param arg1 cause +058 */ +059 public InvalidRepresentationException(String arg0, Throwable arg1) { +060 super(arg0, arg1); +061 } +062 +063 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/ListPopulation.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/ListPopulation.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,216 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 import java.util.ArrayList; +020 import java.util.Iterator; +021 import java.util.List; +022 +023 /** +024 * Population of chromosomes represented by a {@link List}. +025 * +026 * @since 2.0 +027 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +028 */ +029 public abstract class ListPopulation implements Population { +030 +031 /** List of chromosomes */ +032 private List<Chromosome> chromosomes; +033 +034 /** maximial size of the population */ +035 private int populationLimit; +036 +037 +038 /** +039 * Creates a new ListPopulation instance. +040 * +041 * @param chromosomes list of chromosomes in the population +042 * @param populationLimit maximal size of the population +043 */ +044 public ListPopulation (List<Chromosome> chromosomes, int populationLimit) { +045 if (chromosomes.size() > populationLimit) { +046 throw new IllegalArgumentException("List of chromosomes bigger than maxPopulationSize."); +047 } +048 if (populationLimit < 0) { +049 throw new IllegalArgumentException("Population limit has to be >= 0"); +050 } +051 +052 this.chromosomes = chromosomes; +053 this.populationLimit = populationLimit; +054 } +055 +056 /** +057 * Creates a new ListPopulation instance and initializes its inner +058 * chromosome list. +059 * +060 * @param populationLimit maximal size of the population +061 */ +062 public ListPopulation (int populationLimit) { +063 if (populationLimit < 0) { +064 throw new IllegalArgumentException("Population limit has to be >= 0"); +065 } +066 this.populationLimit = populationLimit; +067 this.chromosomes = new ArrayList<Chromosome>(populationLimit); +068 } +069 +070 /** +071 * Sets the list of chromosomes. +072 * @param chromosomes the list of chromosomes +073 */ +074 public void setChromosomes(List<Chromosome> chromosomes) { +075 this.chromosomes = chromosomes; +076 } +077 +078 /** +079 * Access the list of chromosomes. +080 * @return the list of chromosomes +081 */ +082 public List<Chromosome> getChromosomes() { +083 return chromosomes; +084 } +085 +086 /** +087 * Add the given chromosome to the population. +088 * @param chromosome the chromosome to add. +089 */ +090 public void addChromosome(Chromosome chromosome) { +091 this.chromosomes.add(chromosome); +092 } +093 +094 /** +095 * Access the fittest chromosome in this population. +096 * @return the fittest chromosome. +097 */ +098 public Chromosome getFittestChromosome() { +099 // best so far +100 Chromosome bestChromosome = this.chromosomes.get(0); +101 for (Chromosome chromosome : this.chromosomes) { +102 if (chromosome.compareTo(bestChromosome) > 0) { +103 // better chromosome found +104 bestChromosome = chromosome; +105 } +106 } +107 return bestChromosome; +108 } +109 +110 /** +111 * Access the maximum population size. +112 * @return the maximum population size. +113 */ +114 public int getPopulationLimit() { +115 return this.populationLimit; +116 } +117 +118 /** +119 * Sets the maximal population size. +120 * @param populationLimit maximal population size. +121 */ +122 public void setPopulationLimit(int populationLimit) { +123 this.populationLimit = populationLimit; +124 } +125 +126 /** +127 * Access the current population size. +128 * @return the current population size. +129 */ +130 public int getPopulationSize() { +131 return this.chromosomes.size(); +132 } +133 +134 /** +135 * {@inheritDoc} +136 */ +137 @Override +138 public String toString() { +139 return this.chromosomes.toString(); +140 } +141 +142 /** +143 * Chromosome list iterator +144 * +145 * @return chromosome iterator +146 */ +147 public Iterator<Chromosome> iterator() { +148 return chromosomes.iterator(); +149 } +150 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/MutationPolicy.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/MutationPolicy.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,99 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 /** +020 * Algorithm used to mutate a chrommosome. +021 * +022 * @since 2.0 +023 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +024 */ +025 public interface MutationPolicy { +026 +027 /** +028 * Mutate the given chromosome. +029 * @param original the original chromosome. +030 * @return the mutated chromomsome. +031 */ +032 Chromosome mutate(Chromosome original); +033 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/OnePointCrossover.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/OnePointCrossover.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,183 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 import java.util.ArrayList; +020 import java.util.List; +021 +022 +023 /** +024 * One point crossover policy. A random crossover point is selected and the +025 * first part from each parent is copied to the corresponding child, and the +026 * second parts are copied crosswise. +027 * +028 * Example: +029 * <pre> +030 * -C- denotes a crossover point +031 * -C- -C- +032 * p1 = (1 0 1 0 0 1 | 0 1 1) X p2 = (0 1 1 0 1 0 | 1 1 1) +033 * \------------/ \-----/ \------------/ \-----/ +034 * || (*) || (**) +035 * VV (**) VV (*) +036 * /------------\ /-----\ /------------\ /-----\ +037 * c1 = (1 0 1 0 0 1 | 1 1 1) X p2 = (0 1 1 0 1 0 | 0 1 1) +038 * </pre> +039 * +040 * This policy works only on {@link AbstractListChromosome}, and therefore it +041 * is parametrized by T. Moreover, the chromosomes must have same lengths. +042 * +043 * @param <T> generic type of the {@link AbstractListChromosome}s for crossover +044 * @since 2.0 +045 * @version $Revision: 903046 $ $Date: 2010-01-25 21:07:26 -0500 (Mon, 25 Jan 2010) $ +046 * +047 */ +048 public class OnePointCrossover<T> implements CrossoverPolicy { +049 +050 /** +051 * Performs one point crossover. A random crossover point is selected and the +052 * first part from each parent is copied to the corresponding child, and the +053 * second parts are copied crosswise. +054 * +055 * Example: +056 * -C- denotes a crossover point +057 * -C- -C- +058 * p1 = (1 0 1 0 0 1 | 0 1 1) X p2 = (0 1 1 0 1 0 | 1 1 1) +059 * \------------/ \-----/ \------------/ \-----/ +060 * || (*) || (**) +061 * VV (**) VV (*) +062 * /------------\ /-----\ /------------\ /-----\ +063 * c1 = (1 0 1 0 0 1 | 1 1 1) X p2 = (0 1 1 0 1 0 | 0 1 1) +064 * +065 * @param first first parent (p1) +066 * @param second second parent (p2) +067 * @return pair of two children (c1,c2) +068 */ +069 @SuppressWarnings("unchecked") // OK because of instanceof checks +070 public ChromosomePair crossover(Chromosome first, Chromosome second) { +071 if (! (first instanceof AbstractListChromosome<?> && second instanceof AbstractListChromosome<?>)) { +072 throw new IllegalArgumentException("One point crossover works on FixedLengthChromosomes only."); +073 } +074 return crossover((AbstractListChromosome<T>) first, (AbstractListChromosome<T>) second); +075 } +076 +077 +078 /** +079 * Helper for {@link #crossover(Chromosome, Chromosome)}. Performs the actual crossover. +080 * +081 * @param first the first chromosome. +082 * @param second the second chromosome. +083 * @return the pair of new chromosomes that resulted from the crossover. +084 */ +085 private ChromosomePair crossover(AbstractListChromosome<T> first, AbstractListChromosome<T> second) { +086 int length = first.getLength(); +087 if (length != second.getLength()) +088 throw new IllegalArgumentException("Both chromosomes must have same lengths."); +089 +090 // array representations of the parents +091 List<T> parent1Rep = first.getRepresentation(); +092 List<T> parent2Rep = second.getRepresentation(); +093 // and of the children +094 ArrayList<T> child1Rep = new ArrayList<T> (first.getLength()); +095 ArrayList<T> child2Rep = new ArrayList<T> (second.getLength()); +096 +097 // select a crossover point at random (0 and length makes no sense) +098 int crossoverIndex = 1 + (GeneticAlgorithm.getRandomGenerator().nextInt(length-2)); +099 +100 // copy the first part +101 for (int i = 0; i < crossoverIndex; i++) { +102 child1Rep.add(parent1Rep.get(i)); +103 child2Rep.add(parent2Rep.get(i)); +104 } +105 // and switch the second part +106 for (int i = crossoverIndex; i < length; i++) { +107 child1Rep.add(parent2Rep.get(i)); +108 child2Rep.add(parent1Rep.get(i)); +109 } +110 +111 return new ChromosomePair( +112 first.newFixedLengthChromosome(child1Rep), +113 second.newFixedLengthChromosome(child2Rep) +114 ); +115 } +116 +117 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/PermutationChromosome.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/PermutationChromosome.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,110 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 import java.util.List; +020 +021 /** +022 * Interface indicating that the chromosome represents a permutation of objects. +023 * +024 * @param <T> +025 * type of the permuted objects +026 * @since 2.0 +027 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +028 */ +029 public interface PermutationChromosome<T> { +030 +031 /** +032 * Permutes the <code>sequence</code> of objects of type T according to the +033 * permutation this chromosome represents. For example, if this chromosome +034 * represents a permutation (3,0,1,2), and the unpermuted sequence is +035 * (a,b,c,d), this yields (d,a,b,c). +036 * +037 * @param sequence +038 * the unpermuted (original) sequence of objects +039 * @return permutation of <code>sequence</code> represented by this +040 * permutation +041 */ +042 List<T> decode(List<T> sequence); +043 +044 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/Population.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/Population.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,121 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 /** +020 * A collection of chromosomes that facilitates generational evolution. +021 * +022 * @since 2.0 +023 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +024 */ +025 public interface Population extends Iterable<Chromosome> { +026 /** +027 * Access the current population size. +028 * @return the current population size. +029 */ +030 int getPopulationSize(); +031 +032 /** +033 * Access the maximum population size. +034 * @return the maximum population size. +035 */ +036 int getPopulationLimit(); +037 +038 /** +039 * Start the population for the next generation. +040 * @return the beginnings of the next generation. +041 */ +042 Population nextGeneration(); +043 +044 /** +045 * Add the given chromosome to the population. +046 * @param chromosome the chromosome to add. +047 */ +048 void addChromosome(Chromosome chromosome); +049 +050 /** +051 * Access the fittest chromosome in this population. +052 * @return the fittest chromosome. +053 */ +054 Chromosome getFittestChromosome(); +055 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/RandomKey.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/RandomKey.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,356 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 import java.util.ArrayList; +020 import java.util.Arrays; +021 import java.util.Collections; +022 import java.util.Comparator; +023 import java.util.List; +024 +025 /** +026 * <p> +027 * Random Key chromosome is used for permutation representation. It is a vector +028 * of a fixed length of real numbers in [0,1] interval. The index of the i-th +029 * smallest value in the vector represents an i-th member of the permutation. +030 * </p> +031 * +032 * <p> +033 * For example, the random key [0.2, 0.3, 0.8, 0.1] corresponds to the +034 * permutation of indices (3,0,1,2). If the original (unpermuted) sequence would +035 * be (a,b,c,d), this would mean the sequence (d,a,b,c). +036 * </p> +037 * +038 * <p> +039 * With this representation, common operators like n-point crossover can be +040 * used, because any such chromosome represents a valid permutation. +041 * </p> +042 * +043 * <p> +044 * Since the chromosome (and thus its arrayRepresentation) is immutable, the +045 * array representation is sorted only once in the constructor. +046 * </p> +047 * +048 * <p> +049 * For details, see: +050 * <ul> +051 * <li>Bean, J.C.: Genetic algorithms and random keys for sequencing and +052 * optimization. ORSA Journal on Computing 6 (1994) 154–160</li> +053 * <li>Rothlauf, F.: Representations for Genetic and Evolutionary Algorithms. +054 * Volume 104 of Studies in Fuzziness and Soft Computing. Physica-Verlag, +055 * Heidelberg (2002)</li> +056 * </ul> +057 * </p> +058 * +059 * @param <T> +060 * type of the permuted objects +061 * @since 2.0 +062 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +063 */ +064 public abstract class RandomKey<T> extends AbstractListChromosome<Double> implements PermutationChromosome<T> { +065 +066 /** +067 * Cache of sorted representation (unmodifiable). +068 */ +069 private final List<Double> sortedRepresentation; +070 +071 /** +072 * Base sequence [0,1,...,n-1], permuted accorting to the representation (unmodifiable). +073 */ +074 private final List<Integer> baseSeqPermutation; +075 +076 /** +077 * Constructor. +078 * +079 * @param representation list of [0,1] values representing the permutation +080 */ +081 public RandomKey(List<Double> representation) { +082 super(representation); +083 // store the sorted representation +084 List<Double> sortedRepr = new ArrayList<Double> (getRepresentation()); +085 Collections.sort(sortedRepr); +086 sortedRepresentation = Collections.unmodifiableList(sortedRepr); +087 // store the permutation of [0,1,...,n-1] list for toString() and isSame() methods +088 baseSeqPermutation = Collections.unmodifiableList( +089 decodeGeneric(baseSequence(getLength()), getRepresentation(), sortedRepresentation) +090 ); +091 } +092 +093 /** +094 * Constructor. +095 * +096 * @param representation array of [0,1] values representing the permutation +097 */ +098 public RandomKey(Double[] representation) { +099 this(Arrays.asList(representation)); +100 } +101 +102 /** +103 * {@inheritDoc} +104 */ +105 public List<T> decode(List<T> sequence) { +106 return decodeGeneric(sequence, getRepresentation(), sortedRepresentation); +107 } +108 +109 /** +110 * Decodes a permutation represented by <code>representation</code> and +111 * returns a (generic) list with the permuted values. +112 * +113 * @param <S> generic type of the sequence values +114 * @param sequence the unpermuted sequence +115 * @param representation representation of the permutation ([0,1] vector) +116 * @param sortedRepr sorted <code>representation</code> +117 * @return list with the sequence values permuted according to the representation +118 */ +119 private static <S> List<S> decodeGeneric(List<S> sequence, List<Double> representation, List<Double> sortedRepr) { +120 int l = sequence.size(); +121 +122 if (representation.size() != l) { +123 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())); +124 } +125 if (representation.size() != sortedRepr.size()) { +126 throw new IllegalArgumentException(String.format("Representation and sortedRepr must have same sizes, %d != %d", representation.size(), sortedRepr.size())); +127 } +128 +129 List<Double> reprCopy = new ArrayList<Double> (representation);// do not modify the orig. representation +130 +131 // now find the indices in the original repr and use them for permuting +132 List<S> res = new ArrayList<S> (l); +133 for (int i=0; i<l; i++) { +134 int index = reprCopy.indexOf(sortedRepr.get(i)); +135 res.add(sequence.get(index)); +136 reprCopy.set(index, null); +137 } +138 return res; +139 } +140 +141 /** +142 * Returns <code>true</code> iff <code>another</code> is a RandomKey and +143 * encodes the same permutation. +144 * +145 * @param another chromosome to compare +146 * @return true iff chromosomes encode the same permutation +147 */ +148 @Override +149 protected boolean isSame(Chromosome another) { +150 // type check +151 if (! (another instanceof RandomKey<?>)) +152 return false; +153 RandomKey<?> anotherRk = (RandomKey<?>) another; +154 // size check +155 if (getLength() != anotherRk.getLength()) +156 return false; +157 +158 // two different representations can still encode the same permutation +159 // the ordering is what counts +160 List<Integer> thisPerm = this.baseSeqPermutation; +161 List<Integer> anotherPerm = anotherRk.baseSeqPermutation; +162 +163 for (int i=0; i<getLength(); i++) { +164 if (thisPerm.get(i) != anotherPerm.get(i)) +165 return false; +166 } +167 // the permutations are the same +168 return true; +169 } +170 +171 /** +172 * {@inheritDoc} +173 */ +174 @Override +175 protected void checkValidity(java.util.List<Double> chromosomeRepresentation) throws InvalidRepresentationException { +176 for (double val : chromosomeRepresentation) { +177 if (val < 0 || val > 1) { +178 throw new InvalidRepresentationException("Values of representation must be in [0,1] interval"); +179 } +180 } +181 } +182 +183 +184 /** +185 * Generates a representation corresponding to a random permutation of +186 * length l which can be passed to the RandomKey constructor. +187 * +188 * @param l +189 * length of the permutation +190 * @return representation of a random permutation +191 */ +192 public static final List<Double> randomPermutation(int l) { +193 List<Double> repr = new ArrayList<Double>(l); +194 for (int i=0; i<l; i++) { +195 repr.add(GeneticAlgorithm.getRandomGenerator().nextDouble()); +196 } +197 return repr; +198 } +199 +200 /** +201 * Generates a representation corresponding to an identity permutation of +202 * length l which can be passed to the RandomKey constructor. +203 * +204 * @param l +205 * length of the permutation +206 * @return representation of an identity permutation +207 */ +208 public static final List<Double> identityPermutation(int l) { +209 List<Double> repr = new ArrayList<Double>(l); +210 for (int i=0; i<l; i++) { +211 repr.add((double)i/l); +212 } +213 return repr; +214 } +215 +216 /** +217 * Generates a representation of a permutation corresponding to the +218 * <code>data</code> sorted by <code>comparator</code>. The +219 * <code>data</code> is not modified during the process. +220 * +221 * This is useful if you want to inject some permutations to the initial +222 * population. +223 * +224 * @param <S> type of the data +225 * @param data list of data determining the order +226 * @param comparator how the data will be compared +227 * @return list representation of the permutation corresponding to the parameters +228 */ +229 public static <S> List<Double> comparatorPermutation(List<S> data, Comparator<S> comparator) { +230 List<S> sortedData = new ArrayList<S> (data); +231 Collections.sort(sortedData, comparator); +232 +233 return inducedPermutation(data, sortedData); +234 } +235 +236 /** +237 * Generates a representation of a permutation corresponding to a +238 * permutation which yields <code>permutedData</code> when applied to +239 * <code>originalData</code>. +240 * +241 * This method can be viewed as an inverse to {@link #decode(List)}. +242 * +243 * @param <S> type of the data +244 * @param originalData the original, unpermuted data +245 * @param permutedData the data, somehow permuted +246 * @return representation of a permutation corresponding to the permutation <code>originalData -> permutedData</code> +247 * @throws IllegalArgumentException iff the <code>permutedData</code> and <code>originalData</code> contains different data +248 */ +249 public static <S> List<Double> inducedPermutation(List<S> originalData, List<S> permutedData) throws IllegalArgumentException { +250 if (originalData.size() != permutedData.size()) { +251 throw new IllegalArgumentException("originalData and permutedData must have same length"); +252 } +253 int l = originalData.size(); +254 +255 List<S> origDataCopy = new ArrayList<S> (originalData); +256 +257 Double[] res = new Double[l]; +258 for (int i=0; i<l; i++) { +259 int index = origDataCopy.indexOf(permutedData.get(i)); +260 if (index == -1) { +261 throw new IllegalArgumentException("originalData and permutedData must contain the same objects."); +262 } +263 res[index] = (double) i / l; +264 origDataCopy.set(index, null); +265 } +266 return Arrays.asList(res); +267 } +268 +269 /** +270 * {@inheritDoc} +271 */ +272 @Override +273 public String toString() { +274 return String.format("(f=%s pi=(%s))", getFitness(), baseSeqPermutation); +275 } +276 +277 /** +278 * Helper for constructor. Generates a list of natural numbers (0,1,...,l-1). +279 * +280 * @param l length of list to generate +281 * @return list of integers from 0 to l-1 +282 */ +283 private static List<Integer> baseSequence(int l) { +284 List<Integer> baseSequence = new ArrayList<Integer> (l); +285 for (int i=0; i<l; i++) { +286 baseSequence.add(i); +287 } +288 return baseSequence; +289 } +290 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/RandomKeyMutation.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/RandomKeyMutation.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,122 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 import java.util.ArrayList; +020 import java.util.List; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 +024 /** +025 * Mutation operator for {@link RandomKey}s. Changes a randomly chosen element +026 * of the array representation to a random value uniformly distributed in [0,1]. +027 * +028 * @since 2.0 +029 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +030 */ +031 public class RandomKeyMutation implements MutationPolicy { +032 +033 /** +034 * {@inheritDoc} +035 * +036 * @throws IllegalArgumentException if <code>original</code> is not a +037 * {@link RandomKey} instance +038 */ +039 public Chromosome mutate(Chromosome original) { +040 if (!(original instanceof RandomKey<?>)) { +041 throw MathRuntimeException.createIllegalArgumentException( +042 "RandomKeyMutation works only with RandomKeys, got " + +043 original.getClass().getSimpleName()); +044 } +045 +046 RandomKey<?> originalRk = (RandomKey<?>) original; +047 List<Double> repr = originalRk.getRepresentation(); +048 int rInd = GeneticAlgorithm.getRandomGenerator().nextInt(repr.size()); +049 +050 List<Double> newRepr = new ArrayList<Double> (repr); +051 newRepr.set(rInd, GeneticAlgorithm.getRandomGenerator().nextDouble()); +052 +053 return originalRk.newFixedLengthChromosome(newRepr); +054 } +055 +056 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/SelectionPolicy.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/SelectionPolicy.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,98 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 /** +020 * Algorithm used to select a chromosome pair from a population. +021 * +022 * @since 2.0 +023 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +024 */ +025 public interface SelectionPolicy { +026 /** +027 * Select two chromosomes from the population. +028 * @param population the population from which the chromosomes are choosen. +029 * @return the selected chromosomes. +030 */ +031 ChromosomePair select(Population population); +032 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/StoppingCondition.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/StoppingCondition.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,101 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 /** +020 * Algorithm used to determine when to stop evolution. +021 * +022 * @since 2.0 +023 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +024 */ +025 public interface StoppingCondition { +026 /** +027 * Determine whether or not the given population satisfies the stopping +028 * condition. +029 * +030 * @param population the population to test. +031 * @return <code>true</code> if this stopping condition is met by the +032 * given population. <code>false</code> otherwise. +033 */ +034 boolean isSatisfied(Population population); +035 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/TournamentSelection.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/genetics/TournamentSelection.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,180 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.genetics; +018 +019 import java.util.ArrayList; +020 import java.util.List; +021 +022 /** +023 * Tournament selection scheme. Each of the two selected chromosomes is selected +024 * based on n-ary tournament -- this is done by drawing {@link #arity} random +025 * chromosomes without replacement from the population, and then selecting the +026 * fittest chromosome among them. +027 * +028 * @since 2.0 +029 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +030 */ +031 public class TournamentSelection implements SelectionPolicy { +032 +033 /** number of chromosomes included in the tournament selections */ +034 private int arity; +035 +036 /** +037 * Creates a new TournamentSelection instance. +038 * +039 * @param arity +040 * how many chromosomes will be drawn to the tournament +041 */ +042 public TournamentSelection(int arity) { +043 this.arity = arity; +044 } +045 +046 /** +047 * Select two chromosomes from the population. Each of the two selected +048 * chromosomes is selected based on n-ary tournament -- this is done by +049 * drawing {@link #arity} random chromosomes without replacement from the +050 * population, and then selecting the fittest chromosome among them. +051 * +052 * @param population +053 * the population from which the chromosomes are choosen. +054 * @return the selected chromosomes. +055 */ +056 public ChromosomePair select(Population population) { +057 return new ChromosomePair( +058 tournament((ListPopulation) population), +059 tournament((ListPopulation)population) +060 ); +061 } +062 +063 /** +064 * Helper for {@link #select(Population)}. Draw {@link #arity} random +065 * chromosomes without replacement from the population, and then select the +066 * fittest chromosome among them. +067 * +068 * @param population +069 * the population from which the chromosomes are choosen. +070 * @return the selected chromosome. +071 */ +072 private Chromosome tournament(ListPopulation population) { +073 if (population.getPopulationSize() < this.arity) +074 throw new IllegalArgumentException("Tournament arity cannot be bigger than population size."); +075 // auxiliary population +076 ListPopulation tournamentPopulation = new ListPopulation(this.arity) { +077 public Population nextGeneration() { +078 // not useful here +079 return null; +080 } +081 }; +082 +083 // create a copy of the chromosome list +084 List<Chromosome> chromosomes = new ArrayList<Chromosome> (population.getChromosomes()); +085 for (int i=0; i<this.arity; i++) { +086 // select a random individual and add it to the tournament +087 int rind = GeneticAlgorithm.getRandomGenerator().nextInt(chromosomes.size()); +088 tournamentPopulation.addChromosome(chromosomes.get(rind)); +089 // do not select it again +090 chromosomes.remove(rind); +091 } +092 // the winner takes it all +093 return tournamentPopulation.getFittestChromosome(); +094 } +095 +096 /** +097 * Gets the arity (number of chromosomes drawn to the tournament). +098 * +099 * @return arity of the tournament +100 */ +101 public int getArity() { +102 return arity; +103 } +104 +105 /** +106 * Sets the arity (number of chromosomes drawn to the tournament). +107 * +108 * @param arity arity of the tournament +109 */ +110 public void setArity(int arity) { +111 this.arity = arity; +112 } +113 +114 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/geometry/CardanEulerSingularityException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/geometry/CardanEulerSingularityException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,110 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.geometry; +019 +020 import org.apache.commons.math.MathException; +021 +022 /** This class represents exceptions thrown while extractiong Cardan +023 * or Euler angles from a rotation. +024 +025 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +026 * @since 1.2 +027 */ +028 public class CardanEulerSingularityException +029 extends MathException { +030 +031 /** Serializable version identifier */ +032 private static final long serialVersionUID = -1360952845582206770L; +033 +034 /** +035 * Simple constructor. +036 * build an exception with a default message. +037 * @param isCardan if true, the rotation is related to Cardan angles, +038 * if false it is related to EulerAngles +039 */ +040 public CardanEulerSingularityException(boolean isCardan) { +041 super(isCardan ? "Cardan angles singularity" : "Euler angles singularity"); +042 } +043 +044 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/geometry/NotARotationMatrixException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/geometry/NotARotationMatrixException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,112 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.geometry; +019 +020 import org.apache.commons.math.MathException; +021 +022 /** +023 * This class represents exceptions thrown while building rotations +024 * from matrices. +025 * +026 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +027 * @since 1.2 +028 */ +029 +030 public class NotARotationMatrixException +031 extends MathException { +032 +033 /** Serializable version identifier */ +034 private static final long serialVersionUID = 5647178478658937642L; +035 +036 /** +037 * Simple constructor. +038 * Build an exception by translating and formating a message +039 * @param specifier format specifier (to be translated) +040 * @param parts to insert in the format (no translation) +041 */ +042 public NotARotationMatrixException(String specifier, Object ... parts) { +043 super(specifier, parts); +044 } +045 +046 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/geometry/Rotation.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/geometry/Rotation.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1118 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.geometry; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 +024 /** +025 * This class implements rotations in a three-dimensional space. +026 * +027 * <p>Rotations can be represented by several different mathematical +028 * entities (matrices, axe and angle, Cardan or Euler angles, +029 * quaternions). This class presents an higher level abstraction, more +030 * user-oriented and hiding this implementation details. Well, for the +031 * curious, we use quaternions for the internal representation. The +032 * user can build a rotation from any of these representations, and +033 * any of these representations can be retrieved from a +034 * <code>Rotation</code> instance (see the various constructors and +035 * getters). In addition, a rotation can also be built implicitely +036 * from a set of vectors and their image.</p> +037 * <p>This implies that this class can be used to convert from one +038 * representation to another one. For example, converting a rotation +039 * matrix into a set of Cardan angles from can be done using the +040 * followong single line of code:</p> +041 * <pre> +042 * double[] angles = new Rotation(matrix, 1.0e-10).getAngles(RotationOrder.XYZ); +043 * </pre> +044 * <p>Focus is oriented on what a rotation <em>do</em> rather than on its +045 * underlying representation. Once it has been built, and regardless of its +046 * internal representation, a rotation is an <em>operator</em> which basically +047 * transforms three dimensional {@link Vector3D vectors} into other three +048 * dimensional {@link Vector3D vectors}. Depending on the application, the +049 * meaning of these vectors may vary and the semantics of the rotation also.</p> +050 * <p>For example in an spacecraft attitude simulation tool, users will often +051 * consider the vectors are fixed (say the Earth direction for example) and the +052 * rotation transforms the coordinates coordinates of this vector in inertial +053 * frame into the coordinates of the same vector in satellite frame. In this +054 * case, the rotation implicitely defines the relation between the two frames. +055 * Another example could be a telescope control application, where the rotation +056 * would transform the sighting direction at rest into the desired observing +057 * direction when the telescope is pointed towards an object of interest. In this +058 * case the rotation transforms the directionf at rest in a topocentric frame +059 * into the sighting direction in the same topocentric frame. In many case, both +060 * approaches will be combined, in our telescope example, we will probably also +061 * need to transform the observing direction in the topocentric frame into the +062 * observing direction in inertial frame taking into account the observatory +063 * location and the Earth rotation.</p> +064 * +065 * <p>These examples show that a rotation is what the user wants it to be, so this +066 * class does not push the user towards one specific definition and hence does not +067 * provide methods like <code>projectVectorIntoDestinationFrame</code> or +068 * <code>computeTransformedDirection</code>. It provides simpler and more generic +069 * methods: {@link #applyTo(Vector3D) applyTo(Vector3D)} and {@link +070 * #applyInverseTo(Vector3D) applyInverseTo(Vector3D)}.</p> +071 * +072 * <p>Since a rotation is basically a vectorial operator, several rotations can be +073 * composed together and the composite operation <code>r = r<sub>1</sub> o +074 * r<sub>2</sub></code> (which means that for each vector <code>u</code>, +075 * <code>r(u) = r<sub>1</sub>(r<sub>2</sub>(u))</code>) is also a rotation. Hence +076 * we can consider that in addition to vectors, a rotation can be applied to other +077 * rotations as well (or to itself). With our previous notations, we would say we +078 * can apply <code>r<sub>1</sub></code> to <code>r<sub>2</sub></code> and the result +079 * we get is <code>r = r<sub>1</sub> o r<sub>2</sub></code>. For this purpose, the +080 * class provides the methods: {@link #applyTo(Rotation) applyTo(Rotation)} and +081 * {@link #applyInverseTo(Rotation) applyInverseTo(Rotation)}.</p> +082 * +083 * <p>Rotations are guaranteed to be immutable objects.</p> +084 * +085 * @version $Revision: 772119 $ $Date: 2009-05-06 05:43:28 -0400 (Wed, 06 May 2009) $ +086 * @see Vector3D +087 * @see RotationOrder +088 * @since 1.2 +089 */ +090 +091 public class Rotation implements Serializable { +092 +093 /** Identity rotation. */ +094 public static final Rotation IDENTITY = new Rotation(1.0, 0.0, 0.0, 0.0, false); +095 +096 /** Serializable version identifier */ +097 private static final long serialVersionUID = -2153622329907944313L; +098 +099 /** Scalar coordinate of the quaternion. */ +100 private final double q0; +101 +102 /** First coordinate of the vectorial part of the quaternion. */ +103 private final double q1; +104 +105 /** Second coordinate of the vectorial part of the quaternion. */ +106 private final double q2; +107 +108 /** Third coordinate of the vectorial part of the quaternion. */ +109 private final double q3; +110 +111 /** Build a rotation from the quaternion coordinates. +112 * <p>A rotation can be built from a <em>normalized</em> quaternion, +113 * i.e. a quaternion for which q<sub>0</sub><sup>2</sup> + +114 * q<sub>1</sub><sup>2</sup> + q<sub>2</sub><sup>2</sup> + +115 * q<sub>3</sub><sup>2</sup> = 1. If the quaternion is not normalized, +116 * the constructor can normalize it in a preprocessing step.</p> +117 * @param q0 scalar part of the quaternion +118 * @param q1 first coordinate of the vectorial part of the quaternion +119 * @param q2 second coordinate of the vectorial part of the quaternion +120 * @param q3 third coordinate of the vectorial part of the quaternion +121 * @param needsNormalization if true, the coordinates are considered +122 * not to be normalized, a normalization preprocessing step is performed +123 * before using them +124 */ +125 public Rotation(double q0, double q1, double q2, double q3, +126 boolean needsNormalization) { +127 +128 if (needsNormalization) { +129 // normalization preprocessing +130 double inv = 1.0 / Math.sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3); +131 q0 *= inv; +132 q1 *= inv; +133 q2 *= inv; +134 q3 *= inv; +135 } +136 +137 this.q0 = q0; +138 this.q1 = q1; +139 this.q2 = q2; +140 this.q3 = q3; +141 +142 } +143 +144 /** Build a rotation from an axis and an angle. +145 * <p>We use the convention that angles are oriented according to +146 * the effect of the rotation on vectors around the axis. That means +147 * that if (i, j, k) is a direct frame and if we first provide +k as +148 * the axis and PI/2 as the angle to this constructor, and then +149 * {@link #applyTo(Vector3D) apply} the instance to +i, we will get +150 * +j.</p> +151 * @param axis axis around which to rotate +152 * @param angle rotation angle. +153 * @exception ArithmeticException if the axis norm is zero +154 */ +155 public Rotation(Vector3D axis, double angle) { +156 +157 double norm = axis.getNorm(); +158 if (norm == 0) { +159 throw MathRuntimeException.createArithmeticException("zero norm for rotation axis"); +160 } +161 +162 double halfAngle = -0.5 * angle; +163 double coeff = Math.sin(halfAngle) / norm; +164 +165 q0 = Math.cos (halfAngle); +166 q1 = coeff * axis.getX(); +167 q2 = coeff * axis.getY(); +168 q3 = coeff * axis.getZ(); +169 +170 } +171 +172 /** Build a rotation from a 3X3 matrix. +173 +174 * <p>Rotation matrices are orthogonal matrices, i.e. unit matrices +175 * (which are matrices for which m.m<sup>T</sup> = I) with real +176 * coefficients. The module of the determinant of unit matrices is +177 * 1, among the orthogonal 3X3 matrices, only the ones having a +178 * positive determinant (+1) are rotation matrices.</p> +179 +180 * <p>When a rotation is defined by a matrix with truncated values +181 * (typically when it is extracted from a technical sheet where only +182 * four to five significant digits are available), the matrix is not +183 * orthogonal anymore. This constructor handles this case +184 * transparently by using a copy of the given matrix and applying a +185 * correction to the copy in order to perfect its orthogonality. If +186 * the Frobenius norm of the correction needed is above the given +187 * threshold, then the matrix is considered to be too far from a +188 * true rotation matrix and an exception is thrown.<p> +189 +190 * @param m rotation matrix +191 * @param threshold convergence threshold for the iterative +192 * orthogonality correction (convergence is reached when the +193 * difference between two steps of the Frobenius norm of the +194 * correction is below this threshold) +195 +196 * @exception NotARotationMatrixException if the matrix is not a 3X3 +197 * matrix, or if it cannot be transformed into an orthogonal matrix +198 * with the given threshold, or if the determinant of the resulting +199 * orthogonal matrix is negative +200 +201 */ +202 public Rotation(double[][] m, double threshold) +203 throws NotARotationMatrixException { +204 +205 // dimension check +206 if ((m.length != 3) || (m[0].length != 3) || +207 (m[1].length != 3) || (m[2].length != 3)) { +208 throw new NotARotationMatrixException( +209 "a {0}x{1} matrix cannot be a rotation matrix", +210 m.length, m[0].length); +211 } +212 +213 // compute a "close" orthogonal matrix +214 double[][] ort = orthogonalizeMatrix(m, threshold); +215 +216 // check the sign of the determinant +217 double det = ort[0][0] * (ort[1][1] * ort[2][2] - ort[2][1] * ort[1][2]) - +218 ort[1][0] * (ort[0][1] * ort[2][2] - ort[2][1] * ort[0][2]) + +219 ort[2][0] * (ort[0][1] * ort[1][2] - ort[1][1] * ort[0][2]); +220 if (det < 0.0) { +221 throw new NotARotationMatrixException( +222 "the closest orthogonal matrix has a negative determinant {0}", +223 det); +224 } +225 +226 // There are different ways to compute the quaternions elements +227 // from the matrix. They all involve computing one element from +228 // the diagonal of the matrix, and computing the three other ones +229 // using a formula involving a division by the first element, +230 // which unfortunately can be zero. Since the norm of the +231 // quaternion is 1, we know at least one element has an absolute +232 // value greater or equal to 0.5, so it is always possible to +233 // select the right formula and avoid division by zero and even +234 // numerical inaccuracy. Checking the elements in turn and using +235 // the first one greater than 0.45 is safe (this leads to a simple +236 // test since qi = 0.45 implies 4 qi^2 - 1 = -0.19) +237 double s = ort[0][0] + ort[1][1] + ort[2][2]; +238 if (s > -0.19) { +239 // compute q0 and deduce q1, q2 and q3 +240 q0 = 0.5 * Math.sqrt(s + 1.0); +241 double inv = 0.25 / q0; +242 q1 = inv * (ort[1][2] - ort[2][1]); +243 q2 = inv * (ort[2][0] - ort[0][2]); +244 q3 = inv * (ort[0][1] - ort[1][0]); +245 } else { +246 s = ort[0][0] - ort[1][1] - ort[2][2]; +247 if (s > -0.19) { +248 // compute q1 and deduce q0, q2 and q3 +249 q1 = 0.5 * Math.sqrt(s + 1.0); +250 double inv = 0.25 / q1; +251 q0 = inv * (ort[1][2] - ort[2][1]); +252 q2 = inv * (ort[0][1] + ort[1][0]); +253 q3 = inv * (ort[0][2] + ort[2][0]); +254 } else { +255 s = ort[1][1] - ort[0][0] - ort[2][2]; +256 if (s > -0.19) { +257 // compute q2 and deduce q0, q1 and q3 +258 q2 = 0.5 * Math.sqrt(s + 1.0); +259 double inv = 0.25 / q2; +260 q0 = inv * (ort[2][0] - ort[0][2]); +261 q1 = inv * (ort[0][1] + ort[1][0]); +262 q3 = inv * (ort[2][1] + ort[1][2]); +263 } else { +264 // compute q3 and deduce q0, q1 and q2 +265 s = ort[2][2] - ort[0][0] - ort[1][1]; +266 q3 = 0.5 * Math.sqrt(s + 1.0); +267 double inv = 0.25 / q3; +268 q0 = inv * (ort[0][1] - ort[1][0]); +269 q1 = inv * (ort[0][2] + ort[2][0]); +270 q2 = inv * (ort[2][1] + ort[1][2]); +271 } +272 } +273 } +274 +275 } +276 +277 /** Build the rotation that transforms a pair of vector into another pair. +278 +279 * <p>Except for possible scale factors, if the instance were applied to +280 * the pair (u<sub>1</sub>, u<sub>2</sub>) it will produce the pair +281 * (v<sub>1</sub>, v<sub>2</sub>).</p> +282 +283 * <p>If the angular separation between u<sub>1</sub> and u<sub>2</sub> is +284 * not the same as the angular separation between v<sub>1</sub> and +285 * v<sub>2</sub>, then a corrected v'<sub>2</sub> will be used rather than +286 * v<sub>2</sub>, the corrected vector will be in the (v<sub>1</sub>, +287 * v<sub>2</sub>) plane.</p> +288 +289 * @param u1 first vector of the origin pair +290 * @param u2 second vector of the origin pair +291 * @param v1 desired image of u1 by the rotation +292 * @param v2 desired image of u2 by the rotation +293 * @exception IllegalArgumentException if the norm of one of the vectors is zero +294 */ +295 public Rotation(Vector3D u1, Vector3D u2, Vector3D v1, Vector3D v2) { +296 +297 // norms computation +298 double u1u1 = Vector3D.dotProduct(u1, u1); +299 double u2u2 = Vector3D.dotProduct(u2, u2); +300 double v1v1 = Vector3D.dotProduct(v1, v1); +301 double v2v2 = Vector3D.dotProduct(v2, v2); +302 if ((u1u1 == 0) || (u2u2 == 0) || (v1v1 == 0) || (v2v2 == 0)) { +303 throw MathRuntimeException.createIllegalArgumentException("zero norm for rotation defining vector"); +304 } +305 +306 double u1x = u1.getX(); +307 double u1y = u1.getY(); +308 double u1z = u1.getZ(); +309 +310 double u2x = u2.getX(); +311 double u2y = u2.getY(); +312 double u2z = u2.getZ(); +313 +314 // normalize v1 in order to have (v1'|v1') = (u1|u1) +315 double coeff = Math.sqrt (u1u1 / v1v1); +316 double v1x = coeff * v1.getX(); +317 double v1y = coeff * v1.getY(); +318 double v1z = coeff * v1.getZ(); +319 v1 = new Vector3D(v1x, v1y, v1z); +320 +321 // adjust v2 in order to have (u1|u2) = (v1|v2) and (v2'|v2') = (u2|u2) +322 double u1u2 = Vector3D.dotProduct(u1, u2); +323 double v1v2 = Vector3D.dotProduct(v1, v2); +324 double coeffU = u1u2 / u1u1; +325 double coeffV = v1v2 / u1u1; +326 double beta = Math.sqrt((u2u2 - u1u2 * coeffU) / (v2v2 - v1v2 * coeffV)); +327 double alpha = coeffU - beta * coeffV; +328 double v2x = alpha * v1x + beta * v2.getX(); +329 double v2y = alpha * v1y + beta * v2.getY(); +330 double v2z = alpha * v1z + beta * v2.getZ(); +331 v2 = new Vector3D(v2x, v2y, v2z); +332 +333 // preliminary computation (we use explicit formulation instead +334 // of relying on the Vector3D class in order to avoid building lots +335 // of temporary objects) +336 Vector3D uRef = u1; +337 Vector3D vRef = v1; +338 double dx1 = v1x - u1.getX(); +339 double dy1 = v1y - u1.getY(); +340 double dz1 = v1z - u1.getZ(); +341 double dx2 = v2x - u2.getX(); +342 double dy2 = v2y - u2.getY(); +343 double dz2 = v2z - u2.getZ(); +344 Vector3D k = new Vector3D(dy1 * dz2 - dz1 * dy2, +345 dz1 * dx2 - dx1 * dz2, +346 dx1 * dy2 - dy1 * dx2); +347 double c = k.getX() * (u1y * u2z - u1z * u2y) + +348 k.getY() * (u1z * u2x - u1x * u2z) + +349 k.getZ() * (u1x * u2y - u1y * u2x); +350 +351 if (c == 0) { +352 // the (q1, q2, q3) vector is in the (u1, u2) plane +353 // we try other vectors +354 Vector3D u3 = Vector3D.crossProduct(u1, u2); +355 Vector3D v3 = Vector3D.crossProduct(v1, v2); +356 double u3x = u3.getX(); +357 double u3y = u3.getY(); +358 double u3z = u3.getZ(); +359 double v3x = v3.getX(); +360 double v3y = v3.getY(); +361 double v3z = v3.getZ(); +362 +363 double dx3 = v3x - u3x; +364 double dy3 = v3y - u3y; +365 double dz3 = v3z - u3z; +366 k = new Vector3D(dy1 * dz3 - dz1 * dy3, +367 dz1 * dx3 - dx1 * dz3, +368 dx1 * dy3 - dy1 * dx3); +369 c = k.getX() * (u1y * u3z - u1z * u3y) + +370 k.getY() * (u1z * u3x - u1x * u3z) + +371 k.getZ() * (u1x * u3y - u1y * u3x); +372 +373 if (c == 0) { +374 // the (q1, q2, q3) vector is aligned with u1: +375 // we try (u2, u3) and (v2, v3) +376 k = new Vector3D(dy2 * dz3 - dz2 * dy3, +377 dz2 * dx3 - dx2 * dz3, +378 dx2 * dy3 - dy2 * dx3); +379 c = k.getX() * (u2y * u3z - u2z * u3y) + +380 k.getY() * (u2z * u3x - u2x * u3z) + +381 k.getZ() * (u2x * u3y - u2y * u3x); +382 +383 if (c == 0) { +384 // the (q1, q2, q3) vector is aligned with everything +385 // this is really the identity rotation +386 q0 = 1.0; +387 q1 = 0.0; +388 q2 = 0.0; +389 q3 = 0.0; +390 return; +391 } +392 +393 // we will have to use u2 and v2 to compute the scalar part +394 uRef = u2; +395 vRef = v2; +396 +397 } +398 +399 } +400 +401 // compute the vectorial part +402 c = Math.sqrt(c); +403 double inv = 1.0 / (c + c); +404 q1 = inv * k.getX(); +405 q2 = inv * k.getY(); +406 q3 = inv * k.getZ(); +407 +408 // compute the scalar part +409 k = new Vector3D(uRef.getY() * q3 - uRef.getZ() * q2, +410 uRef.getZ() * q1 - uRef.getX() * q3, +411 uRef.getX() * q2 - uRef.getY() * q1); +412 c = Vector3D.dotProduct(k, k); +413 q0 = Vector3D.dotProduct(vRef, k) / (c + c); +414 +415 } +416 +417 /** Build one of the rotations that transform one vector into another one. +418 +419 * <p>Except for a possible scale factor, if the instance were +420 * applied to the vector u it will produce the vector v. There is an +421 * infinite number of such rotations, this constructor choose the +422 * one with the smallest associated angle (i.e. the one whose axis +423 * is orthogonal to the (u, v) plane). If u and v are colinear, an +424 * arbitrary rotation axis is chosen.</p> +425 +426 * @param u origin vector +427 * @param v desired image of u by the rotation +428 * @exception IllegalArgumentException if the norm of one of the vectors is zero +429 */ +430 public Rotation(Vector3D u, Vector3D v) { +431 +432 double normProduct = u.getNorm() * v.getNorm(); +433 if (normProduct == 0) { +434 throw MathRuntimeException.createIllegalArgumentException("zero norm for rotation defining vector"); +435 } +436 +437 double dot = Vector3D.dotProduct(u, v); +438 +439 if (dot < ((2.0e-15 - 1.0) * normProduct)) { +440 // special case u = -v: we select a PI angle rotation around +441 // an arbitrary vector orthogonal to u +442 Vector3D w = u.orthogonal(); +443 q0 = 0.0; +444 q1 = -w.getX(); +445 q2 = -w.getY(); +446 q3 = -w.getZ(); +447 } else { +448 // general case: (u, v) defines a plane, we select +449 // the shortest possible rotation: axis orthogonal to this plane +450 q0 = Math.sqrt(0.5 * (1.0 + dot / normProduct)); +451 double coeff = 1.0 / (2.0 * q0 * normProduct); +452 q1 = coeff * (v.getY() * u.getZ() - v.getZ() * u.getY()); +453 q2 = coeff * (v.getZ() * u.getX() - v.getX() * u.getZ()); +454 q3 = coeff * (v.getX() * u.getY() - v.getY() * u.getX()); +455 } +456 +457 } +458 +459 /** Build a rotation from three Cardan or Euler elementary rotations. +460 +461 * <p>Cardan rotations are three successive rotations around the +462 * canonical axes X, Y and Z, each axis being used once. There are +463 * 6 such sets of rotations (XYZ, XZY, YXZ, YZX, ZXY and ZYX). Euler +464 * rotations are three successive rotations around the canonical +465 * axes X, Y and Z, the first and last rotations being around the +466 * same axis. There are 6 such sets of rotations (XYX, XZX, YXY, +467 * YZY, ZXZ and ZYZ), the most popular one being ZXZ.</p> +468 * <p>Beware that many people routinely use the term Euler angles even +469 * for what really are Cardan angles (this confusion is especially +470 * widespread in the aerospace business where Roll, Pitch and Yaw angles +471 * are often wrongly tagged as Euler angles).</p> +472 +473 * @param order order of rotations to use +474 * @param alpha1 angle of the first elementary rotation +475 * @param alpha2 angle of the second elementary rotation +476 * @param alpha3 angle of the third elementary rotation +477 */ +478 public Rotation(RotationOrder order, +479 double alpha1, double alpha2, double alpha3) { +480 Rotation r1 = new Rotation(order.getA1(), alpha1); +481 Rotation r2 = new Rotation(order.getA2(), alpha2); +482 Rotation r3 = new Rotation(order.getA3(), alpha3); +483 Rotation composed = r1.applyTo(r2.applyTo(r3)); +484 q0 = composed.q0; +485 q1 = composed.q1; +486 q2 = composed.q2; +487 q3 = composed.q3; +488 } +489 +490 /** Revert a rotation. +491 * Build a rotation which reverse the effect of another +492 * rotation. This means that if r(u) = v, then r.revert(v) = u. The +493 * instance is not changed. +494 * @return a new rotation whose effect is the reverse of the effect +495 * of the instance +496 */ +497 public Rotation revert() { +498 return new Rotation(-q0, q1, q2, q3, false); +499 } +500 +501 /** Get the scalar coordinate of the quaternion. +502 * @return scalar coordinate of the quaternion +503 */ +504 public double getQ0() { +505 return q0; +506 } +507 +508 /** Get the first coordinate of the vectorial part of the quaternion. +509 * @return first coordinate of the vectorial part of the quaternion +510 */ +511 public double getQ1() { +512 return q1; +513 } +514 +515 /** Get the second coordinate of the vectorial part of the quaternion. +516 * @return second coordinate of the vectorial part of the quaternion +517 */ +518 public double getQ2() { +519 return q2; +520 } +521 +522 /** Get the third coordinate of the vectorial part of the quaternion. +523 * @return third coordinate of the vectorial part of the quaternion +524 */ +525 public double getQ3() { +526 return q3; +527 } +528 +529 /** Get the normalized axis of the rotation. +530 * @return normalized axis of the rotation +531 */ +532 public Vector3D getAxis() { +533 double squaredSine = q1 * q1 + q2 * q2 + q3 * q3; +534 if (squaredSine == 0) { +535 return new Vector3D(1, 0, 0); +536 } else if (q0 < 0) { +537 double inverse = 1 / Math.sqrt(squaredSine); +538 return new Vector3D(q1 * inverse, q2 * inverse, q3 * inverse); +539 } +540 double inverse = -1 / Math.sqrt(squaredSine); +541 return new Vector3D(q1 * inverse, q2 * inverse, q3 * inverse); +542 } +543 +544 /** Get the angle of the rotation. +545 * @return angle of the rotation (between 0 and π) +546 */ +547 public double getAngle() { +548 if ((q0 < -0.1) || (q0 > 0.1)) { +549 return 2 * Math.asin(Math.sqrt(q1 * q1 + q2 * q2 + q3 * q3)); +550 } else if (q0 < 0) { +551 return 2 * Math.acos(-q0); +552 } +553 return 2 * Math.acos(q0); +554 } +555 +556 /** Get the Cardan or Euler angles corresponding to the instance. +557 +558 * <p>The equations show that each rotation can be defined by two +559 * different values of the Cardan or Euler angles set. For example +560 * if Cardan angles are used, the rotation defined by the angles +561 * a<sub>1</sub>, a<sub>2</sub> and a<sub>3</sub> is the same as +562 * the rotation defined by the angles π + a<sub>1</sub>, π +563 * - a<sub>2</sub> and π + a<sub>3</sub>. This method implements +564 * the following arbitrary choices:</p> +565 * <ul> +566 * <li>for Cardan angles, the chosen set is the one for which the +567 * second angle is between -π/2 and π/2 (i.e its cosine is +568 * positive),</li> +569 * <li>for Euler angles, the chosen set is the one for which the +570 * second angle is between 0 and π (i.e its sine is positive).</li> +571 * </ul> +572 +573 * <p>Cardan and Euler angle have a very disappointing drawback: all +574 * of them have singularities. This means that if the instance is +575 * too close to the singularities corresponding to the given +576 * rotation order, it will be impossible to retrieve the angles. For +577 * Cardan angles, this is often called gimbal lock. There is +578 * <em>nothing</em> to do to prevent this, it is an intrinsic problem +579 * with Cardan and Euler representation (but not a problem with the +580 * rotation itself, which is perfectly well defined). For Cardan +581 * angles, singularities occur when the second angle is close to +582 * -π/2 or +π/2, for Euler angle singularities occur when the +583 * second angle is close to 0 or π, this implies that the identity +584 * rotation is always singular for Euler angles!</p> +585 +586 * @param order rotation order to use +587 * @return an array of three angles, in the order specified by the set +588 * @exception CardanEulerSingularityException if the rotation is +589 * singular with respect to the angles set specified +590 */ +591 public double[] getAngles(RotationOrder order) +592 throws CardanEulerSingularityException { +593 +594 if (order == RotationOrder.XYZ) { +595 +596 // r (Vector3D.plusK) coordinates are : +597 // sin (theta), -cos (theta) sin (phi), cos (theta) cos (phi) +598 // (-r) (Vector3D.plusI) coordinates are : +599 // cos (psi) cos (theta), -sin (psi) cos (theta), sin (theta) +600 // and we can choose to have theta in the interval [-PI/2 ; +PI/2] +601 Vector3D v1 = applyTo(Vector3D.PLUS_K); +602 Vector3D v2 = applyInverseTo(Vector3D.PLUS_I); +603 if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) { +604 throw new CardanEulerSingularityException(true); +605 } +606 return new double[] { +607 Math.atan2(-(v1.getY()), v1.getZ()), +608 Math.asin(v2.getZ()), +609 Math.atan2(-(v2.getY()), v2.getX()) +610 }; +611 +612 } else if (order == RotationOrder.XZY) { +613 +614 // r (Vector3D.plusJ) coordinates are : +615 // -sin (psi), cos (psi) cos (phi), cos (psi) sin (phi) +616 // (-r) (Vector3D.plusI) coordinates are : +617 // cos (theta) cos (psi), -sin (psi), sin (theta) cos (psi) +618 // and we can choose to have psi in the interval [-PI/2 ; +PI/2] +619 Vector3D v1 = applyTo(Vector3D.PLUS_J); +620 Vector3D v2 = applyInverseTo(Vector3D.PLUS_I); +621 if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) { +622 throw new CardanEulerSingularityException(true); +623 } +624 return new double[] { +625 Math.atan2(v1.getZ(), v1.getY()), +626 -Math.asin(v2.getY()), +627 Math.atan2(v2.getZ(), v2.getX()) +628 }; +629 +630 } else if (order == RotationOrder.YXZ) { +631 +632 // r (Vector3D.plusK) coordinates are : +633 // cos (phi) sin (theta), -sin (phi), cos (phi) cos (theta) +634 // (-r) (Vector3D.plusJ) coordinates are : +635 // sin (psi) cos (phi), cos (psi) cos (phi), -sin (phi) +636 // and we can choose to have phi in the interval [-PI/2 ; +PI/2] +637 Vector3D v1 = applyTo(Vector3D.PLUS_K); +638 Vector3D v2 = applyInverseTo(Vector3D.PLUS_J); +639 if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) { +640 throw new CardanEulerSingularityException(true); +641 } +642 return new double[] { +643 Math.atan2(v1.getX(), v1.getZ()), +644 -Math.asin(v2.getZ()), +645 Math.atan2(v2.getX(), v2.getY()) +646 }; +647 +648 } else if (order == RotationOrder.YZX) { +649 +650 // r (Vector3D.plusI) coordinates are : +651 // cos (psi) cos (theta), sin (psi), -cos (psi) sin (theta) +652 // (-r) (Vector3D.plusJ) coordinates are : +653 // sin (psi), cos (phi) cos (psi), -sin (phi) cos (psi) +654 // and we can choose to have psi in the interval [-PI/2 ; +PI/2] +655 Vector3D v1 = applyTo(Vector3D.PLUS_I); +656 Vector3D v2 = applyInverseTo(Vector3D.PLUS_J); +657 if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) { +658 throw new CardanEulerSingularityException(true); +659 } +660 return new double[] { +661 Math.atan2(-(v1.getZ()), v1.getX()), +662 Math.asin(v2.getX()), +663 Math.atan2(-(v2.getZ()), v2.getY()) +664 }; +665 +666 } else if (order == RotationOrder.ZXY) { +667 +668 // r (Vector3D.plusJ) coordinates are : +669 // -cos (phi) sin (psi), cos (phi) cos (psi), sin (phi) +670 // (-r) (Vector3D.plusK) coordinates are : +671 // -sin (theta) cos (phi), sin (phi), cos (theta) cos (phi) +672 // and we can choose to have phi in the interval [-PI/2 ; +PI/2] +673 Vector3D v1 = applyTo(Vector3D.PLUS_J); +674 Vector3D v2 = applyInverseTo(Vector3D.PLUS_K); +675 if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) { +676 throw new CardanEulerSingularityException(true); +677 } +678 return new double[] { +679 Math.atan2(-(v1.getX()), v1.getY()), +680 Math.asin(v2.getY()), +681 Math.atan2(-(v2.getX()), v2.getZ()) +682 }; +683 +684 } else if (order == RotationOrder.ZYX) { +685 +686 // r (Vector3D.plusI) coordinates are : +687 // cos (theta) cos (psi), cos (theta) sin (psi), -sin (theta) +688 // (-r) (Vector3D.plusK) coordinates are : +689 // -sin (theta), sin (phi) cos (theta), cos (phi) cos (theta) +690 // and we can choose to have theta in the interval [-PI/2 ; +PI/2] +691 Vector3D v1 = applyTo(Vector3D.PLUS_I); +692 Vector3D v2 = applyInverseTo(Vector3D.PLUS_K); +693 if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) { +694 throw new CardanEulerSingularityException(true); +695 } +696 return new double[] { +697 Math.atan2(v1.getY(), v1.getX()), +698 -Math.asin(v2.getX()), +699 Math.atan2(v2.getY(), v2.getZ()) +700 }; +701 +702 } else if (order == RotationOrder.XYX) { +703 +704 // r (Vector3D.plusI) coordinates are : +705 // cos (theta), sin (phi1) sin (theta), -cos (phi1) sin (theta) +706 // (-r) (Vector3D.plusI) coordinates are : +707 // cos (theta), sin (theta) sin (phi2), sin (theta) cos (phi2) +708 // and we can choose to have theta in the interval [0 ; PI] +709 Vector3D v1 = applyTo(Vector3D.PLUS_I); +710 Vector3D v2 = applyInverseTo(Vector3D.PLUS_I); +711 if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) { +712 throw new CardanEulerSingularityException(false); +713 } +714 return new double[] { +715 Math.atan2(v1.getY(), -v1.getZ()), +716 Math.acos(v2.getX()), +717 Math.atan2(v2.getY(), v2.getZ()) +718 }; +719 +720 } else if (order == RotationOrder.XZX) { +721 +722 // r (Vector3D.plusI) coordinates are : +723 // cos (psi), cos (phi1) sin (psi), sin (phi1) sin (psi) +724 // (-r) (Vector3D.plusI) coordinates are : +725 // cos (psi), -sin (psi) cos (phi2), sin (psi) sin (phi2) +726 // and we can choose to have psi in the interval [0 ; PI] +727 Vector3D v1 = applyTo(Vector3D.PLUS_I); +728 Vector3D v2 = applyInverseTo(Vector3D.PLUS_I); +729 if ((v2.getX() < -0.9999999999) || (v2.getX() > 0.9999999999)) { +730 throw new CardanEulerSingularityException(false); +731 } +732 return new double[] { +733 Math.atan2(v1.getZ(), v1.getY()), +734 Math.acos(v2.getX()), +735 Math.atan2(v2.getZ(), -v2.getY()) +736 }; +737 +738 } else if (order == RotationOrder.YXY) { +739 +740 // r (Vector3D.plusJ) coordinates are : +741 // sin (theta1) sin (phi), cos (phi), cos (theta1) sin (phi) +742 // (-r) (Vector3D.plusJ) coordinates are : +743 // sin (phi) sin (theta2), cos (phi), -sin (phi) cos (theta2) +744 // and we can choose to have phi in the interval [0 ; PI] +745 Vector3D v1 = applyTo(Vector3D.PLUS_J); +746 Vector3D v2 = applyInverseTo(Vector3D.PLUS_J); +747 if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) { +748 throw new CardanEulerSingularityException(false); +749 } +750 return new double[] { +751 Math.atan2(v1.getX(), v1.getZ()), +752 Math.acos(v2.getY()), +753 Math.atan2(v2.getX(), -v2.getZ()) +754 }; +755 +756 } else if (order == RotationOrder.YZY) { +757 +758 // r (Vector3D.plusJ) coordinates are : +759 // -cos (theta1) sin (psi), cos (psi), sin (theta1) sin (psi) +760 // (-r) (Vector3D.plusJ) coordinates are : +761 // sin (psi) cos (theta2), cos (psi), sin (psi) sin (theta2) +762 // and we can choose to have psi in the interval [0 ; PI] +763 Vector3D v1 = applyTo(Vector3D.PLUS_J); +764 Vector3D v2 = applyInverseTo(Vector3D.PLUS_J); +765 if ((v2.getY() < -0.9999999999) || (v2.getY() > 0.9999999999)) { +766 throw new CardanEulerSingularityException(false); +767 } +768 return new double[] { +769 Math.atan2(v1.getZ(), -v1.getX()), +770 Math.acos(v2.getY()), +771 Math.atan2(v2.getZ(), v2.getX()) +772 }; +773 +774 } else if (order == RotationOrder.ZXZ) { +775 +776 // r (Vector3D.plusK) coordinates are : +777 // sin (psi1) sin (phi), -cos (psi1) sin (phi), cos (phi) +778 // (-r) (Vector3D.plusK) coordinates are : +779 // sin (phi) sin (psi2), sin (phi) cos (psi2), cos (phi) +780 // and we can choose to have phi in the interval [0 ; PI] +781 Vector3D v1 = applyTo(Vector3D.PLUS_K); +782 Vector3D v2 = applyInverseTo(Vector3D.PLUS_K); +783 if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) { +784 throw new CardanEulerSingularityException(false); +785 } +786 return new double[] { +787 Math.atan2(v1.getX(), -v1.getY()), +788 Math.acos(v2.getZ()), +789 Math.atan2(v2.getX(), v2.getY()) +790 }; +791 +792 } else { // last possibility is ZYZ +793 +794 // r (Vector3D.plusK) coordinates are : +795 // cos (psi1) sin (theta), sin (psi1) sin (theta), cos (theta) +796 // (-r) (Vector3D.plusK) coordinates are : +797 // -sin (theta) cos (psi2), sin (theta) sin (psi2), cos (theta) +798 // and we can choose to have theta in the interval [0 ; PI] +799 Vector3D v1 = applyTo(Vector3D.PLUS_K); +800 Vector3D v2 = applyInverseTo(Vector3D.PLUS_K); +801 if ((v2.getZ() < -0.9999999999) || (v2.getZ() > 0.9999999999)) { +802 throw new CardanEulerSingularityException(false); +803 } +804 return new double[] { +805 Math.atan2(v1.getY(), v1.getX()), +806 Math.acos(v2.getZ()), +807 Math.atan2(v2.getY(), -v2.getX()) +808 }; +809 +810 } +811 +812 } +813 +814 /** Get the 3X3 matrix corresponding to the instance +815 * @return the matrix corresponding to the instance +816 */ +817 public double[][] getMatrix() { +818 +819 // products +820 double q0q0 = q0 * q0; +821 double q0q1 = q0 * q1; +822 double q0q2 = q0 * q2; +823 double q0q3 = q0 * q3; +824 double q1q1 = q1 * q1; +825 double q1q2 = q1 * q2; +826 double q1q3 = q1 * q3; +827 double q2q2 = q2 * q2; +828 double q2q3 = q2 * q3; +829 double q3q3 = q3 * q3; +830 +831 // create the matrix +832 double[][] m = new double[3][]; +833 m[0] = new double[3]; +834 m[1] = new double[3]; +835 m[2] = new double[3]; +836 +837 m [0][0] = 2.0 * (q0q0 + q1q1) - 1.0; +838 m [1][0] = 2.0 * (q1q2 - q0q3); +839 m [2][0] = 2.0 * (q1q3 + q0q2); +840 +841 m [0][1] = 2.0 * (q1q2 + q0q3); +842 m [1][1] = 2.0 * (q0q0 + q2q2) - 1.0; +843 m [2][1] = 2.0 * (q2q3 - q0q1); +844 +845 m [0][2] = 2.0 * (q1q3 - q0q2); +846 m [1][2] = 2.0 * (q2q3 + q0q1); +847 m [2][2] = 2.0 * (q0q0 + q3q3) - 1.0; +848 +849 return m; +850 +851 } +852 +853 /** Apply the rotation to a vector. +854 * @param u vector to apply the rotation to +855 * @return a new vector which is the image of u by the rotation +856 */ +857 public Vector3D applyTo(Vector3D u) { +858 +859 double x = u.getX(); +860 double y = u.getY(); +861 double z = u.getZ(); +862 +863 double s = q1 * x + q2 * y + q3 * z; +864 +865 return new Vector3D(2 * (q0 * (x * q0 - (q2 * z - q3 * y)) + s * q1) - x, +866 2 * (q0 * (y * q0 - (q3 * x - q1 * z)) + s * q2) - y, +867 2 * (q0 * (z * q0 - (q1 * y - q2 * x)) + s * q3) - z); +868 +869 } +870 +871 /** Apply the inverse of the rotation to a vector. +872 * @param u vector to apply the inverse of the rotation to +873 * @return a new vector which such that u is its image by the rotation +874 */ +875 public Vector3D applyInverseTo(Vector3D u) { +876 +877 double x = u.getX(); +878 double y = u.getY(); +879 double z = u.getZ(); +880 +881 double s = q1 * x + q2 * y + q3 * z; +882 double m0 = -q0; +883 +884 return new Vector3D(2 * (m0 * (x * m0 - (q2 * z - q3 * y)) + s * q1) - x, +885 2 * (m0 * (y * m0 - (q3 * x - q1 * z)) + s * q2) - y, +886 2 * (m0 * (z * m0 - (q1 * y - q2 * x)) + s * q3) - z); +887 +888 } +889 +890 /** Apply the instance to another rotation. +891 * Applying the instance to a rotation is computing the composition +892 * in an order compliant with the following rule : let u be any +893 * vector and v its image by r (i.e. r.applyTo(u) = v), let w be the image +894 * of v by the instance (i.e. applyTo(v) = w), then w = comp.applyTo(u), +895 * where comp = applyTo(r). +896 * @param r rotation to apply the rotation to +897 * @return a new rotation which is the composition of r by the instance +898 */ +899 public Rotation applyTo(Rotation r) { +900 return new Rotation(r.q0 * q0 - (r.q1 * q1 + r.q2 * q2 + r.q3 * q3), +901 r.q1 * q0 + r.q0 * q1 + (r.q2 * q3 - r.q3 * q2), +902 r.q2 * q0 + r.q0 * q2 + (r.q3 * q1 - r.q1 * q3), +903 r.q3 * q0 + r.q0 * q3 + (r.q1 * q2 - r.q2 * q1), +904 false); +905 } +906 +907 /** Apply the inverse of the instance to another rotation. +908 * Applying the inverse of the instance to a rotation is computing +909 * the composition in an order compliant with the following rule : +910 * let u be any vector and v its image by r (i.e. r.applyTo(u) = v), +911 * let w be the inverse image of v by the instance +912 * (i.e. applyInverseTo(v) = w), then w = comp.applyTo(u), where +913 * comp = applyInverseTo(r). +914 * @param r rotation to apply the rotation to +915 * @return a new rotation which is the composition of r by the inverse +916 * of the instance +917 */ +918 public Rotation applyInverseTo(Rotation r) { +919 return new Rotation(-r.q0 * q0 - (r.q1 * q1 + r.q2 * q2 + r.q3 * q3), +920 -r.q1 * q0 + r.q0 * q1 + (r.q2 * q3 - r.q3 * q2), +921 -r.q2 * q0 + r.q0 * q2 + (r.q3 * q1 - r.q1 * q3), +922 -r.q3 * q0 + r.q0 * q3 + (r.q1 * q2 - r.q2 * q1), +923 false); +924 } +925 +926 /** Perfect orthogonality on a 3X3 matrix. +927 * @param m initial matrix (not exactly orthogonal) +928 * @param threshold convergence threshold for the iterative +929 * orthogonality correction (convergence is reached when the +930 * difference between two steps of the Frobenius norm of the +931 * correction is below this threshold) +932 * @return an orthogonal matrix close to m +933 * @exception NotARotationMatrixException if the matrix cannot be +934 * orthogonalized with the given threshold after 10 iterations +935 */ +936 private double[][] orthogonalizeMatrix(double[][] m, double threshold) +937 throws NotARotationMatrixException { +938 double[] m0 = m[0]; +939 double[] m1 = m[1]; +940 double[] m2 = m[2]; +941 double x00 = m0[0]; +942 double x01 = m0[1]; +943 double x02 = m0[2]; +944 double x10 = m1[0]; +945 double x11 = m1[1]; +946 double x12 = m1[2]; +947 double x20 = m2[0]; +948 double x21 = m2[1]; +949 double x22 = m2[2]; +950 double fn = 0; +951 double fn1; +952 +953 double[][] o = new double[3][3]; +954 double[] o0 = o[0]; +955 double[] o1 = o[1]; +956 double[] o2 = o[2]; +957 +958 // iterative correction: Xn+1 = Xn - 0.5 * (Xn.Mt.Xn - M) +959 int i = 0; +960 while (++i < 11) { +961 +962 // Mt.Xn +963 double mx00 = m0[0] * x00 + m1[0] * x10 + m2[0] * x20; +964 double mx10 = m0[1] * x00 + m1[1] * x10 + m2[1] * x20; +965 double mx20 = m0[2] * x00 + m1[2] * x10 + m2[2] * x20; +966 double mx01 = m0[0] * x01 + m1[0] * x11 + m2[0] * x21; +967 double mx11 = m0[1] * x01 + m1[1] * x11 + m2[1] * x21; +968 double mx21 = m0[2] * x01 + m1[2] * x11 + m2[2] * x21; +969 double mx02 = m0[0] * x02 + m1[0] * x12 + m2[0] * x22; +970 double mx12 = m0[1] * x02 + m1[1] * x12 + m2[1] * x22; +971 double mx22 = m0[2] * x02 + m1[2] * x12 + m2[2] * x22; +972 +973 // Xn+1 +974 o0[0] = x00 - 0.5 * (x00 * mx00 + x01 * mx10 + x02 * mx20 - m0[0]); +975 o0[1] = x01 - 0.5 * (x00 * mx01 + x01 * mx11 + x02 * mx21 - m0[1]); +976 o0[2] = x02 - 0.5 * (x00 * mx02 + x01 * mx12 + x02 * mx22 - m0[2]); +977 o1[0] = x10 - 0.5 * (x10 * mx00 + x11 * mx10 + x12 * mx20 - m1[0]); +978 o1[1] = x11 - 0.5 * (x10 * mx01 + x11 * mx11 + x12 * mx21 - m1[1]); +979 o1[2] = x12 - 0.5 * (x10 * mx02 + x11 * mx12 + x12 * mx22 - m1[2]); +980 o2[0] = x20 - 0.5 * (x20 * mx00 + x21 * mx10 + x22 * mx20 - m2[0]); +981 o2[1] = x21 - 0.5 * (x20 * mx01 + x21 * mx11 + x22 * mx21 - m2[1]); +982 o2[2] = x22 - 0.5 * (x20 * mx02 + x21 * mx12 + x22 * mx22 - m2[2]); +983 +984 // correction on each elements +985 double corr00 = o0[0] - m0[0]; +986 double corr01 = o0[1] - m0[1]; +987 double corr02 = o0[2] - m0[2]; +988 double corr10 = o1[0] - m1[0]; +989 double corr11 = o1[1] - m1[1]; +990 double corr12 = o1[2] - m1[2]; +991 double corr20 = o2[0] - m2[0]; +992 double corr21 = o2[1] - m2[1]; +993 double corr22 = o2[2] - m2[2]; +994 +995 // Frobenius norm of the correction +996 fn1 = corr00 * corr00 + corr01 * corr01 + corr02 * corr02 + +997 corr10 * corr10 + corr11 * corr11 + corr12 * corr12 + +998 corr20 * corr20 + corr21 * corr21 + corr22 * corr22; +999 +1000 // convergence test +1001 if (Math.abs(fn1 - fn) <= threshold) +1002 return o; +1003 +1004 // prepare next iteration +1005 x00 = o0[0]; +1006 x01 = o0[1]; +1007 x02 = o0[2]; +1008 x10 = o1[0]; +1009 x11 = o1[1]; +1010 x12 = o1[2]; +1011 x20 = o2[0]; +1012 x21 = o2[1]; +1013 x22 = o2[2]; +1014 fn = fn1; +1015 +1016 } +1017 +1018 // the algorithm did not converge after 10 iterations +1019 throw new NotARotationMatrixException( +1020 "unable to orthogonalize matrix in {0} iterations", +1021 i - 1); +1022 } +1023 +1024 /** Compute the <i>distance</i> between two rotations. +1025 * <p>The <i>distance</i> is intended here as a way to check if two +1026 * rotations are almost similar (i.e. they transform vectors the same way) +1027 * or very different. It is mathematically defined as the angle of +1028 * the rotation r that prepended to one of the rotations gives the other +1029 * one:</p> +1030 * <pre> +1031 * r<sub>1</sub>(r) = r<sub>2</sub> +1032 * </pre> +1033 * <p>This distance is an angle between 0 and π. Its value is the smallest +1034 * possible upper bound of the angle in radians between r<sub>1</sub>(v) +1035 * and r<sub>2</sub>(v) for all possible vectors v. This upper bound is +1036 * reached for some v. The distance is equal to 0 if and only if the two +1037 * rotations are identical.</p> +1038 * <p>Comparing two rotations should always be done using this value rather +1039 * than for example comparing the components of the quaternions. It is much +1040 * more stable, and has a geometric meaning. Also comparing quaternions +1041 * components is error prone since for example quaternions (0.36, 0.48, -0.48, -0.64) +1042 * and (-0.36, -0.48, 0.48, 0.64) represent exactly the same rotation despite +1043 * their components are different (they are exact opposites).</p> +1044 * @param r1 first rotation +1045 * @param r2 second rotation +1046 * @return <i>distance</i> between r1 and r2 +1047 */ +1048 public static double distance(Rotation r1, Rotation r2) { +1049 return r1.applyInverseTo(r2).getAngle(); +1050 } +1051 +1052 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/geometry/RotationOrder.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/geometry/RotationOrder.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,241 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.geometry; +019 +020 /** +021 * This class is a utility representing a rotation order specification +022 * for Cardan or Euler angles specification. +023 * +024 * This class cannot be instanciated by the user. He can only use one +025 * of the twelve predefined supported orders as an argument to either +026 * the {@link Rotation#Rotation(RotationOrder,double,double,double)} +027 * constructor or the {@link Rotation#getAngles} method. +028 * +029 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +030 * @since 1.2 +031 */ +032 public final class RotationOrder { +033 +034 /** Set of Cardan angles. +035 * this ordered set of rotations is around X, then around Y, then +036 * around Z +037 */ +038 public static final RotationOrder XYZ = +039 new RotationOrder("XYZ", Vector3D.PLUS_I, Vector3D.PLUS_J, Vector3D.PLUS_K); +040 +041 /** Set of Cardan angles. +042 * this ordered set of rotations is around X, then around Z, then +043 * around Y +044 */ +045 public static final RotationOrder XZY = +046 new RotationOrder("XZY", Vector3D.PLUS_I, Vector3D.PLUS_K, Vector3D.PLUS_J); +047 +048 /** Set of Cardan angles. +049 * this ordered set of rotations is around Y, then around X, then +050 * around Z +051 */ +052 public static final RotationOrder YXZ = +053 new RotationOrder("YXZ", Vector3D.PLUS_J, Vector3D.PLUS_I, Vector3D.PLUS_K); +054 +055 /** Set of Cardan angles. +056 * this ordered set of rotations is around Y, then around Z, then +057 * around X +058 */ +059 public static final RotationOrder YZX = +060 new RotationOrder("YZX", Vector3D.PLUS_J, Vector3D.PLUS_K, Vector3D.PLUS_I); +061 +062 /** Set of Cardan angles. +063 * this ordered set of rotations is around Z, then around X, then +064 * around Y +065 */ +066 public static final RotationOrder ZXY = +067 new RotationOrder("ZXY", Vector3D.PLUS_K, Vector3D.PLUS_I, Vector3D.PLUS_J); +068 +069 /** Set of Cardan angles. +070 * this ordered set of rotations is around Z, then around Y, then +071 * around X +072 */ +073 public static final RotationOrder ZYX = +074 new RotationOrder("ZYX", Vector3D.PLUS_K, Vector3D.PLUS_J, Vector3D.PLUS_I); +075 +076 /** Set of Euler angles. +077 * this ordered set of rotations is around X, then around Y, then +078 * around X +079 */ +080 public static final RotationOrder XYX = +081 new RotationOrder("XYX", Vector3D.PLUS_I, Vector3D.PLUS_J, Vector3D.PLUS_I); +082 +083 /** Set of Euler angles. +084 * this ordered set of rotations is around X, then around Z, then +085 * around X +086 */ +087 public static final RotationOrder XZX = +088 new RotationOrder("XZX", Vector3D.PLUS_I, Vector3D.PLUS_K, Vector3D.PLUS_I); +089 +090 /** Set of Euler angles. +091 * this ordered set of rotations is around Y, then around X, then +092 * around Y +093 */ +094 public static final RotationOrder YXY = +095 new RotationOrder("YXY", Vector3D.PLUS_J, Vector3D.PLUS_I, Vector3D.PLUS_J); +096 +097 /** Set of Euler angles. +098 * this ordered set of rotations is around Y, then around Z, then +099 * around Y +100 */ +101 public static final RotationOrder YZY = +102 new RotationOrder("YZY", Vector3D.PLUS_J, Vector3D.PLUS_K, Vector3D.PLUS_J); +103 +104 /** Set of Euler angles. +105 * this ordered set of rotations is around Z, then around X, then +106 * around Z +107 */ +108 public static final RotationOrder ZXZ = +109 new RotationOrder("ZXZ", Vector3D.PLUS_K, Vector3D.PLUS_I, Vector3D.PLUS_K); +110 +111 /** Set of Euler angles. +112 * this ordered set of rotations is around Z, then around Y, then +113 * around Z +114 */ +115 public static final RotationOrder ZYZ = +116 new RotationOrder("ZYZ", Vector3D.PLUS_K, Vector3D.PLUS_J, Vector3D.PLUS_K); +117 +118 /** Name of the rotations order. */ +119 private final String name; +120 +121 /** Axis of the first rotation. */ +122 private final Vector3D a1; +123 +124 /** Axis of the second rotation. */ +125 private final Vector3D a2; +126 +127 /** Axis of the third rotation. */ +128 private final Vector3D a3; +129 +130 /** Private constructor. +131 * This is a utility class that cannot be instantiated by the user, +132 * so its only constructor is private. +133 * @param name name of the rotation order +134 * @param a1 axis of the first rotation +135 * @param a2 axis of the second rotation +136 * @param a3 axis of the third rotation +137 */ +138 private RotationOrder(final String name, +139 final Vector3D a1, final Vector3D a2, final Vector3D a3) { +140 this.name = name; +141 this.a1 = a1; +142 this.a2 = a2; +143 this.a3 = a3; +144 } +145 +146 /** Get a string representation of the instance. +147 * @return a string representation of the instance (in fact, its name) +148 */ +149 @Override +150 public String toString() { +151 return name; +152 } +153 +154 /** Get the axis of the first rotation. +155 * @return axis of the first rotation +156 */ +157 public Vector3D getA1() { +158 return a1; +159 } +160 +161 /** Get the axis of the second rotation. +162 * @return axis of the second rotation +163 */ +164 public Vector3D getA2() { +165 return a2; +166 } +167 +168 /** Get the axis of the second rotation. +169 * @return axis of the second rotation +170 */ +171 public Vector3D getA3() { +172 return a3; +173 } +174 +175 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/geometry/Vector3D.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/geometry/Vector3D.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,598 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.geometry; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.util.MathUtils; +024 +025 /** +026 * This class implements vectors in a three-dimensional space. +027 * <p>Instance of this class are guaranteed to be immutable.</p> +028 * @version $Revision: 922713 $ $Date: 2010-03-13 20:26:13 -0500 (Sat, 13 Mar 2010) $ +029 * @since 1.2 +030 */ +031 +032 public class Vector3D +033 implements Serializable { +034 +035 /** Null vector (coordinates: 0, 0, 0). */ +036 public static final Vector3D ZERO = new Vector3D(0, 0, 0); +037 +038 /** First canonical vector (coordinates: 1, 0, 0). */ +039 public static final Vector3D PLUS_I = new Vector3D(1, 0, 0); +040 +041 /** Opposite of the first canonical vector (coordinates: -1, 0, 0). */ +042 public static final Vector3D MINUS_I = new Vector3D(-1, 0, 0); +043 +044 /** Second canonical vector (coordinates: 0, 1, 0). */ +045 public static final Vector3D PLUS_J = new Vector3D(0, 1, 0); +046 +047 /** Opposite of the second canonical vector (coordinates: 0, -1, 0). */ +048 public static final Vector3D MINUS_J = new Vector3D(0, -1, 0); +049 +050 /** Third canonical vector (coordinates: 0, 0, 1). */ +051 public static final Vector3D PLUS_K = new Vector3D(0, 0, 1); +052 +053 /** Opposite of the third canonical vector (coordinates: 0, 0, -1). */ +054 public static final Vector3D MINUS_K = new Vector3D(0, 0, -1); +055 +056 // CHECKSTYLE: stop ConstantName +057 /** A vector with all coordinates set to NaN. */ +058 public static final Vector3D NaN = new Vector3D(Double.NaN, Double.NaN, Double.NaN); +059 // CHECKSTYLE: resume ConstantName +060 +061 /** A vector with all coordinates set to positive infinity. */ +062 public static final Vector3D POSITIVE_INFINITY = +063 new Vector3D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); +064 +065 /** A vector with all coordinates set to negative infinity. */ +066 public static final Vector3D NEGATIVE_INFINITY = +067 new Vector3D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY); +068 +069 /** Default format. */ +070 private static final Vector3DFormat DEFAULT_FORMAT = +071 Vector3DFormat.getInstance(); +072 +073 /** Serializable version identifier. */ +074 private static final long serialVersionUID = 5133268763396045979L; +075 +076 /** Abscissa. */ +077 private final double x; +078 +079 /** Ordinate. */ +080 private final double y; +081 +082 /** Height. */ +083 private final double z; +084 +085 /** Simple constructor. +086 * Build a vector from its coordinates +087 * @param x abscissa +088 * @param y ordinate +089 * @param z height +090 * @see #getX() +091 * @see #getY() +092 * @see #getZ() +093 */ +094 public Vector3D(double x, double y, double z) { +095 this.x = x; +096 this.y = y; +097 this.z = z; +098 } +099 +100 /** Simple constructor. +101 * Build a vector from its azimuthal coordinates +102 * @param alpha azimuth (α) around Z +103 * (0 is +X, π/2 is +Y, π is -X and 3π/2 is -Y) +104 * @param delta elevation (δ) above (XY) plane, from -π/2 to +π/2 +105 * @see #getAlpha() +106 * @see #getDelta() +107 */ +108 public Vector3D(double alpha, double delta) { +109 double cosDelta = Math.cos(delta); +110 this.x = Math.cos(alpha) * cosDelta; +111 this.y = Math.sin(alpha) * cosDelta; +112 this.z = Math.sin(delta); +113 } +114 +115 /** Multiplicative constructor +116 * Build a vector from another one and a scale factor. +117 * The vector built will be a * u +118 * @param a scale factor +119 * @param u base (unscaled) vector +120 */ +121 public Vector3D(double a, Vector3D u) { +122 this.x = a * u.x; +123 this.y = a * u.y; +124 this.z = a * u.z; +125 } +126 +127 /** Linear constructor +128 * Build a vector from two other ones and corresponding scale factors. +129 * The vector built will be a1 * u1 + a2 * u2 +130 * @param a1 first scale factor +131 * @param u1 first base (unscaled) vector +132 * @param a2 second scale factor +133 * @param u2 second base (unscaled) vector +134 */ +135 public Vector3D(double a1, Vector3D u1, double a2, Vector3D u2) { +136 this.x = a1 * u1.x + a2 * u2.x; +137 this.y = a1 * u1.y + a2 * u2.y; +138 this.z = a1 * u1.z + a2 * u2.z; +139 } +140 +141 /** Linear constructor +142 * Build a vector from three other ones and corresponding scale factors. +143 * The vector built will be a1 * u1 + a2 * u2 + a3 * u3 +144 * @param a1 first scale factor +145 * @param u1 first base (unscaled) vector +146 * @param a2 second scale factor +147 * @param u2 second base (unscaled) vector +148 * @param a3 third scale factor +149 * @param u3 third base (unscaled) vector +150 */ +151 public Vector3D(double a1, Vector3D u1, double a2, Vector3D u2, +152 double a3, Vector3D u3) { +153 this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x; +154 this.y = a1 * u1.y + a2 * u2.y + a3 * u3.y; +155 this.z = a1 * u1.z + a2 * u2.z + a3 * u3.z; +156 } +157 +158 /** Linear constructor +159 * Build a vector from four other ones and corresponding scale factors. +160 * The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4 +161 * @param a1 first scale factor +162 * @param u1 first base (unscaled) vector +163 * @param a2 second scale factor +164 * @param u2 second base (unscaled) vector +165 * @param a3 third scale factor +166 * @param u3 third base (unscaled) vector +167 * @param a4 fourth scale factor +168 * @param u4 fourth base (unscaled) vector +169 */ +170 public Vector3D(double a1, Vector3D u1, double a2, Vector3D u2, +171 double a3, Vector3D u3, double a4, Vector3D u4) { +172 this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x + a4 * u4.x; +173 this.y = a1 * u1.y + a2 * u2.y + a3 * u3.y + a4 * u4.y; +174 this.z = a1 * u1.z + a2 * u2.z + a3 * u3.z + a4 * u4.z; +175 } +176 +177 /** Get the abscissa of the vector. +178 * @return abscissa of the vector +179 * @see #Vector3D(double, double, double) +180 */ +181 public double getX() { +182 return x; +183 } +184 +185 /** Get the ordinate of the vector. +186 * @return ordinate of the vector +187 * @see #Vector3D(double, double, double) +188 */ +189 public double getY() { +190 return y; +191 } +192 +193 /** Get the height of the vector. +194 * @return height of the vector +195 * @see #Vector3D(double, double, double) +196 */ +197 public double getZ() { +198 return z; +199 } +200 +201 /** Get the L<sub>1</sub> norm for the vector. +202 * @return L<sub>1</sub> norm for the vector +203 */ +204 public double getNorm1() { +205 return Math.abs(x) + Math.abs(y) + Math.abs(z); +206 } +207 +208 /** Get the L<sub>2</sub> norm for the vector. +209 * @return euclidian norm for the vector +210 */ +211 public double getNorm() { +212 return Math.sqrt (x * x + y * y + z * z); +213 } +214 +215 /** Get the square of the norm for the vector. +216 * @return square of the euclidian norm for the vector +217 */ +218 public double getNormSq() { +219 return x * x + y * y + z * z; +220 } +221 +222 /** Get the L<sub>∞</sub> norm for the vector. +223 * @return L<sub>∞</sub> norm for the vector +224 */ +225 public double getNormInf() { +226 return Math.max(Math.max(Math.abs(x), Math.abs(y)), Math.abs(z)); +227 } +228 +229 /** Get the azimuth of the vector. +230 * @return azimuth (α) of the vector, between -π and +π +231 * @see #Vector3D(double, double) +232 */ +233 public double getAlpha() { +234 return Math.atan2(y, x); +235 } +236 +237 /** Get the elevation of the vector. +238 * @return elevation (δ) of the vector, between -π/2 and +π/2 +239 * @see #Vector3D(double, double) +240 */ +241 public double getDelta() { +242 return Math.asin(z / getNorm()); +243 } +244 +245 /** Add a vector to the instance. +246 * @param v vector to add +247 * @return a new vector +248 */ +249 public Vector3D add(Vector3D v) { +250 return new Vector3D(x + v.x, y + v.y, z + v.z); +251 } +252 +253 /** Add a scaled vector to the instance. +254 * @param factor scale factor to apply to v before adding it +255 * @param v vector to add +256 * @return a new vector +257 */ +258 public Vector3D add(double factor, Vector3D v) { +259 return new Vector3D(x + factor * v.x, y + factor * v.y, z + factor * v.z); +260 } +261 +262 /** Subtract a vector from the instance. +263 * @param v vector to subtract +264 * @return a new vector +265 */ +266 public Vector3D subtract(Vector3D v) { +267 return new Vector3D(x - v.x, y - v.y, z - v.z); +268 } +269 +270 /** Subtract a scaled vector from the instance. +271 * @param factor scale factor to apply to v before subtracting it +272 * @param v vector to subtract +273 * @return a new vector +274 */ +275 public Vector3D subtract(double factor, Vector3D v) { +276 return new Vector3D(x - factor * v.x, y - factor * v.y, z - factor * v.z); +277 } +278 +279 /** Get a normalized vector aligned with the instance. +280 * @return a new normalized vector +281 * @exception ArithmeticException if the norm is zero +282 */ +283 public Vector3D normalize() { +284 double s = getNorm(); +285 if (s == 0) { +286 throw MathRuntimeException.createArithmeticException("cannot normalize a zero norm vector"); +287 } +288 return scalarMultiply(1 / s); +289 } +290 +291 /** Get a vector orthogonal to the instance. +292 * <p>There are an infinite number of normalized vectors orthogonal +293 * to the instance. This method picks up one of them almost +294 * arbitrarily. It is useful when one needs to compute a reference +295 * frame with one of the axes in a predefined direction. The +296 * following example shows how to build a frame having the k axis +297 * aligned with the known vector u : +298 * <pre><code> +299 * Vector3D k = u.normalize(); +300 * Vector3D i = k.orthogonal(); +301 * Vector3D j = Vector3D.crossProduct(k, i); +302 * </code></pre></p> +303 * @return a new normalized vector orthogonal to the instance +304 * @exception ArithmeticException if the norm of the instance is null +305 */ +306 public Vector3D orthogonal() { +307 +308 double threshold = 0.6 * getNorm(); +309 if (threshold == 0) { +310 throw MathRuntimeException.createArithmeticException("zero norm"); +311 } +312 +313 if ((x >= -threshold) && (x <= threshold)) { +314 double inverse = 1 / Math.sqrt(y * y + z * z); +315 return new Vector3D(0, inverse * z, -inverse * y); +316 } else if ((y >= -threshold) && (y <= threshold)) { +317 double inverse = 1 / Math.sqrt(x * x + z * z); +318 return new Vector3D(-inverse * z, 0, inverse * x); +319 } +320 double inverse = 1 / Math.sqrt(x * x + y * y); +321 return new Vector3D(inverse * y, -inverse * x, 0); +322 +323 } +324 +325 /** Compute the angular separation between two vectors. +326 * <p>This method computes the angular separation between two +327 * vectors using the dot product for well separated vectors and the +328 * cross product for almost aligned vectors. This allows to have a +329 * good accuracy in all cases, even for vectors very close to each +330 * other.</p> +331 * @param v1 first vector +332 * @param v2 second vector +333 * @return angular separation between v1 and v2 +334 * @exception ArithmeticException if either vector has a null norm +335 */ +336 public static double angle(Vector3D v1, Vector3D v2) { +337 +338 double normProduct = v1.getNorm() * v2.getNorm(); +339 if (normProduct == 0) { +340 throw MathRuntimeException.createArithmeticException("zero norm"); +341 } +342 +343 double dot = dotProduct(v1, v2); +344 double threshold = normProduct * 0.9999; +345 if ((dot < -threshold) || (dot > threshold)) { +346 // the vectors are almost aligned, compute using the sine +347 Vector3D v3 = crossProduct(v1, v2); +348 if (dot >= 0) { +349 return Math.asin(v3.getNorm() / normProduct); +350 } +351 return Math.PI - Math.asin(v3.getNorm() / normProduct); +352 } +353 +354 // the vectors are sufficiently separated to use the cosine +355 return Math.acos(dot / normProduct); +356 +357 } +358 +359 /** Get the opposite of the instance. +360 * @return a new vector which is opposite to the instance +361 */ +362 public Vector3D negate() { +363 return new Vector3D(-x, -y, -z); +364 } +365 +366 /** Multiply the instance by a scalar +367 * @param a scalar +368 * @return a new vector +369 */ +370 public Vector3D scalarMultiply(double a) { +371 return new Vector3D(a * x, a * y, a * z); +372 } +373 +374 /** +375 * Returns true if any coordinate of this vector is NaN; false otherwise +376 * @return true if any coordinate of this vector is NaN; false otherwise +377 */ +378 public boolean isNaN() { +379 return Double.isNaN(x) || Double.isNaN(y) || Double.isNaN(z); +380 } +381 +382 /** +383 * Returns true if any coordinate of this vector is infinite and none are NaN; +384 * false otherwise +385 * @return true if any coordinate of this vector is infinite and none are NaN; +386 * false otherwise +387 */ +388 public boolean isInfinite() { +389 return !isNaN() && (Double.isInfinite(x) || Double.isInfinite(y) || Double.isInfinite(z)); +390 } +391 +392 /** +393 * Test for the equality of two 3D vectors. +394 * <p> +395 * If all coordinates of two 3D vectors are exactly the same, and none are +396 * <code>Double.NaN</code>, the two 3D vectors are considered to be equal. +397 * </p> +398 * <p> +399 * <code>NaN</code> coordinates are considered to affect globally the vector +400 * and be equals to each other - i.e, if either (or all) coordinates of the +401 * 3D vector are equal to <code>Double.NaN</code>, the 3D vector is equal to +402 * {@link #NaN}. +403 * </p> +404 * +405 * @param other Object to test for equality to this +406 * @return true if two 3D vector objects are equal, false if +407 * object is null, not an instance of Vector3D, or +408 * not equal to this Vector3D instance +409 * +410 */ +411 @Override +412 public boolean equals(Object other) { +413 +414 if (this == other) { +415 return true; +416 } +417 +418 if (other instanceof Vector3D) { +419 final Vector3D rhs = (Vector3D)other; +420 if (rhs.isNaN()) { +421 return this.isNaN(); +422 } +423 +424 return (x == rhs.x) && (y == rhs.y) && (z == rhs.z); +425 } +426 return false; +427 } +428 +429 /** +430 * Get a hashCode for the 3D vector. +431 * <p> +432 * All NaN values have the same hash code.</p> +433 * +434 * @return a hash code value for this object +435 */ +436 @Override +437 public int hashCode() { +438 if (isNaN()) { +439 return 8; +440 } +441 return 31 * (23 * MathUtils.hash(x) + 19 * MathUtils.hash(y) + MathUtils.hash(z)); +442 } +443 +444 /** Compute the dot-product of two vectors. +445 * @param v1 first vector +446 * @param v2 second vector +447 * @return the dot product v1.v2 +448 */ +449 public static double dotProduct(Vector3D v1, Vector3D v2) { +450 return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; +451 } +452 +453 /** Compute the cross-product of two vectors. +454 * @param v1 first vector +455 * @param v2 second vector +456 * @return the cross product v1 ^ v2 as a new Vector +457 */ +458 public static Vector3D crossProduct(Vector3D v1, Vector3D v2) { +459 return new Vector3D(v1.y * v2.z - v1.z * v2.y, +460 v1.z * v2.x - v1.x * v2.z, +461 v1.x * v2.y - v1.y * v2.x); +462 } +463 +464 /** Compute the distance between two vectors according to the L<sub>1</sub> norm. +465 * <p>Calling this method is equivalent to calling: +466 * <code>v1.subtract(v2).getNorm1()</code> except that no intermediate +467 * vector is built</p> +468 * @param v1 first vector +469 * @param v2 second vector +470 * @return the distance between v1 and v2 according to the L<sub>1</sub> norm +471 */ +472 public static double distance1(Vector3D v1, Vector3D v2) { +473 final double dx = Math.abs(v2.x - v1.x); +474 final double dy = Math.abs(v2.y - v1.y); +475 final double dz = Math.abs(v2.z - v1.z); +476 return dx + dy + dz; +477 } +478 +479 /** Compute the distance between two vectors according to the L<sub>2</sub> norm. +480 * <p>Calling this method is equivalent to calling: +481 * <code>v1.subtract(v2).getNorm()</code> except that no intermediate +482 * vector is built</p> +483 * @param v1 first vector +484 * @param v2 second vector +485 * @return the distance between v1 and v2 according to the L<sub>2</sub> norm +486 */ +487 public static double distance(Vector3D v1, Vector3D v2) { +488 final double dx = v2.x - v1.x; +489 final double dy = v2.y - v1.y; +490 final double dz = v2.z - v1.z; +491 return Math.sqrt(dx * dx + dy * dy + dz * dz); +492 } +493 +494 /** Compute the distance between two vectors according to the L<sub>∞</sub> norm. +495 * <p>Calling this method is equivalent to calling: +496 * <code>v1.subtract(v2).getNormInf()</code> except that no intermediate +497 * vector is built</p> +498 * @param v1 first vector +499 * @param v2 second vector +500 * @return the distance between v1 and v2 according to the L<sub>∞</sub> norm +501 */ +502 public static double distanceInf(Vector3D v1, Vector3D v2) { +503 final double dx = Math.abs(v2.x - v1.x); +504 final double dy = Math.abs(v2.y - v1.y); +505 final double dz = Math.abs(v2.z - v1.z); +506 return Math.max(Math.max(dx, dy), dz); +507 } +508 +509 /** Compute the square of the distance between two vectors. +510 * <p>Calling this method is equivalent to calling: +511 * <code>v1.subtract(v2).getNormSq()</code> except that no intermediate +512 * vector is built</p> +513 * @param v1 first vector +514 * @param v2 second vector +515 * @return the square of the distance between v1 and v2 +516 */ +517 public static double distanceSq(Vector3D v1, Vector3D v2) { +518 final double dx = v2.x - v1.x; +519 final double dy = v2.y - v1.y; +520 final double dz = v2.z - v1.z; +521 return dx * dx + dy * dy + dz * dz; +522 } +523 +524 /** Get a string representation of this vector. +525 * @return a string representation of this vector +526 */ +527 @Override +528 public String toString() { +529 return DEFAULT_FORMAT.format(this); +530 } +531 +532 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/geometry/Vector3DFormat.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/geometry/Vector3DFormat.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,408 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.geometry; +019 +020 import java.text.FieldPosition; +021 import java.text.NumberFormat; +022 import java.text.ParseException; +023 import java.text.ParsePosition; +024 import java.util.Locale; +025 +026 import org.apache.commons.math.MathRuntimeException; +027 import org.apache.commons.math.util.CompositeFormat; +028 +029 /** +030 * Formats a 3D vector in components list format "{x; y; z}". +031 * <p>The prefix and suffix "{" and "}" and the separator "; " can be replaced by +032 * any user-defined strings. The number format for components can be configured.</p> +033 * <p>White space is ignored at parse time, even if it is in the prefix, suffix +034 * or separator specifications. So even if the default separator does include a space +035 * character that is used at format time, both input string "{1;1;1}" and +036 * " { 1 ; 1 ; 1 } " will be parsed without error and the same vector will be +037 * returned. In the second case, however, the parse position after parsing will be +038 * just after the closing curly brace, i.e. just before the trailing space.</p> +039 * +040 * @version $Revision: 772119 $ $Date: 2009-05-06 05:43:28 -0400 (Wed, 06 May 2009) $ +041 */ +042 public class Vector3DFormat extends CompositeFormat { +043 +044 /** Serializable version identifier */ +045 private static final long serialVersionUID = -5447606608652576301L; +046 +047 /** The default prefix: "{". */ +048 private static final String DEFAULT_PREFIX = "{"; +049 +050 /** The default suffix: "}". */ +051 private static final String DEFAULT_SUFFIX = "}"; +052 +053 /** The default separator: ", ". */ +054 private static final String DEFAULT_SEPARATOR = "; "; +055 +056 /** Prefix. */ +057 private final String prefix; +058 +059 /** Suffix. */ +060 private final String suffix; +061 +062 /** Separator. */ +063 private final String separator; +064 +065 /** Trimmed prefix. */ +066 private final String trimmedPrefix; +067 +068 /** Trimmed suffix. */ +069 private final String trimmedSuffix; +070 +071 /** Trimmed separator. */ +072 private final String trimmedSeparator; +073 +074 /** The format used for components. */ +075 private NumberFormat format; +076 +077 /** +078 * Create an instance with default settings. +079 * <p>The instance uses the default prefix, suffix and separator: +080 * "{", "}", and "; " and the default number format for components.</p> +081 */ +082 public Vector3DFormat() { +083 this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, getDefaultNumberFormat()); +084 } +085 +086 /** +087 * Create an instance with a custom number format for components. +088 * @param format the custom format for components. +089 */ +090 public Vector3DFormat(final NumberFormat format) { +091 this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, format); +092 } +093 +094 /** +095 * Create an instance with custom prefix, suffix and separator. +096 * @param prefix prefix to use instead of the default "{" +097 * @param suffix suffix to use instead of the default "}" +098 * @param separator separator to use instead of the default "; " +099 */ +100 public Vector3DFormat(final String prefix, final String suffix, +101 final String separator) { +102 this(prefix, suffix, separator, getDefaultNumberFormat()); +103 } +104 +105 /** +106 * Create an instance with custom prefix, suffix, separator and format +107 * for components. +108 * @param prefix prefix to use instead of the default "{" +109 * @param suffix suffix to use instead of the default "}" +110 * @param separator separator to use instead of the default "; " +111 * @param format the custom format for components. +112 */ +113 public Vector3DFormat(final String prefix, final String suffix, +114 final String separator, final NumberFormat format) { +115 this.prefix = prefix; +116 this.suffix = suffix; +117 this.separator = separator; +118 trimmedPrefix = prefix.trim(); +119 trimmedSuffix = suffix.trim(); +120 trimmedSeparator = separator.trim(); +121 this.format = format; +122 } +123 +124 /** +125 * Get the set of locales for which 3D vectors formats are available. +126 * <p>This is the same set as the {@link NumberFormat} set.</p> +127 * @return available 3D vector format locales. +128 */ +129 public static Locale[] getAvailableLocales() { +130 return NumberFormat.getAvailableLocales(); +131 } +132 +133 /** +134 * Get the format prefix. +135 * @return format prefix. +136 */ +137 public String getPrefix() { +138 return prefix; +139 } +140 +141 /** +142 * Get the format suffix. +143 * @return format suffix. +144 */ +145 public String getSuffix() { +146 return suffix; +147 } +148 +149 /** +150 * Get the format separator between components. +151 * @return format separator. +152 */ +153 public String getSeparator() { +154 return separator; +155 } +156 +157 /** +158 * Get the components format. +159 * @return components format. +160 */ +161 public NumberFormat getFormat() { +162 return format; +163 } +164 +165 /** +166 * Returns the default 3D vector format for the current locale. +167 * @return the default 3D vector format. +168 */ +169 public static Vector3DFormat getInstance() { +170 return getInstance(Locale.getDefault()); +171 } +172 +173 /** +174 * Returns the default 3D vector format for the given locale. +175 * @param locale the specific locale used by the format. +176 * @return the 3D vector format specific to the given locale. +177 */ +178 public static Vector3DFormat getInstance(final Locale locale) { +179 return new Vector3DFormat(getDefaultNumberFormat(locale)); +180 } +181 +182 /** +183 * This static method calls {@link #format(Object)} on a default instance of +184 * Vector3DFormat. +185 * +186 * @param v Vector3D object to format +187 * @return A formatted vector +188 */ +189 public static String formatVector3D(Vector3D v) { +190 return getInstance().format(v); +191 } +192 +193 /** +194 * Formats a {@link Vector3D} object to produce a string. +195 * @param vector the object to format. +196 * @param toAppendTo where the text is to be appended +197 * @param pos On input: an alignment field, if desired. On output: the +198 * offsets of the alignment field +199 * @return the value passed in as toAppendTo. +200 */ +201 public StringBuffer format(Vector3D vector, StringBuffer toAppendTo, +202 FieldPosition pos) { +203 +204 pos.setBeginIndex(0); +205 pos.setEndIndex(0); +206 +207 // format prefix +208 toAppendTo.append(prefix); +209 +210 // format components +211 formatDouble(vector.getX(), format, toAppendTo, pos); +212 toAppendTo.append(separator); +213 formatDouble(vector.getY(), format, toAppendTo, pos); +214 toAppendTo.append(separator); +215 formatDouble(vector.getZ(), format, toAppendTo, pos); +216 +217 // format suffix +218 toAppendTo.append(suffix); +219 +220 return toAppendTo; +221 +222 } +223 +224 /** +225 * Formats a object to produce a string. +226 * <p><code>obj</code> must be a {@link Vector3D} object. Any other type of +227 * object will result in an {@link IllegalArgumentException} being thrown.</p> +228 * @param obj the object to format. +229 * @param toAppendTo where the text is to be appended +230 * @param pos On input: an alignment field, if desired. On output: the +231 * offsets of the alignment field +232 * @return the value passed in as toAppendTo. +233 * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) +234 * @throws IllegalArgumentException is <code>obj</code> is not a valid type. +235 */ +236 @Override +237 public StringBuffer format(Object obj, StringBuffer toAppendTo, +238 FieldPosition pos) { +239 +240 if (obj instanceof Vector3D) { +241 return format( (Vector3D)obj, toAppendTo, pos); +242 } +243 +244 throw MathRuntimeException.createIllegalArgumentException("cannot format a {0} instance as a 3D vector", +245 obj.getClass().getName()); +246 +247 } +248 +249 /** +250 * Parses a string to produce a {@link Vector3D} object. +251 * @param source the string to parse +252 * @return the parsed {@link Vector3D} object. +253 * @exception ParseException if the beginning of the specified string +254 * cannot be parsed. +255 */ +256 public Vector3D parse(String source) throws ParseException { +257 ParsePosition parsePosition = new ParsePosition(0); +258 Vector3D result = parse(source, parsePosition); +259 if (parsePosition.getIndex() == 0) { +260 throw MathRuntimeException.createParseException( +261 parsePosition.getErrorIndex(), +262 "unparseable 3D vector: \"{0}\"", source); +263 } +264 return result; +265 } +266 +267 /** +268 * Parses a string to produce a {@link Vector3D} object. +269 * @param source the string to parse +270 * @param pos input/ouput parsing parameter. +271 * @return the parsed {@link Vector3D} object. +272 */ +273 public Vector3D parse(String source, ParsePosition pos) { +274 int initialIndex = pos.getIndex(); +275 +276 // parse prefix +277 parseAndIgnoreWhitespace(source, pos); +278 if (!parseFixedstring(source, trimmedPrefix, pos)) { +279 return null; +280 } +281 +282 // parse X component +283 parseAndIgnoreWhitespace(source, pos); +284 Number x = parseNumber(source, format, pos); +285 if (x == null) { +286 // invalid abscissa +287 // set index back to initial, error index should already be set +288 pos.setIndex(initialIndex); +289 return null; +290 } +291 +292 // parse Y component +293 parseAndIgnoreWhitespace(source, pos); +294 if (!parseFixedstring(source, trimmedSeparator, pos)) { +295 return null; +296 } +297 parseAndIgnoreWhitespace(source, pos); +298 Number y = parseNumber(source, format, pos); +299 if (y == null) { +300 // invalid ordinate +301 // set index back to initial, error index should already be set +302 pos.setIndex(initialIndex); +303 return null; +304 } +305 +306 // parse Z component +307 parseAndIgnoreWhitespace(source, pos); +308 if (!parseFixedstring(source, trimmedSeparator, pos)) { +309 return null; +310 } +311 parseAndIgnoreWhitespace(source, pos); +312 Number z = parseNumber(source, format, pos); +313 if (z == null) { +314 // invalid height +315 // set index back to initial, error index should already be set +316 pos.setIndex(initialIndex); +317 return null; +318 } +319 +320 // parse suffix +321 parseAndIgnoreWhitespace(source, pos); +322 if (!parseFixedstring(source, trimmedSuffix, pos)) { +323 return null; +324 } +325 +326 return new Vector3D(x.doubleValue(), y.doubleValue(), z.doubleValue()); +327 +328 } +329 +330 /** +331 * Parses a string to produce a object. +332 * @param source the string to parse +333 * @param pos input/ouput parsing parameter. +334 * @return the parsed object. +335 * @see java.text.Format#parseObject(java.lang.String, java.text.ParsePosition) +336 */ +337 @Override +338 public Object parseObject(String source, ParsePosition pos) { +339 return parse(source, pos); +340 } +341 +342 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/AbstractFieldMatrix.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/AbstractFieldMatrix.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1205 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.lang.reflect.Array; +021 import java.util.Arrays; +022 +023 import org.apache.commons.math.Field; +024 import org.apache.commons.math.FieldElement; +025 import org.apache.commons.math.MathRuntimeException; +026 +027 /** +028 * Basic implementation of {@link FieldMatrix} methods regardless of the underlying storage. +029 * <p>All the methods implemented here use {@link #getEntry(int, int)} to access +030 * matrix elements. Derived class can provide faster implementations. </p> +031 * +032 * @param <T> the type of the field elements +033 * @version $Revision: 903046 $ $Date: 2010-01-25 21:07:26 -0500 (Mon, 25 Jan 2010) $ +034 * @since 2.0 +035 */ +036 public abstract class AbstractFieldMatrix<T extends FieldElement<T>> implements FieldMatrix<T> { +037 +038 /** Field to which the elements belong. */ +039 private final Field<T> field; +040 +041 /** +042 * Constructor for use with Serializable +043 */ +044 protected AbstractFieldMatrix() { +045 field = null; +046 } +047 +048 /** +049 * Creates a matrix with no data +050 * @param field field to which the elements belong +051 */ +052 protected AbstractFieldMatrix(final Field<T> field) { +053 this.field = field; +054 } +055 +056 /** +057 * Create a new FieldMatrix<T> with the supplied row and column dimensions. +058 * +059 * @param field field to which the elements belong +060 * @param rowDimension the number of rows in the new matrix +061 * @param columnDimension the number of columns in the new matrix +062 * @throws IllegalArgumentException if row or column dimension is not positive +063 */ +064 protected AbstractFieldMatrix(final Field<T> field, +065 final int rowDimension, final int columnDimension) +066 throws IllegalArgumentException { +067 if (rowDimension <= 0 ) { +068 throw MathRuntimeException.createIllegalArgumentException( +069 "invalid row dimension {0} (must be positive)", +070 rowDimension); +071 } +072 if (columnDimension <= 0) { +073 throw MathRuntimeException.createIllegalArgumentException( +074 "invalid column dimension {0} (must be positive)", +075 columnDimension); +076 } +077 this.field = field; +078 } +079 +080 /** +081 * Get the elements type from an array. +082 * @param <T> the type of the field elements +083 * @param d data array +084 * @return field to which array elements belong +085 * @exception IllegalArgumentException if array is empty +086 */ +087 protected static <T extends FieldElement<T>> Field<T> extractField(final T[][] d) +088 throws IllegalArgumentException { +089 if (d.length == 0) { +090 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row"); +091 } +092 if (d[0].length == 0) { +093 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column"); +094 } +095 return d[0][0].getField(); +096 } +097 +098 /** +099 * Get the elements type from an array. +100 * @param <T> the type of the field elements +101 * @param d data array +102 * @return field to which array elements belong +103 * @exception IllegalArgumentException if array is empty +104 */ +105 protected static <T extends FieldElement<T>> Field<T> extractField(final T[] d) +106 throws IllegalArgumentException { +107 if (d.length == 0) { +108 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row"); +109 } +110 return d[0].getField(); +111 } +112 +113 /** Build an array of elements. +114 * <p> +115 * Complete arrays are filled with field.getZero() +116 * </p> +117 * @param <T> the type of the field elements +118 * @param field field to which array elements belong +119 * @param rows number of rows +120 * @param columns number of columns (may be negative to build partial +121 * arrays in the same way <code>new Field[rows][]</code> works) +122 * @return a new array +123 */ +124 @SuppressWarnings("unchecked") +125 protected static <T extends FieldElement<T>> T[][] buildArray(final Field<T> field, +126 final int rows, +127 final int columns) { +128 if (columns < 0) { +129 T[] dummyRow = (T[]) Array.newInstance(field.getZero().getClass(), 0); +130 return (T[][]) Array.newInstance(dummyRow.getClass(), rows); +131 } +132 T[][] array = +133 (T[][]) Array.newInstance(field.getZero().getClass(), new int[] { rows, columns }); +134 for (int i = 0; i < array.length; ++i) { +135 Arrays.fill(array[i], field.getZero()); +136 } +137 return array; +138 } +139 +140 /** Build an array of elements. +141 * <p> +142 * Arrays are filled with field.getZero() +143 * </p> +144 * @param <T> the type of the field elements +145 * @param field field to which array elements belong +146 * @param length of the array +147 * @return a new array +148 */ +149 protected static <T extends FieldElement<T>> T[] buildArray(final Field<T> field, +150 final int length) { +151 @SuppressWarnings("unchecked") // OK because field must be correct class +152 T[] array = (T[]) Array.newInstance(field.getZero().getClass(), length); +153 Arrays.fill(array, field.getZero()); +154 return array; +155 } +156 +157 /** {@inheritDoc} */ +158 public Field<T> getField() { +159 return field; +160 } +161 +162 /** {@inheritDoc} */ +163 public abstract FieldMatrix<T> createMatrix(final int rowDimension, final int columnDimension) +164 throws IllegalArgumentException; +165 +166 /** {@inheritDoc} */ +167 public abstract FieldMatrix<T> copy(); +168 +169 /** {@inheritDoc} */ +170 public FieldMatrix<T> add(FieldMatrix<T> m) throws IllegalArgumentException { +171 +172 // safety check +173 checkAdditionCompatible(m); +174 +175 final int rowCount = getRowDimension(); +176 final int columnCount = getColumnDimension(); +177 final FieldMatrix<T> out = createMatrix(rowCount, columnCount); +178 for (int row = 0; row < rowCount; ++row) { +179 for (int col = 0; col < columnCount; ++col) { +180 out.setEntry(row, col, getEntry(row, col).add(m.getEntry(row, col))); +181 } +182 } +183 +184 return out; +185 +186 } +187 +188 /** {@inheritDoc} */ +189 public FieldMatrix<T> subtract(final FieldMatrix<T> m) throws IllegalArgumentException { +190 +191 // safety check +192 checkSubtractionCompatible(m); +193 +194 final int rowCount = getRowDimension(); +195 final int columnCount = getColumnDimension(); +196 final FieldMatrix<T> out = createMatrix(rowCount, columnCount); +197 for (int row = 0; row < rowCount; ++row) { +198 for (int col = 0; col < columnCount; ++col) { +199 out.setEntry(row, col, getEntry(row, col).subtract(m.getEntry(row, col))); +200 } +201 } +202 +203 return out; +204 +205 } +206 +207 /** {@inheritDoc} */ +208 public FieldMatrix<T> scalarAdd(final T d) { +209 +210 final int rowCount = getRowDimension(); +211 final int columnCount = getColumnDimension(); +212 final FieldMatrix<T> out = createMatrix(rowCount, columnCount); +213 for (int row = 0; row < rowCount; ++row) { +214 for (int col = 0; col < columnCount; ++col) { +215 out.setEntry(row, col, getEntry(row, col).add(d)); +216 } +217 } +218 +219 return out; +220 +221 } +222 +223 /** {@inheritDoc} */ +224 public FieldMatrix<T> scalarMultiply(final T d) { +225 +226 final int rowCount = getRowDimension(); +227 final int columnCount = getColumnDimension(); +228 final FieldMatrix<T> out = createMatrix(rowCount, columnCount); +229 for (int row = 0; row < rowCount; ++row) { +230 for (int col = 0; col < columnCount; ++col) { +231 out.setEntry(row, col, getEntry(row, col).multiply(d)); +232 } +233 } +234 +235 return out; +236 +237 } +238 +239 /** {@inheritDoc} */ +240 public FieldMatrix<T> multiply(final FieldMatrix<T> m) +241 throws IllegalArgumentException { +242 +243 // safety check +244 checkMultiplicationCompatible(m); +245 +246 final int nRows = getRowDimension(); +247 final int nCols = m.getColumnDimension(); +248 final int nSum = getColumnDimension(); +249 final FieldMatrix<T> out = createMatrix(nRows, nCols); +250 for (int row = 0; row < nRows; ++row) { +251 for (int col = 0; col < nCols; ++col) { +252 T sum = field.getZero(); +253 for (int i = 0; i < nSum; ++i) { +254 sum = sum.add(getEntry(row, i).multiply(m.getEntry(i, col))); +255 } +256 out.setEntry(row, col, sum); +257 } +258 } +259 +260 return out; +261 +262 } +263 +264 /** {@inheritDoc} */ +265 public FieldMatrix<T> preMultiply(final FieldMatrix<T> m) +266 throws IllegalArgumentException { +267 return m.multiply(this); +268 } +269 +270 /** {@inheritDoc} */ +271 public T[][] getData() { +272 +273 final T[][] data = buildArray(field, getRowDimension(), getColumnDimension()); +274 +275 for (int i = 0; i < data.length; ++i) { +276 final T[] dataI = data[i]; +277 for (int j = 0; j < dataI.length; ++j) { +278 dataI[j] = getEntry(i, j); +279 } +280 } +281 +282 return data; +283 +284 } +285 +286 /** {@inheritDoc} */ +287 public FieldMatrix<T> getSubMatrix(final int startRow, final int endRow, +288 final int startColumn, final int endColumn) +289 throws MatrixIndexException { +290 +291 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +292 +293 final FieldMatrix<T> subMatrix = +294 createMatrix(endRow - startRow + 1, endColumn - startColumn + 1); +295 for (int i = startRow; i <= endRow; ++i) { +296 for (int j = startColumn; j <= endColumn; ++j) { +297 subMatrix.setEntry(i - startRow, j - startColumn, getEntry(i, j)); +298 } +299 } +300 +301 return subMatrix; +302 +303 } +304 +305 /** {@inheritDoc} */ +306 public FieldMatrix<T> getSubMatrix(final int[] selectedRows, final int[] selectedColumns) +307 throws MatrixIndexException { +308 +309 // safety checks +310 checkSubMatrixIndex(selectedRows, selectedColumns); +311 +312 // copy entries +313 final FieldMatrix<T> subMatrix = +314 createMatrix(selectedRows.length, selectedColumns.length); +315 subMatrix.walkInOptimizedOrder(new DefaultFieldMatrixChangingVisitor<T>(field.getZero()) { +316 +317 /** {@inheritDoc} */ +318 @Override +319 public T visit(final int row, final int column, final T value) { +320 return getEntry(selectedRows[row], selectedColumns[column]); +321 } +322 +323 }); +324 +325 return subMatrix; +326 +327 } +328 +329 /** {@inheritDoc} */ +330 public void copySubMatrix(final int startRow, final int endRow, +331 final int startColumn, final int endColumn, +332 final T[][] destination) +333 throws MatrixIndexException, IllegalArgumentException { +334 +335 // safety checks +336 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +337 final int rowsCount = endRow + 1 - startRow; +338 final int columnsCount = endColumn + 1 - startColumn; +339 if ((destination.length < rowsCount) || (destination[0].length < columnsCount)) { +340 throw MathRuntimeException.createIllegalArgumentException( +341 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +342 destination.length, destination[0].length, +343 rowsCount, columnsCount); +344 } +345 +346 // copy entries +347 walkInOptimizedOrder(new DefaultFieldMatrixPreservingVisitor<T>(field.getZero()) { +348 +349 /** Initial row index. */ +350 private int startRow; +351 +352 /** Initial column index. */ +353 private int startColumn; +354 +355 /** {@inheritDoc} */ +356 @Override +357 public void start(final int rows, final int columns, +358 final int startRow, final int endRow, +359 final int startColumn, final int endColumn) { +360 this.startRow = startRow; +361 this.startColumn = startColumn; +362 } +363 +364 /** {@inheritDoc} */ +365 @Override +366 public void visit(final int row, final int column, final T value) { +367 destination[row - startRow][column - startColumn] = value; +368 } +369 +370 }, startRow, endRow, startColumn, endColumn); +371 +372 } +373 +374 /** {@inheritDoc} */ +375 public void copySubMatrix(int[] selectedRows, int[] selectedColumns, T[][] destination) +376 throws MatrixIndexException, IllegalArgumentException { +377 +378 // safety checks +379 checkSubMatrixIndex(selectedRows, selectedColumns); +380 if ((destination.length < selectedRows.length) || +381 (destination[0].length < selectedColumns.length)) { +382 throw MathRuntimeException.createIllegalArgumentException( +383 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +384 destination.length, destination[0].length, +385 selectedRows.length, selectedColumns.length); +386 } +387 +388 // copy entries +389 for (int i = 0; i < selectedRows.length; i++) { +390 final T[] destinationI = destination[i]; +391 for (int j = 0; j < selectedColumns.length; j++) { +392 destinationI[j] = getEntry(selectedRows[i], selectedColumns[j]); +393 } +394 } +395 +396 } +397 +398 /** {@inheritDoc} */ +399 public void setSubMatrix(final T[][] subMatrix, final int row, final int column) +400 throws MatrixIndexException { +401 +402 final int nRows = subMatrix.length; +403 if (nRows == 0) { +404 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row"); +405 } +406 +407 final int nCols = subMatrix[0].length; +408 if (nCols == 0) { +409 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column"); +410 } +411 +412 for (int r = 1; r < nRows; ++r) { +413 if (subMatrix[r].length != nCols) { +414 throw MathRuntimeException.createIllegalArgumentException( +415 "some rows have length {0} while others have length {1}", +416 nCols, subMatrix[r].length); +417 } +418 } +419 +420 checkRowIndex(row); +421 checkColumnIndex(column); +422 checkRowIndex(nRows + row - 1); +423 checkColumnIndex(nCols + column - 1); +424 +425 for (int i = 0; i < nRows; ++i) { +426 for (int j = 0; j < nCols; ++j) { +427 setEntry(row + i, column + j, subMatrix[i][j]); +428 } +429 } +430 +431 } +432 +433 /** {@inheritDoc} */ +434 public FieldMatrix<T> getRowMatrix(final int row) +435 throws MatrixIndexException { +436 +437 checkRowIndex(row); +438 final int nCols = getColumnDimension(); +439 final FieldMatrix<T> out = createMatrix(1, nCols); +440 for (int i = 0; i < nCols; ++i) { +441 out.setEntry(0, i, getEntry(row, i)); +442 } +443 +444 return out; +445 +446 } +447 +448 /** {@inheritDoc} */ +449 public void setRowMatrix(final int row, final FieldMatrix<T> matrix) +450 throws MatrixIndexException, InvalidMatrixException { +451 +452 checkRowIndex(row); +453 final int nCols = getColumnDimension(); +454 if ((matrix.getRowDimension() != 1) || +455 (matrix.getColumnDimension() != nCols)) { +456 throw new InvalidMatrixException( +457 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +458 matrix.getRowDimension(), matrix.getColumnDimension(), 1, nCols); +459 } +460 for (int i = 0; i < nCols; ++i) { +461 setEntry(row, i, matrix.getEntry(0, i)); +462 } +463 +464 } +465 +466 /** {@inheritDoc} */ +467 public FieldMatrix<T> getColumnMatrix(final int column) +468 throws MatrixIndexException { +469 +470 checkColumnIndex(column); +471 final int nRows = getRowDimension(); +472 final FieldMatrix<T> out = createMatrix(nRows, 1); +473 for (int i = 0; i < nRows; ++i) { +474 out.setEntry(i, 0, getEntry(i, column)); +475 } +476 +477 return out; +478 +479 } +480 +481 /** {@inheritDoc} */ +482 public void setColumnMatrix(final int column, final FieldMatrix<T> matrix) +483 throws MatrixIndexException, InvalidMatrixException { +484 +485 checkColumnIndex(column); +486 final int nRows = getRowDimension(); +487 if ((matrix.getRowDimension() != nRows) || +488 (matrix.getColumnDimension() != 1)) { +489 throw new InvalidMatrixException( +490 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +491 matrix.getRowDimension(), matrix.getColumnDimension(), nRows, 1); +492 } +493 for (int i = 0; i < nRows; ++i) { +494 setEntry(i, column, matrix.getEntry(i, 0)); +495 } +496 +497 } +498 +499 /** {@inheritDoc} */ +500 public FieldVector<T> getRowVector(final int row) +501 throws MatrixIndexException { +502 return new ArrayFieldVector<T>(getRow(row), false); +503 } +504 +505 /** {@inheritDoc} */ +506 public void setRowVector(final int row, final FieldVector<T> vector) +507 throws MatrixIndexException, InvalidMatrixException { +508 +509 checkRowIndex(row); +510 final int nCols = getColumnDimension(); +511 if (vector.getDimension() != nCols) { +512 throw new InvalidMatrixException( +513 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +514 1, vector.getDimension(), 1, nCols); +515 } +516 for (int i = 0; i < nCols; ++i) { +517 setEntry(row, i, vector.getEntry(i)); +518 } +519 +520 } +521 +522 /** {@inheritDoc} */ +523 public FieldVector<T> getColumnVector(final int column) +524 throws MatrixIndexException { +525 return new ArrayFieldVector<T>(getColumn(column), false); +526 } +527 +528 /** {@inheritDoc} */ +529 public void setColumnVector(final int column, final FieldVector<T> vector) +530 throws MatrixIndexException, InvalidMatrixException { +531 +532 checkColumnIndex(column); +533 final int nRows = getRowDimension(); +534 if (vector.getDimension() != nRows) { +535 throw new InvalidMatrixException( +536 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +537 vector.getDimension(), 1, nRows, 1); +538 } +539 for (int i = 0; i < nRows; ++i) { +540 setEntry(i, column, vector.getEntry(i)); +541 } +542 +543 } +544 +545 /** {@inheritDoc} */ +546 public T[] getRow(final int row) +547 throws MatrixIndexException { +548 +549 checkRowIndex(row); +550 final int nCols = getColumnDimension(); +551 final T[] out = buildArray(field, nCols); +552 for (int i = 0; i < nCols; ++i) { +553 out[i] = getEntry(row, i); +554 } +555 +556 return out; +557 +558 } +559 +560 /** {@inheritDoc} */ +561 public void setRow(final int row, final T[] array) +562 throws MatrixIndexException, InvalidMatrixException { +563 +564 checkRowIndex(row); +565 final int nCols = getColumnDimension(); +566 if (array.length != nCols) { +567 throw new InvalidMatrixException( +568 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +569 1, array.length, 1, nCols); +570 } +571 for (int i = 0; i < nCols; ++i) { +572 setEntry(row, i, array[i]); +573 } +574 +575 } +576 +577 /** {@inheritDoc} */ +578 public T[] getColumn(final int column) +579 throws MatrixIndexException { +580 +581 checkColumnIndex(column); +582 final int nRows = getRowDimension(); +583 final T[] out = buildArray(field, nRows); +584 for (int i = 0; i < nRows; ++i) { +585 out[i] = getEntry(i, column); +586 } +587 +588 return out; +589 +590 } +591 +592 /** {@inheritDoc} */ +593 public void setColumn(final int column, final T[] array) +594 throws MatrixIndexException, InvalidMatrixException { +595 +596 checkColumnIndex(column); +597 final int nRows = getRowDimension(); +598 if (array.length != nRows) { +599 throw new InvalidMatrixException( +600 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +601 array.length, 1, nRows, 1); +602 } +603 for (int i = 0; i < nRows; ++i) { +604 setEntry(i, column, array[i]); +605 } +606 +607 } +608 +609 /** {@inheritDoc} */ +610 public abstract T getEntry(int row, int column) +611 throws MatrixIndexException; +612 +613 /** {@inheritDoc} */ +614 public abstract void setEntry(int row, int column, T value) +615 throws MatrixIndexException; +616 +617 /** {@inheritDoc} */ +618 public abstract void addToEntry(int row, int column, T increment) +619 throws MatrixIndexException; +620 +621 /** {@inheritDoc} */ +622 public abstract void multiplyEntry(int row, int column, T factor) +623 throws MatrixIndexException; +624 +625 /** {@inheritDoc} */ +626 public FieldMatrix<T> transpose() { +627 +628 final int nRows = getRowDimension(); +629 final int nCols = getColumnDimension(); +630 final FieldMatrix<T> out = createMatrix(nCols, nRows); +631 walkInOptimizedOrder(new DefaultFieldMatrixPreservingVisitor<T>(field.getZero()) { +632 +633 /** {@inheritDoc} */ +634 @Override +635 public void visit(final int row, final int column, final T value) { +636 out.setEntry(column, row, value); +637 } +638 +639 }); +640 +641 return out; +642 +643 } +644 +645 /** {@inheritDoc} */ +646 public boolean isSquare() { +647 return getColumnDimension() == getRowDimension(); +648 } +649 +650 /** {@inheritDoc} */ +651 public abstract int getRowDimension(); +652 +653 /** {@inheritDoc} */ +654 public abstract int getColumnDimension(); +655 +656 /** {@inheritDoc} */ +657 public T getTrace() +658 throws NonSquareMatrixException { +659 final int nRows = getRowDimension(); +660 final int nCols = getColumnDimension(); +661 if (nRows != nCols) { +662 throw new NonSquareMatrixException(nRows, nCols); +663 } +664 T trace = field.getZero(); +665 for (int i = 0; i < nRows; ++i) { +666 trace = trace.add(getEntry(i, i)); +667 } +668 return trace; +669 } +670 +671 /** {@inheritDoc} */ +672 public T[] operate(final T[] v) +673 throws IllegalArgumentException { +674 +675 final int nRows = getRowDimension(); +676 final int nCols = getColumnDimension(); +677 if (v.length != nCols) { +678 throw MathRuntimeException.createIllegalArgumentException( +679 "vector length mismatch: got {0} but expected {1}", +680 v.length, nCols); +681 } +682 +683 final T[] out = buildArray(field, nRows); +684 for (int row = 0; row < nRows; ++row) { +685 T sum = field.getZero(); +686 for (int i = 0; i < nCols; ++i) { +687 sum = sum.add(getEntry(row, i).multiply(v[i])); +688 } +689 out[row] = sum; +690 } +691 +692 return out; +693 +694 } +695 +696 /** {@inheritDoc} */ +697 public FieldVector<T> operate(final FieldVector<T> v) +698 throws IllegalArgumentException { +699 try { +700 return new ArrayFieldVector<T>(operate(((ArrayFieldVector<T>) v).getDataRef()), false); +701 } catch (ClassCastException cce) { +702 final int nRows = getRowDimension(); +703 final int nCols = getColumnDimension(); +704 if (v.getDimension() != nCols) { +705 throw MathRuntimeException.createIllegalArgumentException( +706 "vector length mismatch: got {0} but expected {1}", +707 v.getDimension(), nCols); +708 } +709 +710 final T[] out = buildArray(field, nRows); +711 for (int row = 0; row < nRows; ++row) { +712 T sum = field.getZero(); +713 for (int i = 0; i < nCols; ++i) { +714 sum = sum.add(getEntry(row, i).multiply(v.getEntry(i))); +715 } +716 out[row] = sum; +717 } +718 +719 return new ArrayFieldVector<T>(out, false); +720 } +721 } +722 +723 /** {@inheritDoc} */ +724 public T[] preMultiply(final T[] v) +725 throws IllegalArgumentException { +726 +727 final int nRows = getRowDimension(); +728 final int nCols = getColumnDimension(); +729 if (v.length != nRows) { +730 throw MathRuntimeException.createIllegalArgumentException( +731 "vector length mismatch: got {0} but expected {1}", +732 v.length, nRows); +733 } +734 +735 final T[] out = buildArray(field, nCols); +736 for (int col = 0; col < nCols; ++col) { +737 T sum = field.getZero(); +738 for (int i = 0; i < nRows; ++i) { +739 sum = sum.add(getEntry(i, col).multiply(v[i])); +740 } +741 out[col] = sum; +742 } +743 +744 return out; +745 +746 } +747 +748 /** {@inheritDoc} */ +749 public FieldVector<T> preMultiply(final FieldVector<T> v) +750 throws IllegalArgumentException { +751 try { +752 return new ArrayFieldVector<T>(preMultiply(((ArrayFieldVector<T>) v).getDataRef()), false); +753 } catch (ClassCastException cce) { +754 +755 final int nRows = getRowDimension(); +756 final int nCols = getColumnDimension(); +757 if (v.getDimension() != nRows) { +758 throw MathRuntimeException.createIllegalArgumentException( +759 "vector length mismatch: got {0} but expected {1}", +760 v.getDimension(), nRows); +761 } +762 +763 final T[] out = buildArray(field, nCols); +764 for (int col = 0; col < nCols; ++col) { +765 T sum = field.getZero(); +766 for (int i = 0; i < nRows; ++i) { +767 sum = sum.add(getEntry(i, col).multiply(v.getEntry(i))); +768 } +769 out[col] = sum; +770 } +771 +772 return new ArrayFieldVector<T>(out); +773 +774 } +775 } +776 +777 /** {@inheritDoc} */ +778 public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor) +779 throws MatrixVisitorException { +780 final int rows = getRowDimension(); +781 final int columns = getColumnDimension(); +782 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +783 for (int row = 0; row < rows; ++row) { +784 for (int column = 0; column < columns; ++column) { +785 final T oldValue = getEntry(row, column); +786 final T newValue = visitor.visit(row, column, oldValue); +787 setEntry(row, column, newValue); +788 } +789 } +790 return visitor.end(); +791 } +792 +793 /** {@inheritDoc} */ +794 public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor) +795 throws MatrixVisitorException { +796 final int rows = getRowDimension(); +797 final int columns = getColumnDimension(); +798 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +799 for (int row = 0; row < rows; ++row) { +800 for (int column = 0; column < columns; ++column) { +801 visitor.visit(row, column, getEntry(row, column)); +802 } +803 } +804 return visitor.end(); +805 } +806 +807 /** {@inheritDoc} */ +808 public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor, +809 final int startRow, final int endRow, +810 final int startColumn, final int endColumn) +811 throws MatrixIndexException, MatrixVisitorException { +812 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +813 visitor.start(getRowDimension(), getColumnDimension(), +814 startRow, endRow, startColumn, endColumn); +815 for (int row = startRow; row <= endRow; ++row) { +816 for (int column = startColumn; column <= endColumn; ++column) { +817 final T oldValue = getEntry(row, column); +818 final T newValue = visitor.visit(row, column, oldValue); +819 setEntry(row, column, newValue); +820 } +821 } +822 return visitor.end(); +823 } +824 +825 /** {@inheritDoc} */ +826 public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor, +827 final int startRow, final int endRow, +828 final int startColumn, final int endColumn) +829 throws MatrixIndexException, MatrixVisitorException { +830 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +831 visitor.start(getRowDimension(), getColumnDimension(), +832 startRow, endRow, startColumn, endColumn); +833 for (int row = startRow; row <= endRow; ++row) { +834 for (int column = startColumn; column <= endColumn; ++column) { +835 visitor.visit(row, column, getEntry(row, column)); +836 } +837 } +838 return visitor.end(); +839 } +840 +841 /** {@inheritDoc} */ +842 public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor) +843 throws MatrixVisitorException { +844 final int rows = getRowDimension(); +845 final int columns = getColumnDimension(); +846 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +847 for (int column = 0; column < columns; ++column) { +848 for (int row = 0; row < rows; ++row) { +849 final T oldValue = getEntry(row, column); +850 final T newValue = visitor.visit(row, column, oldValue); +851 setEntry(row, column, newValue); +852 } +853 } +854 return visitor.end(); +855 } +856 +857 /** {@inheritDoc} */ +858 public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor) +859 throws MatrixVisitorException { +860 final int rows = getRowDimension(); +861 final int columns = getColumnDimension(); +862 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +863 for (int column = 0; column < columns; ++column) { +864 for (int row = 0; row < rows; ++row) { +865 visitor.visit(row, column, getEntry(row, column)); +866 } +867 } +868 return visitor.end(); +869 } +870 +871 /** {@inheritDoc} */ +872 public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor, +873 final int startRow, final int endRow, +874 final int startColumn, final int endColumn) +875 throws MatrixIndexException, MatrixVisitorException { +876 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +877 visitor.start(getRowDimension(), getColumnDimension(), +878 startRow, endRow, startColumn, endColumn); +879 for (int column = startColumn; column <= endColumn; ++column) { +880 for (int row = startRow; row <= endRow; ++row) { +881 final T oldValue = getEntry(row, column); +882 final T newValue = visitor.visit(row, column, oldValue); +883 setEntry(row, column, newValue); +884 } +885 } +886 return visitor.end(); +887 } +888 +889 /** {@inheritDoc} */ +890 public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor, +891 final int startRow, final int endRow, +892 final int startColumn, final int endColumn) +893 throws MatrixIndexException, MatrixVisitorException { +894 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +895 visitor.start(getRowDimension(), getColumnDimension(), +896 startRow, endRow, startColumn, endColumn); +897 for (int column = startColumn; column <= endColumn; ++column) { +898 for (int row = startRow; row <= endRow; ++row) { +899 visitor.visit(row, column, getEntry(row, column)); +900 } +901 } +902 return visitor.end(); +903 } +904 +905 /** {@inheritDoc} */ +906 public T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor) +907 throws MatrixVisitorException { +908 return walkInRowOrder(visitor); +909 } +910 +911 /** {@inheritDoc} */ +912 public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor) +913 throws MatrixVisitorException { +914 return walkInRowOrder(visitor); +915 } +916 +917 /** {@inheritDoc} */ +918 public T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor, +919 final int startRow, final int endRow, +920 final int startColumn, final int endColumn) +921 throws MatrixIndexException, MatrixVisitorException { +922 return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn); +923 } +924 +925 /** {@inheritDoc} */ +926 public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor, +927 final int startRow, final int endRow, +928 final int startColumn, final int endColumn) +929 throws MatrixIndexException, MatrixVisitorException { +930 return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn); +931 } +932 +933 /** +934 * Get a string representation for this matrix. +935 * @return a string representation for this matrix +936 */ +937 @Override +938 public String toString() { +939 final int nRows = getRowDimension(); +940 final int nCols = getColumnDimension(); +941 final StringBuffer res = new StringBuffer(); +942 String fullClassName = getClass().getName(); +943 String shortClassName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1); +944 res.append(shortClassName).append("{"); +945 +946 for (int i = 0; i < nRows; ++i) { +947 if (i > 0) { +948 res.append(","); +949 } +950 res.append("{"); +951 for (int j = 0; j < nCols; ++j) { +952 if (j > 0) { +953 res.append(","); +954 } +955 res.append(getEntry(i, j)); +956 } +957 res.append("}"); +958 } +959 +960 res.append("}"); +961 return res.toString(); +962 +963 } +964 +965 /** +966 * Returns true iff <code>object</code> is a +967 * <code>FieldMatrix</code> instance with the same dimensions as this +968 * and all corresponding matrix entries are equal. +969 * +970 * @param object the object to test equality against. +971 * @return true if object equals this +972 */ +973 @Override +974 public boolean equals(final Object object) { +975 if (object == this ) { +976 return true; +977 } +978 if (object instanceof FieldMatrix<?> == false) { +979 return false; +980 } +981 FieldMatrix<?> m = (FieldMatrix<?>) object; +982 final int nRows = getRowDimension(); +983 final int nCols = getColumnDimension(); +984 if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows) { +985 return false; +986 } +987 for (int row = 0; row < nRows; ++row) { +988 for (int col = 0; col < nCols; ++col) { +989 if (!getEntry(row, col).equals(m.getEntry(row, col))) { +990 return false; +991 } +992 } +993 } +994 return true; +995 } +996 +997 /** +998 * Computes a hashcode for the matrix. +999 * +1000 * @return hashcode for matrix +1001 */ +1002 @Override +1003 public int hashCode() { +1004 int ret = 322562; +1005 final int nRows = getRowDimension(); +1006 final int nCols = getColumnDimension(); +1007 ret = ret * 31 + nRows; +1008 ret = ret * 31 + nCols; +1009 for (int row = 0; row < nRows; ++row) { +1010 for (int col = 0; col < nCols; ++col) { +1011 ret = ret * 31 + (11 * (row+1) + 17 * (col+1)) * getEntry(row, col).hashCode(); +1012 } +1013 } +1014 return ret; +1015 } +1016 +1017 /** +1018 * Check if a row index is valid. +1019 * @param row row index to check +1020 * @exception MatrixIndexException if index is not valid +1021 */ +1022 protected void checkRowIndex(final int row) { +1023 if (row < 0 || row >= getRowDimension()) { +1024 throw new MatrixIndexException("row index {0} out of allowed range [{1}, {2}]", +1025 row, 0, getRowDimension() - 1); +1026 } +1027 } +1028 +1029 /** +1030 * Check if a column index is valid. +1031 * @param column column index to check +1032 * @exception MatrixIndexException if index is not valid +1033 */ +1034 protected void checkColumnIndex(final int column) +1035 throws MatrixIndexException { +1036 if (column < 0 || column >= getColumnDimension()) { +1037 throw new MatrixIndexException("column index {0} out of allowed range [{1}, {2}]", +1038 column, 0, getColumnDimension() - 1); +1039 } +1040 } +1041 +1042 /** +1043 * Check if submatrix ranges indices are valid. +1044 * Rows and columns are indicated counting from 0 to n-1. +1045 * +1046 * @param startRow Initial row index +1047 * @param endRow Final row index +1048 * @param startColumn Initial column index +1049 * @param endColumn Final column index +1050 * @exception MatrixIndexException if the indices are not valid +1051 */ +1052 protected void checkSubMatrixIndex(final int startRow, final int endRow, +1053 final int startColumn, final int endColumn) { +1054 checkRowIndex(startRow); +1055 checkRowIndex(endRow); +1056 if (startRow > endRow) { +1057 throw new MatrixIndexException("initial row {0} after final row {1}", +1058 startRow, endRow); +1059 } +1060 +1061 checkColumnIndex(startColumn); +1062 checkColumnIndex(endColumn); +1063 if (startColumn > endColumn) { +1064 throw new MatrixIndexException("initial column {0} after final column {1}", +1065 startColumn, endColumn); +1066 } +1067 +1068 +1069 } +1070 +1071 /** +1072 * Check if submatrix ranges indices are valid. +1073 * Rows and columns are indicated counting from 0 to n-1. +1074 * +1075 * @param selectedRows Array of row indices. +1076 * @param selectedColumns Array of column indices. +1077 * @exception MatrixIndexException if row or column selections are not valid +1078 */ +1079 protected void checkSubMatrixIndex(final int[] selectedRows, final int[] selectedColumns) { +1080 if (selectedRows.length * selectedColumns.length == 0) { +1081 if (selectedRows.length == 0) { +1082 throw new MatrixIndexException("empty selected row index array"); +1083 } +1084 throw new MatrixIndexException("empty selected column index array"); +1085 } +1086 +1087 for (final int row : selectedRows) { +1088 checkRowIndex(row); +1089 } +1090 for (final int column : selectedColumns) { +1091 checkColumnIndex(column); +1092 } +1093 } +1094 +1095 /** +1096 * Check if a matrix is addition compatible with the instance +1097 * @param m matrix to check +1098 * @exception IllegalArgumentException if matrix is not addition compatible with instance +1099 */ +1100 protected void checkAdditionCompatible(final FieldMatrix<T> m) { +1101 if ((getRowDimension() != m.getRowDimension()) || +1102 (getColumnDimension() != m.getColumnDimension())) { +1103 throw MathRuntimeException.createIllegalArgumentException( +1104 "{0}x{1} and {2}x{3} matrices are not addition compatible", +1105 getRowDimension(), getColumnDimension(), +1106 m.getRowDimension(), m.getColumnDimension()); +1107 } +1108 } +1109 +1110 /** +1111 * Check if a matrix is subtraction compatible with the instance +1112 * @param m matrix to check +1113 * @exception IllegalArgumentException if matrix is not subtraction compatible with instance +1114 */ +1115 protected void checkSubtractionCompatible(final FieldMatrix<T> m) { +1116 if ((getRowDimension() != m.getRowDimension()) || +1117 (getColumnDimension() != m.getColumnDimension())) { +1118 throw MathRuntimeException.createIllegalArgumentException( +1119 "{0}x{1} and {2}x{3} matrices are not subtraction compatible", +1120 getRowDimension(), getColumnDimension(), +1121 m.getRowDimension(), m.getColumnDimension()); +1122 } +1123 } +1124 +1125 /** +1126 * Check if a matrix is multiplication compatible with the instance +1127 * @param m matrix to check +1128 * @exception IllegalArgumentException if matrix is not multiplication compatible with instance +1129 */ +1130 protected void checkMultiplicationCompatible(final FieldMatrix<T> m) { +1131 if (getColumnDimension() != m.getRowDimension()) { +1132 throw MathRuntimeException.createIllegalArgumentException( +1133 "{0}x{1} and {2}x{3} matrices are not multiplication compatible", +1134 getRowDimension(), getColumnDimension(), +1135 m.getRowDimension(), m.getColumnDimension()); +1136 } +1137 } +1138 +1139 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/AbstractRealMatrix.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/AbstractRealMatrix.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1136 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.util.MathUtils; +022 +023 /** +024 * Basic implementation of RealMatrix methods regardless of the underlying storage. +025 * <p>All the methods implemented here use {@link #getEntry(int, int)} to access +026 * matrix elements. Derived class can provide faster implementations. </p> +027 * +028 * @version $Revision: 811833 $ $Date: 2009-09-06 12:27:50 -0400 (Sun, 06 Sep 2009) $ +029 * @since 2.0 +030 */ +031 public abstract class AbstractRealMatrix implements RealMatrix { +032 +033 +034 /** Cached LU solver. +035 * @deprecated as of release 2.0, since all methods using this are deprecated +036 */ +037 @Deprecated +038 private DecompositionSolver lu; +039 +040 /** +041 * Creates a matrix with no data +042 */ +043 protected AbstractRealMatrix() { +044 lu = null; +045 } +046 +047 /** +048 * Create a new RealMatrix with the supplied row and column dimensions. +049 * +050 * @param rowDimension the number of rows in the new matrix +051 * @param columnDimension the number of columns in the new matrix +052 * @throws IllegalArgumentException if row or column dimension is not positive +053 */ +054 protected AbstractRealMatrix(final int rowDimension, final int columnDimension) +055 throws IllegalArgumentException { +056 if (rowDimension <= 0 ) { +057 throw MathRuntimeException.createIllegalArgumentException( +058 "invalid row dimension {0} (must be positive)", +059 rowDimension); +060 } +061 if (columnDimension <= 0) { +062 throw MathRuntimeException.createIllegalArgumentException( +063 "invalid column dimension {0} (must be positive)", +064 columnDimension); +065 } +066 lu = null; +067 } +068 +069 /** {@inheritDoc} */ +070 public abstract RealMatrix createMatrix(final int rowDimension, final int columnDimension) +071 throws IllegalArgumentException; +072 +073 /** {@inheritDoc} */ +074 public abstract RealMatrix copy(); +075 +076 /** {@inheritDoc} */ +077 public RealMatrix add(RealMatrix m) throws IllegalArgumentException { +078 +079 // safety check +080 MatrixUtils.checkAdditionCompatible(this, m); +081 +082 final int rowCount = getRowDimension(); +083 final int columnCount = getColumnDimension(); +084 final RealMatrix out = createMatrix(rowCount, columnCount); +085 for (int row = 0; row < rowCount; ++row) { +086 for (int col = 0; col < columnCount; ++col) { +087 out.setEntry(row, col, getEntry(row, col) + m.getEntry(row, col)); +088 } +089 } +090 +091 return out; +092 +093 } +094 +095 /** {@inheritDoc} */ +096 public RealMatrix subtract(final RealMatrix m) throws IllegalArgumentException { +097 +098 // safety check +099 MatrixUtils.checkSubtractionCompatible(this, m); +100 +101 final int rowCount = getRowDimension(); +102 final int columnCount = getColumnDimension(); +103 final RealMatrix out = createMatrix(rowCount, columnCount); +104 for (int row = 0; row < rowCount; ++row) { +105 for (int col = 0; col < columnCount; ++col) { +106 out.setEntry(row, col, getEntry(row, col) - m.getEntry(row, col)); +107 } +108 } +109 +110 return out; +111 +112 } +113 +114 /** {@inheritDoc} */ +115 public RealMatrix scalarAdd(final double d) { +116 +117 final int rowCount = getRowDimension(); +118 final int columnCount = getColumnDimension(); +119 final RealMatrix out = createMatrix(rowCount, columnCount); +120 for (int row = 0; row < rowCount; ++row) { +121 for (int col = 0; col < columnCount; ++col) { +122 out.setEntry(row, col, getEntry(row, col) + d); +123 } +124 } +125 +126 return out; +127 +128 } +129 +130 /** {@inheritDoc} */ +131 public RealMatrix scalarMultiply(final double d) { +132 +133 final int rowCount = getRowDimension(); +134 final int columnCount = getColumnDimension(); +135 final RealMatrix out = createMatrix(rowCount, columnCount); +136 for (int row = 0; row < rowCount; ++row) { +137 for (int col = 0; col < columnCount; ++col) { +138 out.setEntry(row, col, getEntry(row, col) * d); +139 } +140 } +141 +142 return out; +143 +144 } +145 +146 /** {@inheritDoc} */ +147 public RealMatrix multiply(final RealMatrix m) +148 throws IllegalArgumentException { +149 +150 // safety check +151 MatrixUtils.checkMultiplicationCompatible(this, m); +152 +153 final int nRows = getRowDimension(); +154 final int nCols = m.getColumnDimension(); +155 final int nSum = getColumnDimension(); +156 final RealMatrix out = createMatrix(nRows, nCols); +157 for (int row = 0; row < nRows; ++row) { +158 for (int col = 0; col < nCols; ++col) { +159 double sum = 0; +160 for (int i = 0; i < nSum; ++i) { +161 sum += getEntry(row, i) * m.getEntry(i, col); +162 } +163 out.setEntry(row, col, sum); +164 } +165 } +166 +167 return out; +168 +169 } +170 +171 /** {@inheritDoc} */ +172 public RealMatrix preMultiply(final RealMatrix m) +173 throws IllegalArgumentException { +174 return m.multiply(this); +175 } +176 +177 /** {@inheritDoc} */ +178 public double[][] getData() { +179 +180 final double[][] data = new double[getRowDimension()][getColumnDimension()]; +181 +182 for (int i = 0; i < data.length; ++i) { +183 final double[] dataI = data[i]; +184 for (int j = 0; j < dataI.length; ++j) { +185 dataI[j] = getEntry(i, j); +186 } +187 } +188 +189 return data; +190 +191 } +192 +193 /** {@inheritDoc} */ +194 public double getNorm() { +195 return walkInColumnOrder(new RealMatrixPreservingVisitor() { +196 +197 /** Last row index. */ +198 private double endRow; +199 +200 /** Sum of absolute values on one column. */ +201 private double columnSum; +202 +203 /** Maximal sum across all columns. */ +204 private double maxColSum; +205 +206 /** {@inheritDoc} */ +207 public void start(final int rows, final int columns, +208 final int startRow, final int endRow, +209 final int startColumn, final int endColumn) { +210 this.endRow = endRow; +211 columnSum = 0; +212 maxColSum = 0; +213 } +214 +215 /** {@inheritDoc} */ +216 public void visit(final int row, final int column, final double value) { +217 columnSum += Math.abs(value); +218 if (row == endRow) { +219 maxColSum = Math.max(maxColSum, columnSum); +220 columnSum = 0; +221 } +222 } +223 +224 /** {@inheritDoc} */ +225 public double end() { +226 return maxColSum; +227 } +228 +229 }); +230 } +231 +232 /** {@inheritDoc} */ +233 public double getFrobeniusNorm() { +234 return walkInOptimizedOrder(new RealMatrixPreservingVisitor() { +235 +236 /** Sum of squared entries. */ +237 private double sum; +238 +239 /** {@inheritDoc} */ +240 public void start(final int rows, final int columns, +241 final int startRow, final int endRow, +242 final int startColumn, final int endColumn) { +243 sum = 0; +244 } +245 +246 /** {@inheritDoc} */ +247 public void visit(final int row, final int column, final double value) { +248 sum += value * value; +249 } +250 +251 /** {@inheritDoc} */ +252 public double end() { +253 return Math.sqrt(sum); +254 } +255 +256 }); +257 } +258 +259 /** {@inheritDoc} */ +260 public RealMatrix getSubMatrix(final int startRow, final int endRow, +261 final int startColumn, final int endColumn) +262 throws MatrixIndexException { +263 +264 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +265 +266 final RealMatrix subMatrix = +267 createMatrix(endRow - startRow + 1, endColumn - startColumn + 1); +268 for (int i = startRow; i <= endRow; ++i) { +269 for (int j = startColumn; j <= endColumn; ++j) { +270 subMatrix.setEntry(i - startRow, j - startColumn, getEntry(i, j)); +271 } +272 } +273 +274 return subMatrix; +275 +276 } +277 +278 /** {@inheritDoc} */ +279 public RealMatrix getSubMatrix(final int[] selectedRows, final int[] selectedColumns) +280 throws MatrixIndexException { +281 +282 // safety checks +283 MatrixUtils.checkSubMatrixIndex(this, selectedRows, selectedColumns); +284 +285 // copy entries +286 final RealMatrix subMatrix = +287 createMatrix(selectedRows.length, selectedColumns.length); +288 subMatrix.walkInOptimizedOrder(new DefaultRealMatrixChangingVisitor() { +289 +290 /** {@inheritDoc} */ +291 @Override +292 public double visit(final int row, final int column, final double value) { +293 return getEntry(selectedRows[row], selectedColumns[column]); +294 } +295 +296 }); +297 +298 return subMatrix; +299 +300 } +301 +302 /** {@inheritDoc} */ +303 public void copySubMatrix(final int startRow, final int endRow, +304 final int startColumn, final int endColumn, +305 final double[][] destination) +306 throws MatrixIndexException, IllegalArgumentException { +307 +308 // safety checks +309 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +310 final int rowsCount = endRow + 1 - startRow; +311 final int columnsCount = endColumn + 1 - startColumn; +312 if ((destination.length < rowsCount) || (destination[0].length < columnsCount)) { +313 throw MathRuntimeException.createIllegalArgumentException( +314 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +315 destination.length, destination[0].length, +316 rowsCount, columnsCount); +317 } +318 +319 // copy entries +320 walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() { +321 +322 /** Initial row index. */ +323 private int startRow; +324 +325 /** Initial column index. */ +326 private int startColumn; +327 +328 /** {@inheritDoc} */ +329 @Override +330 public void start(final int rows, final int columns, +331 final int startRow, final int endRow, +332 final int startColumn, final int endColumn) { +333 this.startRow = startRow; +334 this.startColumn = startColumn; +335 } +336 +337 /** {@inheritDoc} */ +338 @Override +339 public void visit(final int row, final int column, final double value) { +340 destination[row - startRow][column - startColumn] = value; +341 } +342 +343 }, startRow, endRow, startColumn, endColumn); +344 +345 } +346 +347 /** {@inheritDoc} */ +348 public void copySubMatrix(int[] selectedRows, int[] selectedColumns, double[][] destination) +349 throws MatrixIndexException, IllegalArgumentException { +350 +351 // safety checks +352 MatrixUtils.checkSubMatrixIndex(this, selectedRows, selectedColumns); +353 if ((destination.length < selectedRows.length) || +354 (destination[0].length < selectedColumns.length)) { +355 throw MathRuntimeException.createIllegalArgumentException( +356 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +357 destination.length, destination[0].length, +358 selectedRows.length, selectedColumns.length); +359 } +360 +361 // copy entries +362 for (int i = 0; i < selectedRows.length; i++) { +363 final double[] destinationI = destination[i]; +364 for (int j = 0; j < selectedColumns.length; j++) { +365 destinationI[j] = getEntry(selectedRows[i], selectedColumns[j]); +366 } +367 } +368 +369 } +370 +371 /** {@inheritDoc} */ +372 public void setSubMatrix(final double[][] subMatrix, final int row, final int column) +373 throws MatrixIndexException { +374 +375 final int nRows = subMatrix.length; +376 if (nRows == 0) { +377 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row"); +378 } +379 +380 final int nCols = subMatrix[0].length; +381 if (nCols == 0) { +382 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column"); +383 } +384 +385 for (int r = 1; r < nRows; ++r) { +386 if (subMatrix[r].length != nCols) { +387 throw MathRuntimeException.createIllegalArgumentException( +388 "some rows have length {0} while others have length {1}", +389 nCols, subMatrix[r].length); +390 } +391 } +392 +393 MatrixUtils.checkRowIndex(this, row); +394 MatrixUtils.checkColumnIndex(this, column); +395 MatrixUtils.checkRowIndex(this, nRows + row - 1); +396 MatrixUtils.checkColumnIndex(this, nCols + column - 1); +397 +398 for (int i = 0; i < nRows; ++i) { +399 for (int j = 0; j < nCols; ++j) { +400 setEntry(row + i, column + j, subMatrix[i][j]); +401 } +402 } +403 +404 lu = null; +405 +406 } +407 +408 /** {@inheritDoc} */ +409 public RealMatrix getRowMatrix(final int row) +410 throws MatrixIndexException { +411 +412 MatrixUtils.checkRowIndex(this, row); +413 final int nCols = getColumnDimension(); +414 final RealMatrix out = createMatrix(1, nCols); +415 for (int i = 0; i < nCols; ++i) { +416 out.setEntry(0, i, getEntry(row, i)); +417 } +418 +419 return out; +420 +421 } +422 +423 /** {@inheritDoc} */ +424 public void setRowMatrix(final int row, final RealMatrix matrix) +425 throws MatrixIndexException, InvalidMatrixException { +426 +427 MatrixUtils.checkRowIndex(this, row); +428 final int nCols = getColumnDimension(); +429 if ((matrix.getRowDimension() != 1) || +430 (matrix.getColumnDimension() != nCols)) { +431 throw new InvalidMatrixException( +432 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +433 matrix.getRowDimension(), matrix.getColumnDimension(), 1, nCols); +434 } +435 for (int i = 0; i < nCols; ++i) { +436 setEntry(row, i, matrix.getEntry(0, i)); +437 } +438 +439 } +440 +441 /** {@inheritDoc} */ +442 public RealMatrix getColumnMatrix(final int column) +443 throws MatrixIndexException { +444 +445 MatrixUtils.checkColumnIndex(this, column); +446 final int nRows = getRowDimension(); +447 final RealMatrix out = createMatrix(nRows, 1); +448 for (int i = 0; i < nRows; ++i) { +449 out.setEntry(i, 0, getEntry(i, column)); +450 } +451 +452 return out; +453 +454 } +455 +456 /** {@inheritDoc} */ +457 public void setColumnMatrix(final int column, final RealMatrix matrix) +458 throws MatrixIndexException, InvalidMatrixException { +459 +460 MatrixUtils.checkColumnIndex(this, column); +461 final int nRows = getRowDimension(); +462 if ((matrix.getRowDimension() != nRows) || +463 (matrix.getColumnDimension() != 1)) { +464 throw new InvalidMatrixException( +465 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +466 matrix.getRowDimension(), matrix.getColumnDimension(), nRows, 1); +467 } +468 for (int i = 0; i < nRows; ++i) { +469 setEntry(i, column, matrix.getEntry(i, 0)); +470 } +471 +472 } +473 +474 /** {@inheritDoc} */ +475 public RealVector getRowVector(final int row) +476 throws MatrixIndexException { +477 return new ArrayRealVector(getRow(row), false); +478 } +479 +480 /** {@inheritDoc} */ +481 public void setRowVector(final int row, final RealVector vector) +482 throws MatrixIndexException, InvalidMatrixException { +483 +484 MatrixUtils.checkRowIndex(this, row); +485 final int nCols = getColumnDimension(); +486 if (vector.getDimension() != nCols) { +487 throw new InvalidMatrixException( +488 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +489 1, vector.getDimension(), 1, nCols); +490 } +491 for (int i = 0; i < nCols; ++i) { +492 setEntry(row, i, vector.getEntry(i)); +493 } +494 +495 } +496 +497 /** {@inheritDoc} */ +498 public RealVector getColumnVector(final int column) +499 throws MatrixIndexException { +500 return new ArrayRealVector(getColumn(column), false); +501 } +502 +503 /** {@inheritDoc} */ +504 public void setColumnVector(final int column, final RealVector vector) +505 throws MatrixIndexException, InvalidMatrixException { +506 +507 MatrixUtils.checkColumnIndex(this, column); +508 final int nRows = getRowDimension(); +509 if (vector.getDimension() != nRows) { +510 throw new InvalidMatrixException( +511 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +512 vector.getDimension(), 1, nRows, 1); +513 } +514 for (int i = 0; i < nRows; ++i) { +515 setEntry(i, column, vector.getEntry(i)); +516 } +517 +518 } +519 +520 /** {@inheritDoc} */ +521 public double[] getRow(final int row) +522 throws MatrixIndexException { +523 +524 MatrixUtils.checkRowIndex(this, row); +525 final int nCols = getColumnDimension(); +526 final double[] out = new double[nCols]; +527 for (int i = 0; i < nCols; ++i) { +528 out[i] = getEntry(row, i); +529 } +530 +531 return out; +532 +533 } +534 +535 /** {@inheritDoc} */ +536 public void setRow(final int row, final double[] array) +537 throws MatrixIndexException, InvalidMatrixException { +538 +539 MatrixUtils.checkRowIndex(this, row); +540 final int nCols = getColumnDimension(); +541 if (array.length != nCols) { +542 throw new InvalidMatrixException( +543 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +544 1, array.length, 1, nCols); +545 } +546 for (int i = 0; i < nCols; ++i) { +547 setEntry(row, i, array[i]); +548 } +549 +550 } +551 +552 /** {@inheritDoc} */ +553 public double[] getColumn(final int column) +554 throws MatrixIndexException { +555 +556 MatrixUtils.checkColumnIndex(this, column); +557 final int nRows = getRowDimension(); +558 final double[] out = new double[nRows]; +559 for (int i = 0; i < nRows; ++i) { +560 out[i] = getEntry(i, column); +561 } +562 +563 return out; +564 +565 } +566 +567 /** {@inheritDoc} */ +568 public void setColumn(final int column, final double[] array) +569 throws MatrixIndexException, InvalidMatrixException { +570 +571 MatrixUtils.checkColumnIndex(this, column); +572 final int nRows = getRowDimension(); +573 if (array.length != nRows) { +574 throw new InvalidMatrixException( +575 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +576 array.length, 1, nRows, 1); +577 } +578 for (int i = 0; i < nRows; ++i) { +579 setEntry(i, column, array[i]); +580 } +581 +582 } +583 +584 /** {@inheritDoc} */ +585 public abstract double getEntry(int row, int column) +586 throws MatrixIndexException; +587 +588 /** {@inheritDoc} */ +589 public abstract void setEntry(int row, int column, double value) +590 throws MatrixIndexException; +591 +592 /** {@inheritDoc} */ +593 public abstract void addToEntry(int row, int column, double increment) +594 throws MatrixIndexException; +595 +596 /** {@inheritDoc} */ +597 public abstract void multiplyEntry(int row, int column, double factor) +598 throws MatrixIndexException; +599 +600 /** {@inheritDoc} */ +601 public RealMatrix transpose() { +602 +603 final int nRows = getRowDimension(); +604 final int nCols = getColumnDimension(); +605 final RealMatrix out = createMatrix(nCols, nRows); +606 walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() { +607 +608 /** {@inheritDoc} */ +609 @Override +610 public void visit(final int row, final int column, final double value) { +611 out.setEntry(column, row, value); +612 } +613 +614 }); +615 +616 return out; +617 +618 } +619 +620 /** {@inheritDoc} */ +621 @Deprecated +622 public RealMatrix inverse() +623 throws InvalidMatrixException { +624 if (lu == null) { +625 lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver(); +626 } +627 return lu.getInverse(); +628 } +629 +630 /** {@inheritDoc} */ +631 @Deprecated +632 public double getDeterminant() +633 throws InvalidMatrixException { +634 return new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getDeterminant(); +635 } +636 +637 /** {@inheritDoc} */ +638 public boolean isSquare() { +639 return getColumnDimension() == getRowDimension(); +640 } +641 +642 /** {@inheritDoc} */ +643 @Deprecated +644 public boolean isSingular() { +645 if (lu == null) { +646 lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver(); +647 } +648 return !lu.isNonSingular(); +649 } +650 +651 /** {@inheritDoc} */ +652 public abstract int getRowDimension(); +653 +654 /** {@inheritDoc} */ +655 public abstract int getColumnDimension(); +656 +657 /** {@inheritDoc} */ +658 public double getTrace() +659 throws NonSquareMatrixException { +660 final int nRows = getRowDimension(); +661 final int nCols = getColumnDimension(); +662 if (nRows != nCols) { +663 throw new NonSquareMatrixException(nRows, nCols); +664 } +665 double trace = 0; +666 for (int i = 0; i < nRows; ++i) { +667 trace += getEntry(i, i); +668 } +669 return trace; +670 } +671 +672 /** {@inheritDoc} */ +673 public double[] operate(final double[] v) +674 throws IllegalArgumentException { +675 +676 final int nRows = getRowDimension(); +677 final int nCols = getColumnDimension(); +678 if (v.length != nCols) { +679 throw MathRuntimeException.createIllegalArgumentException( +680 "vector length mismatch: got {0} but expected {1}", +681 v.length, nCols); +682 } +683 +684 final double[] out = new double[nRows]; +685 for (int row = 0; row < nRows; ++row) { +686 double sum = 0; +687 for (int i = 0; i < nCols; ++i) { +688 sum += getEntry(row, i) * v[i]; +689 } +690 out[row] = sum; +691 } +692 +693 return out; +694 +695 } +696 +697 /** {@inheritDoc} */ +698 public RealVector operate(final RealVector v) +699 throws IllegalArgumentException { +700 try { +701 return new ArrayRealVector(operate(((ArrayRealVector) v).getDataRef()), false); +702 } catch (ClassCastException cce) { +703 final int nRows = getRowDimension(); +704 final int nCols = getColumnDimension(); +705 if (v.getDimension() != nCols) { +706 throw MathRuntimeException.createIllegalArgumentException( +707 "vector length mismatch: got {0} but expected {1}", +708 v.getDimension(), nCols); +709 } +710 +711 final double[] out = new double[nRows]; +712 for (int row = 0; row < nRows; ++row) { +713 double sum = 0; +714 for (int i = 0; i < nCols; ++i) { +715 sum += getEntry(row, i) * v.getEntry(i); +716 } +717 out[row] = sum; +718 } +719 +720 return new ArrayRealVector(out, false); +721 } +722 } +723 +724 /** {@inheritDoc} */ +725 public double[] preMultiply(final double[] v) +726 throws IllegalArgumentException { +727 +728 final int nRows = getRowDimension(); +729 final int nCols = getColumnDimension(); +730 if (v.length != nRows) { +731 throw MathRuntimeException.createIllegalArgumentException( +732 "vector length mismatch: got {0} but expected {1}", +733 v.length, nRows); +734 } +735 +736 final double[] out = new double[nCols]; +737 for (int col = 0; col < nCols; ++col) { +738 double sum = 0; +739 for (int i = 0; i < nRows; ++i) { +740 sum += getEntry(i, col) * v[i]; +741 } +742 out[col] = sum; +743 } +744 +745 return out; +746 +747 } +748 +749 /** {@inheritDoc} */ +750 public RealVector preMultiply(final RealVector v) +751 throws IllegalArgumentException { +752 try { +753 return new ArrayRealVector(preMultiply(((ArrayRealVector) v).getDataRef()), false); +754 } catch (ClassCastException cce) { +755 +756 final int nRows = getRowDimension(); +757 final int nCols = getColumnDimension(); +758 if (v.getDimension() != nRows) { +759 throw MathRuntimeException.createIllegalArgumentException( +760 "vector length mismatch: got {0} but expected {1}", +761 v.getDimension(), nRows); +762 } +763 +764 final double[] out = new double[nCols]; +765 for (int col = 0; col < nCols; ++col) { +766 double sum = 0; +767 for (int i = 0; i < nRows; ++i) { +768 sum += getEntry(i, col) * v.getEntry(i); +769 } +770 out[col] = sum; +771 } +772 +773 return new ArrayRealVector(out); +774 +775 } +776 } +777 +778 /** {@inheritDoc} */ +779 public double walkInRowOrder(final RealMatrixChangingVisitor visitor) +780 throws MatrixVisitorException { +781 final int rows = getRowDimension(); +782 final int columns = getColumnDimension(); +783 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +784 for (int row = 0; row < rows; ++row) { +785 for (int column = 0; column < columns; ++column) { +786 final double oldValue = getEntry(row, column); +787 final double newValue = visitor.visit(row, column, oldValue); +788 setEntry(row, column, newValue); +789 } +790 } +791 lu = null; +792 return visitor.end(); +793 } +794 +795 /** {@inheritDoc} */ +796 public double walkInRowOrder(final RealMatrixPreservingVisitor visitor) +797 throws MatrixVisitorException { +798 final int rows = getRowDimension(); +799 final int columns = getColumnDimension(); +800 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +801 for (int row = 0; row < rows; ++row) { +802 for (int column = 0; column < columns; ++column) { +803 visitor.visit(row, column, getEntry(row, column)); +804 } +805 } +806 return visitor.end(); +807 } +808 +809 /** {@inheritDoc} */ +810 public double walkInRowOrder(final RealMatrixChangingVisitor visitor, +811 final int startRow, final int endRow, +812 final int startColumn, final int endColumn) +813 throws MatrixIndexException, MatrixVisitorException { +814 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +815 visitor.start(getRowDimension(), getColumnDimension(), +816 startRow, endRow, startColumn, endColumn); +817 for (int row = startRow; row <= endRow; ++row) { +818 for (int column = startColumn; column <= endColumn; ++column) { +819 final double oldValue = getEntry(row, column); +820 final double newValue = visitor.visit(row, column, oldValue); +821 setEntry(row, column, newValue); +822 } +823 } +824 lu = null; +825 return visitor.end(); +826 } +827 +828 /** {@inheritDoc} */ +829 public double walkInRowOrder(final RealMatrixPreservingVisitor visitor, +830 final int startRow, final int endRow, +831 final int startColumn, final int endColumn) +832 throws MatrixIndexException, MatrixVisitorException { +833 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +834 visitor.start(getRowDimension(), getColumnDimension(), +835 startRow, endRow, startColumn, endColumn); +836 for (int row = startRow; row <= endRow; ++row) { +837 for (int column = startColumn; column <= endColumn; ++column) { +838 visitor.visit(row, column, getEntry(row, column)); +839 } +840 } +841 return visitor.end(); +842 } +843 +844 /** {@inheritDoc} */ +845 public double walkInColumnOrder(final RealMatrixChangingVisitor visitor) +846 throws MatrixVisitorException { +847 final int rows = getRowDimension(); +848 final int columns = getColumnDimension(); +849 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +850 for (int column = 0; column < columns; ++column) { +851 for (int row = 0; row < rows; ++row) { +852 final double oldValue = getEntry(row, column); +853 final double newValue = visitor.visit(row, column, oldValue); +854 setEntry(row, column, newValue); +855 } +856 } +857 lu = null; +858 return visitor.end(); +859 } +860 +861 /** {@inheritDoc} */ +862 public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor) +863 throws MatrixVisitorException { +864 final int rows = getRowDimension(); +865 final int columns = getColumnDimension(); +866 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +867 for (int column = 0; column < columns; ++column) { +868 for (int row = 0; row < rows; ++row) { +869 visitor.visit(row, column, getEntry(row, column)); +870 } +871 } +872 return visitor.end(); +873 } +874 +875 /** {@inheritDoc} */ +876 public double walkInColumnOrder(final RealMatrixChangingVisitor visitor, +877 final int startRow, final int endRow, +878 final int startColumn, final int endColumn) +879 throws MatrixIndexException, MatrixVisitorException { +880 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +881 visitor.start(getRowDimension(), getColumnDimension(), +882 startRow, endRow, startColumn, endColumn); +883 for (int column = startColumn; column <= endColumn; ++column) { +884 for (int row = startRow; row <= endRow; ++row) { +885 final double oldValue = getEntry(row, column); +886 final double newValue = visitor.visit(row, column, oldValue); +887 setEntry(row, column, newValue); +888 } +889 } +890 lu = null; +891 return visitor.end(); +892 } +893 +894 /** {@inheritDoc} */ +895 public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor, +896 final int startRow, final int endRow, +897 final int startColumn, final int endColumn) +898 throws MatrixIndexException, MatrixVisitorException { +899 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +900 visitor.start(getRowDimension(), getColumnDimension(), +901 startRow, endRow, startColumn, endColumn); +902 for (int column = startColumn; column <= endColumn; ++column) { +903 for (int row = startRow; row <= endRow; ++row) { +904 visitor.visit(row, column, getEntry(row, column)); +905 } +906 } +907 return visitor.end(); +908 } +909 +910 /** {@inheritDoc} */ +911 public double walkInOptimizedOrder(final RealMatrixChangingVisitor visitor) +912 throws MatrixVisitorException { +913 return walkInRowOrder(visitor); +914 } +915 +916 /** {@inheritDoc} */ +917 public double walkInOptimizedOrder(final RealMatrixPreservingVisitor visitor) +918 throws MatrixVisitorException { +919 return walkInRowOrder(visitor); +920 } +921 +922 /** {@inheritDoc} */ +923 public double walkInOptimizedOrder(final RealMatrixChangingVisitor visitor, +924 final int startRow, final int endRow, +925 final int startColumn, final int endColumn) +926 throws MatrixIndexException, MatrixVisitorException { +927 return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn); +928 } +929 +930 /** {@inheritDoc} */ +931 public double walkInOptimizedOrder(final RealMatrixPreservingVisitor visitor, +932 final int startRow, final int endRow, +933 final int startColumn, final int endColumn) +934 throws MatrixIndexException, MatrixVisitorException { +935 return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn); +936 } +937 +938 /** {@inheritDoc} */ +939 @Deprecated +940 public double[] solve(final double[] b) +941 throws IllegalArgumentException, InvalidMatrixException { +942 if (lu == null) { +943 lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver(); +944 } +945 return lu.solve(b); +946 } +947 +948 /** {@inheritDoc} */ +949 @Deprecated +950 public RealMatrix solve(final RealMatrix b) +951 throws IllegalArgumentException, InvalidMatrixException { +952 if (lu == null) { +953 lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver(); +954 } +955 return lu.solve(b); +956 } +957 +958 /** +959 * Computes a new +960 * <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf"> +961 * LU decomposition</a> for this matrix, storing the result for use by other methods. +962 * <p> +963 * <strong>Implementation Note</strong>:<br> +964 * Uses <a href="http://www.damtp.cam.ac.uk/user/fdl/people/sd/lectures/nummeth98/linear.htm"> +965 * Crout's algorithm</a>, with partial pivoting.</p> +966 * <p> +967 * <strong>Usage Note</strong>:<br> +968 * This method should rarely be invoked directly. Its only use is +969 * to force recomputation of the LU decomposition when changes have been +970 * made to the underlying data using direct array references. Changes +971 * made using setXxx methods will trigger recomputation when needed +972 * automatically.</p> +973 * +974 * @throws InvalidMatrixException if the matrix is non-square or singular. +975 * @deprecated as of release 2.0, replaced by {@link LUDecomposition} +976 */ +977 @Deprecated +978 public void luDecompose() +979 throws InvalidMatrixException { +980 if (lu == null) { +981 lu = new LUDecompositionImpl(this, MathUtils.SAFE_MIN).getSolver(); +982 } +983 } +984 +985 /** +986 * Get a string representation for this matrix. +987 * @return a string representation for this matrix +988 */ +989 @Override +990 public String toString() { +991 final int nRows = getRowDimension(); +992 final int nCols = getColumnDimension(); +993 final StringBuffer res = new StringBuffer(); +994 String fullClassName = getClass().getName(); +995 String shortClassName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1); +996 res.append(shortClassName).append("{"); +997 +998 for (int i = 0; i < nRows; ++i) { +999 if (i > 0) { +1000 res.append(","); +1001 } +1002 res.append("{"); +1003 for (int j = 0; j < nCols; ++j) { +1004 if (j > 0) { +1005 res.append(","); +1006 } +1007 res.append(getEntry(i, j)); +1008 } +1009 res.append("}"); +1010 } +1011 +1012 res.append("}"); +1013 return res.toString(); +1014 +1015 } +1016 +1017 /** +1018 * Returns true iff <code>object</code> is a +1019 * <code>RealMatrix</code> instance with the same dimensions as this +1020 * and all corresponding matrix entries are equal. +1021 * +1022 * @param object the object to test equality against. +1023 * @return true if object equals this +1024 */ +1025 @Override +1026 public boolean equals(final Object object) { +1027 if (object == this ) { +1028 return true; +1029 } +1030 if (object instanceof RealMatrix == false) { +1031 return false; +1032 } +1033 RealMatrix m = (RealMatrix) object; +1034 final int nRows = getRowDimension(); +1035 final int nCols = getColumnDimension(); +1036 if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows) { +1037 return false; +1038 } +1039 for (int row = 0; row < nRows; ++row) { +1040 for (int col = 0; col < nCols; ++col) { +1041 if (getEntry(row, col) != m.getEntry(row, col)) { +1042 return false; +1043 } +1044 } +1045 } +1046 return true; +1047 } +1048 +1049 /** +1050 * Computes a hashcode for the matrix. +1051 * +1052 * @return hashcode for matrix +1053 */ +1054 @Override +1055 public int hashCode() { +1056 int ret = 7; +1057 final int nRows = getRowDimension(); +1058 final int nCols = getColumnDimension(); +1059 ret = ret * 31 + nRows; +1060 ret = ret * 31 + nCols; +1061 for (int row = 0; row < nRows; ++row) { +1062 for (int col = 0; col < nCols; ++col) { +1063 ret = ret * 31 + (11 * (row+1) + 17 * (col+1)) * +1064 MathUtils.hash(getEntry(row, col)); +1065 } +1066 } +1067 return ret; +1068 } +1069 +1070 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/AbstractRealVector.EntryImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/AbstractRealVector.EntryImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1012 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.util.Iterator; +021 +022 import org.apache.commons.math.FunctionEvaluationException; +023 import org.apache.commons.math.MathRuntimeException; +024 import org.apache.commons.math.analysis.BinaryFunction; +025 import org.apache.commons.math.analysis.UnivariateRealFunction; +026 import org.apache.commons.math.analysis.ComposableFunction; +027 +028 /** +029 * This class provides default basic implementations for many methods in the +030 * {@link RealVector} interface with. +031 * @version $Revision: 904231 $ $Date: 2010-01-28 14:42:31 -0500 (Thu, 28 Jan 2010) $ +032 * @since 2.1 +033 */ +034 public abstract class AbstractRealVector implements RealVector { +035 +036 /** +037 * Check if instance and specified vectors have the same dimension. +038 * @param v vector to compare instance with +039 * @exception IllegalArgumentException if the vectors do not +040 * have the same dimension +041 */ +042 protected void checkVectorDimensions(RealVector v) { +043 checkVectorDimensions(v.getDimension()); +044 } +045 +046 /** +047 * Check if instance dimension is equal to some expected value. +048 * +049 * @param n expected dimension. +050 * @exception IllegalArgumentException if the dimension is +051 * inconsistent with vector size +052 */ +053 protected void checkVectorDimensions(int n) +054 throws IllegalArgumentException { +055 double d = getDimension(); +056 if (d != n) { +057 throw MathRuntimeException.createIllegalArgumentException( +058 "vector length mismatch: got {0} but expected {1}", +059 d, n); +060 } +061 } +062 +063 /** +064 * Check if an index is valid. +065 * @param index index to check +066 * @exception MatrixIndexException if index is not valid +067 */ +068 protected void checkIndex(final int index) +069 throws MatrixIndexException { +070 if (index < 0 || index >= getDimension()) { +071 throw new MatrixIndexException( +072 "index {0} out of allowed range [{1}, {2}]", +073 index, 0, getDimension() - 1); +074 } +075 } +076 +077 /** {@inheritDoc} */ +078 public void setSubVector(int index, RealVector v) throws MatrixIndexException { +079 checkIndex(index); +080 checkIndex(index + v.getDimension() - 1); +081 setSubVector(index, v.getData()); +082 } +083 +084 /** {@inheritDoc} */ +085 public void setSubVector(int index, double[] v) throws MatrixIndexException { +086 checkIndex(index); +087 checkIndex(index + v.length - 1); +088 for (int i = 0; i < v.length; i++) { +089 setEntry(i + index, v[i]); +090 } +091 } +092 +093 /** {@inheritDoc} */ +094 public RealVector add(double[] v) throws IllegalArgumentException { +095 double[] result = v.clone(); +096 Iterator<Entry> it = sparseIterator(); +097 Entry e; +098 while (it.hasNext() && (e = it.next()) != null) { +099 result[e.getIndex()] += e.getValue(); +100 } +101 return new ArrayRealVector(result, false); +102 } +103 +104 /** {@inheritDoc} */ +105 public RealVector add(RealVector v) throws IllegalArgumentException { +106 if (v instanceof ArrayRealVector) { +107 double[] values = ((ArrayRealVector)v).getDataRef(); +108 return add(values); +109 } +110 RealVector result = v.copy(); +111 Iterator<Entry> it = sparseIterator(); +112 Entry e; +113 while (it.hasNext() && (e = it.next()) != null) { +114 final int index = e.getIndex(); +115 result.setEntry(index, e.getValue() + result.getEntry(index)); +116 } +117 return result; +118 } +119 +120 /** {@inheritDoc} */ +121 public RealVector subtract(double[] v) throws IllegalArgumentException { +122 double[] result = v.clone(); +123 Iterator<Entry> it = sparseIterator(); +124 Entry e; +125 while (it.hasNext() && (e = it.next()) != null) { +126 final int index = e.getIndex(); +127 result[index] = e.getValue() - result[index]; +128 } +129 return new ArrayRealVector(result, false); +130 } +131 +132 /** {@inheritDoc} */ +133 public RealVector subtract(RealVector v) throws IllegalArgumentException { +134 if (v instanceof ArrayRealVector) { +135 double[] values = ((ArrayRealVector)v).getDataRef(); +136 return add(values); +137 } +138 RealVector result = v.copy(); +139 Iterator<Entry> it = sparseIterator(); +140 Entry e; +141 while (it.hasNext() && (e = it.next()) != null) { +142 final int index = e.getIndex(); +143 v.setEntry(index, e.getValue() - result.getEntry(index)); +144 } +145 return result; +146 } +147 +148 /** {@inheritDoc} */ +149 public RealVector mapAdd(double d) { +150 return copy().mapAddToSelf(d); +151 } +152 +153 /** {@inheritDoc} */ +154 public RealVector mapAddToSelf(double d) { +155 if (d != 0) { +156 try { +157 return mapToSelf(BinaryFunction.ADD.fix1stArgument(d)); +158 } catch (FunctionEvaluationException e) { +159 throw new IllegalArgumentException(e); +160 } +161 } +162 return this; +163 } +164 +165 /** {@inheritDoc} */ +166 public abstract AbstractRealVector copy(); +167 +168 /** {@inheritDoc} */ +169 public double dotProduct(double[] v) throws IllegalArgumentException { +170 return dotProduct(new ArrayRealVector(v, false)); +171 } +172 +173 /** {@inheritDoc} */ +174 public double dotProduct(RealVector v) throws IllegalArgumentException { +175 checkVectorDimensions(v); +176 double d = 0; +177 Iterator<Entry> it = sparseIterator(); +178 Entry e; +179 while (it.hasNext() && (e = it.next()) != null) { +180 d += e.getValue() * v.getEntry(e.getIndex()); +181 } +182 return d; +183 } +184 +185 /** {@inheritDoc} */ +186 public RealVector ebeDivide(double[] v) throws IllegalArgumentException { +187 return ebeDivide(new ArrayRealVector(v, false)); +188 } +189 +190 /** {@inheritDoc} */ +191 public RealVector ebeMultiply(double[] v) throws IllegalArgumentException { +192 return ebeMultiply(new ArrayRealVector(v, false)); +193 } +194 +195 /** {@inheritDoc} */ +196 public double getDistance(RealVector v) throws IllegalArgumentException { +197 checkVectorDimensions(v); +198 double d = 0; +199 Iterator<Entry> it = iterator(); +200 Entry e; +201 while (it.hasNext() && (e = it.next()) != null) { +202 final double diff = e.getValue() - v.getEntry(e.getIndex()); +203 d += diff * diff; +204 } +205 return Math.sqrt(d); +206 } +207 +208 /** {@inheritDoc} */ +209 public double getNorm() { +210 double sum = 0; +211 Iterator<Entry> it = sparseIterator(); +212 Entry e; +213 while (it.hasNext() && (e = it.next()) != null) { +214 final double value = e.getValue(); +215 sum += value * value; +216 } +217 return Math.sqrt(sum); +218 } +219 +220 /** {@inheritDoc} */ +221 public double getL1Norm() { +222 double norm = 0; +223 Iterator<Entry> it = sparseIterator(); +224 Entry e; +225 while (it.hasNext() && (e = it.next()) != null) { +226 norm += Math.abs(e.getValue()); +227 } +228 return norm; +229 } +230 +231 /** {@inheritDoc} */ +232 public double getLInfNorm() { +233 double norm = 0; +234 Iterator<Entry> it = sparseIterator(); +235 Entry e; +236 while (it.hasNext() && (e = it.next()) != null) { +237 norm = Math.max(norm, Math.abs(e.getValue())); +238 } +239 return norm; +240 } +241 +242 /** {@inheritDoc} */ +243 public double getDistance(double[] v) throws IllegalArgumentException { +244 return getDistance(new ArrayRealVector(v,false)); +245 } +246 +247 /** {@inheritDoc} */ +248 public double getL1Distance(RealVector v) throws IllegalArgumentException { +249 checkVectorDimensions(v); +250 double d = 0; +251 Iterator<Entry> it = iterator(); +252 Entry e; +253 while (it.hasNext() && (e = it.next()) != null) { +254 d += Math.abs(e.getValue() - v.getEntry(e.getIndex())); +255 } +256 return d; +257 } +258 +259 /** {@inheritDoc} */ +260 public double getL1Distance(double[] v) throws IllegalArgumentException { +261 checkVectorDimensions(v.length); +262 double d = 0; +263 Iterator<Entry> it = iterator(); +264 Entry e; +265 while (it.hasNext() && (e = it.next()) != null) { +266 d += Math.abs(e.getValue() - v[e.getIndex()]); +267 } +268 return d; +269 } +270 +271 /** {@inheritDoc} */ +272 public double getLInfDistance(RealVector v) throws IllegalArgumentException { +273 checkVectorDimensions(v); +274 double d = 0; +275 Iterator<Entry> it = iterator(); +276 Entry e; +277 while (it.hasNext() && (e = it.next()) != null) { +278 d = Math.max(Math.abs(e.getValue() - v.getEntry(e.getIndex())), d); +279 } +280 return d; +281 } +282 +283 /** {@inheritDoc} */ +284 public double getLInfDistance(double[] v) throws IllegalArgumentException { +285 checkVectorDimensions(v.length); +286 double d = 0; +287 Iterator<Entry> it = iterator(); +288 Entry e; +289 while (it.hasNext() && (e = it.next()) != null) { +290 d = Math.max(Math.abs(e.getValue() - v[e.getIndex()]), d); +291 } +292 return d; +293 } +294 +295 /** Get the index of the minimum entry. +296 * @return index of the minimum entry or -1 if vector length is 0 +297 * or all entries are NaN +298 */ +299 public int getMinIndex() { +300 int minIndex = -1; +301 double minValue = Double.POSITIVE_INFINITY; +302 Iterator<Entry> iterator = iterator(); +303 while (iterator.hasNext()) { +304 final Entry entry = iterator.next(); +305 if (entry.getValue() <= minValue) { +306 minIndex = entry.getIndex(); +307 minValue = entry.getValue(); +308 } +309 } +310 return minIndex; +311 } +312 +313 /** Get the value of the minimum entry. +314 * @return value of the minimum entry or NaN if all entries are NaN +315 */ +316 public double getMinValue() { +317 final int minIndex = getMinIndex(); +318 return minIndex < 0 ? Double.NaN : getEntry(minIndex); +319 } +320 +321 /** Get the index of the maximum entry. +322 * @return index of the maximum entry or -1 if vector length is 0 +323 * or all entries are NaN +324 */ +325 public int getMaxIndex() { +326 int maxIndex = -1; +327 double maxValue = Double.NEGATIVE_INFINITY; +328 Iterator<Entry> iterator = iterator(); +329 while (iterator.hasNext()) { +330 final Entry entry = iterator.next(); +331 if (entry.getValue() >= maxValue) { +332 maxIndex = entry.getIndex(); +333 maxValue = entry.getValue(); +334 } +335 } +336 return maxIndex; +337 } +338 +339 /** Get the value of the maximum entry. +340 * @return value of the maximum entry or NaN if all entries are NaN +341 */ +342 public double getMaxValue() { +343 final int maxIndex = getMaxIndex(); +344 return maxIndex < 0 ? Double.NaN : getEntry(maxIndex); +345 } +346 +347 /** {@inheritDoc} */ +348 public RealVector mapAbs() { +349 return copy().mapAbsToSelf(); +350 } +351 +352 /** {@inheritDoc} */ +353 public RealVector mapAbsToSelf() { +354 try { +355 return mapToSelf(ComposableFunction.ABS); +356 } catch (FunctionEvaluationException e) { +357 throw new IllegalArgumentException(e); +358 } +359 } +360 +361 /** {@inheritDoc} */ +362 public RealVector mapAcos() { +363 return copy().mapAcosToSelf(); +364 } +365 +366 /** {@inheritDoc} */ +367 public RealVector mapAcosToSelf() { +368 try { +369 return mapToSelf(ComposableFunction.ACOS); +370 } catch (FunctionEvaluationException e) { +371 throw new IllegalArgumentException(e); +372 } +373 } +374 +375 /** {@inheritDoc} */ +376 public RealVector mapAsin() { +377 return copy().mapAsinToSelf(); +378 } +379 +380 /** {@inheritDoc} */ +381 public RealVector mapAsinToSelf() { +382 try { +383 return mapToSelf(ComposableFunction.ASIN); +384 } catch (FunctionEvaluationException e) { +385 throw new IllegalArgumentException(e); +386 } +387 } +388 +389 /** {@inheritDoc} */ +390 public RealVector mapAtan() { +391 return copy().mapAtanToSelf(); +392 } +393 +394 /** {@inheritDoc} */ +395 public RealVector mapAtanToSelf() { +396 try { +397 return mapToSelf(ComposableFunction.ATAN); +398 } catch (FunctionEvaluationException e) { +399 throw new IllegalArgumentException(e); +400 } +401 } +402 +403 /** {@inheritDoc} */ +404 public RealVector mapCbrt() { +405 return copy().mapCbrtToSelf(); +406 } +407 +408 /** {@inheritDoc} */ +409 public RealVector mapCbrtToSelf() { +410 try { +411 return mapToSelf(ComposableFunction.CBRT); +412 } catch (FunctionEvaluationException e) { +413 throw new IllegalArgumentException(e); +414 } +415 } +416 +417 /** {@inheritDoc} */ +418 public RealVector mapCeil() { +419 return copy().mapCeilToSelf(); +420 } +421 +422 /** {@inheritDoc} */ +423 public RealVector mapCeilToSelf() { +424 try { +425 return mapToSelf(ComposableFunction.CEIL); +426 } catch (FunctionEvaluationException e) { +427 throw new IllegalArgumentException(e); +428 } +429 } +430 +431 /** {@inheritDoc} */ +432 public RealVector mapCos() { +433 return copy().mapCosToSelf(); +434 } +435 +436 /** {@inheritDoc} */ +437 public RealVector mapCosToSelf() { +438 try { +439 return mapToSelf(ComposableFunction.COS); +440 } catch (FunctionEvaluationException e) { +441 throw new IllegalArgumentException(e); +442 } +443 } +444 +445 /** {@inheritDoc} */ +446 public RealVector mapCosh() { +447 return copy().mapCoshToSelf(); +448 } +449 +450 /** {@inheritDoc} */ +451 public RealVector mapCoshToSelf() { +452 try { +453 return mapToSelf(ComposableFunction.COSH); +454 } catch (FunctionEvaluationException e) { +455 throw new IllegalArgumentException(e); +456 } +457 } +458 +459 /** {@inheritDoc} */ +460 public RealVector mapDivide(double d) { +461 return copy().mapDivideToSelf(d); +462 } +463 +464 /** {@inheritDoc} */ +465 public RealVector mapDivideToSelf(double d){ +466 try { +467 return mapToSelf(BinaryFunction.DIVIDE.fix2ndArgument(d)); +468 } catch (FunctionEvaluationException e) { +469 throw new IllegalArgumentException(e); +470 } +471 } +472 +473 /** {@inheritDoc} */ +474 public RealVector mapExp() { +475 return copy().mapExpToSelf(); +476 } +477 +478 /** {@inheritDoc} */ +479 public RealVector mapExpToSelf() { +480 try { +481 return mapToSelf(ComposableFunction.EXP); +482 } catch (FunctionEvaluationException e) { +483 throw new IllegalArgumentException(e); +484 } +485 } +486 +487 /** {@inheritDoc} */ +488 public RealVector mapExpm1() { +489 return copy().mapExpm1ToSelf(); +490 } +491 +492 /** {@inheritDoc} */ +493 public RealVector mapExpm1ToSelf() { +494 try { +495 return mapToSelf(ComposableFunction.EXPM1); +496 } catch (FunctionEvaluationException e) { +497 throw new IllegalArgumentException(e); +498 } +499 } +500 +501 /** {@inheritDoc} */ +502 public RealVector mapFloor() { +503 return copy().mapFloorToSelf(); +504 } +505 +506 /** {@inheritDoc} */ +507 public RealVector mapFloorToSelf() { +508 try { +509 return mapToSelf(ComposableFunction.FLOOR); +510 } catch (FunctionEvaluationException e) { +511 throw new IllegalArgumentException(e); +512 } +513 } +514 +515 /** {@inheritDoc} */ +516 public RealVector mapInv() { +517 return copy().mapInvToSelf(); +518 } +519 +520 /** {@inheritDoc} */ +521 public RealVector mapInvToSelf() { +522 try { +523 return mapToSelf(ComposableFunction.INVERT); +524 } catch (FunctionEvaluationException e) { +525 throw new IllegalArgumentException(e); +526 } +527 } +528 +529 /** {@inheritDoc} */ +530 public RealVector mapLog() { +531 return copy().mapLogToSelf(); +532 } +533 +534 /** {@inheritDoc} */ +535 public RealVector mapLogToSelf() { +536 try { +537 return mapToSelf(ComposableFunction.LOG); +538 } catch (FunctionEvaluationException e) { +539 throw new IllegalArgumentException(e); +540 } +541 } +542 +543 /** {@inheritDoc} */ +544 public RealVector mapLog10() { +545 return copy().mapLog10ToSelf(); +546 } +547 +548 /** {@inheritDoc} */ +549 public RealVector mapLog10ToSelf() { +550 try { +551 return mapToSelf(ComposableFunction.LOG10); +552 } catch (FunctionEvaluationException e) { +553 throw new IllegalArgumentException(e); +554 } +555 } +556 +557 /** {@inheritDoc} */ +558 public RealVector mapLog1p() { +559 return copy().mapLog1pToSelf(); +560 } +561 +562 /** {@inheritDoc} */ +563 public RealVector mapLog1pToSelf() { +564 try { +565 return mapToSelf(ComposableFunction.LOG1P); +566 } catch (FunctionEvaluationException e) { +567 throw new IllegalArgumentException(e); +568 } +569 } +570 +571 /** {@inheritDoc} */ +572 public RealVector mapMultiply(double d) { +573 return copy().mapMultiplyToSelf(d); +574 } +575 +576 /** {@inheritDoc} */ +577 public RealVector mapMultiplyToSelf(double d){ +578 try { +579 return mapToSelf(BinaryFunction.MULTIPLY.fix1stArgument(d)); +580 } catch (FunctionEvaluationException e) { +581 throw new IllegalArgumentException(e); +582 } +583 } +584 +585 /** {@inheritDoc} */ +586 public RealVector mapPow(double d) { +587 return copy().mapPowToSelf(d); +588 } +589 +590 /** {@inheritDoc} */ +591 public RealVector mapPowToSelf(double d){ +592 try { +593 return mapToSelf(BinaryFunction.POW.fix2ndArgument(d)); +594 } catch (FunctionEvaluationException e) { +595 throw new IllegalArgumentException(e); +596 } +597 } +598 +599 /** {@inheritDoc} */ +600 public RealVector mapRint() { +601 return copy().mapRintToSelf(); +602 } +603 +604 /** {@inheritDoc} */ +605 public RealVector mapRintToSelf() { +606 try { +607 return mapToSelf(ComposableFunction.RINT); +608 } catch (FunctionEvaluationException e) { +609 throw new IllegalArgumentException(e); +610 } +611 } +612 +613 /** {@inheritDoc} */ +614 public RealVector mapSignum() { +615 return copy().mapSignumToSelf(); +616 } +617 +618 /** {@inheritDoc} */ +619 public RealVector mapSignumToSelf() { +620 try { +621 return mapToSelf(ComposableFunction.SIGNUM); +622 } catch (FunctionEvaluationException e) { +623 throw new IllegalArgumentException(e); +624 } +625 } +626 +627 /** {@inheritDoc} */ +628 public RealVector mapSin() { +629 return copy().mapSinToSelf(); +630 } +631 +632 /** {@inheritDoc} */ +633 public RealVector mapSinToSelf() { +634 try { +635 return mapToSelf(ComposableFunction.SIN); +636 } catch (FunctionEvaluationException e) { +637 throw new IllegalArgumentException(e); +638 } +639 } +640 +641 /** {@inheritDoc} */ +642 public RealVector mapSinh() { +643 return copy().mapSinhToSelf(); +644 } +645 +646 /** {@inheritDoc} */ +647 public RealVector mapSinhToSelf() { +648 try { +649 return mapToSelf(ComposableFunction.SINH); +650 } catch (FunctionEvaluationException e) { +651 throw new IllegalArgumentException(e); +652 } +653 } +654 +655 /** {@inheritDoc} */ +656 public RealVector mapSqrt() { +657 return copy().mapSqrtToSelf(); +658 } +659 +660 /** {@inheritDoc} */ +661 public RealVector mapSqrtToSelf() { +662 try { +663 return mapToSelf(ComposableFunction.SQRT); +664 } catch (FunctionEvaluationException e) { +665 throw new IllegalArgumentException(e); +666 } +667 } +668 +669 /** {@inheritDoc} */ +670 public RealVector mapSubtract(double d) { +671 return copy().mapSubtractToSelf(d); +672 } +673 +674 /** {@inheritDoc} */ +675 public RealVector mapSubtractToSelf(double d){ +676 return mapAddToSelf(-d); +677 } +678 +679 /** {@inheritDoc} */ +680 public RealVector mapTan() { +681 return copy().mapTanToSelf(); +682 } +683 +684 /** {@inheritDoc} */ +685 public RealVector mapTanToSelf() { +686 try { +687 return mapToSelf(ComposableFunction.TAN); +688 } catch (FunctionEvaluationException e) { +689 throw new IllegalArgumentException(e); +690 } +691 } +692 +693 /** {@inheritDoc} */ +694 public RealVector mapTanh() { +695 return copy().mapTanhToSelf(); +696 } +697 +698 /** {@inheritDoc} */ +699 public RealVector mapTanhToSelf() { +700 try { +701 return mapToSelf(ComposableFunction.TANH); +702 } catch (FunctionEvaluationException e) { +703 throw new IllegalArgumentException(e); +704 } +705 } +706 +707 /** {@inheritDoc} */ +708 public RealVector mapUlp() { +709 return copy().mapUlpToSelf(); +710 } +711 +712 /** {@inheritDoc} */ +713 public RealVector mapUlpToSelf() { +714 try { +715 return mapToSelf(ComposableFunction.ULP); +716 } catch (FunctionEvaluationException e) { +717 throw new IllegalArgumentException(e); +718 } +719 } +720 +721 /** {@inheritDoc} */ +722 public RealMatrix outerProduct(RealVector v) throws IllegalArgumentException { +723 RealMatrix product; +724 if (v instanceof SparseRealVector || this instanceof SparseRealVector) { +725 product = new OpenMapRealMatrix(this.getDimension(), v.getDimension()); +726 } else { +727 product = new Array2DRowRealMatrix(this.getDimension(), v.getDimension()); +728 } +729 Iterator<Entry> thisIt = sparseIterator(); +730 Entry thisE = null; +731 while (thisIt.hasNext() && (thisE = thisIt.next()) != null) { +732 Iterator<Entry> otherIt = v.sparseIterator(); +733 Entry otherE = null; +734 while (otherIt.hasNext() && (otherE = otherIt.next()) != null) { +735 product.setEntry(thisE.getIndex(), otherE.getIndex(), +736 thisE.getValue() * otherE.getValue()); +737 } +738 } +739 +740 return product; +741 +742 } +743 +744 /** {@inheritDoc} */ +745 public RealMatrix outerProduct(double[] v) throws IllegalArgumentException { +746 return outerProduct(new ArrayRealVector(v, false)); +747 } +748 +749 /** {@inheritDoc} */ +750 public RealVector projection(double[] v) throws IllegalArgumentException { +751 return projection(new ArrayRealVector(v, false)); +752 } +753 +754 /** {@inheritDoc} */ +755 public void set(double value) { +756 Iterator<Entry> it = iterator(); +757 Entry e = null; +758 while (it.hasNext() && (e = it.next()) != null) { +759 e.setValue(value); +760 } +761 } +762 +763 /** {@inheritDoc} */ +764 public double[] toArray() { +765 int dim = getDimension(); +766 double[] values = new double[dim]; +767 for (int i = 0; i < dim; i++) { +768 values[i] = getEntry(i); +769 } +770 return values; +771 } +772 +773 /** {@inheritDoc} */ +774 public double[] getData() { +775 return toArray(); +776 } +777 +778 /** {@inheritDoc} */ +779 public RealVector unitVector() { +780 RealVector copy = copy(); +781 copy.unitize(); +782 return copy; +783 } +784 +785 /** {@inheritDoc} */ +786 public void unitize() { +787 mapDivideToSelf(getNorm()); +788 } +789 +790 /** {@inheritDoc} */ +791 public Iterator<Entry> sparseIterator() { +792 return new SparseEntryIterator(); +793 } +794 +795 /** {@inheritDoc} */ +796 public Iterator<Entry> iterator() { +797 final int dim = getDimension(); +798 return new Iterator<Entry>() { +799 +800 /** Current index. */ +801 private int i = 0; +802 +803 /** Current entry. */ +804 private EntryImpl e = new EntryImpl(); +805 +806 /** {@inheritDoc} */ +807 public boolean hasNext() { +808 return i < dim; +809 } +810 +811 /** {@inheritDoc} */ +812 public Entry next() { +813 e.setIndex(i++); +814 return e; +815 } +816 +817 /** {@inheritDoc} */ +818 public void remove() { +819 throw new UnsupportedOperationException("Not supported"); +820 } +821 }; +822 } +823 +824 /** {@inheritDoc} */ +825 public RealVector map(UnivariateRealFunction function) throws FunctionEvaluationException { +826 return copy().mapToSelf(function); +827 } +828 +829 /** {@inheritDoc} */ +830 public RealVector mapToSelf(UnivariateRealFunction function) throws FunctionEvaluationException { +831 Iterator<Entry> it = (function.value(0) == 0) ? sparseIterator() : iterator(); +832 Entry e; +833 while (it.hasNext() && (e = it.next()) != null) { +834 e.setValue(function.value(e.getValue())); +835 } +836 return this; +837 } +838 +839 /** An entry in the vector. */ +840 protected class EntryImpl extends Entry { +841 +842 /** Simple constructor. */ +843 public EntryImpl() { +844 setIndex(0); +845 } +846 +847 /** {@inheritDoc} */ +848 @Override +849 public double getValue() { +850 return getEntry(getIndex()); +851 } +852 +853 /** {@inheritDoc} */ +854 @Override +855 public void setValue(double newValue) { +856 setEntry(getIndex(), newValue); +857 } +858 } +859 +860 /** +861 * This class should rare be used, but is here to provide +862 * a default implementation of sparseIterator(), which is implemented +863 * by walking over the entries, skipping those whose values are the default one. +864 * +865 * Concrete subclasses which are SparseVector implementations should +866 * make their own sparse iterator, not use this one. +867 * +868 * This implementation might be useful for ArrayRealVector, when expensive +869 * operations which preserve the default value are to be done on the entries, +870 * and the fraction of non-default values is small (i.e. someone took a +871 * SparseVector, and passed it into the copy-constructor of ArrayRealVector) +872 */ +873 protected class SparseEntryIterator implements Iterator<Entry> { +874 +875 /** Dimension of the vector. */ +876 private final int dim; +877 +878 /** Temporary entry (reused on each call to {@link #next()}. */ +879 private EntryImpl tmp = new EntryImpl(); +880 +881 /** Current entry. */ +882 private EntryImpl current; +883 +884 /** Next entry. */ +885 private EntryImpl next; +886 +887 /** Simple constructor. */ +888 protected SparseEntryIterator() { +889 dim = getDimension(); +890 current = new EntryImpl(); +891 if (current.getValue() == 0) { +892 advance(current); +893 } +894 if(current.getIndex() >= 0){ +895 // There is at least one non-zero entry +896 next = new EntryImpl(); +897 next.setIndex(current.getIndex()); +898 advance(next); +899 } else { +900 // The vector consists of only zero entries, so deny having a next +901 current = null; +902 } +903 } +904 +905 /** Advance an entry up to the next non null one. +906 * @param e entry to advance +907 */ +908 protected void advance(EntryImpl e) { +909 if (e == null) { +910 return; +911 } +912 do { +913 e.setIndex(e.getIndex() + 1); +914 } while (e.getIndex() < dim && e.getValue() == 0); +915 if (e.getIndex() >= dim) { +916 e.setIndex(-1); +917 } +918 } +919 +920 /** {@inheritDoc} */ +921 public boolean hasNext() { +922 return current != null; +923 } +924 +925 /** {@inheritDoc} */ +926 public Entry next() { +927 tmp.setIndex(current.getIndex()); +928 if (next != null) { +929 current.setIndex(next.getIndex()); +930 advance(next); +931 if (next.getIndex() < 0) { +932 next = null; +933 } +934 } else { +935 current = null; +936 } +937 return tmp; +938 } +939 +940 /** {@inheritDoc} */ +941 public void remove() { +942 throw new UnsupportedOperationException("Not supported"); +943 } +944 } +945 +946 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/AbstractRealVector.SparseEntryIterator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/AbstractRealVector.SparseEntryIterator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1012 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.util.Iterator; +021 +022 import org.apache.commons.math.FunctionEvaluationException; +023 import org.apache.commons.math.MathRuntimeException; +024 import org.apache.commons.math.analysis.BinaryFunction; +025 import org.apache.commons.math.analysis.UnivariateRealFunction; +026 import org.apache.commons.math.analysis.ComposableFunction; +027 +028 /** +029 * This class provides default basic implementations for many methods in the +030 * {@link RealVector} interface with. +031 * @version $Revision: 904231 $ $Date: 2010-01-28 14:42:31 -0500 (Thu, 28 Jan 2010) $ +032 * @since 2.1 +033 */ +034 public abstract class AbstractRealVector implements RealVector { +035 +036 /** +037 * Check if instance and specified vectors have the same dimension. +038 * @param v vector to compare instance with +039 * @exception IllegalArgumentException if the vectors do not +040 * have the same dimension +041 */ +042 protected void checkVectorDimensions(RealVector v) { +043 checkVectorDimensions(v.getDimension()); +044 } +045 +046 /** +047 * Check if instance dimension is equal to some expected value. +048 * +049 * @param n expected dimension. +050 * @exception IllegalArgumentException if the dimension is +051 * inconsistent with vector size +052 */ +053 protected void checkVectorDimensions(int n) +054 throws IllegalArgumentException { +055 double d = getDimension(); +056 if (d != n) { +057 throw MathRuntimeException.createIllegalArgumentException( +058 "vector length mismatch: got {0} but expected {1}", +059 d, n); +060 } +061 } +062 +063 /** +064 * Check if an index is valid. +065 * @param index index to check +066 * @exception MatrixIndexException if index is not valid +067 */ +068 protected void checkIndex(final int index) +069 throws MatrixIndexException { +070 if (index < 0 || index >= getDimension()) { +071 throw new MatrixIndexException( +072 "index {0} out of allowed range [{1}, {2}]", +073 index, 0, getDimension() - 1); +074 } +075 } +076 +077 /** {@inheritDoc} */ +078 public void setSubVector(int index, RealVector v) throws MatrixIndexException { +079 checkIndex(index); +080 checkIndex(index + v.getDimension() - 1); +081 setSubVector(index, v.getData()); +082 } +083 +084 /** {@inheritDoc} */ +085 public void setSubVector(int index, double[] v) throws MatrixIndexException { +086 checkIndex(index); +087 checkIndex(index + v.length - 1); +088 for (int i = 0; i < v.length; i++) { +089 setEntry(i + index, v[i]); +090 } +091 } +092 +093 /** {@inheritDoc} */ +094 public RealVector add(double[] v) throws IllegalArgumentException { +095 double[] result = v.clone(); +096 Iterator<Entry> it = sparseIterator(); +097 Entry e; +098 while (it.hasNext() && (e = it.next()) != null) { +099 result[e.getIndex()] += e.getValue(); +100 } +101 return new ArrayRealVector(result, false); +102 } +103 +104 /** {@inheritDoc} */ +105 public RealVector add(RealVector v) throws IllegalArgumentException { +106 if (v instanceof ArrayRealVector) { +107 double[] values = ((ArrayRealVector)v).getDataRef(); +108 return add(values); +109 } +110 RealVector result = v.copy(); +111 Iterator<Entry> it = sparseIterator(); +112 Entry e; +113 while (it.hasNext() && (e = it.next()) != null) { +114 final int index = e.getIndex(); +115 result.setEntry(index, e.getValue() + result.getEntry(index)); +116 } +117 return result; +118 } +119 +120 /** {@inheritDoc} */ +121 public RealVector subtract(double[] v) throws IllegalArgumentException { +122 double[] result = v.clone(); +123 Iterator<Entry> it = sparseIterator(); +124 Entry e; +125 while (it.hasNext() && (e = it.next()) != null) { +126 final int index = e.getIndex(); +127 result[index] = e.getValue() - result[index]; +128 } +129 return new ArrayRealVector(result, false); +130 } +131 +132 /** {@inheritDoc} */ +133 public RealVector subtract(RealVector v) throws IllegalArgumentException { +134 if (v instanceof ArrayRealVector) { +135 double[] values = ((ArrayRealVector)v).getDataRef(); +136 return add(values); +137 } +138 RealVector result = v.copy(); +139 Iterator<Entry> it = sparseIterator(); +140 Entry e; +141 while (it.hasNext() && (e = it.next()) != null) { +142 final int index = e.getIndex(); +143 v.setEntry(index, e.getValue() - result.getEntry(index)); +144 } +145 return result; +146 } +147 +148 /** {@inheritDoc} */ +149 public RealVector mapAdd(double d) { +150 return copy().mapAddToSelf(d); +151 } +152 +153 /** {@inheritDoc} */ +154 public RealVector mapAddToSelf(double d) { +155 if (d != 0) { +156 try { +157 return mapToSelf(BinaryFunction.ADD.fix1stArgument(d)); +158 } catch (FunctionEvaluationException e) { +159 throw new IllegalArgumentException(e); +160 } +161 } +162 return this; +163 } +164 +165 /** {@inheritDoc} */ +166 public abstract AbstractRealVector copy(); +167 +168 /** {@inheritDoc} */ +169 public double dotProduct(double[] v) throws IllegalArgumentException { +170 return dotProduct(new ArrayRealVector(v, false)); +171 } +172 +173 /** {@inheritDoc} */ +174 public double dotProduct(RealVector v) throws IllegalArgumentException { +175 checkVectorDimensions(v); +176 double d = 0; +177 Iterator<Entry> it = sparseIterator(); +178 Entry e; +179 while (it.hasNext() && (e = it.next()) != null) { +180 d += e.getValue() * v.getEntry(e.getIndex()); +181 } +182 return d; +183 } +184 +185 /** {@inheritDoc} */ +186 public RealVector ebeDivide(double[] v) throws IllegalArgumentException { +187 return ebeDivide(new ArrayRealVector(v, false)); +188 } +189 +190 /** {@inheritDoc} */ +191 public RealVector ebeMultiply(double[] v) throws IllegalArgumentException { +192 return ebeMultiply(new ArrayRealVector(v, false)); +193 } +194 +195 /** {@inheritDoc} */ +196 public double getDistance(RealVector v) throws IllegalArgumentException { +197 checkVectorDimensions(v); +198 double d = 0; +199 Iterator<Entry> it = iterator(); +200 Entry e; +201 while (it.hasNext() && (e = it.next()) != null) { +202 final double diff = e.getValue() - v.getEntry(e.getIndex()); +203 d += diff * diff; +204 } +205 return Math.sqrt(d); +206 } +207 +208 /** {@inheritDoc} */ +209 public double getNorm() { +210 double sum = 0; +211 Iterator<Entry> it = sparseIterator(); +212 Entry e; +213 while (it.hasNext() && (e = it.next()) != null) { +214 final double value = e.getValue(); +215 sum += value * value; +216 } +217 return Math.sqrt(sum); +218 } +219 +220 /** {@inheritDoc} */ +221 public double getL1Norm() { +222 double norm = 0; +223 Iterator<Entry> it = sparseIterator(); +224 Entry e; +225 while (it.hasNext() && (e = it.next()) != null) { +226 norm += Math.abs(e.getValue()); +227 } +228 return norm; +229 } +230 +231 /** {@inheritDoc} */ +232 public double getLInfNorm() { +233 double norm = 0; +234 Iterator<Entry> it = sparseIterator(); +235 Entry e; +236 while (it.hasNext() && (e = it.next()) != null) { +237 norm = Math.max(norm, Math.abs(e.getValue())); +238 } +239 return norm; +240 } +241 +242 /** {@inheritDoc} */ +243 public double getDistance(double[] v) throws IllegalArgumentException { +244 return getDistance(new ArrayRealVector(v,false)); +245 } +246 +247 /** {@inheritDoc} */ +248 public double getL1Distance(RealVector v) throws IllegalArgumentException { +249 checkVectorDimensions(v); +250 double d = 0; +251 Iterator<Entry> it = iterator(); +252 Entry e; +253 while (it.hasNext() && (e = it.next()) != null) { +254 d += Math.abs(e.getValue() - v.getEntry(e.getIndex())); +255 } +256 return d; +257 } +258 +259 /** {@inheritDoc} */ +260 public double getL1Distance(double[] v) throws IllegalArgumentException { +261 checkVectorDimensions(v.length); +262 double d = 0; +263 Iterator<Entry> it = iterator(); +264 Entry e; +265 while (it.hasNext() && (e = it.next()) != null) { +266 d += Math.abs(e.getValue() - v[e.getIndex()]); +267 } +268 return d; +269 } +270 +271 /** {@inheritDoc} */ +272 public double getLInfDistance(RealVector v) throws IllegalArgumentException { +273 checkVectorDimensions(v); +274 double d = 0; +275 Iterator<Entry> it = iterator(); +276 Entry e; +277 while (it.hasNext() && (e = it.next()) != null) { +278 d = Math.max(Math.abs(e.getValue() - v.getEntry(e.getIndex())), d); +279 } +280 return d; +281 } +282 +283 /** {@inheritDoc} */ +284 public double getLInfDistance(double[] v) throws IllegalArgumentException { +285 checkVectorDimensions(v.length); +286 double d = 0; +287 Iterator<Entry> it = iterator(); +288 Entry e; +289 while (it.hasNext() && (e = it.next()) != null) { +290 d = Math.max(Math.abs(e.getValue() - v[e.getIndex()]), d); +291 } +292 return d; +293 } +294 +295 /** Get the index of the minimum entry. +296 * @return index of the minimum entry or -1 if vector length is 0 +297 * or all entries are NaN +298 */ +299 public int getMinIndex() { +300 int minIndex = -1; +301 double minValue = Double.POSITIVE_INFINITY; +302 Iterator<Entry> iterator = iterator(); +303 while (iterator.hasNext()) { +304 final Entry entry = iterator.next(); +305 if (entry.getValue() <= minValue) { +306 minIndex = entry.getIndex(); +307 minValue = entry.getValue(); +308 } +309 } +310 return minIndex; +311 } +312 +313 /** Get the value of the minimum entry. +314 * @return value of the minimum entry or NaN if all entries are NaN +315 */ +316 public double getMinValue() { +317 final int minIndex = getMinIndex(); +318 return minIndex < 0 ? Double.NaN : getEntry(minIndex); +319 } +320 +321 /** Get the index of the maximum entry. +322 * @return index of the maximum entry or -1 if vector length is 0 +323 * or all entries are NaN +324 */ +325 public int getMaxIndex() { +326 int maxIndex = -1; +327 double maxValue = Double.NEGATIVE_INFINITY; +328 Iterator<Entry> iterator = iterator(); +329 while (iterator.hasNext()) { +330 final Entry entry = iterator.next(); +331 if (entry.getValue() >= maxValue) { +332 maxIndex = entry.getIndex(); +333 maxValue = entry.getValue(); +334 } +335 } +336 return maxIndex; +337 } +338 +339 /** Get the value of the maximum entry. +340 * @return value of the maximum entry or NaN if all entries are NaN +341 */ +342 public double getMaxValue() { +343 final int maxIndex = getMaxIndex(); +344 return maxIndex < 0 ? Double.NaN : getEntry(maxIndex); +345 } +346 +347 /** {@inheritDoc} */ +348 public RealVector mapAbs() { +349 return copy().mapAbsToSelf(); +350 } +351 +352 /** {@inheritDoc} */ +353 public RealVector mapAbsToSelf() { +354 try { +355 return mapToSelf(ComposableFunction.ABS); +356 } catch (FunctionEvaluationException e) { +357 throw new IllegalArgumentException(e); +358 } +359 } +360 +361 /** {@inheritDoc} */ +362 public RealVector mapAcos() { +363 return copy().mapAcosToSelf(); +364 } +365 +366 /** {@inheritDoc} */ +367 public RealVector mapAcosToSelf() { +368 try { +369 return mapToSelf(ComposableFunction.ACOS); +370 } catch (FunctionEvaluationException e) { +371 throw new IllegalArgumentException(e); +372 } +373 } +374 +375 /** {@inheritDoc} */ +376 public RealVector mapAsin() { +377 return copy().mapAsinToSelf(); +378 } +379 +380 /** {@inheritDoc} */ +381 public RealVector mapAsinToSelf() { +382 try { +383 return mapToSelf(ComposableFunction.ASIN); +384 } catch (FunctionEvaluationException e) { +385 throw new IllegalArgumentException(e); +386 } +387 } +388 +389 /** {@inheritDoc} */ +390 public RealVector mapAtan() { +391 return copy().mapAtanToSelf(); +392 } +393 +394 /** {@inheritDoc} */ +395 public RealVector mapAtanToSelf() { +396 try { +397 return mapToSelf(ComposableFunction.ATAN); +398 } catch (FunctionEvaluationException e) { +399 throw new IllegalArgumentException(e); +400 } +401 } +402 +403 /** {@inheritDoc} */ +404 public RealVector mapCbrt() { +405 return copy().mapCbrtToSelf(); +406 } +407 +408 /** {@inheritDoc} */ +409 public RealVector mapCbrtToSelf() { +410 try { +411 return mapToSelf(ComposableFunction.CBRT); +412 } catch (FunctionEvaluationException e) { +413 throw new IllegalArgumentException(e); +414 } +415 } +416 +417 /** {@inheritDoc} */ +418 public RealVector mapCeil() { +419 return copy().mapCeilToSelf(); +420 } +421 +422 /** {@inheritDoc} */ +423 public RealVector mapCeilToSelf() { +424 try { +425 return mapToSelf(ComposableFunction.CEIL); +426 } catch (FunctionEvaluationException e) { +427 throw new IllegalArgumentException(e); +428 } +429 } +430 +431 /** {@inheritDoc} */ +432 public RealVector mapCos() { +433 return copy().mapCosToSelf(); +434 } +435 +436 /** {@inheritDoc} */ +437 public RealVector mapCosToSelf() { +438 try { +439 return mapToSelf(ComposableFunction.COS); +440 } catch (FunctionEvaluationException e) { +441 throw new IllegalArgumentException(e); +442 } +443 } +444 +445 /** {@inheritDoc} */ +446 public RealVector mapCosh() { +447 return copy().mapCoshToSelf(); +448 } +449 +450 /** {@inheritDoc} */ +451 public RealVector mapCoshToSelf() { +452 try { +453 return mapToSelf(ComposableFunction.COSH); +454 } catch (FunctionEvaluationException e) { +455 throw new IllegalArgumentException(e); +456 } +457 } +458 +459 /** {@inheritDoc} */ +460 public RealVector mapDivide(double d) { +461 return copy().mapDivideToSelf(d); +462 } +463 +464 /** {@inheritDoc} */ +465 public RealVector mapDivideToSelf(double d){ +466 try { +467 return mapToSelf(BinaryFunction.DIVIDE.fix2ndArgument(d)); +468 } catch (FunctionEvaluationException e) { +469 throw new IllegalArgumentException(e); +470 } +471 } +472 +473 /** {@inheritDoc} */ +474 public RealVector mapExp() { +475 return copy().mapExpToSelf(); +476 } +477 +478 /** {@inheritDoc} */ +479 public RealVector mapExpToSelf() { +480 try { +481 return mapToSelf(ComposableFunction.EXP); +482 } catch (FunctionEvaluationException e) { +483 throw new IllegalArgumentException(e); +484 } +485 } +486 +487 /** {@inheritDoc} */ +488 public RealVector mapExpm1() { +489 return copy().mapExpm1ToSelf(); +490 } +491 +492 /** {@inheritDoc} */ +493 public RealVector mapExpm1ToSelf() { +494 try { +495 return mapToSelf(ComposableFunction.EXPM1); +496 } catch (FunctionEvaluationException e) { +497 throw new IllegalArgumentException(e); +498 } +499 } +500 +501 /** {@inheritDoc} */ +502 public RealVector mapFloor() { +503 return copy().mapFloorToSelf(); +504 } +505 +506 /** {@inheritDoc} */ +507 public RealVector mapFloorToSelf() { +508 try { +509 return mapToSelf(ComposableFunction.FLOOR); +510 } catch (FunctionEvaluationException e) { +511 throw new IllegalArgumentException(e); +512 } +513 } +514 +515 /** {@inheritDoc} */ +516 public RealVector mapInv() { +517 return copy().mapInvToSelf(); +518 } +519 +520 /** {@inheritDoc} */ +521 public RealVector mapInvToSelf() { +522 try { +523 return mapToSelf(ComposableFunction.INVERT); +524 } catch (FunctionEvaluationException e) { +525 throw new IllegalArgumentException(e); +526 } +527 } +528 +529 /** {@inheritDoc} */ +530 public RealVector mapLog() { +531 return copy().mapLogToSelf(); +532 } +533 +534 /** {@inheritDoc} */ +535 public RealVector mapLogToSelf() { +536 try { +537 return mapToSelf(ComposableFunction.LOG); +538 } catch (FunctionEvaluationException e) { +539 throw new IllegalArgumentException(e); +540 } +541 } +542 +543 /** {@inheritDoc} */ +544 public RealVector mapLog10() { +545 return copy().mapLog10ToSelf(); +546 } +547 +548 /** {@inheritDoc} */ +549 public RealVector mapLog10ToSelf() { +550 try { +551 return mapToSelf(ComposableFunction.LOG10); +552 } catch (FunctionEvaluationException e) { +553 throw new IllegalArgumentException(e); +554 } +555 } +556 +557 /** {@inheritDoc} */ +558 public RealVector mapLog1p() { +559 return copy().mapLog1pToSelf(); +560 } +561 +562 /** {@inheritDoc} */ +563 public RealVector mapLog1pToSelf() { +564 try { +565 return mapToSelf(ComposableFunction.LOG1P); +566 } catch (FunctionEvaluationException e) { +567 throw new IllegalArgumentException(e); +568 } +569 } +570 +571 /** {@inheritDoc} */ +572 public RealVector mapMultiply(double d) { +573 return copy().mapMultiplyToSelf(d); +574 } +575 +576 /** {@inheritDoc} */ +577 public RealVector mapMultiplyToSelf(double d){ +578 try { +579 return mapToSelf(BinaryFunction.MULTIPLY.fix1stArgument(d)); +580 } catch (FunctionEvaluationException e) { +581 throw new IllegalArgumentException(e); +582 } +583 } +584 +585 /** {@inheritDoc} */ +586 public RealVector mapPow(double d) { +587 return copy().mapPowToSelf(d); +588 } +589 +590 /** {@inheritDoc} */ +591 public RealVector mapPowToSelf(double d){ +592 try { +593 return mapToSelf(BinaryFunction.POW.fix2ndArgument(d)); +594 } catch (FunctionEvaluationException e) { +595 throw new IllegalArgumentException(e); +596 } +597 } +598 +599 /** {@inheritDoc} */ +600 public RealVector mapRint() { +601 return copy().mapRintToSelf(); +602 } +603 +604 /** {@inheritDoc} */ +605 public RealVector mapRintToSelf() { +606 try { +607 return mapToSelf(ComposableFunction.RINT); +608 } catch (FunctionEvaluationException e) { +609 throw new IllegalArgumentException(e); +610 } +611 } +612 +613 /** {@inheritDoc} */ +614 public RealVector mapSignum() { +615 return copy().mapSignumToSelf(); +616 } +617 +618 /** {@inheritDoc} */ +619 public RealVector mapSignumToSelf() { +620 try { +621 return mapToSelf(ComposableFunction.SIGNUM); +622 } catch (FunctionEvaluationException e) { +623 throw new IllegalArgumentException(e); +624 } +625 } +626 +627 /** {@inheritDoc} */ +628 public RealVector mapSin() { +629 return copy().mapSinToSelf(); +630 } +631 +632 /** {@inheritDoc} */ +633 public RealVector mapSinToSelf() { +634 try { +635 return mapToSelf(ComposableFunction.SIN); +636 } catch (FunctionEvaluationException e) { +637 throw new IllegalArgumentException(e); +638 } +639 } +640 +641 /** {@inheritDoc} */ +642 public RealVector mapSinh() { +643 return copy().mapSinhToSelf(); +644 } +645 +646 /** {@inheritDoc} */ +647 public RealVector mapSinhToSelf() { +648 try { +649 return mapToSelf(ComposableFunction.SINH); +650 } catch (FunctionEvaluationException e) { +651 throw new IllegalArgumentException(e); +652 } +653 } +654 +655 /** {@inheritDoc} */ +656 public RealVector mapSqrt() { +657 return copy().mapSqrtToSelf(); +658 } +659 +660 /** {@inheritDoc} */ +661 public RealVector mapSqrtToSelf() { +662 try { +663 return mapToSelf(ComposableFunction.SQRT); +664 } catch (FunctionEvaluationException e) { +665 throw new IllegalArgumentException(e); +666 } +667 } +668 +669 /** {@inheritDoc} */ +670 public RealVector mapSubtract(double d) { +671 return copy().mapSubtractToSelf(d); +672 } +673 +674 /** {@inheritDoc} */ +675 public RealVector mapSubtractToSelf(double d){ +676 return mapAddToSelf(-d); +677 } +678 +679 /** {@inheritDoc} */ +680 public RealVector mapTan() { +681 return copy().mapTanToSelf(); +682 } +683 +684 /** {@inheritDoc} */ +685 public RealVector mapTanToSelf() { +686 try { +687 return mapToSelf(ComposableFunction.TAN); +688 } catch (FunctionEvaluationException e) { +689 throw new IllegalArgumentException(e); +690 } +691 } +692 +693 /** {@inheritDoc} */ +694 public RealVector mapTanh() { +695 return copy().mapTanhToSelf(); +696 } +697 +698 /** {@inheritDoc} */ +699 public RealVector mapTanhToSelf() { +700 try { +701 return mapToSelf(ComposableFunction.TANH); +702 } catch (FunctionEvaluationException e) { +703 throw new IllegalArgumentException(e); +704 } +705 } +706 +707 /** {@inheritDoc} */ +708 public RealVector mapUlp() { +709 return copy().mapUlpToSelf(); +710 } +711 +712 /** {@inheritDoc} */ +713 public RealVector mapUlpToSelf() { +714 try { +715 return mapToSelf(ComposableFunction.ULP); +716 } catch (FunctionEvaluationException e) { +717 throw new IllegalArgumentException(e); +718 } +719 } +720 +721 /** {@inheritDoc} */ +722 public RealMatrix outerProduct(RealVector v) throws IllegalArgumentException { +723 RealMatrix product; +724 if (v instanceof SparseRealVector || this instanceof SparseRealVector) { +725 product = new OpenMapRealMatrix(this.getDimension(), v.getDimension()); +726 } else { +727 product = new Array2DRowRealMatrix(this.getDimension(), v.getDimension()); +728 } +729 Iterator<Entry> thisIt = sparseIterator(); +730 Entry thisE = null; +731 while (thisIt.hasNext() && (thisE = thisIt.next()) != null) { +732 Iterator<Entry> otherIt = v.sparseIterator(); +733 Entry otherE = null; +734 while (otherIt.hasNext() && (otherE = otherIt.next()) != null) { +735 product.setEntry(thisE.getIndex(), otherE.getIndex(), +736 thisE.getValue() * otherE.getValue()); +737 } +738 } +739 +740 return product; +741 +742 } +743 +744 /** {@inheritDoc} */ +745 public RealMatrix outerProduct(double[] v) throws IllegalArgumentException { +746 return outerProduct(new ArrayRealVector(v, false)); +747 } +748 +749 /** {@inheritDoc} */ +750 public RealVector projection(double[] v) throws IllegalArgumentException { +751 return projection(new ArrayRealVector(v, false)); +752 } +753 +754 /** {@inheritDoc} */ +755 public void set(double value) { +756 Iterator<Entry> it = iterator(); +757 Entry e = null; +758 while (it.hasNext() && (e = it.next()) != null) { +759 e.setValue(value); +760 } +761 } +762 +763 /** {@inheritDoc} */ +764 public double[] toArray() { +765 int dim = getDimension(); +766 double[] values = new double[dim]; +767 for (int i = 0; i < dim; i++) { +768 values[i] = getEntry(i); +769 } +770 return values; +771 } +772 +773 /** {@inheritDoc} */ +774 public double[] getData() { +775 return toArray(); +776 } +777 +778 /** {@inheritDoc} */ +779 public RealVector unitVector() { +780 RealVector copy = copy(); +781 copy.unitize(); +782 return copy; +783 } +784 +785 /** {@inheritDoc} */ +786 public void unitize() { +787 mapDivideToSelf(getNorm()); +788 } +789 +790 /** {@inheritDoc} */ +791 public Iterator<Entry> sparseIterator() { +792 return new SparseEntryIterator(); +793 } +794 +795 /** {@inheritDoc} */ +796 public Iterator<Entry> iterator() { +797 final int dim = getDimension(); +798 return new Iterator<Entry>() { +799 +800 /** Current index. */ +801 private int i = 0; +802 +803 /** Current entry. */ +804 private EntryImpl e = new EntryImpl(); +805 +806 /** {@inheritDoc} */ +807 public boolean hasNext() { +808 return i < dim; +809 } +810 +811 /** {@inheritDoc} */ +812 public Entry next() { +813 e.setIndex(i++); +814 return e; +815 } +816 +817 /** {@inheritDoc} */ +818 public void remove() { +819 throw new UnsupportedOperationException("Not supported"); +820 } +821 }; +822 } +823 +824 /** {@inheritDoc} */ +825 public RealVector map(UnivariateRealFunction function) throws FunctionEvaluationException { +826 return copy().mapToSelf(function); +827 } +828 +829 /** {@inheritDoc} */ +830 public RealVector mapToSelf(UnivariateRealFunction function) throws FunctionEvaluationException { +831 Iterator<Entry> it = (function.value(0) == 0) ? sparseIterator() : iterator(); +832 Entry e; +833 while (it.hasNext() && (e = it.next()) != null) { +834 e.setValue(function.value(e.getValue())); +835 } +836 return this; +837 } +838 +839 /** An entry in the vector. */ +840 protected class EntryImpl extends Entry { +841 +842 /** Simple constructor. */ +843 public EntryImpl() { +844 setIndex(0); +845 } +846 +847 /** {@inheritDoc} */ +848 @Override +849 public double getValue() { +850 return getEntry(getIndex()); +851 } +852 +853 /** {@inheritDoc} */ +854 @Override +855 public void setValue(double newValue) { +856 setEntry(getIndex(), newValue); +857 } +858 } +859 +860 /** +861 * This class should rare be used, but is here to provide +862 * a default implementation of sparseIterator(), which is implemented +863 * by walking over the entries, skipping those whose values are the default one. +864 * +865 * Concrete subclasses which are SparseVector implementations should +866 * make their own sparse iterator, not use this one. +867 * +868 * This implementation might be useful for ArrayRealVector, when expensive +869 * operations which preserve the default value are to be done on the entries, +870 * and the fraction of non-default values is small (i.e. someone took a +871 * SparseVector, and passed it into the copy-constructor of ArrayRealVector) +872 */ +873 protected class SparseEntryIterator implements Iterator<Entry> { +874 +875 /** Dimension of the vector. */ +876 private final int dim; +877 +878 /** Temporary entry (reused on each call to {@link #next()}. */ +879 private EntryImpl tmp = new EntryImpl(); +880 +881 /** Current entry. */ +882 private EntryImpl current; +883 +884 /** Next entry. */ +885 private EntryImpl next; +886 +887 /** Simple constructor. */ +888 protected SparseEntryIterator() { +889 dim = getDimension(); +890 current = new EntryImpl(); +891 if (current.getValue() == 0) { +892 advance(current); +893 } +894 if(current.getIndex() >= 0){ +895 // There is at least one non-zero entry +896 next = new EntryImpl(); +897 next.setIndex(current.getIndex()); +898 advance(next); +899 } else { +900 // The vector consists of only zero entries, so deny having a next +901 current = null; +902 } +903 } +904 +905 /** Advance an entry up to the next non null one. +906 * @param e entry to advance +907 */ +908 protected void advance(EntryImpl e) { +909 if (e == null) { +910 return; +911 } +912 do { +913 e.setIndex(e.getIndex() + 1); +914 } while (e.getIndex() < dim && e.getValue() == 0); +915 if (e.getIndex() >= dim) { +916 e.setIndex(-1); +917 } +918 } +919 +920 /** {@inheritDoc} */ +921 public boolean hasNext() { +922 return current != null; +923 } +924 +925 /** {@inheritDoc} */ +926 public Entry next() { +927 tmp.setIndex(current.getIndex()); +928 if (next != null) { +929 current.setIndex(next.getIndex()); +930 advance(next); +931 if (next.getIndex() < 0) { +932 next = null; +933 } +934 } else { +935 current = null; +936 } +937 return tmp; +938 } +939 +940 /** {@inheritDoc} */ +941 public void remove() { +942 throw new UnsupportedOperationException("Not supported"); +943 } +944 } +945 +946 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/AbstractRealVector.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/AbstractRealVector.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1012 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.util.Iterator; +021 +022 import org.apache.commons.math.FunctionEvaluationException; +023 import org.apache.commons.math.MathRuntimeException; +024 import org.apache.commons.math.analysis.BinaryFunction; +025 import org.apache.commons.math.analysis.UnivariateRealFunction; +026 import org.apache.commons.math.analysis.ComposableFunction; +027 +028 /** +029 * This class provides default basic implementations for many methods in the +030 * {@link RealVector} interface with. +031 * @version $Revision: 904231 $ $Date: 2010-01-28 14:42:31 -0500 (Thu, 28 Jan 2010) $ +032 * @since 2.1 +033 */ +034 public abstract class AbstractRealVector implements RealVector { +035 +036 /** +037 * Check if instance and specified vectors have the same dimension. +038 * @param v vector to compare instance with +039 * @exception IllegalArgumentException if the vectors do not +040 * have the same dimension +041 */ +042 protected void checkVectorDimensions(RealVector v) { +043 checkVectorDimensions(v.getDimension()); +044 } +045 +046 /** +047 * Check if instance dimension is equal to some expected value. +048 * +049 * @param n expected dimension. +050 * @exception IllegalArgumentException if the dimension is +051 * inconsistent with vector size +052 */ +053 protected void checkVectorDimensions(int n) +054 throws IllegalArgumentException { +055 double d = getDimension(); +056 if (d != n) { +057 throw MathRuntimeException.createIllegalArgumentException( +058 "vector length mismatch: got {0} but expected {1}", +059 d, n); +060 } +061 } +062 +063 /** +064 * Check if an index is valid. +065 * @param index index to check +066 * @exception MatrixIndexException if index is not valid +067 */ +068 protected void checkIndex(final int index) +069 throws MatrixIndexException { +070 if (index < 0 || index >= getDimension()) { +071 throw new MatrixIndexException( +072 "index {0} out of allowed range [{1}, {2}]", +073 index, 0, getDimension() - 1); +074 } +075 } +076 +077 /** {@inheritDoc} */ +078 public void setSubVector(int index, RealVector v) throws MatrixIndexException { +079 checkIndex(index); +080 checkIndex(index + v.getDimension() - 1); +081 setSubVector(index, v.getData()); +082 } +083 +084 /** {@inheritDoc} */ +085 public void setSubVector(int index, double[] v) throws MatrixIndexException { +086 checkIndex(index); +087 checkIndex(index + v.length - 1); +088 for (int i = 0; i < v.length; i++) { +089 setEntry(i + index, v[i]); +090 } +091 } +092 +093 /** {@inheritDoc} */ +094 public RealVector add(double[] v) throws IllegalArgumentException { +095 double[] result = v.clone(); +096 Iterator<Entry> it = sparseIterator(); +097 Entry e; +098 while (it.hasNext() && (e = it.next()) != null) { +099 result[e.getIndex()] += e.getValue(); +100 } +101 return new ArrayRealVector(result, false); +102 } +103 +104 /** {@inheritDoc} */ +105 public RealVector add(RealVector v) throws IllegalArgumentException { +106 if (v instanceof ArrayRealVector) { +107 double[] values = ((ArrayRealVector)v).getDataRef(); +108 return add(values); +109 } +110 RealVector result = v.copy(); +111 Iterator<Entry> it = sparseIterator(); +112 Entry e; +113 while (it.hasNext() && (e = it.next()) != null) { +114 final int index = e.getIndex(); +115 result.setEntry(index, e.getValue() + result.getEntry(index)); +116 } +117 return result; +118 } +119 +120 /** {@inheritDoc} */ +121 public RealVector subtract(double[] v) throws IllegalArgumentException { +122 double[] result = v.clone(); +123 Iterator<Entry> it = sparseIterator(); +124 Entry e; +125 while (it.hasNext() && (e = it.next()) != null) { +126 final int index = e.getIndex(); +127 result[index] = e.getValue() - result[index]; +128 } +129 return new ArrayRealVector(result, false); +130 } +131 +132 /** {@inheritDoc} */ +133 public RealVector subtract(RealVector v) throws IllegalArgumentException { +134 if (v instanceof ArrayRealVector) { +135 double[] values = ((ArrayRealVector)v).getDataRef(); +136 return add(values); +137 } +138 RealVector result = v.copy(); +139 Iterator<Entry> it = sparseIterator(); +140 Entry e; +141 while (it.hasNext() && (e = it.next()) != null) { +142 final int index = e.getIndex(); +143 v.setEntry(index, e.getValue() - result.getEntry(index)); +144 } +145 return result; +146 } +147 +148 /** {@inheritDoc} */ +149 public RealVector mapAdd(double d) { +150 return copy().mapAddToSelf(d); +151 } +152 +153 /** {@inheritDoc} */ +154 public RealVector mapAddToSelf(double d) { +155 if (d != 0) { +156 try { +157 return mapToSelf(BinaryFunction.ADD.fix1stArgument(d)); +158 } catch (FunctionEvaluationException e) { +159 throw new IllegalArgumentException(e); +160 } +161 } +162 return this; +163 } +164 +165 /** {@inheritDoc} */ +166 public abstract AbstractRealVector copy(); +167 +168 /** {@inheritDoc} */ +169 public double dotProduct(double[] v) throws IllegalArgumentException { +170 return dotProduct(new ArrayRealVector(v, false)); +171 } +172 +173 /** {@inheritDoc} */ +174 public double dotProduct(RealVector v) throws IllegalArgumentException { +175 checkVectorDimensions(v); +176 double d = 0; +177 Iterator<Entry> it = sparseIterator(); +178 Entry e; +179 while (it.hasNext() && (e = it.next()) != null) { +180 d += e.getValue() * v.getEntry(e.getIndex()); +181 } +182 return d; +183 } +184 +185 /** {@inheritDoc} */ +186 public RealVector ebeDivide(double[] v) throws IllegalArgumentException { +187 return ebeDivide(new ArrayRealVector(v, false)); +188 } +189 +190 /** {@inheritDoc} */ +191 public RealVector ebeMultiply(double[] v) throws IllegalArgumentException { +192 return ebeMultiply(new ArrayRealVector(v, false)); +193 } +194 +195 /** {@inheritDoc} */ +196 public double getDistance(RealVector v) throws IllegalArgumentException { +197 checkVectorDimensions(v); +198 double d = 0; +199 Iterator<Entry> it = iterator(); +200 Entry e; +201 while (it.hasNext() && (e = it.next()) != null) { +202 final double diff = e.getValue() - v.getEntry(e.getIndex()); +203 d += diff * diff; +204 } +205 return Math.sqrt(d); +206 } +207 +208 /** {@inheritDoc} */ +209 public double getNorm() { +210 double sum = 0; +211 Iterator<Entry> it = sparseIterator(); +212 Entry e; +213 while (it.hasNext() && (e = it.next()) != null) { +214 final double value = e.getValue(); +215 sum += value * value; +216 } +217 return Math.sqrt(sum); +218 } +219 +220 /** {@inheritDoc} */ +221 public double getL1Norm() { +222 double norm = 0; +223 Iterator<Entry> it = sparseIterator(); +224 Entry e; +225 while (it.hasNext() && (e = it.next()) != null) { +226 norm += Math.abs(e.getValue()); +227 } +228 return norm; +229 } +230 +231 /** {@inheritDoc} */ +232 public double getLInfNorm() { +233 double norm = 0; +234 Iterator<Entry> it = sparseIterator(); +235 Entry e; +236 while (it.hasNext() && (e = it.next()) != null) { +237 norm = Math.max(norm, Math.abs(e.getValue())); +238 } +239 return norm; +240 } +241 +242 /** {@inheritDoc} */ +243 public double getDistance(double[] v) throws IllegalArgumentException { +244 return getDistance(new ArrayRealVector(v,false)); +245 } +246 +247 /** {@inheritDoc} */ +248 public double getL1Distance(RealVector v) throws IllegalArgumentException { +249 checkVectorDimensions(v); +250 double d = 0; +251 Iterator<Entry> it = iterator(); +252 Entry e; +253 while (it.hasNext() && (e = it.next()) != null) { +254 d += Math.abs(e.getValue() - v.getEntry(e.getIndex())); +255 } +256 return d; +257 } +258 +259 /** {@inheritDoc} */ +260 public double getL1Distance(double[] v) throws IllegalArgumentException { +261 checkVectorDimensions(v.length); +262 double d = 0; +263 Iterator<Entry> it = iterator(); +264 Entry e; +265 while (it.hasNext() && (e = it.next()) != null) { +266 d += Math.abs(e.getValue() - v[e.getIndex()]); +267 } +268 return d; +269 } +270 +271 /** {@inheritDoc} */ +272 public double getLInfDistance(RealVector v) throws IllegalArgumentException { +273 checkVectorDimensions(v); +274 double d = 0; +275 Iterator<Entry> it = iterator(); +276 Entry e; +277 while (it.hasNext() && (e = it.next()) != null) { +278 d = Math.max(Math.abs(e.getValue() - v.getEntry(e.getIndex())), d); +279 } +280 return d; +281 } +282 +283 /** {@inheritDoc} */ +284 public double getLInfDistance(double[] v) throws IllegalArgumentException { +285 checkVectorDimensions(v.length); +286 double d = 0; +287 Iterator<Entry> it = iterator(); +288 Entry e; +289 while (it.hasNext() && (e = it.next()) != null) { +290 d = Math.max(Math.abs(e.getValue() - v[e.getIndex()]), d); +291 } +292 return d; +293 } +294 +295 /** Get the index of the minimum entry. +296 * @return index of the minimum entry or -1 if vector length is 0 +297 * or all entries are NaN +298 */ +299 public int getMinIndex() { +300 int minIndex = -1; +301 double minValue = Double.POSITIVE_INFINITY; +302 Iterator<Entry> iterator = iterator(); +303 while (iterator.hasNext()) { +304 final Entry entry = iterator.next(); +305 if (entry.getValue() <= minValue) { +306 minIndex = entry.getIndex(); +307 minValue = entry.getValue(); +308 } +309 } +310 return minIndex; +311 } +312 +313 /** Get the value of the minimum entry. +314 * @return value of the minimum entry or NaN if all entries are NaN +315 */ +316 public double getMinValue() { +317 final int minIndex = getMinIndex(); +318 return minIndex < 0 ? Double.NaN : getEntry(minIndex); +319 } +320 +321 /** Get the index of the maximum entry. +322 * @return index of the maximum entry or -1 if vector length is 0 +323 * or all entries are NaN +324 */ +325 public int getMaxIndex() { +326 int maxIndex = -1; +327 double maxValue = Double.NEGATIVE_INFINITY; +328 Iterator<Entry> iterator = iterator(); +329 while (iterator.hasNext()) { +330 final Entry entry = iterator.next(); +331 if (entry.getValue() >= maxValue) { +332 maxIndex = entry.getIndex(); +333 maxValue = entry.getValue(); +334 } +335 } +336 return maxIndex; +337 } +338 +339 /** Get the value of the maximum entry. +340 * @return value of the maximum entry or NaN if all entries are NaN +341 */ +342 public double getMaxValue() { +343 final int maxIndex = getMaxIndex(); +344 return maxIndex < 0 ? Double.NaN : getEntry(maxIndex); +345 } +346 +347 /** {@inheritDoc} */ +348 public RealVector mapAbs() { +349 return copy().mapAbsToSelf(); +350 } +351 +352 /** {@inheritDoc} */ +353 public RealVector mapAbsToSelf() { +354 try { +355 return mapToSelf(ComposableFunction.ABS); +356 } catch (FunctionEvaluationException e) { +357 throw new IllegalArgumentException(e); +358 } +359 } +360 +361 /** {@inheritDoc} */ +362 public RealVector mapAcos() { +363 return copy().mapAcosToSelf(); +364 } +365 +366 /** {@inheritDoc} */ +367 public RealVector mapAcosToSelf() { +368 try { +369 return mapToSelf(ComposableFunction.ACOS); +370 } catch (FunctionEvaluationException e) { +371 throw new IllegalArgumentException(e); +372 } +373 } +374 +375 /** {@inheritDoc} */ +376 public RealVector mapAsin() { +377 return copy().mapAsinToSelf(); +378 } +379 +380 /** {@inheritDoc} */ +381 public RealVector mapAsinToSelf() { +382 try { +383 return mapToSelf(ComposableFunction.ASIN); +384 } catch (FunctionEvaluationException e) { +385 throw new IllegalArgumentException(e); +386 } +387 } +388 +389 /** {@inheritDoc} */ +390 public RealVector mapAtan() { +391 return copy().mapAtanToSelf(); +392 } +393 +394 /** {@inheritDoc} */ +395 public RealVector mapAtanToSelf() { +396 try { +397 return mapToSelf(ComposableFunction.ATAN); +398 } catch (FunctionEvaluationException e) { +399 throw new IllegalArgumentException(e); +400 } +401 } +402 +403 /** {@inheritDoc} */ +404 public RealVector mapCbrt() { +405 return copy().mapCbrtToSelf(); +406 } +407 +408 /** {@inheritDoc} */ +409 public RealVector mapCbrtToSelf() { +410 try { +411 return mapToSelf(ComposableFunction.CBRT); +412 } catch (FunctionEvaluationException e) { +413 throw new IllegalArgumentException(e); +414 } +415 } +416 +417 /** {@inheritDoc} */ +418 public RealVector mapCeil() { +419 return copy().mapCeilToSelf(); +420 } +421 +422 /** {@inheritDoc} */ +423 public RealVector mapCeilToSelf() { +424 try { +425 return mapToSelf(ComposableFunction.CEIL); +426 } catch (FunctionEvaluationException e) { +427 throw new IllegalArgumentException(e); +428 } +429 } +430 +431 /** {@inheritDoc} */ +432 public RealVector mapCos() { +433 return copy().mapCosToSelf(); +434 } +435 +436 /** {@inheritDoc} */ +437 public RealVector mapCosToSelf() { +438 try { +439 return mapToSelf(ComposableFunction.COS); +440 } catch (FunctionEvaluationException e) { +441 throw new IllegalArgumentException(e); +442 } +443 } +444 +445 /** {@inheritDoc} */ +446 public RealVector mapCosh() { +447 return copy().mapCoshToSelf(); +448 } +449 +450 /** {@inheritDoc} */ +451 public RealVector mapCoshToSelf() { +452 try { +453 return mapToSelf(ComposableFunction.COSH); +454 } catch (FunctionEvaluationException e) { +455 throw new IllegalArgumentException(e); +456 } +457 } +458 +459 /** {@inheritDoc} */ +460 public RealVector mapDivide(double d) { +461 return copy().mapDivideToSelf(d); +462 } +463 +464 /** {@inheritDoc} */ +465 public RealVector mapDivideToSelf(double d){ +466 try { +467 return mapToSelf(BinaryFunction.DIVIDE.fix2ndArgument(d)); +468 } catch (FunctionEvaluationException e) { +469 throw new IllegalArgumentException(e); +470 } +471 } +472 +473 /** {@inheritDoc} */ +474 public RealVector mapExp() { +475 return copy().mapExpToSelf(); +476 } +477 +478 /** {@inheritDoc} */ +479 public RealVector mapExpToSelf() { +480 try { +481 return mapToSelf(ComposableFunction.EXP); +482 } catch (FunctionEvaluationException e) { +483 throw new IllegalArgumentException(e); +484 } +485 } +486 +487 /** {@inheritDoc} */ +488 public RealVector mapExpm1() { +489 return copy().mapExpm1ToSelf(); +490 } +491 +492 /** {@inheritDoc} */ +493 public RealVector mapExpm1ToSelf() { +494 try { +495 return mapToSelf(ComposableFunction.EXPM1); +496 } catch (FunctionEvaluationException e) { +497 throw new IllegalArgumentException(e); +498 } +499 } +500 +501 /** {@inheritDoc} */ +502 public RealVector mapFloor() { +503 return copy().mapFloorToSelf(); +504 } +505 +506 /** {@inheritDoc} */ +507 public RealVector mapFloorToSelf() { +508 try { +509 return mapToSelf(ComposableFunction.FLOOR); +510 } catch (FunctionEvaluationException e) { +511 throw new IllegalArgumentException(e); +512 } +513 } +514 +515 /** {@inheritDoc} */ +516 public RealVector mapInv() { +517 return copy().mapInvToSelf(); +518 } +519 +520 /** {@inheritDoc} */ +521 public RealVector mapInvToSelf() { +522 try { +523 return mapToSelf(ComposableFunction.INVERT); +524 } catch (FunctionEvaluationException e) { +525 throw new IllegalArgumentException(e); +526 } +527 } +528 +529 /** {@inheritDoc} */ +530 public RealVector mapLog() { +531 return copy().mapLogToSelf(); +532 } +533 +534 /** {@inheritDoc} */ +535 public RealVector mapLogToSelf() { +536 try { +537 return mapToSelf(ComposableFunction.LOG); +538 } catch (FunctionEvaluationException e) { +539 throw new IllegalArgumentException(e); +540 } +541 } +542 +543 /** {@inheritDoc} */ +544 public RealVector mapLog10() { +545 return copy().mapLog10ToSelf(); +546 } +547 +548 /** {@inheritDoc} */ +549 public RealVector mapLog10ToSelf() { +550 try { +551 return mapToSelf(ComposableFunction.LOG10); +552 } catch (FunctionEvaluationException e) { +553 throw new IllegalArgumentException(e); +554 } +555 } +556 +557 /** {@inheritDoc} */ +558 public RealVector mapLog1p() { +559 return copy().mapLog1pToSelf(); +560 } +561 +562 /** {@inheritDoc} */ +563 public RealVector mapLog1pToSelf() { +564 try { +565 return mapToSelf(ComposableFunction.LOG1P); +566 } catch (FunctionEvaluationException e) { +567 throw new IllegalArgumentException(e); +568 } +569 } +570 +571 /** {@inheritDoc} */ +572 public RealVector mapMultiply(double d) { +573 return copy().mapMultiplyToSelf(d); +574 } +575 +576 /** {@inheritDoc} */ +577 public RealVector mapMultiplyToSelf(double d){ +578 try { +579 return mapToSelf(BinaryFunction.MULTIPLY.fix1stArgument(d)); +580 } catch (FunctionEvaluationException e) { +581 throw new IllegalArgumentException(e); +582 } +583 } +584 +585 /** {@inheritDoc} */ +586 public RealVector mapPow(double d) { +587 return copy().mapPowToSelf(d); +588 } +589 +590 /** {@inheritDoc} */ +591 public RealVector mapPowToSelf(double d){ +592 try { +593 return mapToSelf(BinaryFunction.POW.fix2ndArgument(d)); +594 } catch (FunctionEvaluationException e) { +595 throw new IllegalArgumentException(e); +596 } +597 } +598 +599 /** {@inheritDoc} */ +600 public RealVector mapRint() { +601 return copy().mapRintToSelf(); +602 } +603 +604 /** {@inheritDoc} */ +605 public RealVector mapRintToSelf() { +606 try { +607 return mapToSelf(ComposableFunction.RINT); +608 } catch (FunctionEvaluationException e) { +609 throw new IllegalArgumentException(e); +610 } +611 } +612 +613 /** {@inheritDoc} */ +614 public RealVector mapSignum() { +615 return copy().mapSignumToSelf(); +616 } +617 +618 /** {@inheritDoc} */ +619 public RealVector mapSignumToSelf() { +620 try { +621 return mapToSelf(ComposableFunction.SIGNUM); +622 } catch (FunctionEvaluationException e) { +623 throw new IllegalArgumentException(e); +624 } +625 } +626 +627 /** {@inheritDoc} */ +628 public RealVector mapSin() { +629 return copy().mapSinToSelf(); +630 } +631 +632 /** {@inheritDoc} */ +633 public RealVector mapSinToSelf() { +634 try { +635 return mapToSelf(ComposableFunction.SIN); +636 } catch (FunctionEvaluationException e) { +637 throw new IllegalArgumentException(e); +638 } +639 } +640 +641 /** {@inheritDoc} */ +642 public RealVector mapSinh() { +643 return copy().mapSinhToSelf(); +644 } +645 +646 /** {@inheritDoc} */ +647 public RealVector mapSinhToSelf() { +648 try { +649 return mapToSelf(ComposableFunction.SINH); +650 } catch (FunctionEvaluationException e) { +651 throw new IllegalArgumentException(e); +652 } +653 } +654 +655 /** {@inheritDoc} */ +656 public RealVector mapSqrt() { +657 return copy().mapSqrtToSelf(); +658 } +659 +660 /** {@inheritDoc} */ +661 public RealVector mapSqrtToSelf() { +662 try { +663 return mapToSelf(ComposableFunction.SQRT); +664 } catch (FunctionEvaluationException e) { +665 throw new IllegalArgumentException(e); +666 } +667 } +668 +669 /** {@inheritDoc} */ +670 public RealVector mapSubtract(double d) { +671 return copy().mapSubtractToSelf(d); +672 } +673 +674 /** {@inheritDoc} */ +675 public RealVector mapSubtractToSelf(double d){ +676 return mapAddToSelf(-d); +677 } +678 +679 /** {@inheritDoc} */ +680 public RealVector mapTan() { +681 return copy().mapTanToSelf(); +682 } +683 +684 /** {@inheritDoc} */ +685 public RealVector mapTanToSelf() { +686 try { +687 return mapToSelf(ComposableFunction.TAN); +688 } catch (FunctionEvaluationException e) { +689 throw new IllegalArgumentException(e); +690 } +691 } +692 +693 /** {@inheritDoc} */ +694 public RealVector mapTanh() { +695 return copy().mapTanhToSelf(); +696 } +697 +698 /** {@inheritDoc} */ +699 public RealVector mapTanhToSelf() { +700 try { +701 return mapToSelf(ComposableFunction.TANH); +702 } catch (FunctionEvaluationException e) { +703 throw new IllegalArgumentException(e); +704 } +705 } +706 +707 /** {@inheritDoc} */ +708 public RealVector mapUlp() { +709 return copy().mapUlpToSelf(); +710 } +711 +712 /** {@inheritDoc} */ +713 public RealVector mapUlpToSelf() { +714 try { +715 return mapToSelf(ComposableFunction.ULP); +716 } catch (FunctionEvaluationException e) { +717 throw new IllegalArgumentException(e); +718 } +719 } +720 +721 /** {@inheritDoc} */ +722 public RealMatrix outerProduct(RealVector v) throws IllegalArgumentException { +723 RealMatrix product; +724 if (v instanceof SparseRealVector || this instanceof SparseRealVector) { +725 product = new OpenMapRealMatrix(this.getDimension(), v.getDimension()); +726 } else { +727 product = new Array2DRowRealMatrix(this.getDimension(), v.getDimension()); +728 } +729 Iterator<Entry> thisIt = sparseIterator(); +730 Entry thisE = null; +731 while (thisIt.hasNext() && (thisE = thisIt.next()) != null) { +732 Iterator<Entry> otherIt = v.sparseIterator(); +733 Entry otherE = null; +734 while (otherIt.hasNext() && (otherE = otherIt.next()) != null) { +735 product.setEntry(thisE.getIndex(), otherE.getIndex(), +736 thisE.getValue() * otherE.getValue()); +737 } +738 } +739 +740 return product; +741 +742 } +743 +744 /** {@inheritDoc} */ +745 public RealMatrix outerProduct(double[] v) throws IllegalArgumentException { +746 return outerProduct(new ArrayRealVector(v, false)); +747 } +748 +749 /** {@inheritDoc} */ +750 public RealVector projection(double[] v) throws IllegalArgumentException { +751 return projection(new ArrayRealVector(v, false)); +752 } +753 +754 /** {@inheritDoc} */ +755 public void set(double value) { +756 Iterator<Entry> it = iterator(); +757 Entry e = null; +758 while (it.hasNext() && (e = it.next()) != null) { +759 e.setValue(value); +760 } +761 } +762 +763 /** {@inheritDoc} */ +764 public double[] toArray() { +765 int dim = getDimension(); +766 double[] values = new double[dim]; +767 for (int i = 0; i < dim; i++) { +768 values[i] = getEntry(i); +769 } +770 return values; +771 } +772 +773 /** {@inheritDoc} */ +774 public double[] getData() { +775 return toArray(); +776 } +777 +778 /** {@inheritDoc} */ +779 public RealVector unitVector() { +780 RealVector copy = copy(); +781 copy.unitize(); +782 return copy; +783 } +784 +785 /** {@inheritDoc} */ +786 public void unitize() { +787 mapDivideToSelf(getNorm()); +788 } +789 +790 /** {@inheritDoc} */ +791 public Iterator<Entry> sparseIterator() { +792 return new SparseEntryIterator(); +793 } +794 +795 /** {@inheritDoc} */ +796 public Iterator<Entry> iterator() { +797 final int dim = getDimension(); +798 return new Iterator<Entry>() { +799 +800 /** Current index. */ +801 private int i = 0; +802 +803 /** Current entry. */ +804 private EntryImpl e = new EntryImpl(); +805 +806 /** {@inheritDoc} */ +807 public boolean hasNext() { +808 return i < dim; +809 } +810 +811 /** {@inheritDoc} */ +812 public Entry next() { +813 e.setIndex(i++); +814 return e; +815 } +816 +817 /** {@inheritDoc} */ +818 public void remove() { +819 throw new UnsupportedOperationException("Not supported"); +820 } +821 }; +822 } +823 +824 /** {@inheritDoc} */ +825 public RealVector map(UnivariateRealFunction function) throws FunctionEvaluationException { +826 return copy().mapToSelf(function); +827 } +828 +829 /** {@inheritDoc} */ +830 public RealVector mapToSelf(UnivariateRealFunction function) throws FunctionEvaluationException { +831 Iterator<Entry> it = (function.value(0) == 0) ? sparseIterator() : iterator(); +832 Entry e; +833 while (it.hasNext() && (e = it.next()) != null) { +834 e.setValue(function.value(e.getValue())); +835 } +836 return this; +837 } +838 +839 /** An entry in the vector. */ +840 protected class EntryImpl extends Entry { +841 +842 /** Simple constructor. */ +843 public EntryImpl() { +844 setIndex(0); +845 } +846 +847 /** {@inheritDoc} */ +848 @Override +849 public double getValue() { +850 return getEntry(getIndex()); +851 } +852 +853 /** {@inheritDoc} */ +854 @Override +855 public void setValue(double newValue) { +856 setEntry(getIndex(), newValue); +857 } +858 } +859 +860 /** +861 * This class should rare be used, but is here to provide +862 * a default implementation of sparseIterator(), which is implemented +863 * by walking over the entries, skipping those whose values are the default one. +864 * +865 * Concrete subclasses which are SparseVector implementations should +866 * make their own sparse iterator, not use this one. +867 * +868 * This implementation might be useful for ArrayRealVector, when expensive +869 * operations which preserve the default value are to be done on the entries, +870 * and the fraction of non-default values is small (i.e. someone took a +871 * SparseVector, and passed it into the copy-constructor of ArrayRealVector) +872 */ +873 protected class SparseEntryIterator implements Iterator<Entry> { +874 +875 /** Dimension of the vector. */ +876 private final int dim; +877 +878 /** Temporary entry (reused on each call to {@link #next()}. */ +879 private EntryImpl tmp = new EntryImpl(); +880 +881 /** Current entry. */ +882 private EntryImpl current; +883 +884 /** Next entry. */ +885 private EntryImpl next; +886 +887 /** Simple constructor. */ +888 protected SparseEntryIterator() { +889 dim = getDimension(); +890 current = new EntryImpl(); +891 if (current.getValue() == 0) { +892 advance(current); +893 } +894 if(current.getIndex() >= 0){ +895 // There is at least one non-zero entry +896 next = new EntryImpl(); +897 next.setIndex(current.getIndex()); +898 advance(next); +899 } else { +900 // The vector consists of only zero entries, so deny having a next +901 current = null; +902 } +903 } +904 +905 /** Advance an entry up to the next non null one. +906 * @param e entry to advance +907 */ +908 protected void advance(EntryImpl e) { +909 if (e == null) { +910 return; +911 } +912 do { +913 e.setIndex(e.getIndex() + 1); +914 } while (e.getIndex() < dim && e.getValue() == 0); +915 if (e.getIndex() >= dim) { +916 e.setIndex(-1); +917 } +918 } +919 +920 /** {@inheritDoc} */ +921 public boolean hasNext() { +922 return current != null; +923 } +924 +925 /** {@inheritDoc} */ +926 public Entry next() { +927 tmp.setIndex(current.getIndex()); +928 if (next != null) { +929 current.setIndex(next.getIndex()); +930 advance(next); +931 if (next.getIndex() < 0) { +932 next = null; +933 } +934 } else { +935 current = null; +936 } +937 return tmp; +938 } +939 +940 /** {@inheritDoc} */ +941 public void remove() { +942 throw new UnsupportedOperationException("Not supported"); +943 } +944 } +945 +946 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/AnyMatrix.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/AnyMatrix.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,114 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 +021 /** +022 * Interface defining very basic matrix operations. +023 * @version $Revision: 772119 $ $Date: 2009-05-06 05:43:28 -0400 (Wed, 06 May 2009) $ +024 * @since 2.0 +025 */ +026 public interface AnyMatrix { +027 +028 /** +029 * Is this a square matrix? +030 * @return true if the matrix is square (rowDimension = columnDimension) +031 */ +032 boolean isSquare(); +033 +034 /** +035 * Returns the number of rows in the matrix. +036 * +037 * @return rowDimension +038 */ +039 int getRowDimension(); +040 +041 /** +042 * Returns the number of columns in the matrix. +043 * +044 * @return columnDimension +045 */ +046 int getColumnDimension(); +047 +048 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/Array2DRowFieldMatrix.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/Array2DRowFieldMatrix.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,697 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.Field; +023 import org.apache.commons.math.FieldElement; +024 import org.apache.commons.math.MathRuntimeException; +025 +026 /** +027 * Implementation of FieldMatrix<T> using a {@link FieldElement}[][] array to store entries. +028 * <p> +029 * As specified in the {@link FieldMatrix} interface, matrix element indexing +030 * is 0-based -- e.g., <code>getEntry(0, 0)</code> +031 * returns the element in the first row, first column of the matrix.</li></ul> +032 * </p> +033 * +034 * @param <T> the type of the field elements +035 * @version $Revision: 885278 $ $Date: 2009-11-29 16:47:51 -0500 (Sun, 29 Nov 2009) $ +036 */ +037 public class Array2DRowFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMatrix<T> implements Serializable { +038 +039 /** Serializable version identifier */ +040 private static final long serialVersionUID = 7260756672015356458L; +041 +042 /** Message for at least one row. */ +043 private static final String AT_LEAST_ONE_ROW_MESSAGE = +044 "matrix must have at least one row"; +045 +046 /** Message for at least one column. */ +047 private static final String AT_LEAST_ONE_COLUMN_MESSAGE = +048 "matrix must have at least one column"; +049 +050 /** Message for different rows lengths. */ +051 private static final String DIFFERENT_ROWS_LENGTHS_MESSAGE = +052 "some rows have length {0} while others have length {1}"; +053 +054 /** Message for no entry at selected indices. */ +055 private static final String NO_ENTRY_MESSAGE = +056 "no entry at indices ({0}, {1}) in a {2}x{3} matrix"; +057 +058 /** Message for vector lengths mismatch. */ +059 private static final String VECTOR_LENGTHS_MISMATCH = +060 "vector length mismatch: got {0} but expected {1}"; +061 +062 /** Entries of the matrix */ +063 protected T[][] data; +064 +065 /** +066 * Creates a matrix with no data +067 * @param field field to which the elements belong +068 */ +069 public Array2DRowFieldMatrix(final Field<T> field) { +070 super(field); +071 } +072 +073 /** +074 * Create a new FieldMatrix<T> with the supplied row and column dimensions. +075 * +076 * @param field field to which the elements belong +077 * @param rowDimension the number of rows in the new matrix +078 * @param columnDimension the number of columns in the new matrix +079 * @throws IllegalArgumentException if row or column dimension is not +080 * positive +081 */ +082 public Array2DRowFieldMatrix(final Field<T> field, +083 final int rowDimension, final int columnDimension) +084 throws IllegalArgumentException { +085 super(field, rowDimension, columnDimension); +086 data = buildArray(field, rowDimension, columnDimension); +087 } +088 +089 /** +090 * Create a new FieldMatrix<T> using the input array as the underlying +091 * data array. +092 * <p>The input array is copied, not referenced. This constructor has +093 * the same effect as calling {@link #Array2DRowFieldMatrix(FieldElement[][], boolean)} +094 * with the second argument set to <code>true</code>.</p> +095 * +096 * @param d data for new matrix +097 * @throws IllegalArgumentException if <code>d</code> is not rectangular +098 * (not all rows have the same length) or empty +099 * @throws NullPointerException if <code>d</code> is null +100 * @see #Array2DRowFieldMatrix(FieldElement[][], boolean) +101 */ +102 public Array2DRowFieldMatrix(final T[][] d) +103 throws IllegalArgumentException, NullPointerException { +104 super(extractField(d)); +105 copyIn(d); +106 } +107 +108 /** +109 * Create a new FieldMatrix<T> using the input array as the underlying +110 * data array. +111 * <p>If an array is built specially in order to be embedded in a +112 * FieldMatrix<T> and not used directly, the <code>copyArray</code> may be +113 * set to <code>false</code. This will prevent the copying and improve +114 * performance as no new array will be built and no data will be copied.</p> +115 * @param d data for new matrix +116 * @param copyArray if true, the input array will be copied, otherwise +117 * it will be referenced +118 * @throws IllegalArgumentException if <code>d</code> is not rectangular +119 * (not all rows have the same length) or empty +120 * @throws NullPointerException if <code>d</code> is null +121 * @see #Array2DRowFieldMatrix(FieldElement[][]) +122 */ +123 public Array2DRowFieldMatrix(final T[][] d, final boolean copyArray) +124 throws IllegalArgumentException, NullPointerException { +125 super(extractField(d)); +126 if (copyArray) { +127 copyIn(d); +128 } else { +129 if (d == null) { +130 throw new NullPointerException(); +131 } +132 final int nRows = d.length; +133 if (nRows == 0) { +134 throw MathRuntimeException.createIllegalArgumentException( +135 AT_LEAST_ONE_ROW_MESSAGE); +136 } +137 final int nCols = d[0].length; +138 if (nCols == 0) { +139 throw MathRuntimeException.createIllegalArgumentException( +140 AT_LEAST_ONE_COLUMN_MESSAGE); +141 } +142 for (int r = 1; r < nRows; r++) { +143 if (d[r].length != nCols) { +144 throw MathRuntimeException.createIllegalArgumentException( +145 DIFFERENT_ROWS_LENGTHS_MESSAGE, nCols, d[r].length); +146 } +147 } +148 data = d; +149 } +150 } +151 +152 /** +153 * Create a new (column) FieldMatrix<T> using <code>v</code> as the +154 * data for the unique column of the <code>v.length x 1</code> matrix +155 * created. +156 * <p>The input array is copied, not referenced.</p> +157 * +158 * @param v column vector holding data for new matrix +159 */ +160 public Array2DRowFieldMatrix(final T[] v) { +161 super(extractField(v)); +162 final int nRows = v.length; +163 data = buildArray(getField(), nRows, 1); +164 for (int row = 0; row < nRows; row++) { +165 data[row][0] = v[row]; +166 } +167 } +168 +169 /** {@inheritDoc} */ +170 @Override +171 public FieldMatrix<T> createMatrix(final int rowDimension, final int columnDimension) +172 throws IllegalArgumentException { +173 return new Array2DRowFieldMatrix<T>(getField(), rowDimension, columnDimension); +174 } +175 +176 /** {@inheritDoc} */ +177 @Override +178 public FieldMatrix<T> copy() { +179 return new Array2DRowFieldMatrix<T>(copyOut(), false); +180 } +181 +182 /** {@inheritDoc} */ +183 @Override +184 public FieldMatrix<T> add(final FieldMatrix<T> m) +185 throws IllegalArgumentException { +186 try { +187 return add((Array2DRowFieldMatrix<T>) m); +188 } catch (ClassCastException cce) { +189 return super.add(m); +190 } +191 } +192 +193 /** +194 * Compute the sum of this and <code>m</code>. +195 * +196 * @param m matrix to be added +197 * @return this + m +198 * @throws IllegalArgumentException if m is not the same size as this +199 */ +200 public Array2DRowFieldMatrix<T> add(final Array2DRowFieldMatrix<T> m) +201 throws IllegalArgumentException { +202 +203 // safety check +204 checkAdditionCompatible(m); +205 +206 final int rowCount = getRowDimension(); +207 final int columnCount = getColumnDimension(); +208 final T[][] outData = buildArray(getField(), rowCount, columnCount); +209 for (int row = 0; row < rowCount; row++) { +210 final T[] dataRow = data[row]; +211 final T[] mRow = m.data[row]; +212 final T[] outDataRow = outData[row]; +213 for (int col = 0; col < columnCount; col++) { +214 outDataRow[col] = dataRow[col].add(mRow[col]); +215 } +216 } +217 +218 return new Array2DRowFieldMatrix<T>(outData, false); +219 +220 } +221 +222 /** {@inheritDoc} */ +223 @Override +224 public FieldMatrix<T> subtract(final FieldMatrix<T> m) +225 throws IllegalArgumentException { +226 try { +227 return subtract((Array2DRowFieldMatrix<T>) m); +228 } catch (ClassCastException cce) { +229 return super.subtract(m); +230 } +231 } +232 +233 /** +234 * Compute this minus <code>m</code>. +235 * +236 * @param m matrix to be subtracted +237 * @return this + m +238 * @throws IllegalArgumentException if m is not the same size as this +239 */ +240 public Array2DRowFieldMatrix<T> subtract(final Array2DRowFieldMatrix<T> m) +241 throws IllegalArgumentException { +242 +243 // safety check +244 checkSubtractionCompatible(m); +245 +246 final int rowCount = getRowDimension(); +247 final int columnCount = getColumnDimension(); +248 final T[][] outData = buildArray(getField(), rowCount, columnCount); +249 for (int row = 0; row < rowCount; row++) { +250 final T[] dataRow = data[row]; +251 final T[] mRow = m.data[row]; +252 final T[] outDataRow = outData[row]; +253 for (int col = 0; col < columnCount; col++) { +254 outDataRow[col] = dataRow[col].subtract(mRow[col]); +255 } +256 } +257 +258 return new Array2DRowFieldMatrix<T>(outData, false); +259 +260 } +261 +262 /** {@inheritDoc} */ +263 @Override +264 public FieldMatrix<T> multiply(final FieldMatrix<T> m) +265 throws IllegalArgumentException { +266 try { +267 return multiply((Array2DRowFieldMatrix<T>) m); +268 } catch (ClassCastException cce) { +269 return super.multiply(m); +270 } +271 } +272 +273 /** +274 * Returns the result of postmultiplying this by <code>m</code>. +275 * @param m matrix to postmultiply by +276 * @return this*m +277 * @throws IllegalArgumentException +278 * if columnDimension(this) != rowDimension(m) +279 */ +280 public Array2DRowFieldMatrix<T> multiply(final Array2DRowFieldMatrix<T> m) +281 throws IllegalArgumentException { +282 +283 // safety check +284 checkMultiplicationCompatible(m); +285 +286 final int nRows = this.getRowDimension(); +287 final int nCols = m.getColumnDimension(); +288 final int nSum = this.getColumnDimension(); +289 final T[][] outData = buildArray(getField(), nRows, nCols); +290 for (int row = 0; row < nRows; row++) { +291 final T[] dataRow = data[row]; +292 final T[] outDataRow = outData[row]; +293 for (int col = 0; col < nCols; col++) { +294 T sum = getField().getZero(); +295 for (int i = 0; i < nSum; i++) { +296 sum = sum.add(dataRow[i].multiply(m.data[i][col])); +297 } +298 outDataRow[col] = sum; +299 } +300 } +301 +302 return new Array2DRowFieldMatrix<T>(outData, false); +303 +304 } +305 +306 /** {@inheritDoc} */ +307 @Override +308 public T[][] getData() { +309 return copyOut(); +310 } +311 +312 /** +313 * Returns a reference to the underlying data array. +314 * <p> +315 * Does <strong>not</strong> make a fresh copy of the underlying data.</p> +316 * +317 * @return 2-dimensional array of entries +318 */ +319 public T[][] getDataRef() { +320 return data; +321 } +322 +323 /** {@inheritDoc} */ +324 @Override +325 public void setSubMatrix(final T[][] subMatrix, final int row, final int column) +326 throws MatrixIndexException { +327 if (data == null) { +328 if (row > 0) { +329 throw MathRuntimeException.createIllegalStateException( +330 "first {0} rows are not initialized yet", row); +331 } +332 if (column > 0) { +333 throw MathRuntimeException.createIllegalStateException( +334 "first {0} columns are not initialized yet", column); +335 } +336 final int nRows = subMatrix.length; +337 if (nRows == 0) { +338 throw MathRuntimeException.createIllegalArgumentException( +339 AT_LEAST_ONE_ROW_MESSAGE); +340 } +341 +342 final int nCols = subMatrix[0].length; +343 if (nCols == 0) { +344 throw MathRuntimeException.createIllegalArgumentException( +345 AT_LEAST_ONE_COLUMN_MESSAGE); +346 } +347 data = buildArray(getField(), subMatrix.length, nCols); +348 for (int i = 0; i < data.length; ++i) { +349 if (subMatrix[i].length != nCols) { +350 throw MathRuntimeException.createIllegalArgumentException( +351 DIFFERENT_ROWS_LENGTHS_MESSAGE, nCols, subMatrix[i].length); +352 } +353 System.arraycopy(subMatrix[i], 0, data[i + row], column, nCols); +354 } +355 } else { +356 super.setSubMatrix(subMatrix, row, column); +357 } +358 +359 } +360 +361 /** {@inheritDoc} */ +362 @Override +363 public T getEntry(final int row, final int column) +364 throws MatrixIndexException { +365 try { +366 return data[row][column]; +367 } catch (ArrayIndexOutOfBoundsException e) { +368 throw new MatrixIndexException( +369 NO_ENTRY_MESSAGE, row, column, getRowDimension(), getColumnDimension()); +370 } +371 } +372 +373 /** {@inheritDoc} */ +374 @Override +375 public void setEntry(final int row, final int column, final T value) +376 throws MatrixIndexException { +377 try { +378 data[row][column] = value; +379 } catch (ArrayIndexOutOfBoundsException e) { +380 throw new MatrixIndexException( +381 NO_ENTRY_MESSAGE, row, column, getRowDimension(), getColumnDimension()); +382 } +383 } +384 +385 /** {@inheritDoc} */ +386 @Override +387 public void addToEntry(final int row, final int column, final T increment) +388 throws MatrixIndexException { +389 try { +390 data[row][column] = data[row][column].add(increment); +391 } catch (ArrayIndexOutOfBoundsException e) { +392 throw new MatrixIndexException( +393 NO_ENTRY_MESSAGE, row, column, getRowDimension(), getColumnDimension()); +394 } +395 } +396 +397 /** {@inheritDoc} */ +398 @Override +399 public void multiplyEntry(final int row, final int column, final T factor) +400 throws MatrixIndexException { +401 try { +402 data[row][column] = data[row][column].multiply(factor); +403 } catch (ArrayIndexOutOfBoundsException e) { +404 throw new MatrixIndexException( +405 NO_ENTRY_MESSAGE, row, column, getRowDimension(), getColumnDimension()); +406 } +407 } +408 +409 /** {@inheritDoc} */ +410 @Override +411 public int getRowDimension() { +412 return (data == null) ? 0 : data.length; +413 } +414 +415 /** {@inheritDoc} */ +416 @Override +417 public int getColumnDimension() { +418 return ((data == null) || (data[0] == null)) ? 0 : data[0].length; +419 } +420 +421 /** {@inheritDoc} */ +422 @Override +423 public T[] operate(final T[] v) +424 throws IllegalArgumentException { +425 final int nRows = this.getRowDimension(); +426 final int nCols = this.getColumnDimension(); +427 if (v.length != nCols) { +428 throw MathRuntimeException.createIllegalArgumentException( +429 VECTOR_LENGTHS_MISMATCH, v.length, nCols); +430 } +431 final T[] out = buildArray(getField(), nRows); +432 for (int row = 0; row < nRows; row++) { +433 final T[] dataRow = data[row]; +434 T sum = getField().getZero(); +435 for (int i = 0; i < nCols; i++) { +436 sum = sum.add(dataRow[i].multiply(v[i])); +437 } +438 out[row] = sum; +439 } +440 return out; +441 } +442 +443 /** {@inheritDoc} */ +444 @Override +445 public T[] preMultiply(final T[] v) +446 throws IllegalArgumentException { +447 +448 final int nRows = getRowDimension(); +449 final int nCols = getColumnDimension(); +450 if (v.length != nRows) { +451 throw MathRuntimeException.createIllegalArgumentException( +452 VECTOR_LENGTHS_MISMATCH, v.length, nRows); +453 } +454 +455 final T[] out = buildArray(getField(), nCols); +456 for (int col = 0; col < nCols; ++col) { +457 T sum = getField().getZero(); +458 for (int i = 0; i < nRows; ++i) { +459 sum = sum.add(data[i][col].multiply(v[i])); +460 } +461 out[col] = sum; +462 } +463 +464 return out; +465 +466 } +467 +468 /** {@inheritDoc} */ +469 @Override +470 public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor) +471 throws MatrixVisitorException { +472 final int rows = getRowDimension(); +473 final int columns = getColumnDimension(); +474 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +475 for (int i = 0; i < rows; ++i) { +476 final T[] rowI = data[i]; +477 for (int j = 0; j < columns; ++j) { +478 rowI[j] = visitor.visit(i, j, rowI[j]); +479 } +480 } +481 return visitor.end(); +482 } +483 +484 /** {@inheritDoc} */ +485 @Override +486 public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor) +487 throws MatrixVisitorException { +488 final int rows = getRowDimension(); +489 final int columns = getColumnDimension(); +490 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +491 for (int i = 0; i < rows; ++i) { +492 final T[] rowI = data[i]; +493 for (int j = 0; j < columns; ++j) { +494 visitor.visit(i, j, rowI[j]); +495 } +496 } +497 return visitor.end(); +498 } +499 +500 /** {@inheritDoc} */ +501 @Override +502 public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor, +503 final int startRow, final int endRow, +504 final int startColumn, final int endColumn) +505 throws MatrixIndexException, MatrixVisitorException { +506 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +507 visitor.start(getRowDimension(), getColumnDimension(), +508 startRow, endRow, startColumn, endColumn); +509 for (int i = startRow; i <= endRow; ++i) { +510 final T[] rowI = data[i]; +511 for (int j = startColumn; j <= endColumn; ++j) { +512 rowI[j] = visitor.visit(i, j, rowI[j]); +513 } +514 } +515 return visitor.end(); +516 } +517 +518 /** {@inheritDoc} */ +519 @Override +520 public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor, +521 final int startRow, final int endRow, +522 final int startColumn, final int endColumn) +523 throws MatrixIndexException, MatrixVisitorException { +524 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +525 visitor.start(getRowDimension(), getColumnDimension(), +526 startRow, endRow, startColumn, endColumn); +527 for (int i = startRow; i <= endRow; ++i) { +528 final T[] rowI = data[i]; +529 for (int j = startColumn; j <= endColumn; ++j) { +530 visitor.visit(i, j, rowI[j]); +531 } +532 } +533 return visitor.end(); +534 } +535 +536 /** {@inheritDoc} */ +537 @Override +538 public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor) +539 throws MatrixVisitorException { +540 final int rows = getRowDimension(); +541 final int columns = getColumnDimension(); +542 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +543 for (int j = 0; j < columns; ++j) { +544 for (int i = 0; i < rows; ++i) { +545 final T[] rowI = data[i]; +546 rowI[j] = visitor.visit(i, j, rowI[j]); +547 } +548 } +549 return visitor.end(); +550 } +551 +552 /** {@inheritDoc} */ +553 @Override +554 public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor) +555 throws MatrixVisitorException { +556 final int rows = getRowDimension(); +557 final int columns = getColumnDimension(); +558 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +559 for (int j = 0; j < columns; ++j) { +560 for (int i = 0; i < rows; ++i) { +561 visitor.visit(i, j, data[i][j]); +562 } +563 } +564 return visitor.end(); +565 } +566 +567 /** {@inheritDoc} */ +568 @Override +569 public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor, +570 final int startRow, final int endRow, +571 final int startColumn, final int endColumn) +572 throws MatrixIndexException, MatrixVisitorException { +573 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +574 visitor.start(getRowDimension(), getColumnDimension(), +575 startRow, endRow, startColumn, endColumn); +576 for (int j = startColumn; j <= endColumn; ++j) { +577 for (int i = startRow; i <= endRow; ++i) { +578 final T[] rowI = data[i]; +579 rowI[j] = visitor.visit(i, j, rowI[j]); +580 } +581 } +582 return visitor.end(); +583 } +584 +585 /** {@inheritDoc} */ +586 @Override +587 public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor, +588 final int startRow, final int endRow, +589 final int startColumn, final int endColumn) +590 throws MatrixIndexException, MatrixVisitorException { +591 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +592 visitor.start(getRowDimension(), getColumnDimension(), +593 startRow, endRow, startColumn, endColumn); +594 for (int j = startColumn; j <= endColumn; ++j) { +595 for (int i = startRow; i <= endRow; ++i) { +596 visitor.visit(i, j, data[i][j]); +597 } +598 } +599 return visitor.end(); +600 } +601 +602 /** +603 * Returns a fresh copy of the underlying data array. +604 * +605 * @return a copy of the underlying data array. +606 */ +607 private T[][] copyOut() { +608 final int nRows = this.getRowDimension(); +609 final T[][] out = buildArray(getField(), nRows, getColumnDimension()); +610 // can't copy 2-d array in one shot, otherwise get row references +611 for (int i = 0; i < nRows; i++) { +612 System.arraycopy(data[i], 0, out[i], 0, data[i].length); +613 } +614 return out; +615 } +616 +617 /** +618 * Replaces data with a fresh copy of the input array. +619 * <p> +620 * Verifies that the input array is rectangular and non-empty.</p> +621 * +622 * @param in data to copy in +623 * @throws IllegalArgumentException if input array is empty or not +624 * rectangular +625 * @throws NullPointerException if input array is null +626 */ +627 private void copyIn(final T[][] in) { +628 setSubMatrix(in, 0, 0); +629 } +630 +631 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/Array2DRowRealMatrix.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/Array2DRowRealMatrix.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,705 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 +024 /** +025 * Implementation of RealMatrix using a double[][] array to store entries and +026 * <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf"> +027 * LU decomposition</a> to support linear system +028 * solution and inverse. +029 * <p> +030 * The LU decomposition is performed as needed, to support the following operations: <ul> +031 * <li>solve</li> +032 * <li>isSingular</li> +033 * <li>getDeterminant</li> +034 * <li>inverse</li> </ul></p> +035 * <p> +036 * <strong>Usage notes</strong>:<br> +037 * <ul><li> +038 * The LU decomposition is cached and reused on subsequent calls. +039 * If data are modified via references to the underlying array obtained using +040 * <code>getDataRef()</code>, then the stored LU decomposition will not be +041 * discarded. In this case, you need to explicitly invoke +042 * <code>LUDecompose()</code> to recompute the decomposition +043 * before using any of the methods above.</li> +044 * <li> +045 * As specified in the {@link RealMatrix} interface, matrix element indexing +046 * is 0-based -- e.g., <code>getEntry(0, 0)</code> +047 * returns the element in the first row, first column of the matrix.</li></ul> +048 * </p> +049 * +050 * @version $Revision: 885278 $ $Date: 2009-11-29 16:47:51 -0500 (Sun, 29 Nov 2009) $ +051 */ +052 public class Array2DRowRealMatrix extends AbstractRealMatrix implements Serializable { +053 +054 /** Serializable version identifier */ +055 private static final long serialVersionUID = -1067294169172445528L; +056 +057 /** Message for at least one row. */ +058 private static final String AT_LEAST_ONE_ROW_MESSAGE = +059 "matrix must have at least one row"; +060 +061 /** Message for at least one column. */ +062 private static final String AT_LEAST_ONE_COLUMN_MESSAGE = +063 "matrix must have at least one column"; +064 +065 /** Message for different rows lengths. */ +066 private static final String DIFFERENT_ROWS_LENGTHS_MESSAGE = +067 "some rows have length {0} while others have length {1}"; +068 +069 /** Message for no entry at selected indices. */ +070 private static final String NO_ENTRY_MESSAGE = +071 "no entry at indices ({0}, {1}) in a {2}x{3} matrix"; +072 +073 /** Message for vector lengths mismatch. */ +074 private static final String VECTOR_LENGTHS_MISMATCH = +075 "vector length mismatch: got {0} but expected {1}"; +076 +077 /** Entries of the matrix */ +078 protected double data[][]; +079 +080 /** +081 * Creates a matrix with no data +082 */ +083 public Array2DRowRealMatrix() { +084 } +085 +086 /** +087 * Create a new RealMatrix with the supplied row and column dimensions. +088 * +089 * @param rowDimension the number of rows in the new matrix +090 * @param columnDimension the number of columns in the new matrix +091 * @throws IllegalArgumentException if row or column dimension is not +092 * positive +093 */ +094 public Array2DRowRealMatrix(final int rowDimension, final int columnDimension) +095 throws IllegalArgumentException { +096 super(rowDimension, columnDimension); +097 data = new double[rowDimension][columnDimension]; +098 } +099 +100 /** +101 * Create a new RealMatrix using the input array as the underlying +102 * data array. +103 * <p>The input array is copied, not referenced. This constructor has +104 * the same effect as calling {@link #Array2DRowRealMatrix(double[][], boolean)} +105 * with the second argument set to <code>true</code>.</p> +106 * +107 * @param d data for new matrix +108 * @throws IllegalArgumentException if <code>d</code> is not rectangular +109 * (not all rows have the same length) or empty +110 * @throws NullPointerException if <code>d</code> is null +111 * @see #Array2DRowRealMatrix(double[][], boolean) +112 */ +113 public Array2DRowRealMatrix(final double[][] d) +114 throws IllegalArgumentException, NullPointerException { +115 copyIn(d); +116 } +117 +118 /** +119 * Create a new RealMatrix using the input array as the underlying +120 * data array. +121 * <p>If an array is built specially in order to be embedded in a +122 * RealMatrix and not used directly, the <code>copyArray</code> may be +123 * set to <code>false</code. This will prevent the copying and improve +124 * performance as no new array will be built and no data will be copied.</p> +125 * @param d data for new matrix +126 * @param copyArray if true, the input array will be copied, otherwise +127 * it will be referenced +128 * @throws IllegalArgumentException if <code>d</code> is not rectangular +129 * (not all rows have the same length) or empty +130 * @throws NullPointerException if <code>d</code> is null +131 * @see #Array2DRowRealMatrix(double[][]) +132 */ +133 public Array2DRowRealMatrix(final double[][] d, final boolean copyArray) +134 throws IllegalArgumentException, NullPointerException { +135 if (copyArray) { +136 copyIn(d); +137 } else { +138 if (d == null) { +139 throw new NullPointerException(); +140 } +141 final int nRows = d.length; +142 if (nRows == 0) { +143 throw MathRuntimeException.createIllegalArgumentException( +144 AT_LEAST_ONE_ROW_MESSAGE); +145 } +146 final int nCols = d[0].length; +147 if (nCols == 0) { +148 throw MathRuntimeException.createIllegalArgumentException( +149 AT_LEAST_ONE_COLUMN_MESSAGE); +150 } +151 for (int r = 1; r < nRows; r++) { +152 if (d[r].length != nCols) { +153 throw MathRuntimeException.createIllegalArgumentException( +154 DIFFERENT_ROWS_LENGTHS_MESSAGE, nCols, d[r].length); +155 } +156 } +157 data = d; +158 } +159 } +160 +161 /** +162 * Create a new (column) RealMatrix using <code>v</code> as the +163 * data for the unique column of the <code>v.length x 1</code> matrix +164 * created. +165 * <p>The input array is copied, not referenced.</p> +166 * +167 * @param v column vector holding data for new matrix +168 */ +169 public Array2DRowRealMatrix(final double[] v) { +170 final int nRows = v.length; +171 data = new double[nRows][1]; +172 for (int row = 0; row < nRows; row++) { +173 data[row][0] = v[row]; +174 } +175 } +176 +177 /** {@inheritDoc} */ +178 @Override +179 public RealMatrix createMatrix(final int rowDimension, final int columnDimension) +180 throws IllegalArgumentException { +181 return new Array2DRowRealMatrix(rowDimension, columnDimension); +182 } +183 +184 /** {@inheritDoc} */ +185 @Override +186 public RealMatrix copy() { +187 return new Array2DRowRealMatrix(copyOut(), false); +188 } +189 +190 /** {@inheritDoc} */ +191 @Override +192 public RealMatrix add(final RealMatrix m) +193 throws IllegalArgumentException { +194 try { +195 return add((Array2DRowRealMatrix) m); +196 } catch (ClassCastException cce) { +197 return super.add(m); +198 } +199 } +200 +201 /** +202 * Compute the sum of this and <code>m</code>. +203 * +204 * @param m matrix to be added +205 * @return this + m +206 * @throws IllegalArgumentException if m is not the same size as this +207 */ +208 public Array2DRowRealMatrix add(final Array2DRowRealMatrix m) +209 throws IllegalArgumentException { +210 +211 // safety check +212 MatrixUtils.checkAdditionCompatible(this, m); +213 +214 final int rowCount = getRowDimension(); +215 final int columnCount = getColumnDimension(); +216 final double[][] outData = new double[rowCount][columnCount]; +217 for (int row = 0; row < rowCount; row++) { +218 final double[] dataRow = data[row]; +219 final double[] mRow = m.data[row]; +220 final double[] outDataRow = outData[row]; +221 for (int col = 0; col < columnCount; col++) { +222 outDataRow[col] = dataRow[col] + mRow[col]; +223 } +224 } +225 +226 return new Array2DRowRealMatrix(outData, false); +227 +228 } +229 +230 /** {@inheritDoc} */ +231 @Override +232 public RealMatrix subtract(final RealMatrix m) +233 throws IllegalArgumentException { +234 try { +235 return subtract((Array2DRowRealMatrix) m); +236 } catch (ClassCastException cce) { +237 return super.subtract(m); +238 } +239 } +240 +241 /** +242 * Compute this minus <code>m</code>. +243 * +244 * @param m matrix to be subtracted +245 * @return this + m +246 * @throws IllegalArgumentException if m is not the same size as this +247 */ +248 public Array2DRowRealMatrix subtract(final Array2DRowRealMatrix m) +249 throws IllegalArgumentException { +250 +251 // safety check +252 MatrixUtils.checkSubtractionCompatible(this, m); +253 +254 final int rowCount = getRowDimension(); +255 final int columnCount = getColumnDimension(); +256 final double[][] outData = new double[rowCount][columnCount]; +257 for (int row = 0; row < rowCount; row++) { +258 final double[] dataRow = data[row]; +259 final double[] mRow = m.data[row]; +260 final double[] outDataRow = outData[row]; +261 for (int col = 0; col < columnCount; col++) { +262 outDataRow[col] = dataRow[col] - mRow[col]; +263 } +264 } +265 +266 return new Array2DRowRealMatrix(outData, false); +267 +268 } +269 +270 /** {@inheritDoc} */ +271 @Override +272 public RealMatrix multiply(final RealMatrix m) +273 throws IllegalArgumentException { +274 try { +275 return multiply((Array2DRowRealMatrix) m); +276 } catch (ClassCastException cce) { +277 return super.multiply(m); +278 } +279 } +280 +281 /** +282 * Returns the result of postmultiplying this by <code>m</code>. +283 * @param m matrix to postmultiply by +284 * @return this*m +285 * @throws IllegalArgumentException +286 * if columnDimension(this) != rowDimension(m) +287 */ +288 public Array2DRowRealMatrix multiply(final Array2DRowRealMatrix m) +289 throws IllegalArgumentException { +290 +291 // safety check +292 MatrixUtils.checkMultiplicationCompatible(this, m); +293 +294 final int nRows = this.getRowDimension(); +295 final int nCols = m.getColumnDimension(); +296 final int nSum = this.getColumnDimension(); +297 final double[][] outData = new double[nRows][nCols]; +298 for (int row = 0; row < nRows; row++) { +299 final double[] dataRow = data[row]; +300 final double[] outDataRow = outData[row]; +301 for (int col = 0; col < nCols; col++) { +302 double sum = 0; +303 for (int i = 0; i < nSum; i++) { +304 sum += dataRow[i] * m.data[i][col]; +305 } +306 outDataRow[col] = sum; +307 } +308 } +309 +310 return new Array2DRowRealMatrix(outData, false); +311 +312 } +313 +314 /** {@inheritDoc} */ +315 @Override +316 public double[][] getData() { +317 return copyOut(); +318 } +319 +320 /** +321 * Returns a reference to the underlying data array. +322 * <p> +323 * Does <strong>not</strong> make a fresh copy of the underlying data.</p> +324 * +325 * @return 2-dimensional array of entries +326 */ +327 public double[][] getDataRef() { +328 return data; +329 } +330 +331 /** {@inheritDoc} */ +332 @Override +333 public void setSubMatrix(final double[][] subMatrix, final int row, final int column) +334 throws MatrixIndexException { +335 if (data == null) { +336 if (row > 0) { +337 throw MathRuntimeException.createIllegalStateException( +338 "first {0} rows are not initialized yet", row); +339 } +340 if (column > 0) { +341 throw MathRuntimeException.createIllegalStateException( +342 "first {0} columns are not initialized yet", column); +343 } +344 final int nRows = subMatrix.length; +345 if (nRows == 0) { +346 throw MathRuntimeException.createIllegalArgumentException( +347 AT_LEAST_ONE_ROW_MESSAGE); +348 } +349 +350 final int nCols = subMatrix[0].length; +351 if (nCols == 0) { +352 throw MathRuntimeException.createIllegalArgumentException( +353 AT_LEAST_ONE_COLUMN_MESSAGE); +354 } +355 data = new double[subMatrix.length][nCols]; +356 for (int i = 0; i < data.length; ++i) { +357 if (subMatrix[i].length != nCols) { +358 throw MathRuntimeException.createIllegalArgumentException( +359 DIFFERENT_ROWS_LENGTHS_MESSAGE, nCols, subMatrix[i].length); +360 } +361 System.arraycopy(subMatrix[i], 0, data[i + row], column, nCols); +362 } +363 } else { +364 super.setSubMatrix(subMatrix, row, column); +365 } +366 +367 } +368 +369 /** {@inheritDoc} */ +370 @Override +371 public double getEntry(final int row, final int column) +372 throws MatrixIndexException { +373 try { +374 return data[row][column]; +375 } catch (ArrayIndexOutOfBoundsException e) { +376 throw new MatrixIndexException( +377 NO_ENTRY_MESSAGE, row, column, getRowDimension(), getColumnDimension()); +378 } +379 } +380 +381 /** {@inheritDoc} */ +382 @Override +383 public void setEntry(final int row, final int column, final double value) +384 throws MatrixIndexException { +385 try { +386 data[row][column] = value; +387 } catch (ArrayIndexOutOfBoundsException e) { +388 throw new MatrixIndexException( +389 NO_ENTRY_MESSAGE, row, column, getRowDimension(), getColumnDimension()); +390 } +391 } +392 +393 /** {@inheritDoc} */ +394 @Override +395 public void addToEntry(final int row, final int column, final double increment) +396 throws MatrixIndexException { +397 try { +398 data[row][column] += increment; +399 } catch (ArrayIndexOutOfBoundsException e) { +400 throw new MatrixIndexException( +401 NO_ENTRY_MESSAGE, row, column, getRowDimension(), getColumnDimension()); +402 } +403 } +404 +405 /** {@inheritDoc} */ +406 @Override +407 public void multiplyEntry(final int row, final int column, final double factor) +408 throws MatrixIndexException { +409 try { +410 data[row][column] *= factor; +411 } catch (ArrayIndexOutOfBoundsException e) { +412 throw new MatrixIndexException( +413 NO_ENTRY_MESSAGE, row, column, getRowDimension(), getColumnDimension()); +414 } +415 } +416 +417 /** {@inheritDoc} */ +418 @Override +419 public int getRowDimension() { +420 return (data == null) ? 0 : data.length; +421 } +422 +423 /** {@inheritDoc} */ +424 @Override +425 public int getColumnDimension() { +426 return ((data == null) || (data[0] == null)) ? 0 : data[0].length; +427 } +428 +429 /** {@inheritDoc} */ +430 @Override +431 public double[] operate(final double[] v) +432 throws IllegalArgumentException { +433 final int nRows = this.getRowDimension(); +434 final int nCols = this.getColumnDimension(); +435 if (v.length != nCols) { +436 throw MathRuntimeException.createIllegalArgumentException( +437 VECTOR_LENGTHS_MISMATCH, v.length, nCols); +438 } +439 final double[] out = new double[nRows]; +440 for (int row = 0; row < nRows; row++) { +441 final double[] dataRow = data[row]; +442 double sum = 0; +443 for (int i = 0; i < nCols; i++) { +444 sum += dataRow[i] * v[i]; +445 } +446 out[row] = sum; +447 } +448 return out; +449 } +450 +451 /** {@inheritDoc} */ +452 @Override +453 public double[] preMultiply(final double[] v) +454 throws IllegalArgumentException { +455 +456 final int nRows = getRowDimension(); +457 final int nCols = getColumnDimension(); +458 if (v.length != nRows) { +459 throw MathRuntimeException.createIllegalArgumentException( +460 VECTOR_LENGTHS_MISMATCH, v.length, nRows); +461 } +462 +463 final double[] out = new double[nCols]; +464 for (int col = 0; col < nCols; ++col) { +465 double sum = 0; +466 for (int i = 0; i < nRows; ++i) { +467 sum += data[i][col] * v[i]; +468 } +469 out[col] = sum; +470 } +471 +472 return out; +473 +474 } +475 +476 /** {@inheritDoc} */ +477 @Override +478 public double walkInRowOrder(final RealMatrixChangingVisitor visitor) +479 throws MatrixVisitorException { +480 final int rows = getRowDimension(); +481 final int columns = getColumnDimension(); +482 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +483 for (int i = 0; i < rows; ++i) { +484 final double[] rowI = data[i]; +485 for (int j = 0; j < columns; ++j) { +486 rowI[j] = visitor.visit(i, j, rowI[j]); +487 } +488 } +489 return visitor.end(); +490 } +491 +492 /** {@inheritDoc} */ +493 @Override +494 public double walkInRowOrder(final RealMatrixPreservingVisitor visitor) +495 throws MatrixVisitorException { +496 final int rows = getRowDimension(); +497 final int columns = getColumnDimension(); +498 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +499 for (int i = 0; i < rows; ++i) { +500 final double[] rowI = data[i]; +501 for (int j = 0; j < columns; ++j) { +502 visitor.visit(i, j, rowI[j]); +503 } +504 } +505 return visitor.end(); +506 } +507 +508 /** {@inheritDoc} */ +509 @Override +510 public double walkInRowOrder(final RealMatrixChangingVisitor visitor, +511 final int startRow, final int endRow, +512 final int startColumn, final int endColumn) +513 throws MatrixIndexException, MatrixVisitorException { +514 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +515 visitor.start(getRowDimension(), getColumnDimension(), +516 startRow, endRow, startColumn, endColumn); +517 for (int i = startRow; i <= endRow; ++i) { +518 final double[] rowI = data[i]; +519 for (int j = startColumn; j <= endColumn; ++j) { +520 rowI[j] = visitor.visit(i, j, rowI[j]); +521 } +522 } +523 return visitor.end(); +524 } +525 +526 /** {@inheritDoc} */ +527 @Override +528 public double walkInRowOrder(final RealMatrixPreservingVisitor visitor, +529 final int startRow, final int endRow, +530 final int startColumn, final int endColumn) +531 throws MatrixIndexException, MatrixVisitorException { +532 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +533 visitor.start(getRowDimension(), getColumnDimension(), +534 startRow, endRow, startColumn, endColumn); +535 for (int i = startRow; i <= endRow; ++i) { +536 final double[] rowI = data[i]; +537 for (int j = startColumn; j <= endColumn; ++j) { +538 visitor.visit(i, j, rowI[j]); +539 } +540 } +541 return visitor.end(); +542 } +543 +544 /** {@inheritDoc} */ +545 @Override +546 public double walkInColumnOrder(final RealMatrixChangingVisitor visitor) +547 throws MatrixVisitorException { +548 final int rows = getRowDimension(); +549 final int columns = getColumnDimension(); +550 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +551 for (int j = 0; j < columns; ++j) { +552 for (int i = 0; i < rows; ++i) { +553 final double[] rowI = data[i]; +554 rowI[j] = visitor.visit(i, j, rowI[j]); +555 } +556 } +557 return visitor.end(); +558 } +559 +560 /** {@inheritDoc} */ +561 @Override +562 public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor) +563 throws MatrixVisitorException { +564 final int rows = getRowDimension(); +565 final int columns = getColumnDimension(); +566 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +567 for (int j = 0; j < columns; ++j) { +568 for (int i = 0; i < rows; ++i) { +569 visitor.visit(i, j, data[i][j]); +570 } +571 } +572 return visitor.end(); +573 } +574 +575 /** {@inheritDoc} */ +576 @Override +577 public double walkInColumnOrder(final RealMatrixChangingVisitor visitor, +578 final int startRow, final int endRow, +579 final int startColumn, final int endColumn) +580 throws MatrixIndexException, MatrixVisitorException { +581 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +582 visitor.start(getRowDimension(), getColumnDimension(), +583 startRow, endRow, startColumn, endColumn); +584 for (int j = startColumn; j <= endColumn; ++j) { +585 for (int i = startRow; i <= endRow; ++i) { +586 final double[] rowI = data[i]; +587 rowI[j] = visitor.visit(i, j, rowI[j]); +588 } +589 } +590 return visitor.end(); +591 } +592 +593 /** {@inheritDoc} */ +594 @Override +595 public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor, +596 final int startRow, final int endRow, +597 final int startColumn, final int endColumn) +598 throws MatrixIndexException, MatrixVisitorException { +599 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +600 visitor.start(getRowDimension(), getColumnDimension(), +601 startRow, endRow, startColumn, endColumn); +602 for (int j = startColumn; j <= endColumn; ++j) { +603 for (int i = startRow; i <= endRow; ++i) { +604 visitor.visit(i, j, data[i][j]); +605 } +606 } +607 return visitor.end(); +608 } +609 +610 /** +611 * Returns a fresh copy of the underlying data array. +612 * +613 * @return a copy of the underlying data array. +614 */ +615 private double[][] copyOut() { +616 final int nRows = this.getRowDimension(); +617 final double[][] out = new double[nRows][this.getColumnDimension()]; +618 // can't copy 2-d array in one shot, otherwise get row references +619 for (int i = 0; i < nRows; i++) { +620 System.arraycopy(data[i], 0, out[i], 0, data[i].length); +621 } +622 return out; +623 } +624 +625 /** +626 * Replaces data with a fresh copy of the input array. +627 * <p> +628 * Verifies that the input array is rectangular and non-empty.</p> +629 * +630 * @param in data to copy in +631 * @throws IllegalArgumentException if input array is empty or not +632 * rectangular +633 * @throws NullPointerException if input array is null +634 */ +635 private void copyIn(final double[][] in) { +636 setSubMatrix(in, 0, 0); +637 } +638 +639 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/ArrayFieldVector.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/ArrayFieldVector.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,868 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.linear; +018 +019 import java.io.Serializable; +020 import java.lang.reflect.Array; +021 import java.util.Arrays; +022 +023 import org.apache.commons.math.Field; +024 import org.apache.commons.math.FieldElement; +025 import org.apache.commons.math.MathRuntimeException; +026 +027 /** +028 * This class implements the {@link FieldVector} interface with a {@link FieldElement} array. +029 * @param <T> the type of the field elements +030 * @version $Revision: 903046 $ $Date: 2010-01-25 21:07:26 -0500 (Mon, 25 Jan 2010) $ +031 * @since 2.0 +032 */ +033 public class ArrayFieldVector<T extends FieldElement<T>> implements FieldVector<T>, Serializable { +034 +035 /** Serializable version identifier. */ +036 private static final long serialVersionUID = 7648186910365927050L; +037 +038 /** Entries of the vector. */ +039 protected T[] data; +040 +041 /** Field to which the elements belong. */ +042 private final Field<T> field; +043 +044 /** +045 * Build a 0-length vector. +046 * <p>Zero-length vectors may be used to initialized construction of vectors +047 * by data gathering. We start with zero-length and use either the {@link +048 * #ArrayFieldVector(ArrayFieldVector, ArrayFieldVector)} constructor +049 * or one of the <code>append</code> methods ({@link #append(FieldElement[])}, +050 * {@link #add(FieldVector)}, {@link #append(ArrayFieldVector)}) to gather data +051 * into this vector.</p> +052 * @param field field to which the elements belong +053 */ +054 public ArrayFieldVector(final Field<T> field) { +055 this(field, 0); +056 } +057 +058 /** +059 * Construct a (size)-length vector of zeros. +060 * @param field field to which the elements belong +061 * @param size size of the vector +062 */ +063 public ArrayFieldVector(Field<T> field, int size) { +064 this.field = field; +065 data = buildArray(size); +066 Arrays.fill(data, field.getZero()); +067 } +068 +069 /** +070 * Construct an (size)-length vector with preset values. +071 * @param size size of the vector +072 * @param preset fill the vector with this scalar value +073 */ +074 public ArrayFieldVector(int size, T preset) { +075 this(preset.getField(), size); +076 Arrays.fill(data, preset); +077 } +078 +079 /** +080 * Construct a vector from an array, copying the input array. +081 * @param d array of Ts. +082 * @throws IllegalArgumentException if <code>d</code> is empty +083 */ +084 public ArrayFieldVector(T[] d) +085 throws IllegalArgumentException { +086 try { +087 field = d[0].getField(); +088 data = d.clone(); +089 } catch (ArrayIndexOutOfBoundsException e) { +090 throw MathRuntimeException.createIllegalArgumentException( +091 "vector must have at least one element"); +092 } +093 } +094 +095 /** +096 * Create a new ArrayFieldVector using the input array as the underlying +097 * data array. +098 * <p>If an array is built specially in order to be embedded in a +099 * ArrayFieldVector and not used directly, the <code>copyArray</code> may be +100 * set to <code>false</code. This will prevent the copying and improve +101 * performance as no new array will be built and no data will be copied.</p> +102 * @param d data for new vector +103 * @param copyArray if true, the input array will be copied, otherwise +104 * it will be referenced +105 * @throws IllegalArgumentException if <code>d</code> is empty +106 * @throws NullPointerException if <code>d</code> is null +107 * @see #ArrayFieldVector(FieldElement[]) +108 */ +109 public ArrayFieldVector(T[] d, boolean copyArray) +110 throws NullPointerException, IllegalArgumentException { +111 try { +112 field = d[0].getField(); +113 data = copyArray ? d.clone() : d; +114 } catch (ArrayIndexOutOfBoundsException e) { +115 throw MathRuntimeException.createIllegalArgumentException( +116 "vector must have at least one element"); +117 } +118 } +119 +120 /** +121 * Construct a vector from part of a array. +122 * @param d array of Ts. +123 * @param pos position of first entry +124 * @param size number of entries to copy +125 */ +126 public ArrayFieldVector(T[] d, int pos, int size) { +127 if (d.length < pos + size) { +128 throw MathRuntimeException.createIllegalArgumentException( +129 "position {0} and size {1} don't fit to the size of the input array {2}", +130 pos, size, d.length); +131 } +132 field = d[0].getField(); +133 data = buildArray(size); +134 System.arraycopy(d, pos, data, 0, size); +135 } +136 +137 /** +138 * Construct a vector from another vector, using a deep copy. +139 * @param v vector to copy +140 */ +141 public ArrayFieldVector(FieldVector<T> v) { +142 field = v.getField(); +143 data = buildArray(v.getDimension()); +144 for (int i = 0; i < data.length; ++i) { +145 data[i] = v.getEntry(i); +146 } +147 } +148 +149 /** +150 * Construct a vector from another vector, using a deep copy. +151 * @param v vector to copy +152 */ +153 public ArrayFieldVector(ArrayFieldVector<T> v) { +154 field = v.getField(); +155 data = v.data.clone(); +156 } +157 +158 /** +159 * Construct a vector from another vector. +160 * @param v vector to copy +161 * @param deep if true perform a deep copy otherwise perform a shallow copy +162 */ +163 public ArrayFieldVector(ArrayFieldVector<T> v, boolean deep) { +164 field = v.getField(); +165 data = deep ? v.data.clone() : v.data; +166 } +167 +168 /** +169 * Construct a vector by appending one vector to another vector. +170 * @param v1 first vector (will be put in front of the new vector) +171 * @param v2 second vector (will be put at back of the new vector) +172 */ +173 public ArrayFieldVector(ArrayFieldVector<T> v1, ArrayFieldVector<T> v2) { +174 field = v1.getField(); +175 data = buildArray(v1.data.length + v2.data.length); +176 System.arraycopy(v1.data, 0, data, 0, v1.data.length); +177 System.arraycopy(v2.data, 0, data, v1.data.length, v2.data.length); +178 } +179 +180 /** +181 * Construct a vector by appending one vector to another vector. +182 * @param v1 first vector (will be put in front of the new vector) +183 * @param v2 second vector (will be put at back of the new vector) +184 */ +185 public ArrayFieldVector(ArrayFieldVector<T> v1, T[] v2) { +186 field = v1.getField(); +187 data = buildArray(v1.data.length + v2.length); +188 System.arraycopy(v1.data, 0, data, 0, v1.data.length); +189 System.arraycopy(v2, 0, data, v1.data.length, v2.length); +190 } +191 +192 /** +193 * Construct a vector by appending one vector to another vector. +194 * @param v1 first vector (will be put in front of the new vector) +195 * @param v2 second vector (will be put at back of the new vector) +196 */ +197 public ArrayFieldVector(T[] v1, ArrayFieldVector<T> v2) { +198 field = v2.getField(); +199 data = buildArray(v1.length + v2.data.length); +200 System.arraycopy(v1, 0, data, 0, v1.length); +201 System.arraycopy(v2.data, 0, data, v1.length, v2.data.length); +202 } +203 +204 /** +205 * Construct a vector by appending one vector to another vector. +206 * @param v1 first vector (will be put in front of the new vector) +207 * @param v2 second vector (will be put at back of the new vector) +208 * @exception IllegalArgumentException if both vectors are empty +209 */ +210 public ArrayFieldVector(T[] v1, T[] v2) { +211 try { +212 data = buildArray(v1.length + v2.length); +213 System.arraycopy(v1, 0, data, 0, v1.length); +214 System.arraycopy(v2, 0, data, v1.length, v2.length); +215 field = data[0].getField(); +216 } catch (ArrayIndexOutOfBoundsException e) { +217 throw MathRuntimeException.createIllegalArgumentException( +218 "vector must have at least one element"); +219 } +220 } +221 +222 /** Build an array of elements. +223 * @param length size of the array to build +224 * @return a new array +225 */ +226 @SuppressWarnings("unchecked") // field is of type T +227 private T[] buildArray(final int length) { +228 return (T[]) Array.newInstance(field.getZero().getClass(), length); +229 } +230 +231 /** {@inheritDoc} */ +232 public Field<T> getField() { +233 return field; +234 } +235 +236 /** {@inheritDoc} */ +237 public FieldVector<T> copy() { +238 return new ArrayFieldVector<T>(this, true); +239 } +240 +241 /** {@inheritDoc} */ +242 public FieldVector<T> add(FieldVector<T> v) throws IllegalArgumentException { +243 try { +244 return add((ArrayFieldVector<T>) v); +245 } catch (ClassCastException cce) { +246 checkVectorDimensions(v); +247 T[] out = buildArray(data.length); +248 for (int i = 0; i < data.length; i++) { +249 out[i] = data[i].add(v.getEntry(i)); +250 } +251 return new ArrayFieldVector<T>(out); +252 } +253 } +254 +255 /** {@inheritDoc} */ +256 public FieldVector<T> add(T[] v) throws IllegalArgumentException { +257 checkVectorDimensions(v.length); +258 T[] out = buildArray(data.length); +259 for (int i = 0; i < data.length; i++) { +260 out[i] = data[i].add(v[i]); +261 } +262 return new ArrayFieldVector<T>(out); +263 } +264 +265 /** +266 * Compute the sum of this and v. +267 * @param v vector to be added +268 * @return this + v +269 * @throws IllegalArgumentException if v is not the same size as this +270 */ +271 public ArrayFieldVector<T> add(ArrayFieldVector<T> v) +272 throws IllegalArgumentException { +273 return (ArrayFieldVector<T>) add(v.data); +274 } +275 +276 /** {@inheritDoc} */ +277 public FieldVector<T> subtract(FieldVector<T> v) throws IllegalArgumentException { +278 try { +279 return subtract((ArrayFieldVector<T>) v); +280 } catch (ClassCastException cce) { +281 checkVectorDimensions(v); +282 T[] out = buildArray(data.length); +283 for (int i = 0; i < data.length; i++) { +284 out[i] = data[i].subtract(v.getEntry(i)); +285 } +286 return new ArrayFieldVector<T>(out); +287 } +288 } +289 +290 /** {@inheritDoc} */ +291 public FieldVector<T> subtract(T[] v) throws IllegalArgumentException { +292 checkVectorDimensions(v.length); +293 T[] out = buildArray(data.length); +294 for (int i = 0; i < data.length; i++) { +295 out[i] = data[i].subtract(v[i]); +296 } +297 return new ArrayFieldVector<T>(out); +298 } +299 +300 /** +301 * Compute this minus v. +302 * @param v vector to be subtracted +303 * @return this + v +304 * @throws IllegalArgumentException if v is not the same size as this +305 */ +306 public ArrayFieldVector<T> subtract(ArrayFieldVector<T> v) +307 throws IllegalArgumentException { +308 return (ArrayFieldVector<T>) subtract(v.data); +309 } +310 +311 /** {@inheritDoc} */ +312 public FieldVector<T> mapAdd(T d) { +313 T[] out = buildArray(data.length); +314 for (int i = 0; i < data.length; i++) { +315 out[i] = data[i].add(d); +316 } +317 return new ArrayFieldVector<T>(out); +318 } +319 +320 /** {@inheritDoc} */ +321 public FieldVector<T> mapAddToSelf(T d) { +322 for (int i = 0; i < data.length; i++) { +323 data[i] = data[i].add(d); +324 } +325 return this; +326 } +327 +328 /** {@inheritDoc} */ +329 public FieldVector<T> mapSubtract(T d) { +330 T[] out = buildArray(data.length); +331 for (int i = 0; i < data.length; i++) { +332 out[i] = data[i].subtract(d); +333 } +334 return new ArrayFieldVector<T>(out); +335 } +336 +337 /** {@inheritDoc} */ +338 public FieldVector<T> mapSubtractToSelf(T d) { +339 for (int i = 0; i < data.length; i++) { +340 data[i] = data[i].subtract(d); +341 } +342 return this; +343 } +344 +345 /** {@inheritDoc} */ +346 public FieldVector<T> mapMultiply(T d) { +347 T[] out = buildArray(data.length); +348 for (int i = 0; i < data.length; i++) { +349 out[i] = data[i].multiply(d); +350 } +351 return new ArrayFieldVector<T>(out); +352 } +353 +354 /** {@inheritDoc} */ +355 public FieldVector<T> mapMultiplyToSelf(T d) { +356 for (int i = 0; i < data.length; i++) { +357 data[i] = data[i].multiply(d); +358 } +359 return this; +360 } +361 +362 /** {@inheritDoc} */ +363 public FieldVector<T> mapDivide(T d) { +364 T[] out = buildArray(data.length); +365 for (int i = 0; i < data.length; i++) { +366 out[i] = data[i].divide(d); +367 } +368 return new ArrayFieldVector<T>(out); +369 } +370 +371 /** {@inheritDoc} */ +372 public FieldVector<T> mapDivideToSelf(T d) { +373 for (int i = 0; i < data.length; i++) { +374 data[i] = data[i].divide(d); +375 } +376 return this; +377 } +378 +379 /** {@inheritDoc} */ +380 public FieldVector<T> mapInv() { +381 T[] out = buildArray(data.length); +382 final T one = field.getOne(); +383 for (int i = 0; i < data.length; i++) { +384 out[i] = one.divide(data[i]); +385 } +386 return new ArrayFieldVector<T>(out); +387 } +388 +389 /** {@inheritDoc} */ +390 public FieldVector<T> mapInvToSelf() { +391 final T one = field.getOne(); +392 for (int i = 0; i < data.length; i++) { +393 data[i] = one.divide(data[i]); +394 } +395 return this; +396 } +397 +398 /** {@inheritDoc} */ +399 public FieldVector<T> ebeMultiply(FieldVector<T> v) +400 throws IllegalArgumentException { +401 try { +402 return ebeMultiply((ArrayFieldVector<T>) v); +403 } catch (ClassCastException cce) { +404 checkVectorDimensions(v); +405 T[] out = buildArray(data.length); +406 for (int i = 0; i < data.length; i++) { +407 out[i] = data[i].multiply(v.getEntry(i)); +408 } +409 return new ArrayFieldVector<T>(out); +410 } +411 } +412 +413 /** {@inheritDoc} */ +414 public FieldVector<T> ebeMultiply(T[] v) +415 throws IllegalArgumentException { +416 checkVectorDimensions(v.length); +417 T[] out = buildArray(data.length); +418 for (int i = 0; i < data.length; i++) { +419 out[i] = data[i].multiply(v[i]); +420 } +421 return new ArrayFieldVector<T>(out); +422 } +423 +424 /** +425 * Element-by-element multiplication. +426 * @param v vector by which instance elements must be multiplied +427 * @return a vector containing this[i] * v[i] for all i +428 * @exception IllegalArgumentException if v is not the same size as this +429 */ +430 public ArrayFieldVector<T> ebeMultiply(ArrayFieldVector<T> v) +431 throws IllegalArgumentException { +432 return (ArrayFieldVector<T>) ebeMultiply(v.data); +433 } +434 +435 /** {@inheritDoc} */ +436 public FieldVector<T> ebeDivide(FieldVector<T> v) +437 throws IllegalArgumentException { +438 try { +439 return ebeDivide((ArrayFieldVector<T>) v); +440 } catch (ClassCastException cce) { +441 checkVectorDimensions(v); +442 T[] out = buildArray(data.length); +443 for (int i = 0; i < data.length; i++) { +444 out[i] = data[i].divide(v.getEntry(i)); +445 } +446 return new ArrayFieldVector<T>(out); +447 } +448 } +449 +450 /** {@inheritDoc} */ +451 public FieldVector<T> ebeDivide(T[] v) +452 throws IllegalArgumentException { +453 checkVectorDimensions(v.length); +454 T[] out = buildArray(data.length); +455 for (int i = 0; i < data.length; i++) { +456 out[i] = data[i].divide(v[i]); +457 } +458 return new ArrayFieldVector<T>(out); +459 } +460 +461 /** +462 * Element-by-element division. +463 * @param v vector by which instance elements must be divided +464 * @return a vector containing this[i] / v[i] for all i +465 * @throws IllegalArgumentException if v is not the same size as this +466 */ +467 public ArrayFieldVector<T> ebeDivide(ArrayFieldVector<T> v) +468 throws IllegalArgumentException { +469 return (ArrayFieldVector<T>) ebeDivide(v.data); +470 } +471 +472 /** {@inheritDoc} */ +473 public T[] getData() { +474 return data.clone(); +475 } +476 +477 /** +478 * Returns a reference to the underlying data array. +479 * <p>Does not make a fresh copy of the underlying data.</p> +480 * @return array of entries +481 */ +482 public T[] getDataRef() { +483 return data; +484 } +485 +486 /** {@inheritDoc} */ +487 public T dotProduct(FieldVector<T> v) +488 throws IllegalArgumentException { +489 try { +490 return dotProduct((ArrayFieldVector<T>) v); +491 } catch (ClassCastException cce) { +492 checkVectorDimensions(v); +493 T dot = field.getZero(); +494 for (int i = 0; i < data.length; i++) { +495 dot = dot.add(data[i].multiply(v.getEntry(i))); +496 } +497 return dot; +498 } +499 } +500 +501 /** {@inheritDoc} */ +502 public T dotProduct(T[] v) +503 throws IllegalArgumentException { +504 checkVectorDimensions(v.length); +505 T dot = field.getZero(); +506 for (int i = 0; i < data.length; i++) { +507 dot = dot.add(data[i].multiply(v[i])); +508 } +509 return dot; +510 } +511 +512 /** +513 * Compute the dot product. +514 * @param v vector with which dot product should be computed +515 * @return the scalar dot product between instance and v +516 * @exception IllegalArgumentException if v is not the same size as this +517 */ +518 public T dotProduct(ArrayFieldVector<T> v) +519 throws IllegalArgumentException { +520 return dotProduct(v.data); +521 } +522 +523 /** {@inheritDoc} */ +524 public FieldVector<T> projection(FieldVector<T> v) { +525 return v.mapMultiply(dotProduct(v).divide(v.dotProduct(v))); +526 } +527 +528 /** {@inheritDoc} */ +529 public FieldVector<T> projection(T[] v) { +530 return projection(new ArrayFieldVector<T>(v, false)); +531 } +532 +533 /** Find the orthogonal projection of this vector onto another vector. +534 * @param v vector onto which instance must be projected +535 * @return projection of the instance onto v +536 * @throws IllegalArgumentException if v is not the same size as this +537 */ +538 public ArrayFieldVector<T> projection(ArrayFieldVector<T> v) { +539 return (ArrayFieldVector<T>) v.mapMultiply(dotProduct(v).divide(v.dotProduct(v))); +540 } +541 +542 /** {@inheritDoc} */ +543 public FieldMatrix<T> outerProduct(FieldVector<T> v) +544 throws IllegalArgumentException { +545 try { +546 return outerProduct((ArrayFieldVector<T>) v); +547 } catch (ClassCastException cce) { +548 checkVectorDimensions(v); +549 final int m = data.length; +550 final FieldMatrix<T> out = new Array2DRowFieldMatrix<T>(field, m, m); +551 for (int i = 0; i < data.length; i++) { +552 for (int j = 0; j < data.length; j++) { +553 out.setEntry(i, j, data[i].multiply(v.getEntry(j))); +554 } +555 } +556 return out; +557 } +558 } +559 +560 /** +561 * Compute the outer product. +562 * @param v vector with which outer product should be computed +563 * @return the square matrix outer product between instance and v +564 * @exception IllegalArgumentException if v is not the same size as this +565 */ +566 public FieldMatrix<T> outerProduct(ArrayFieldVector<T> v) +567 throws IllegalArgumentException { +568 return outerProduct(v.data); +569 } +570 +571 /** {@inheritDoc} */ +572 public FieldMatrix<T> outerProduct(T[] v) +573 throws IllegalArgumentException { +574 checkVectorDimensions(v.length); +575 final int m = data.length; +576 final FieldMatrix<T> out = new Array2DRowFieldMatrix<T>(field, m, m); +577 for (int i = 0; i < data.length; i++) { +578 for (int j = 0; j < data.length; j++) { +579 out.setEntry(i, j, data[i].multiply(v[j])); +580 } +581 } +582 return out; +583 } +584 +585 /** {@inheritDoc} */ +586 public T getEntry(int index) throws MatrixIndexException { +587 return data[index]; +588 } +589 +590 /** {@inheritDoc} */ +591 public int getDimension() { +592 return data.length; +593 } +594 +595 /** {@inheritDoc} */ +596 public FieldVector<T> append(FieldVector<T> v) { +597 try { +598 return append((ArrayFieldVector<T>) v); +599 } catch (ClassCastException cce) { +600 return new ArrayFieldVector<T>(this,new ArrayFieldVector<T>(v)); +601 } +602 } +603 +604 /** +605 * Construct a vector by appending a vector to this vector. +606 * @param v vector to append to this one. +607 * @return a new vector +608 */ +609 public ArrayFieldVector<T> append(ArrayFieldVector<T> v) { +610 return new ArrayFieldVector<T>(this, v); +611 } +612 +613 /** {@inheritDoc} */ +614 public FieldVector<T> append(T in) { +615 final T[] out = buildArray(data.length + 1); +616 System.arraycopy(data, 0, out, 0, data.length); +617 out[data.length] = in; +618 return new ArrayFieldVector<T>(out); +619 } +620 +621 /** {@inheritDoc} */ +622 public FieldVector<T> append(T[] in) { +623 return new ArrayFieldVector<T>(this, in); +624 } +625 +626 /** {@inheritDoc} */ +627 public FieldVector<T> getSubVector(int index, int n) { +628 ArrayFieldVector<T> out = new ArrayFieldVector<T>(field, n); +629 try { +630 System.arraycopy(data, index, out.data, 0, n); +631 } catch (IndexOutOfBoundsException e) { +632 checkIndex(index); +633 checkIndex(index + n - 1); +634 } +635 return out; +636 } +637 +638 /** {@inheritDoc} */ +639 public void setEntry(int index, T value) { +640 try { +641 data[index] = value; +642 } catch (IndexOutOfBoundsException e) { +643 checkIndex(index); +644 } +645 } +646 +647 /** {@inheritDoc} */ +648 public void setSubVector(int index, FieldVector<T> v) { +649 try { +650 try { +651 set(index, (ArrayFieldVector<T>) v); +652 } catch (ClassCastException cce) { +653 for (int i = index; i < index + v.getDimension(); ++i) { +654 data[i] = v.getEntry(i-index); +655 } +656 } +657 } catch (IndexOutOfBoundsException e) { +658 checkIndex(index); +659 checkIndex(index + v.getDimension() - 1); +660 } +661 } +662 +663 /** {@inheritDoc} */ +664 public void setSubVector(int index, T[] v) { +665 try { +666 System.arraycopy(v, 0, data, index, v.length); +667 } catch (IndexOutOfBoundsException e) { +668 checkIndex(index); +669 checkIndex(index + v.length - 1); +670 } +671 } +672 +673 /** +674 * Set a set of consecutive elements. +675 * +676 * @param index index of first element to be set. +677 * @param v vector containing the values to set. +678 * @exception MatrixIndexException if the index is +679 * inconsistent with vector size +680 */ +681 public void set(int index, ArrayFieldVector<T> v) +682 throws MatrixIndexException { +683 setSubVector(index, v.data); +684 } +685 +686 /** {@inheritDoc} */ +687 public void set(T value) { +688 Arrays.fill(data, value); +689 } +690 +691 /** {@inheritDoc} */ +692 public T[] toArray(){ +693 return data.clone(); +694 } +695 +696 /** +697 * Check if instance and specified vectors have the same dimension. +698 * @param v vector to compare instance with +699 * @exception IllegalArgumentException if the vectors do not +700 * have the same dimension +701 */ +702 protected void checkVectorDimensions(FieldVector<T> v) +703 throws IllegalArgumentException { +704 checkVectorDimensions(v.getDimension()); +705 } +706 +707 /** +708 * Check if instance dimension is equal to some expected value. +709 * +710 * @param n expected dimension. +711 * @exception IllegalArgumentException if the dimension is +712 * inconsistent with vector size +713 */ +714 protected void checkVectorDimensions(int n) +715 throws IllegalArgumentException { +716 if (data.length != n) { +717 throw MathRuntimeException.createIllegalArgumentException( +718 "vector length mismatch: got {0} but expected {1}", +719 data.length, n); +720 } +721 } +722 +723 /** +724 * Test for the equality of two real vectors. +725 * <p> +726 * If all coordinates of two real vectors are exactly the same, and none are +727 * <code>Double.NaN</code>, the two real vectors are considered to be equal. +728 * </p> +729 * <p> +730 * <code>NaN</code> coordinates are considered to affect globally the vector +731 * and be equals to each other - i.e, if either (or all) coordinates of the +732 * real vector are equal to <code>Double.NaN</code>, the real vector is equal to +733 * a vector with all <code>Double.NaN</code> coordinates. +734 * </p> +735 * +736 * @param other Object to test for equality to this +737 * @return true if two 3D vector objects are equal, false if +738 * object is null, not an instance of Vector3D, or +739 * not equal to this Vector3D instance +740 * +741 */ +742 @Override +743 public boolean equals(Object other) { +744 +745 if (this == other) { +746 return true; +747 } +748 +749 if (other == null) { +750 return false; +751 } +752 +753 try { +754 @SuppressWarnings("unchecked") // May fail, but we ignore ClassCastException +755 FieldVector<T> rhs = (FieldVector<T>) other; +756 if (data.length != rhs.getDimension()) { +757 return false; +758 } +759 +760 for (int i = 0; i < data.length; ++i) { +761 if (!data[i].equals(rhs.getEntry(i))) { +762 return false; +763 } +764 } +765 return true; +766 +767 } catch (ClassCastException ex) { +768 // ignore exception +769 return false; +770 } +771 +772 } +773 +774 /** +775 * Get a hashCode for the real vector. +776 * <p>All NaN values have the same hash code.</p> +777 * @return a hash code value for this object +778 */ +779 @Override +780 public int hashCode() { +781 int h = 3542; +782 for (final T a : data) { +783 h = h ^ a.hashCode(); +784 } +785 return h; +786 } +787 +788 /** +789 * Check if an index is valid. +790 * @param index index to check +791 * @exception MatrixIndexException if index is not valid +792 */ +793 private void checkIndex(final int index) +794 throws MatrixIndexException { +795 if (index < 0 || index >= getDimension()) { +796 throw new MatrixIndexException( +797 "index {0} out of allowed range [{1}, {2}]", +798 index, 0, getDimension() - 1); +799 } +800 } +801 +802 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/ArrayRealVector.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/ArrayRealVector.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1305 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.linear; +018 +019 import java.io.Serializable; +020 import java.util.Arrays; +021 import java.util.Iterator; +022 +023 import org.apache.commons.math.MathRuntimeException; +024 import org.apache.commons.math.util.MathUtils; +025 +026 /** +027 * This class implements the {@link RealVector} interface with a double array. +028 * @version $Revision: 902203 $ $Date: 2010-01-22 13:27:41 -0500 (Fri, 22 Jan 2010) $ +029 * @since 2.0 +030 */ +031 public class ArrayRealVector extends AbstractRealVector implements Serializable { +032 +033 /** Message for non fitting position and size. */ +034 private static final String NON_FITTING_POSITION_AND_SIZE_MESSAGE = +035 "position {0} and size {1} don't fit to the size of the input array {2}"; +036 +037 /** Serializable version identifier. */ +038 private static final long serialVersionUID = -1097961340710804027L; +039 +040 /** Default format. */ +041 private static final RealVectorFormat DEFAULT_FORMAT = +042 RealVectorFormat.getInstance(); +043 +044 /** Entries of the vector. */ +045 protected double data[]; +046 +047 /** +048 * Build a 0-length vector. +049 * <p>Zero-length vectors may be used to initialized construction of vectors +050 * by data gathering. We start with zero-length and use either the {@link +051 * #ArrayRealVector(ArrayRealVector, ArrayRealVector)} constructor +052 * or one of the <code>append</code> method ({@link #append(double)}, {@link +053 * #append(double[])}, {@link #append(ArrayRealVector)}) to gather data +054 * into this vector.</p> +055 */ +056 public ArrayRealVector() { +057 data = new double[0]; +058 } +059 +060 /** +061 * Construct a (size)-length vector of zeros. +062 * @param size size of the vector +063 */ +064 public ArrayRealVector(int size) { +065 data = new double[size]; +066 } +067 +068 /** +069 * Construct an (size)-length vector with preset values. +070 * @param size size of the vector +071 * @param preset fill the vector with this scalar value +072 */ +073 public ArrayRealVector(int size, double preset) { +074 data = new double[size]; +075 Arrays.fill(data, preset); +076 } +077 +078 /** +079 * Construct a vector from an array, copying the input array. +080 * @param d array of doubles. +081 */ +082 public ArrayRealVector(double[] d) { +083 data = d.clone(); +084 } +085 +086 /** +087 * Create a new ArrayRealVector using the input array as the underlying +088 * data array. +089 * <p>If an array is built specially in order to be embedded in a +090 * ArrayRealVector and not used directly, the <code>copyArray</code> may be +091 * set to <code>false</code. This will prevent the copying and improve +092 * performance as no new array will be built and no data will be copied.</p> +093 * @param d data for new vector +094 * @param copyArray if true, the input array will be copied, otherwise +095 * it will be referenced +096 * @throws IllegalArgumentException if <code>d</code> is empty +097 * @throws NullPointerException if <code>d</code> is null +098 * @see #ArrayRealVector(double[]) +099 */ +100 public ArrayRealVector(double[] d, boolean copyArray) +101 throws NullPointerException, IllegalArgumentException { +102 if (d == null) { +103 throw new NullPointerException(); +104 } +105 if (d.length == 0) { +106 throw MathRuntimeException.createIllegalArgumentException("vector must have at least one element"); +107 } +108 data = copyArray ? d.clone() : d; +109 } +110 +111 /** +112 * Construct a vector from part of a array. +113 * @param d array of doubles. +114 * @param pos position of first entry +115 * @param size number of entries to copy +116 */ +117 public ArrayRealVector(double[] d, int pos, int size) { +118 if (d.length < pos + size) { +119 throw MathRuntimeException.createIllegalArgumentException( +120 NON_FITTING_POSITION_AND_SIZE_MESSAGE, pos, size, d.length); +121 } +122 data = new double[size]; +123 System.arraycopy(d, pos, data, 0, size); +124 } +125 +126 /** +127 * Construct a vector from an array. +128 * @param d array of Doubles. +129 */ +130 public ArrayRealVector(Double[] d) { +131 data = new double[d.length]; +132 for (int i = 0; i < d.length; i++) { +133 data[i] = d[i].doubleValue(); +134 } +135 } +136 +137 /** +138 * Construct a vector from part of a Double array +139 * @param d array of Doubles. +140 * @param pos position of first entry +141 * @param size number of entries to copy +142 */ +143 public ArrayRealVector(Double[] d, int pos, int size) { +144 if (d.length < pos + size) { +145 throw MathRuntimeException.createIllegalArgumentException( +146 NON_FITTING_POSITION_AND_SIZE_MESSAGE, pos, size, d.length); +147 } +148 data = new double[size]; +149 for (int i = pos; i < pos + size; i++) { +150 data[i-pos] = d[i].doubleValue(); +151 } +152 } +153 +154 /** +155 * Construct a vector from another vector, using a deep copy. +156 * @param v vector to copy +157 */ +158 public ArrayRealVector(RealVector v) { +159 data = new double[v.getDimension()]; +160 for (int i = 0; i < data.length; ++i) { +161 data[i] = v.getEntry(i); +162 } +163 } +164 +165 /** +166 * Construct a vector from another vector, using a deep copy. +167 * @param v vector to copy +168 */ +169 public ArrayRealVector(ArrayRealVector v) { +170 this(v, true); +171 } +172 +173 /** +174 * Construct a vector from another vector. +175 * @param v vector to copy +176 * @param deep if true perform a deep copy otherwise perform a shallow copy +177 */ +178 public ArrayRealVector(ArrayRealVector v, boolean deep) { +179 data = deep ? v.data.clone() : v.data; +180 } +181 +182 /** +183 * Construct a vector by appending one vector to another vector. +184 * @param v1 first vector (will be put in front of the new vector) +185 * @param v2 second vector (will be put at back of the new vector) +186 */ +187 public ArrayRealVector(ArrayRealVector v1, ArrayRealVector v2) { +188 data = new double[v1.data.length + v2.data.length]; +189 System.arraycopy(v1.data, 0, data, 0, v1.data.length); +190 System.arraycopy(v2.data, 0, data, v1.data.length, v2.data.length); +191 } +192 +193 /** +194 * Construct a vector by appending one vector to another vector. +195 * @param v1 first vector (will be put in front of the new vector) +196 * @param v2 second vector (will be put at back of the new vector) +197 */ +198 public ArrayRealVector(ArrayRealVector v1, RealVector v2) { +199 final int l1 = v1.data.length; +200 final int l2 = v2.getDimension(); +201 data = new double[l1 + l2]; +202 System.arraycopy(v1.data, 0, data, 0, l1); +203 for (int i = 0; i < l2; ++i) { +204 data[l1 + i] = v2.getEntry(i); +205 } +206 } +207 +208 /** +209 * Construct a vector by appending one vector to another vector. +210 * @param v1 first vector (will be put in front of the new vector) +211 * @param v2 second vector (will be put at back of the new vector) +212 */ +213 public ArrayRealVector(RealVector v1, ArrayRealVector v2) { +214 final int l1 = v1.getDimension(); +215 final int l2 = v2.data.length; +216 data = new double[l1 + l2]; +217 for (int i = 0; i < l1; ++i) { +218 data[i] = v1.getEntry(i); +219 } +220 System.arraycopy(v2.data, 0, data, l1, l2); +221 } +222 +223 /** +224 * Construct a vector by appending one vector to another vector. +225 * @param v1 first vector (will be put in front of the new vector) +226 * @param v2 second vector (will be put at back of the new vector) +227 */ +228 public ArrayRealVector(ArrayRealVector v1, double[] v2) { +229 final int l1 = v1.getDimension(); +230 final int l2 = v2.length; +231 data = new double[l1 + l2]; +232 System.arraycopy(v1.data, 0, data, 0, l1); +233 System.arraycopy(v2, 0, data, l1, l2); +234 } +235 +236 /** +237 * Construct a vector by appending one vector to another vector. +238 * @param v1 first vector (will be put in front of the new vector) +239 * @param v2 second vector (will be put at back of the new vector) +240 */ +241 public ArrayRealVector(double[] v1, ArrayRealVector v2) { +242 final int l1 = v1.length; +243 final int l2 = v2.getDimension(); +244 data = new double[l1 + l2]; +245 System.arraycopy(v1, 0, data, 0, l1); +246 System.arraycopy(v2.data, 0, data, l1, l2); +247 } +248 +249 /** +250 * Construct a vector by appending one vector to another vector. +251 * @param v1 first vector (will be put in front of the new vector) +252 * @param v2 second vector (will be put at back of the new vector) +253 */ +254 public ArrayRealVector(double[] v1, double[] v2) { +255 final int l1 = v1.length; +256 final int l2 = v2.length; +257 data = new double[l1 + l2]; +258 System.arraycopy(v1, 0, data, 0, l1); +259 System.arraycopy(v2, 0, data, l1, l2); +260 } +261 +262 /** {@inheritDoc} */ +263 @Override +264 public AbstractRealVector copy() { +265 return new ArrayRealVector(this, true); +266 } +267 +268 /** {@inheritDoc} */ +269 @Override +270 public RealVector add(RealVector v) +271 throws IllegalArgumentException { +272 if (v instanceof ArrayRealVector) { +273 return add((ArrayRealVector) v); +274 } else { +275 checkVectorDimensions(v); +276 double[] out = data.clone(); +277 Iterator<Entry> it = v.sparseIterator(); +278 Entry e; +279 while (it.hasNext() && (e = it.next()) != null) { +280 out[e.getIndex()] += e.getValue(); +281 } +282 return new ArrayRealVector(out, false); +283 } +284 } +285 +286 /** {@inheritDoc} */ +287 @Override +288 public RealVector add(double[] v) +289 throws IllegalArgumentException { +290 checkVectorDimensions(v.length); +291 double[] out = data.clone(); +292 for (int i = 0; i < data.length; i++) { +293 out[i] += v[i]; +294 } +295 return new ArrayRealVector(out, false); +296 } +297 +298 /** +299 * Compute the sum of this and v. +300 * @param v vector to be added +301 * @return this + v +302 * @throws IllegalArgumentException if v is not the same size as this +303 */ +304 public ArrayRealVector add(ArrayRealVector v) +305 throws IllegalArgumentException { +306 return (ArrayRealVector) add(v.data); +307 } +308 +309 /** {@inheritDoc} */ +310 @Override +311 public RealVector subtract(RealVector v) +312 throws IllegalArgumentException { +313 if (v instanceof ArrayRealVector) { +314 return subtract((ArrayRealVector) v); +315 } else { +316 checkVectorDimensions(v); +317 double[] out = data.clone(); +318 Iterator<Entry> it = v.sparseIterator(); +319 Entry e; +320 while(it.hasNext() && (e = it.next()) != null) { +321 out[e.getIndex()] -= e.getValue(); +322 } +323 return new ArrayRealVector(out, false); +324 } +325 } +326 +327 /** {@inheritDoc} */ +328 @Override +329 public RealVector subtract(double[] v) +330 throws IllegalArgumentException { +331 checkVectorDimensions(v.length); +332 double[] out = data.clone(); +333 for (int i = 0; i < data.length; i++) { +334 out[i] -= v[i]; +335 } +336 return new ArrayRealVector(out, false); +337 } +338 +339 /** +340 * Compute this minus v. +341 * @param v vector to be subtracted +342 * @return this + v +343 * @throws IllegalArgumentException if v is not the same size as this +344 */ +345 public ArrayRealVector subtract(ArrayRealVector v) +346 throws IllegalArgumentException { +347 return (ArrayRealVector) subtract(v.data); +348 } +349 +350 /** {@inheritDoc} */ +351 @Override +352 public RealVector mapAddToSelf(double d) { +353 for (int i = 0; i < data.length; i++) { +354 data[i] = data[i] + d; +355 } +356 return this; +357 } +358 +359 /** {@inheritDoc} */ +360 @Override +361 public RealVector mapSubtractToSelf(double d) { +362 for (int i = 0; i < data.length; i++) { +363 data[i] = data[i] - d; +364 } +365 return this; +366 } +367 +368 /** {@inheritDoc} */ +369 @Override +370 public RealVector mapMultiplyToSelf(double d) { +371 for (int i = 0; i < data.length; i++) { +372 data[i] = data[i] * d; +373 } +374 return this; +375 } +376 +377 /** {@inheritDoc} */ +378 @Override +379 public RealVector mapDivideToSelf(double d) { +380 for (int i = 0; i < data.length; i++) { +381 data[i] = data[i] / d; +382 } +383 return this; +384 } +385 +386 /** {@inheritDoc} */ +387 @Override +388 public RealVector mapPowToSelf(double d) { +389 for (int i = 0; i < data.length; i++) { +390 data[i] = Math.pow(data[i], d); +391 } +392 return this; +393 } +394 +395 /** {@inheritDoc} */ +396 @Override +397 public RealVector mapExpToSelf() { +398 for (int i = 0; i < data.length; i++) { +399 data[i] = Math.exp(data[i]); +400 } +401 return this; +402 } +403 +404 /** {@inheritDoc} */ +405 @Override +406 public RealVector mapExpm1ToSelf() { +407 for (int i = 0; i < data.length; i++) { +408 data[i] = Math.expm1(data[i]); +409 } +410 return this; +411 } +412 +413 /** {@inheritDoc} */ +414 @Override +415 public RealVector mapLogToSelf() { +416 for (int i = 0; i < data.length; i++) { +417 data[i] = Math.log(data[i]); +418 } +419 return this; +420 } +421 +422 /** {@inheritDoc} */ +423 @Override +424 public RealVector mapLog10ToSelf() { +425 for (int i = 0; i < data.length; i++) { +426 data[i] = Math.log10(data[i]); +427 } +428 return this; +429 } +430 +431 /** {@inheritDoc} */ +432 @Override +433 public RealVector mapLog1pToSelf() { +434 for (int i = 0; i < data.length; i++) { +435 data[i] = Math.log1p(data[i]); +436 } +437 return this; +438 } +439 +440 /** {@inheritDoc} */ +441 @Override +442 public RealVector mapCoshToSelf() { +443 for (int i = 0; i < data.length; i++) { +444 data[i] = Math.cosh(data[i]); +445 } +446 return this; +447 } +448 +449 /** {@inheritDoc} */ +450 @Override +451 public RealVector mapSinhToSelf() { +452 for (int i = 0; i < data.length; i++) { +453 data[i] = Math.sinh(data[i]); +454 } +455 return this; +456 } +457 +458 /** {@inheritDoc} */ +459 @Override +460 public RealVector mapTanhToSelf() { +461 for (int i = 0; i < data.length; i++) { +462 data[i] = Math.tanh(data[i]); +463 } +464 return this; +465 } +466 +467 /** {@inheritDoc} */ +468 @Override +469 public RealVector mapCosToSelf() { +470 for (int i = 0; i < data.length; i++) { +471 data[i] = Math.cos(data[i]); +472 } +473 return this; +474 } +475 +476 /** {@inheritDoc} */ +477 @Override +478 public RealVector mapSinToSelf() { +479 for (int i = 0; i < data.length; i++) { +480 data[i] = Math.sin(data[i]); +481 } +482 return this; +483 } +484 +485 /** {@inheritDoc} */ +486 @Override +487 public RealVector mapTanToSelf() { +488 for (int i = 0; i < data.length; i++) { +489 data[i] = Math.tan(data[i]); +490 } +491 return this; +492 } +493 +494 /** {@inheritDoc} */ +495 @Override +496 public RealVector mapAcosToSelf() { +497 for (int i = 0; i < data.length; i++) { +498 data[i] = Math.acos(data[i]); +499 } +500 return this; +501 } +502 +503 /** {@inheritDoc} */ +504 @Override +505 public RealVector mapAsinToSelf() { +506 for (int i = 0; i < data.length; i++) { +507 data[i] = Math.asin(data[i]); +508 } +509 return this; +510 } +511 +512 /** {@inheritDoc} */ +513 @Override +514 public RealVector mapAtanToSelf() { +515 for (int i = 0; i < data.length; i++) { +516 data[i] = Math.atan(data[i]); +517 } +518 return this; +519 } +520 +521 /** {@inheritDoc} */ +522 @Override +523 public RealVector mapInvToSelf() { +524 for (int i = 0; i < data.length; i++) { +525 data[i] = 1.0 / data[i]; +526 } +527 return this; +528 } +529 +530 /** {@inheritDoc} */ +531 @Override +532 public RealVector mapAbsToSelf() { +533 for (int i = 0; i < data.length; i++) { +534 data[i] = Math.abs(data[i]); +535 } +536 return this; +537 } +538 +539 /** {@inheritDoc} */ +540 @Override +541 public RealVector mapSqrtToSelf() { +542 for (int i = 0; i < data.length; i++) { +543 data[i] = Math.sqrt(data[i]); +544 } +545 return this; +546 } +547 +548 /** {@inheritDoc} */ +549 @Override +550 public RealVector mapCbrtToSelf() { +551 for (int i = 0; i < data.length; i++) { +552 data[i] = Math.cbrt(data[i]); +553 } +554 return this; +555 } +556 +557 /** {@inheritDoc} */ +558 @Override +559 public RealVector mapCeilToSelf() { +560 for (int i = 0; i < data.length; i++) { +561 data[i] = Math.ceil(data[i]); +562 } +563 return this; +564 } +565 +566 /** {@inheritDoc} */ +567 @Override +568 public RealVector mapFloorToSelf() { +569 for (int i = 0; i < data.length; i++) { +570 data[i] = Math.floor(data[i]); +571 } +572 return this; +573 } +574 +575 /** {@inheritDoc} */ +576 @Override +577 public RealVector mapRintToSelf() { +578 for (int i = 0; i < data.length; i++) { +579 data[i] = Math.rint(data[i]); +580 } +581 return this; +582 } +583 +584 /** {@inheritDoc} */ +585 @Override +586 public RealVector mapSignumToSelf() { +587 for (int i = 0; i < data.length; i++) { +588 data[i] = Math.signum(data[i]); +589 } +590 return this; +591 } +592 +593 /** {@inheritDoc} */ +594 @Override +595 public RealVector mapUlpToSelf() { +596 for (int i = 0; i < data.length; i++) { +597 data[i] = Math.ulp(data[i]); +598 } +599 return this; +600 } +601 +602 /** {@inheritDoc} */ +603 public RealVector ebeMultiply(RealVector v) +604 throws IllegalArgumentException { +605 if (v instanceof ArrayRealVector) { +606 return ebeMultiply((ArrayRealVector) v); +607 } else { +608 checkVectorDimensions(v); +609 double[] out = data.clone(); +610 for (int i = 0; i < data.length; i++) { +611 out[i] *= v.getEntry(i); +612 } +613 return new ArrayRealVector(out, false); +614 } +615 } +616 +617 /** {@inheritDoc} */ +618 @Override +619 public RealVector ebeMultiply(double[] v) +620 throws IllegalArgumentException { +621 checkVectorDimensions(v.length); +622 double[] out = data.clone(); +623 for (int i = 0; i < data.length; i++) { +624 out[i] *= v[i]; +625 } +626 return new ArrayRealVector(out, false); +627 } +628 +629 /** +630 * Element-by-element multiplication. +631 * @param v vector by which instance elements must be multiplied +632 * @return a vector containing this[i] * v[i] for all i +633 * @exception IllegalArgumentException if v is not the same size as this +634 */ +635 public ArrayRealVector ebeMultiply(ArrayRealVector v) +636 throws IllegalArgumentException { +637 return (ArrayRealVector) ebeMultiply(v.data); +638 } +639 +640 /** {@inheritDoc} */ +641 public RealVector ebeDivide(RealVector v) +642 throws IllegalArgumentException { +643 if (v instanceof ArrayRealVector) { +644 return ebeDivide((ArrayRealVector) v); +645 } else { +646 checkVectorDimensions(v); +647 double[] out = data.clone(); +648 for (int i = 0; i < data.length; i++) { +649 out[i] /= v.getEntry(i); +650 } +651 return new ArrayRealVector(out, false); +652 } +653 } +654 +655 /** {@inheritDoc} */ +656 @Override +657 public RealVector ebeDivide(double[] v) +658 throws IllegalArgumentException { +659 checkVectorDimensions(v.length); +660 double[] out = data.clone(); +661 for (int i = 0; i < data.length; i++) { +662 out[i] /= v[i]; +663 } +664 return new ArrayRealVector(out, false); +665 } +666 +667 /** +668 * Element-by-element division. +669 * @param v vector by which instance elements must be divided +670 * @return a vector containing this[i] / v[i] for all i +671 * @throws IllegalArgumentException if v is not the same size as this +672 */ +673 public ArrayRealVector ebeDivide(ArrayRealVector v) +674 throws IllegalArgumentException { +675 return (ArrayRealVector) ebeDivide(v.data); +676 } +677 +678 /** {@inheritDoc} */ +679 @Override +680 public double[] getData() { +681 return data.clone(); +682 } +683 +684 /** +685 * Returns a reference to the underlying data array. +686 * <p>Does not make a fresh copy of the underlying data.</p> +687 * @return array of entries +688 */ +689 public double[] getDataRef() { +690 return data; +691 } +692 +693 /** {@inheritDoc} */ +694 @Override +695 public double dotProduct(RealVector v) +696 throws IllegalArgumentException { +697 if (v instanceof ArrayRealVector) { +698 return dotProduct((ArrayRealVector) v); +699 } else { +700 checkVectorDimensions(v); +701 double dot = 0; +702 Iterator<Entry> it = v.sparseIterator(); +703 Entry e; +704 while(it.hasNext() && (e = it.next()) != null) { +705 dot += data[e.getIndex()] * e.getValue(); +706 } +707 return dot; +708 } +709 } +710 +711 /** {@inheritDoc} */ +712 @Override +713 public double dotProduct(double[] v) +714 throws IllegalArgumentException { +715 checkVectorDimensions(v.length); +716 double dot = 0; +717 for (int i = 0; i < data.length; i++) { +718 dot += data[i] * v[i]; +719 } +720 return dot; +721 } +722 +723 /** +724 * Compute the dot product. +725 * @param v vector with which dot product should be computed +726 * @return the scalar dot product between instance and v +727 * @exception IllegalArgumentException if v is not the same size as this +728 */ +729 public double dotProduct(ArrayRealVector v) +730 throws IllegalArgumentException { +731 return dotProduct(v.data); +732 } +733 +734 /** {@inheritDoc} */ +735 @Override +736 public double getNorm() { +737 double sum = 0; +738 for (double a : data) { +739 sum += a * a; +740 } +741 return Math.sqrt(sum); +742 } +743 +744 /** {@inheritDoc} */ +745 @Override +746 public double getL1Norm() { +747 double sum = 0; +748 for (double a : data) { +749 sum += Math.abs(a); +750 } +751 return sum; +752 } +753 +754 /** {@inheritDoc} */ +755 @Override +756 public double getLInfNorm() { +757 double max = 0; +758 for (double a : data) { +759 max = Math.max(max, Math.abs(a)); +760 } +761 return max; +762 } +763 +764 /** {@inheritDoc} */ +765 @Override +766 public double getDistance(RealVector v) +767 throws IllegalArgumentException { +768 if (v instanceof ArrayRealVector) { +769 return getDistance((ArrayRealVector) v); +770 } else { +771 checkVectorDimensions(v); +772 double sum = 0; +773 for (int i = 0; i < data.length; ++i) { +774 final double delta = data[i] - v.getEntry(i); +775 sum += delta * delta; +776 } +777 return Math.sqrt(sum); +778 } +779 } +780 +781 /** {@inheritDoc} */ +782 @Override +783 public double getDistance(double[] v) +784 throws IllegalArgumentException { +785 checkVectorDimensions(v.length); +786 double sum = 0; +787 for (int i = 0; i < data.length; ++i) { +788 final double delta = data[i] - v[i]; +789 sum += delta * delta; +790 } +791 return Math.sqrt(sum); +792 } +793 +794 /** +795 * Distance between two vectors. +796 * <p>This method computes the distance consistent with the +797 * L<sub>2</sub> norm, i.e. the square root of the sum of +798 * elements differences, or euclidian distance.</p> +799 * @param v vector to which distance is requested +800 * @return distance between two vectors. +801 * @exception IllegalArgumentException if v is not the same size as this +802 * @see #getDistance(RealVector) +803 * @see #getL1Distance(ArrayRealVector) +804 * @see #getLInfDistance(ArrayRealVector) +805 * @see #getNorm() +806 */ +807 public double getDistance(ArrayRealVector v) +808 throws IllegalArgumentException { +809 return getDistance(v.data); +810 } +811 +812 /** {@inheritDoc} */ +813 @Override +814 public double getL1Distance(RealVector v) +815 throws IllegalArgumentException { +816 if (v instanceof ArrayRealVector) { +817 return getL1Distance((ArrayRealVector) v); +818 } else { +819 checkVectorDimensions(v); +820 double sum = 0; +821 for (int i = 0; i < data.length; ++i) { +822 final double delta = data[i] - v.getEntry(i); +823 sum += Math.abs(delta); +824 } +825 return sum; +826 } +827 } +828 +829 /** {@inheritDoc} */ +830 @Override +831 public double getL1Distance(double[] v) +832 throws IllegalArgumentException { +833 checkVectorDimensions(v.length); +834 double sum = 0; +835 for (int i = 0; i < data.length; ++i) { +836 final double delta = data[i] - v[i]; +837 sum += Math.abs(delta); +838 } +839 return sum; +840 } +841 +842 /** +843 * Distance between two vectors. +844 * <p>This method computes the distance consistent with +845 * L<sub>1</sub> norm, i.e. the sum of the absolute values of +846 * elements differences.</p> +847 * @param v vector to which distance is requested +848 * @return distance between two vectors. +849 * @exception IllegalArgumentException if v is not the same size as this +850 * @see #getDistance(RealVector) +851 * @see #getL1Distance(ArrayRealVector) +852 * @see #getLInfDistance(ArrayRealVector) +853 * @see #getNorm() +854 */ +855 public double getL1Distance(ArrayRealVector v) +856 throws IllegalArgumentException { +857 return getL1Distance(v.data); +858 } +859 +860 /** {@inheritDoc} */ +861 @Override +862 public double getLInfDistance(RealVector v) +863 throws IllegalArgumentException { +864 if (v instanceof ArrayRealVector) { +865 return getLInfDistance((ArrayRealVector) v); +866 } else { +867 checkVectorDimensions(v); +868 double max = 0; +869 for (int i = 0; i < data.length; ++i) { +870 final double delta = data[i] - v.getEntry(i); +871 max = Math.max(max, Math.abs(delta)); +872 } +873 return max; +874 } +875 } +876 +877 /** {@inheritDoc} */ +878 @Override +879 public double getLInfDistance(double[] v) +880 throws IllegalArgumentException { +881 checkVectorDimensions(v.length); +882 double max = 0; +883 for (int i = 0; i < data.length; ++i) { +884 final double delta = data[i] - v[i]; +885 max = Math.max(max, Math.abs(delta)); +886 } +887 return max; +888 } +889 +890 /** +891 * Distance between two vectors. +892 * <p>This method computes the distance consistent with +893 * L<sub>∞</sub> norm, i.e. the max of the absolute values of +894 * elements differences.</p> +895 * @param v vector to which distance is requested +896 * @return distance between two vectors. +897 * @exception IllegalArgumentException if v is not the same size as this +898 * @see #getDistance(RealVector) +899 * @see #getL1Distance(ArrayRealVector) +900 * @see #getLInfDistance(ArrayRealVector) +901 * @see #getNorm() +902 */ +903 public double getLInfDistance(ArrayRealVector v) +904 throws IllegalArgumentException { +905 return getLInfDistance(v.data); +906 } +907 +908 /** {@inheritDoc} */ +909 @Override +910 public RealVector unitVector() throws ArithmeticException { +911 final double norm = getNorm(); +912 if (norm == 0) { +913 throw MathRuntimeException.createArithmeticException("zero norm"); +914 } +915 return mapDivide(norm); +916 } +917 +918 /** {@inheritDoc} */ +919 @Override +920 public void unitize() throws ArithmeticException { +921 final double norm = getNorm(); +922 if (norm == 0) { +923 throw MathRuntimeException.createArithmeticException("cannot normalize a zero norm vector"); +924 } +925 mapDivideToSelf(norm); +926 } +927 +928 /** {@inheritDoc} */ +929 public RealVector projection(RealVector v) { +930 return v.mapMultiply(dotProduct(v) / v.dotProduct(v)); +931 } +932 +933 /** {@inheritDoc} */ +934 @Override +935 public RealVector projection(double[] v) { +936 return projection(new ArrayRealVector(v, false)); +937 } +938 +939 /** Find the orthogonal projection of this vector onto another vector. +940 * @param v vector onto which instance must be projected +941 * @return projection of the instance onto v +942 * @throws IllegalArgumentException if v is not the same size as this +943 */ +944 public ArrayRealVector projection(ArrayRealVector v) { +945 return (ArrayRealVector) v.mapMultiply(dotProduct(v) / v.dotProduct(v)); +946 } +947 +948 /** {@inheritDoc} */ +949 @Override +950 public RealMatrix outerProduct(RealVector v) +951 throws IllegalArgumentException { +952 if (v instanceof ArrayRealVector) { +953 return outerProduct((ArrayRealVector) v); +954 } else { +955 checkVectorDimensions(v); +956 final int m = data.length; +957 final RealMatrix out = MatrixUtils.createRealMatrix(m, m); +958 for (int i = 0; i < data.length; i++) { +959 for (int j = 0; j < data.length; j++) { +960 out.setEntry(i, j, data[i] * v.getEntry(j)); +961 } +962 } +963 return out; +964 } +965 } +966 +967 /** +968 * Compute the outer product. +969 * @param v vector with which outer product should be computed +970 * @return the square matrix outer product between instance and v +971 * @exception IllegalArgumentException if v is not the same size as this +972 */ +973 public RealMatrix outerProduct(ArrayRealVector v) +974 throws IllegalArgumentException { +975 return outerProduct(v.data); +976 } +977 +978 /** {@inheritDoc} */ +979 @Override +980 public RealMatrix outerProduct(double[] v) +981 throws IllegalArgumentException { +982 checkVectorDimensions(v.length); +983 final int m = data.length; +984 final RealMatrix out = MatrixUtils.createRealMatrix(m, m); +985 for (int i = 0; i < data.length; i++) { +986 for (int j = 0; j < data.length; j++) { +987 out.setEntry(i, j, data[i] * v[j]); +988 } +989 } +990 return out; +991 } +992 +993 /** {@inheritDoc} */ +994 public double getEntry(int index) throws MatrixIndexException { +995 return data[index]; +996 } +997 +998 /** {@inheritDoc} */ +999 public int getDimension() { +1000 return data.length; +1001 } +1002 +1003 /** {@inheritDoc} */ +1004 public RealVector append(RealVector v) { +1005 try { +1006 return new ArrayRealVector(this, (ArrayRealVector) v); +1007 } catch (ClassCastException cce) { +1008 return new ArrayRealVector(this, v); +1009 } +1010 } +1011 +1012 /** +1013 * Construct a vector by appending a vector to this vector. +1014 * @param v vector to append to this one. +1015 * @return a new vector +1016 */ +1017 public ArrayRealVector append(ArrayRealVector v) { +1018 return new ArrayRealVector(this, v); +1019 } +1020 +1021 /** {@inheritDoc} */ +1022 public RealVector append(double in) { +1023 final double[] out = new double[data.length + 1]; +1024 System.arraycopy(data, 0, out, 0, data.length); +1025 out[data.length] = in; +1026 return new ArrayRealVector(out, false); +1027 } +1028 +1029 /** {@inheritDoc} */ +1030 public RealVector append(double[] in) { +1031 return new ArrayRealVector(this, in); +1032 } +1033 +1034 /** {@inheritDoc} */ +1035 public RealVector getSubVector(int index, int n) { +1036 ArrayRealVector out = new ArrayRealVector(n); +1037 try { +1038 System.arraycopy(data, index, out.data, 0, n); +1039 } catch (IndexOutOfBoundsException e) { +1040 checkIndex(index); +1041 checkIndex(index + n - 1); +1042 } +1043 return out; +1044 } +1045 +1046 /** {@inheritDoc} */ +1047 public void setEntry(int index, double value) { +1048 try { +1049 data[index] = value; +1050 } catch (IndexOutOfBoundsException e) { +1051 checkIndex(index); +1052 } +1053 } +1054 +1055 /** {@inheritDoc} */ +1056 @Override +1057 public void setSubVector(int index, RealVector v) { +1058 try { +1059 try { +1060 set(index, (ArrayRealVector) v); +1061 } catch (ClassCastException cce) { +1062 for (int i = index; i < index + v.getDimension(); ++i) { +1063 data[i] = v.getEntry(i-index); +1064 } +1065 } +1066 } catch (IndexOutOfBoundsException e) { +1067 checkIndex(index); +1068 checkIndex(index + v.getDimension() - 1); +1069 } +1070 } +1071 +1072 /** {@inheritDoc} */ +1073 @Override +1074 public void setSubVector(int index, double[] v) { +1075 try { +1076 System.arraycopy(v, 0, data, index, v.length); +1077 } catch (IndexOutOfBoundsException e) { +1078 checkIndex(index); +1079 checkIndex(index + v.length - 1); +1080 } +1081 } +1082 +1083 /** +1084 * Set a set of consecutive elements. +1085 * +1086 * @param index index of first element to be set. +1087 * @param v vector containing the values to set. +1088 * @exception MatrixIndexException if the index is +1089 * inconsistent with vector size +1090 */ +1091 public void set(int index, ArrayRealVector v) +1092 throws MatrixIndexException { +1093 setSubVector(index, v.data); +1094 } +1095 +1096 /** {@inheritDoc} */ +1097 @Override +1098 public void set(double value) { +1099 Arrays.fill(data, value); +1100 } +1101 +1102 /** {@inheritDoc} */ +1103 @Override +1104 public double[] toArray(){ +1105 return data.clone(); +1106 } +1107 +1108 /** {@inheritDoc} */ +1109 @Override +1110 public String toString(){ +1111 return DEFAULT_FORMAT.format(this); +1112 } +1113 +1114 /** +1115 * Check if instance and specified vectors have the same dimension. +1116 * @param v vector to compare instance with +1117 * @exception IllegalArgumentException if the vectors do not +1118 * have the same dimension +1119 */ +1120 @Override +1121 protected void checkVectorDimensions(RealVector v) +1122 throws IllegalArgumentException { +1123 checkVectorDimensions(v.getDimension()); +1124 } +1125 +1126 /** +1127 * Check if instance dimension is equal to some expected value. +1128 * +1129 * @param n expected dimension. +1130 * @exception IllegalArgumentException if the dimension is +1131 * inconsistent with vector size +1132 */ +1133 @Override +1134 protected void checkVectorDimensions(int n) +1135 throws IllegalArgumentException { +1136 if (data.length != n) { +1137 throw MathRuntimeException.createIllegalArgumentException( +1138 "vector length mismatch: got {0} but expected {1}", +1139 data.length, n); +1140 } +1141 } +1142 +1143 /** +1144 * Returns true if any coordinate of this vector is NaN; false otherwise +1145 * @return true if any coordinate of this vector is NaN; false otherwise +1146 */ +1147 public boolean isNaN() { +1148 for (double v : data) { +1149 if (Double.isNaN(v)) { +1150 return true; +1151 } +1152 } +1153 return false; +1154 } +1155 +1156 /** +1157 * Returns true if any coordinate of this vector is infinite and none are NaN; +1158 * false otherwise +1159 * @return true if any coordinate of this vector is infinite and none are NaN; +1160 * false otherwise +1161 */ +1162 public boolean isInfinite() { +1163 +1164 if (isNaN()) { +1165 return false; +1166 } +1167 +1168 for (double v : data) { +1169 if (Double.isInfinite(v)) { +1170 return true; +1171 } +1172 } +1173 +1174 return false; +1175 +1176 } +1177 +1178 /** +1179 * Test for the equality of two real vectors. +1180 * <p> +1181 * If all coordinates of two real vectors are exactly the same, and none are +1182 * <code>Double.NaN</code>, the two real vectors are considered to be equal. +1183 * </p> +1184 * <p> +1185 * <code>NaN</code> coordinates are considered to affect globally the vector +1186 * and be equals to each other - i.e, if either (or all) coordinates of the +1187 * real vector are equal to <code>Double.NaN</code>, the real vector is equal to +1188 * a vector with all <code>Double.NaN</code> coordinates. +1189 * </p> +1190 * +1191 * @param other Object to test for equality to this +1192 * @return true if two vector objects are equal, false if +1193 * object is null, not an instance of RealVector, or +1194 * not equal to this RealVector instance +1195 * +1196 */ +1197 @Override +1198 public boolean equals(Object other) { +1199 +1200 if (this == other) { +1201 return true; +1202 } +1203 +1204 if (other == null || !(other instanceof RealVector)) { +1205 return false; +1206 } +1207 +1208 +1209 RealVector rhs = (RealVector) other; +1210 if (data.length != rhs.getDimension()) { +1211 return false; +1212 } +1213 +1214 if (rhs.isNaN()) { +1215 return this.isNaN(); +1216 } +1217 +1218 for (int i = 0; i < data.length; ++i) { +1219 if (data[i] != rhs.getEntry(i)) { +1220 return false; +1221 } +1222 } +1223 return true; +1224 } +1225 +1226 /** +1227 * Get a hashCode for the real vector. +1228 * <p>All NaN values have the same hash code.</p> +1229 * @return a hash code value for this object +1230 */ +1231 @Override +1232 public int hashCode() { +1233 if (isNaN()) { +1234 return 9; +1235 } +1236 return MathUtils.hash(data); +1237 } +1238 +1239 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/BigMatrix.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/BigMatrix.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,397 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.math.BigDecimal; +021 +022 /** +023 * Interface defining a real-valued matrix with basic algebraic operations, using +024 * BigDecimal representations for the entries. +025 * <p> +026 * Matrix element indexing is 0-based -- e.g., <code>getEntry(0, 0)</code> +027 * returns the element in the first row, first column of the matrix.</p> +028 * +029 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +030 * @deprecated as of 2.0, replaced by {@link FieldMatrix} with a {@link +031 * org.apache.commons.math.util.BigReal} parameter +032 */ +033 @Deprecated +034 public interface BigMatrix extends AnyMatrix { +035 +036 /** +037 * Returns a (deep) copy of this. +038 * +039 * @return matrix copy +040 */ +041 BigMatrix copy(); +042 +043 /** +044 * Compute the sum of this and m. +045 * +046 * @param m matrix to be added +047 * @return this + m +048 * @exception IllegalArgumentException if m is not the same size as this +049 */ +050 BigMatrix add(BigMatrix m) throws IllegalArgumentException; +051 +052 /** +053 * Compute this minus m. +054 * +055 * @param m matrix to be subtracted +056 * @return this + m +057 * @exception IllegalArgumentException if m is not the same size as this +058 */ +059 BigMatrix subtract(BigMatrix m) throws IllegalArgumentException; +060 +061 /** +062 * Returns the result of adding d to each entry of this. +063 * +064 * @param d value to be added to each entry +065 * @return d + this +066 */ +067 BigMatrix scalarAdd(BigDecimal d); +068 +069 /** +070 * Returns the result multiplying each entry of this by d. +071 * +072 * @param d value to multiply all entries by +073 * @return d * this +074 */ +075 BigMatrix scalarMultiply(BigDecimal d); +076 +077 /** +078 * Returns the result of postmultiplying this by m. +079 * +080 * @param m matrix to postmultiply by +081 * @return this * m +082 * @throws IllegalArgumentException +083 * if columnDimension(this) != rowDimension(m) +084 */ +085 BigMatrix multiply(BigMatrix m) throws IllegalArgumentException; +086 +087 /** +088 * Returns the result premultiplying this by <code>m</code>. +089 * @param m matrix to premultiply by +090 * @return m * this +091 * @throws IllegalArgumentException +092 * if rowDimension(this) != columnDimension(m) +093 */ +094 BigMatrix preMultiply(BigMatrix m) throws IllegalArgumentException; +095 +096 /** +097 * Returns matrix entries as a two-dimensional array. +098 * +099 * @return 2-dimensional array of entries +100 */ +101 BigDecimal[][] getData(); +102 +103 /** +104 * Returns matrix entries as a two-dimensional array. +105 * +106 * @return 2-dimensional array of entries +107 */ +108 double [][] getDataAsDoubleArray(); +109 +110 /*** +111 * Gets the rounding mode +112 * @return the rounding mode +113 */ +114 int getRoundingMode(); +115 +116 /** +117 * Returns the <a href="http://mathworld.wolfram.com/MaximumAbsoluteRowSumNorm.html"> +118 * maximum absolute row sum norm</a> of the matrix. +119 * +120 * @return norm +121 */ +122 BigDecimal getNorm(); +123 +124 /** +125 * Gets a submatrix. Rows and columns are indicated +126 * counting from 0 to n-1. +127 * +128 * @param startRow Initial row index +129 * @param endRow Final row index +130 * @param startColumn Initial column index +131 * @param endColumn Final column index +132 * @return The subMatrix containing the data of the +133 * specified rows and columns +134 * @exception MatrixIndexException if the indices are not valid +135 */ +136 BigMatrix getSubMatrix(int startRow, int endRow, int startColumn, +137 int endColumn) throws MatrixIndexException; +138 +139 /** +140 * Gets a submatrix. Rows and columns are indicated +141 * counting from 0 to n-1. +142 * +143 * @param selectedRows Array of row indices. +144 * @param selectedColumns Array of column indices. +145 * @return The subMatrix containing the data in the +146 * specified rows and columns +147 * @exception MatrixIndexException if row or column selections are not valid +148 */ +149 BigMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns) +150 throws MatrixIndexException; +151 +152 /** +153 * Returns the entries in row number <code>row</code> +154 * as a row matrix. Row indices start at 0. +155 * +156 * @param row the row to be fetched +157 * @return row matrix +158 * @throws MatrixIndexException if the specified row index is invalid +159 */ +160 BigMatrix getRowMatrix(int row) throws MatrixIndexException; +161 +162 /** +163 * Returns the entries in column number <code>column</code> +164 * as a column matrix. Column indices start at 0. +165 * +166 * @param column the column to be fetched +167 * @return column matrix +168 * @throws MatrixIndexException if the specified column index is invalid +169 */ +170 BigMatrix getColumnMatrix(int column) throws MatrixIndexException; +171 +172 /** +173 * Returns the entries in row number <code>row</code> as an array. +174 * <p> +175 * Row indices start at 0. A <code>MatrixIndexException</code> is thrown +176 * unless <code>0 <= row < rowDimension.</code></p> +177 * +178 * @param row the row to be fetched +179 * @return array of entries in the row +180 * @throws MatrixIndexException if the specified row index is not valid +181 */ +182 BigDecimal[] getRow(int row) throws MatrixIndexException; +183 +184 /** +185 * Returns the entries in row number <code>row</code> as an array +186 * of double values. +187 * <p> +188 * Row indices start at 0. A <code>MatrixIndexException</code> is thrown +189 * unless <code>0 <= row < rowDimension.</code></p> +190 * +191 * @param row the row to be fetched +192 * @return array of entries in the row +193 * @throws MatrixIndexException if the specified row index is not valid +194 */ +195 double [] getRowAsDoubleArray(int row) throws MatrixIndexException; +196 +197 /** +198 * Returns the entries in column number <code>col</code> as an array. +199 * <p> +200 * Column indices start at 0. A <code>MatrixIndexException</code> is thrown +201 * unless <code>0 <= column < columnDimension.</code></p> +202 * +203 * @param col the column to be fetched +204 * @return array of entries in the column +205 * @throws MatrixIndexException if the specified column index is not valid +206 */ +207 BigDecimal[] getColumn(int col) throws MatrixIndexException; +208 +209 /** +210 * Returns the entries in column number <code>col</code> as an array +211 * of double values. +212 * <p> +213 * Column indices start at 0. A <code>MatrixIndexException</code> is thrown +214 * unless <code>0 <= column < columnDimension.</code></p> +215 * +216 * @param col the column to be fetched +217 * @return array of entries in the column +218 * @throws MatrixIndexException if the specified column index is not valid +219 */ +220 double [] getColumnAsDoubleArray(int col) throws MatrixIndexException; +221 +222 /** +223 * Returns the entry in the specified row and column. +224 * <p> +225 * Row and column indices start at 0 and must satisfy +226 * <ul> +227 * <li><code>0 <= row < rowDimension</code></li> +228 * <li><code> 0 <= column < columnDimension</code></li> +229 * </ul> +230 * otherwise a <code>MatrixIndexException</code> is thrown.</p> +231 * +232 * @param row row location of entry to be fetched +233 * @param column column location of entry to be fetched +234 * @return matrix entry in row,column +235 * @throws MatrixIndexException if the row or column index is not valid +236 */ +237 BigDecimal getEntry(int row, int column) throws MatrixIndexException; +238 +239 /** +240 * Returns the entry in the specified row and column as a double. +241 * <p> +242 * Row and column indices start at 0 and must satisfy +243 * <ul> +244 * <li><code>0 <= row < rowDimension</code></li> +245 * <li><code> 0 <= column < columnDimension</code></li> +246 * </ul> +247 * otherwise a <code>MatrixIndexException</code> is thrown.</p> +248 * +249 * @param row row location of entry to be fetched +250 * @param column column location of entry to be fetched +251 * @return matrix entry in row,column +252 * @throws MatrixIndexException if the row or column index is not valid +253 */ +254 double getEntryAsDouble(int row, int column) throws MatrixIndexException; +255 +256 /** +257 * Returns the transpose of this matrix. +258 * +259 * @return transpose matrix +260 */ +261 BigMatrix transpose(); +262 +263 /** +264 * Returns the inverse of this matrix. +265 * +266 * @return inverse matrix +267 * @throws org.apache.commons.math.linear.InvalidMatrixException if +268 * this is not invertible +269 */ +270 BigMatrix inverse() throws InvalidMatrixException; +271 +272 /** +273 * Returns the determinant of this matrix. +274 * +275 * @return determinant +276 *@throws org.apache.commons.math.linear.InvalidMatrixException if +277 * matrix is not square +278 */ +279 BigDecimal getDeterminant() throws InvalidMatrixException; +280 +281 /** +282 * Returns the <a href="http://mathworld.wolfram.com/MatrixTrace.html"> +283 * trace</a> of the matrix (the sum of the elements on the main diagonal). +284 * +285 * @return trace +286 */ +287 BigDecimal getTrace(); +288 +289 /** +290 * Returns the result of multiplying this by the vector <code>v</code>. +291 * +292 * @param v the vector to operate on +293 * @return this*v +294 * @throws IllegalArgumentException if columnDimension != v.size() +295 */ +296 BigDecimal[] operate(BigDecimal[] v) throws IllegalArgumentException; +297 +298 /** +299 * Returns the (row) vector result of premultiplying this by the vector <code>v</code>. +300 * +301 * @param v the row vector to premultiply by +302 * @return v*this +303 * @throws IllegalArgumentException if rowDimension != v.size() +304 */ +305 BigDecimal[] preMultiply(BigDecimal[] v) throws IllegalArgumentException; +306 +307 /** +308 * Returns the solution vector for a linear system with coefficient +309 * matrix = this and constant vector = <code>b</code>. +310 * +311 * @param b constant vector +312 * @return vector of solution values to AX = b, where A is *this +313 * @throws IllegalArgumentException if this.rowDimension != b.length +314 * @throws org.apache.commons.math.linear.InvalidMatrixException if this matrix is not square or is singular +315 */ +316 BigDecimal[] solve(BigDecimal[] b) throws IllegalArgumentException, InvalidMatrixException; +317 +318 /** +319 * Returns a matrix of (column) solution vectors for linear systems with +320 * coefficient matrix = this and constant vectors = columns of +321 * <code>b</code>. +322 * +323 * @param b matrix of constant vectors forming RHS of linear systems to +324 * to solve +325 * @return matrix of solution vectors +326 * @throws IllegalArgumentException if this.rowDimension != row dimension +327 * @throws org.apache.commons.math.linear.InvalidMatrixException if this matrix is not square or is singular +328 */ +329 BigMatrix solve(BigMatrix b) throws IllegalArgumentException, InvalidMatrixException; +330 } +331 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/BigMatrixImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/BigMatrixImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1572 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 import java.io.Serializable; +020 import java.math.BigDecimal; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 +024 /** +025 * Implementation of {@link BigMatrix} using a BigDecimal[][] array to store entries +026 * and <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf"> +027 * LU decompostion</a> to support linear system +028 * solution and inverse. +029 * <p> +030 * The LU decompostion is performed as needed, to support the following operations: <ul> +031 * <li>solve</li> +032 * <li>isSingular</li> +033 * <li>getDeterminant</li> +034 * <li>inverse</li> </ul></p> +035 * <p> +036 * <strong>Usage notes</strong>:<br> +037 * <ul><li> +038 * The LU decomposition is stored and reused on subsequent calls. If matrix +039 * data are modified using any of the public setXxx methods, the saved +040 * decomposition is discarded. If data are modified via references to the +041 * underlying array obtained using <code>getDataRef()</code>, then the stored +042 * LU decomposition will not be discarded. In this case, you need to +043 * explicitly invoke <code>LUDecompose()</code> to recompute the decomposition +044 * before using any of the methods above.</li> +045 * <li> +046 * As specified in the {@link BigMatrix} interface, matrix element indexing +047 * is 0-based -- e.g., <code>getEntry(0, 0)</code> +048 * returns the element in the first row, first column of the matrix.</li></ul></p> +049 * +050 * @deprecated as of 2.0, replaced by {@link Array2DRowFieldMatrix} with a {@link +051 * org.apache.commons.math.util.BigReal} parameter +052 * @version $Revision: 811833 $ $Date: 2009-09-06 12:27:50 -0400 (Sun, 06 Sep 2009) $ +053 */ +054 @Deprecated +055 public class BigMatrixImpl implements BigMatrix, Serializable { +056 +057 /** BigDecimal 0 */ +058 static final BigDecimal ZERO = new BigDecimal(0); +059 +060 /** BigDecimal 1 */ +061 static final BigDecimal ONE = new BigDecimal(1); +062 +063 /** Bound to determine effective singularity in LU decomposition */ +064 private static final BigDecimal TOO_SMALL = new BigDecimal(10E-12); +065 +066 /** Serialization id */ +067 private static final long serialVersionUID = -1011428905656140431L; +068 +069 /** Entries of the matrix */ +070 protected BigDecimal data[][] = null; +071 +072 /** Entries of cached LU decomposition. +073 * All updates to data (other than luDecompose()) *must* set this to null +074 */ +075 protected BigDecimal lu[][] = null; +076 +077 /** Permutation associated with LU decomposition */ +078 protected int[] permutation = null; +079 +080 /** Parity of the permutation associated with the LU decomposition */ +081 protected int parity = 1; +082 +083 /** Rounding mode for divisions **/ +084 private int roundingMode = BigDecimal.ROUND_HALF_UP; +085 +086 /*** BigDecimal scale ***/ +087 private int scale = 64; +088 +089 /** +090 * Creates a matrix with no data +091 */ +092 public BigMatrixImpl() { +093 } +094 +095 /** +096 * Create a new BigMatrix with the supplied row and column dimensions. +097 * +098 * @param rowDimension the number of rows in the new matrix +099 * @param columnDimension the number of columns in the new matrix +100 * @throws IllegalArgumentException if row or column dimension is not +101 * positive +102 */ +103 public BigMatrixImpl(int rowDimension, int columnDimension) { +104 if (rowDimension <= 0 ) { +105 throw MathRuntimeException.createIllegalArgumentException( +106 "invalid row dimension {0} (must be positive)", +107 rowDimension); +108 } +109 if (columnDimension <= 0) { +110 throw MathRuntimeException.createIllegalArgumentException( +111 "invalid column dimension {0} (must be positive)", +112 columnDimension); +113 } +114 data = new BigDecimal[rowDimension][columnDimension]; +115 lu = null; +116 } +117 +118 /** +119 * Create a new BigMatrix using <code>d</code> as the underlying +120 * data array. +121 * <p>The input array is copied, not referenced. This constructor has +122 * the same effect as calling {@link #BigMatrixImpl(BigDecimal[][], boolean)} +123 * with the second argument set to <code>true</code>.</p> +124 * +125 * @param d data for new matrix +126 * @throws IllegalArgumentException if <code>d</code> is not rectangular +127 * (not all rows have the same length) or empty +128 * @throws NullPointerException if <code>d</code> is null +129 */ +130 public BigMatrixImpl(BigDecimal[][] d) { +131 this.copyIn(d); +132 lu = null; +133 } +134 +135 /** +136 * Create a new BigMatrix using the input array as the underlying +137 * data array. +138 * <p>If an array is built specially in order to be embedded in a +139 * BigMatrix and not used directly, the <code>copyArray</code> may be +140 * set to <code>false</code. This will prevent the copying and improve +141 * performance as no new array will be built and no data will be copied.</p> +142 * @param d data for new matrix +143 * @param copyArray if true, the input array will be copied, otherwise +144 * it will be referenced +145 * @throws IllegalArgumentException if <code>d</code> is not rectangular +146 * (not all rows have the same length) or empty +147 * @throws NullPointerException if <code>d</code> is null +148 * @see #BigMatrixImpl(BigDecimal[][]) +149 */ +150 public BigMatrixImpl(BigDecimal[][] d, boolean copyArray) { +151 if (copyArray) { +152 copyIn(d); +153 } else { +154 if (d == null) { +155 throw new NullPointerException(); +156 } +157 final int nRows = d.length; +158 if (nRows == 0) { +159 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row"); +160 } +161 +162 final int nCols = d[0].length; +163 if (nCols == 0) { +164 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column"); +165 } +166 for (int r = 1; r < nRows; r++) { +167 if (d[r].length != nCols) { +168 throw MathRuntimeException.createIllegalArgumentException( +169 "some rows have length {0} while others have length {1}", +170 nCols, d[r].length); +171 } +172 } +173 data = d; +174 } +175 lu = null; +176 } +177 +178 /** +179 * Create a new BigMatrix using <code>d</code> as the underlying +180 * data array. +181 * <p>Since the underlying array will hold <code>BigDecimal</code> +182 * instances, it will be created.</p> +183 * +184 * @param d data for new matrix +185 * @throws IllegalArgumentException if <code>d</code> is not rectangular +186 * (not all rows have the same length) or empty +187 * @throws NullPointerException if <code>d</code> is null +188 */ +189 public BigMatrixImpl(double[][] d) { +190 final int nRows = d.length; +191 if (nRows == 0) { +192 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row"); +193 } +194 +195 final int nCols = d[0].length; +196 if (nCols == 0) { +197 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column"); +198 } +199 for (int row = 1; row < nRows; row++) { +200 if (d[row].length != nCols) { +201 throw MathRuntimeException.createIllegalArgumentException( +202 "some rows have length {0} while others have length {1}", +203 nCols, d[row].length); +204 } +205 } +206 this.copyIn(d); +207 lu = null; +208 } +209 +210 /** +211 * Create a new BigMatrix using the values represented by the strings in +212 * <code>d</code> as the underlying data array. +213 * +214 * @param d data for new matrix +215 * @throws IllegalArgumentException if <code>d</code> is not rectangular +216 * (not all rows have the same length) or empty +217 * @throws NullPointerException if <code>d</code> is null +218 */ +219 public BigMatrixImpl(String[][] d) { +220 final int nRows = d.length; +221 if (nRows == 0) { +222 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row"); +223 } +224 +225 final int nCols = d[0].length; +226 if (nCols == 0) { +227 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column"); +228 } +229 for (int row = 1; row < nRows; row++) { +230 if (d[row].length != nCols) { +231 throw MathRuntimeException.createIllegalArgumentException( +232 "some rows have length {0} while others have length {1}", +233 nCols, d[row].length); +234 } +235 } +236 this.copyIn(d); +237 lu = null; +238 } +239 +240 /** +241 * Create a new (column) BigMatrix using <code>v</code> as the +242 * data for the unique column of the <code>v.length x 1</code> matrix +243 * created. +244 * <p> +245 * The input array is copied, not referenced.</p> +246 * +247 * @param v column vector holding data for new matrix +248 */ +249 public BigMatrixImpl(BigDecimal[] v) { +250 final int nRows = v.length; +251 data = new BigDecimal[nRows][1]; +252 for (int row = 0; row < nRows; row++) { +253 data[row][0] = v[row]; +254 } +255 } +256 +257 /** +258 * Create a new BigMatrix which is a copy of this. +259 * +260 * @return the cloned matrix +261 */ +262 public BigMatrix copy() { +263 return new BigMatrixImpl(this.copyOut(), false); +264 } +265 +266 /** +267 * Compute the sum of this and <code>m</code>. +268 * +269 * @param m matrix to be added +270 * @return this + m +271 * @throws IllegalArgumentException if m is not the same size as this +272 */ +273 public BigMatrix add(BigMatrix m) throws IllegalArgumentException { +274 try { +275 return add((BigMatrixImpl) m); +276 } catch (ClassCastException cce) { +277 +278 // safety check +279 MatrixUtils.checkAdditionCompatible(this, m); +280 +281 final int rowCount = getRowDimension(); +282 final int columnCount = getColumnDimension(); +283 final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; +284 for (int row = 0; row < rowCount; row++) { +285 final BigDecimal[] dataRow = data[row]; +286 final BigDecimal[] outDataRow = outData[row]; +287 for (int col = 0; col < columnCount; col++) { +288 outDataRow[col] = dataRow[col].add(m.getEntry(row, col)); +289 } +290 } +291 return new BigMatrixImpl(outData, false); +292 } +293 } +294 +295 /** +296 * Compute the sum of this and <code>m</code>. +297 * +298 * @param m matrix to be added +299 * @return this + m +300 * @throws IllegalArgumentException if m is not the same size as this +301 */ +302 public BigMatrixImpl add(BigMatrixImpl m) throws IllegalArgumentException { +303 +304 // safety check +305 MatrixUtils.checkAdditionCompatible(this, m); +306 +307 final int rowCount = getRowDimension(); +308 final int columnCount = getColumnDimension(); +309 final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; +310 for (int row = 0; row < rowCount; row++) { +311 final BigDecimal[] dataRow = data[row]; +312 final BigDecimal[] mRow = m.data[row]; +313 final BigDecimal[] outDataRow = outData[row]; +314 for (int col = 0; col < columnCount; col++) { +315 outDataRow[col] = dataRow[col].add(mRow[col]); +316 } +317 } +318 return new BigMatrixImpl(outData, false); +319 } +320 +321 /** +322 * Compute this minus <code>m</code>. +323 * +324 * @param m matrix to be subtracted +325 * @return this + m +326 * @throws IllegalArgumentException if m is not the same size as this +327 */ +328 public BigMatrix subtract(BigMatrix m) throws IllegalArgumentException { +329 try { +330 return subtract((BigMatrixImpl) m); +331 } catch (ClassCastException cce) { +332 +333 // safety check +334 MatrixUtils.checkSubtractionCompatible(this, m); +335 +336 final int rowCount = getRowDimension(); +337 final int columnCount = getColumnDimension(); +338 final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; +339 for (int row = 0; row < rowCount; row++) { +340 final BigDecimal[] dataRow = data[row]; +341 final BigDecimal[] outDataRow = outData[row]; +342 for (int col = 0; col < columnCount; col++) { +343 outDataRow[col] = dataRow[col].subtract(getEntry(row, col)); +344 } +345 } +346 return new BigMatrixImpl(outData, false); +347 } +348 } +349 +350 /** +351 * Compute this minus <code>m</code>. +352 * +353 * @param m matrix to be subtracted +354 * @return this + m +355 * @throws IllegalArgumentException if m is not the same size as this +356 */ +357 public BigMatrixImpl subtract(BigMatrixImpl m) throws IllegalArgumentException { +358 +359 // safety check +360 MatrixUtils.checkSubtractionCompatible(this, m); +361 +362 final int rowCount = getRowDimension(); +363 final int columnCount = getColumnDimension(); +364 final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; +365 for (int row = 0; row < rowCount; row++) { +366 final BigDecimal[] dataRow = data[row]; +367 final BigDecimal[] mRow = m.data[row]; +368 final BigDecimal[] outDataRow = outData[row]; +369 for (int col = 0; col < columnCount; col++) { +370 outDataRow[col] = dataRow[col].subtract(mRow[col]); +371 } +372 } +373 return new BigMatrixImpl(outData, false); +374 } +375 +376 /** +377 * Returns the result of adding d to each entry of this. +378 * +379 * @param d value to be added to each entry +380 * @return d + this +381 */ +382 public BigMatrix scalarAdd(BigDecimal d) { +383 final int rowCount = getRowDimension(); +384 final int columnCount = getColumnDimension(); +385 final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; +386 for (int row = 0; row < rowCount; row++) { +387 final BigDecimal[] dataRow = data[row]; +388 final BigDecimal[] outDataRow = outData[row]; +389 for (int col = 0; col < columnCount; col++) { +390 outDataRow[col] = dataRow[col].add(d); +391 } +392 } +393 return new BigMatrixImpl(outData, false); +394 } +395 +396 /** +397 * Returns the result of multiplying each entry of this by <code>d</code> +398 * @param d value to multiply all entries by +399 * @return d * this +400 */ +401 public BigMatrix scalarMultiply(BigDecimal d) { +402 final int rowCount = getRowDimension(); +403 final int columnCount = getColumnDimension(); +404 final BigDecimal[][] outData = new BigDecimal[rowCount][columnCount]; +405 for (int row = 0; row < rowCount; row++) { +406 final BigDecimal[] dataRow = data[row]; +407 final BigDecimal[] outDataRow = outData[row]; +408 for (int col = 0; col < columnCount; col++) { +409 outDataRow[col] = dataRow[col].multiply(d); +410 } +411 } +412 return new BigMatrixImpl(outData, false); +413 } +414 +415 /** +416 * Returns the result of postmultiplying this by <code>m</code>. +417 * @param m matrix to postmultiply by +418 * @return this*m +419 * @throws IllegalArgumentException +420 * if columnDimension(this) != rowDimension(m) +421 */ +422 public BigMatrix multiply(BigMatrix m) throws IllegalArgumentException { +423 try { +424 return multiply((BigMatrixImpl) m); +425 } catch (ClassCastException cce) { +426 +427 // safety check +428 MatrixUtils.checkMultiplicationCompatible(this, m); +429 +430 final int nRows = this.getRowDimension(); +431 final int nCols = m.getColumnDimension(); +432 final int nSum = this.getColumnDimension(); +433 final BigDecimal[][] outData = new BigDecimal[nRows][nCols]; +434 for (int row = 0; row < nRows; row++) { +435 final BigDecimal[] dataRow = data[row]; +436 final BigDecimal[] outDataRow = outData[row]; +437 for (int col = 0; col < nCols; col++) { +438 BigDecimal sum = ZERO; +439 for (int i = 0; i < nSum; i++) { +440 sum = sum.add(dataRow[i].multiply(m.getEntry(i, col))); +441 } +442 outDataRow[col] = sum; +443 } +444 } +445 return new BigMatrixImpl(outData, false); +446 } +447 } +448 +449 /** +450 * Returns the result of postmultiplying this by <code>m</code>. +451 * @param m matrix to postmultiply by +452 * @return this*m +453 * @throws IllegalArgumentException +454 * if columnDimension(this) != rowDimension(m) +455 */ +456 public BigMatrixImpl multiply(BigMatrixImpl m) throws IllegalArgumentException { +457 +458 // safety check +459 MatrixUtils.checkMultiplicationCompatible(this, m); +460 +461 final int nRows = this.getRowDimension(); +462 final int nCols = m.getColumnDimension(); +463 final int nSum = this.getColumnDimension(); +464 final BigDecimal[][] outData = new BigDecimal[nRows][nCols]; +465 for (int row = 0; row < nRows; row++) { +466 final BigDecimal[] dataRow = data[row]; +467 final BigDecimal[] outDataRow = outData[row]; +468 for (int col = 0; col < nCols; col++) { +469 BigDecimal sum = ZERO; +470 for (int i = 0; i < nSum; i++) { +471 sum = sum.add(dataRow[i].multiply(m.data[i][col])); +472 } +473 outDataRow[col] = sum; +474 } +475 } +476 return new BigMatrixImpl(outData, false); +477 } +478 +479 /** +480 * Returns the result premultiplying this by <code>m</code>. +481 * @param m matrix to premultiply by +482 * @return m * this +483 * @throws IllegalArgumentException +484 * if rowDimension(this) != columnDimension(m) +485 */ +486 public BigMatrix preMultiply(BigMatrix m) throws IllegalArgumentException { +487 return m.multiply(this); +488 } +489 +490 /** +491 * Returns matrix entries as a two-dimensional array. +492 * <p> +493 * Makes a fresh copy of the underlying data.</p> +494 * +495 * @return 2-dimensional array of entries +496 */ +497 public BigDecimal[][] getData() { +498 return copyOut(); +499 } +500 +501 /** +502 * Returns matrix entries as a two-dimensional array. +503 * <p> +504 * Makes a fresh copy of the underlying data converted to +505 * <code>double</code> values.</p> +506 * +507 * @return 2-dimensional array of entries +508 */ +509 public double[][] getDataAsDoubleArray() { +510 final int nRows = getRowDimension(); +511 final int nCols = getColumnDimension(); +512 final double d[][] = new double[nRows][nCols]; +513 for (int i = 0; i < nRows; i++) { +514 for (int j = 0; j < nCols; j++) { +515 d[i][j] = data[i][j].doubleValue(); +516 } +517 } +518 return d; +519 } +520 +521 /** +522 * Returns a reference to the underlying data array. +523 * <p> +524 * Does not make a fresh copy of the underlying data.</p> +525 * +526 * @return 2-dimensional array of entries +527 */ +528 public BigDecimal[][] getDataRef() { +529 return data; +530 } +531 +532 /*** +533 * Gets the rounding mode for division operations +534 * The default is {@link java.math.BigDecimal#ROUND_HALF_UP} +535 * @see BigDecimal +536 * @return the rounding mode. +537 */ +538 public int getRoundingMode() { +539 return roundingMode; +540 } +541 +542 /*** +543 * Sets the rounding mode for decimal divisions. +544 * @see BigDecimal +545 * @param roundingMode rounding mode for decimal divisions +546 */ +547 public void setRoundingMode(int roundingMode) { +548 this.roundingMode = roundingMode; +549 } +550 +551 /*** +552 * Sets the scale for division operations. +553 * The default is 64 +554 * @see BigDecimal +555 * @return the scale +556 */ +557 public int getScale() { +558 return scale; +559 } +560 +561 /*** +562 * Sets the scale for division operations. +563 * @see BigDecimal +564 * @param scale scale for division operations +565 */ +566 public void setScale(int scale) { +567 this.scale = scale; +568 } +569 +570 /** +571 * Returns the <a href="http://mathworld.wolfram.com/MaximumAbsoluteRowSumNorm.html"> +572 * maximum absolute row sum norm</a> of the matrix. +573 * +574 * @return norm +575 */ +576 public BigDecimal getNorm() { +577 BigDecimal maxColSum = ZERO; +578 for (int col = 0; col < this.getColumnDimension(); col++) { +579 BigDecimal sum = ZERO; +580 for (int row = 0; row < this.getRowDimension(); row++) { +581 sum = sum.add(data[row][col].abs()); +582 } +583 maxColSum = maxColSum.max(sum); +584 } +585 return maxColSum; +586 } +587 +588 /** +589 * Gets a submatrix. Rows and columns are indicated +590 * counting from 0 to n-1. +591 * +592 * @param startRow Initial row index +593 * @param endRow Final row index +594 * @param startColumn Initial column index +595 * @param endColumn Final column index +596 * @return The subMatrix containing the data of the +597 * specified rows and columns +598 * @exception MatrixIndexException if row or column selections are not valid +599 */ +600 public BigMatrix getSubMatrix(int startRow, int endRow, +601 int startColumn, int endColumn) +602 throws MatrixIndexException { +603 +604 MatrixUtils.checkRowIndex(this, startRow); +605 MatrixUtils.checkRowIndex(this, endRow); +606 if (startRow > endRow) { +607 throw new MatrixIndexException("initial row {0} after final row {1}", +608 startRow, endRow); +609 } +610 +611 MatrixUtils.checkColumnIndex(this, startColumn); +612 MatrixUtils.checkColumnIndex(this, endColumn); +613 if (startColumn > endColumn) { +614 throw new MatrixIndexException("initial column {0} after final column {1}", +615 startColumn, endColumn); +616 } +617 +618 final BigDecimal[][] subMatrixData = +619 new BigDecimal[endRow - startRow + 1][endColumn - startColumn + 1]; +620 for (int i = startRow; i <= endRow; i++) { +621 System.arraycopy(data[i], startColumn, +622 subMatrixData[i - startRow], 0, +623 endColumn - startColumn + 1); +624 } +625 +626 return new BigMatrixImpl(subMatrixData, false); +627 +628 } +629 +630 /** +631 * Gets a submatrix. Rows and columns are indicated +632 * counting from 0 to n-1. +633 * +634 * @param selectedRows Array of row indices must be non-empty +635 * @param selectedColumns Array of column indices must be non-empty +636 * @return The subMatrix containing the data in the +637 * specified rows and columns +638 * @exception MatrixIndexException if supplied row or column index arrays +639 * are not valid +640 */ +641 public BigMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns) +642 throws MatrixIndexException { +643 +644 if (selectedRows.length * selectedColumns.length == 0) { +645 if (selectedRows.length == 0) { +646 throw new MatrixIndexException("empty selected row index array"); +647 } +648 throw new MatrixIndexException("empty selected column index array"); +649 } +650 +651 final BigDecimal[][] subMatrixData = +652 new BigDecimal[selectedRows.length][selectedColumns.length]; +653 try { +654 for (int i = 0; i < selectedRows.length; i++) { +655 final BigDecimal[] subI = subMatrixData[i]; +656 final BigDecimal[] dataSelectedI = data[selectedRows[i]]; +657 for (int j = 0; j < selectedColumns.length; j++) { +658 subI[j] = dataSelectedI[selectedColumns[j]]; +659 } +660 } +661 } catch (ArrayIndexOutOfBoundsException e) { +662 // we redo the loop with checks enabled +663 // in order to generate an appropriate message +664 for (final int row : selectedRows) { +665 MatrixUtils.checkRowIndex(this, row); +666 } +667 for (final int column : selectedColumns) { +668 MatrixUtils.checkColumnIndex(this, column); +669 } +670 } +671 return new BigMatrixImpl(subMatrixData, false); +672 } +673 +674 /** +675 * Replace the submatrix starting at <code>row, column</code> using data in +676 * the input <code>subMatrix</code> array. Indexes are 0-based. +677 * <p> +678 * Example:<br> +679 * Starting with <pre> +680 * 1 2 3 4 +681 * 5 6 7 8 +682 * 9 0 1 2 +683 * </pre> +684 * and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking +685 * <code>setSubMatrix(subMatrix,1,1))</code> will result in <pre> +686 * 1 2 3 4 +687 * 5 3 4 8 +688 * 9 5 6 2 +689 * </pre></p> +690 * +691 * @param subMatrix array containing the submatrix replacement data +692 * @param row row coordinate of the top, left element to be replaced +693 * @param column column coordinate of the top, left element to be replaced +694 * @throws MatrixIndexException if subMatrix does not fit into this +695 * matrix from element in (row, column) +696 * @throws IllegalArgumentException if <code>subMatrix</code> is not rectangular +697 * (not all rows have the same length) or empty +698 * @throws NullPointerException if <code>subMatrix</code> is null +699 * @since 1.1 +700 */ +701 public void setSubMatrix(BigDecimal[][] subMatrix, int row, int column) +702 throws MatrixIndexException { +703 +704 final int nRows = subMatrix.length; +705 if (nRows == 0) { +706 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row"); +707 } +708 +709 final int nCols = subMatrix[0].length; +710 if (nCols == 0) { +711 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column"); +712 } +713 +714 for (int r = 1; r < nRows; r++) { +715 if (subMatrix[r].length != nCols) { +716 throw MathRuntimeException.createIllegalArgumentException( +717 "some rows have length {0} while others have length {1}", +718 nCols, subMatrix[r].length); +719 } +720 } +721 +722 if (data == null) { +723 if (row > 0) { +724 throw MathRuntimeException.createIllegalStateException( +725 "first {0} rows are not initialized yet", +726 row); +727 } +728 if (column > 0) { +729 throw MathRuntimeException.createIllegalStateException( +730 "first {0} columns are not initialized yet", +731 column); +732 } +733 data = new BigDecimal[nRows][nCols]; +734 System.arraycopy(subMatrix, 0, data, 0, subMatrix.length); +735 } else { +736 MatrixUtils.checkRowIndex(this, row); +737 MatrixUtils.checkColumnIndex(this, column); +738 MatrixUtils.checkRowIndex(this, nRows + row - 1); +739 MatrixUtils.checkColumnIndex(this, nCols + column - 1); +740 } +741 for (int i = 0; i < nRows; i++) { +742 System.arraycopy(subMatrix[i], 0, data[row + i], column, nCols); +743 } +744 +745 lu = null; +746 +747 } +748 +749 /** +750 * Returns the entries in row number <code>row</code> +751 * as a row matrix. Row indices start at 0. +752 * +753 * @param row the row to be fetched +754 * @return row matrix +755 * @throws MatrixIndexException if the specified row index is invalid +756 */ +757 public BigMatrix getRowMatrix(int row) throws MatrixIndexException { +758 MatrixUtils.checkRowIndex(this, row); +759 final int ncols = this.getColumnDimension(); +760 final BigDecimal[][] out = new BigDecimal[1][ncols]; +761 System.arraycopy(data[row], 0, out[0], 0, ncols); +762 return new BigMatrixImpl(out, false); +763 } +764 +765 /** +766 * Returns the entries in column number <code>column</code> +767 * as a column matrix. Column indices start at 0. +768 * +769 * @param column the column to be fetched +770 * @return column matrix +771 * @throws MatrixIndexException if the specified column index is invalid +772 */ +773 public BigMatrix getColumnMatrix(int column) throws MatrixIndexException { +774 MatrixUtils.checkColumnIndex(this, column); +775 final int nRows = this.getRowDimension(); +776 final BigDecimal[][] out = new BigDecimal[nRows][1]; +777 for (int row = 0; row < nRows; row++) { +778 out[row][0] = data[row][column]; +779 } +780 return new BigMatrixImpl(out, false); +781 } +782 +783 /** +784 * Returns the entries in row number <code>row</code> as an array. +785 * <p> +786 * Row indices start at 0. A <code>MatrixIndexException</code> is thrown +787 * unless <code>0 <= row < rowDimension.</code></p> +788 * +789 * @param row the row to be fetched +790 * @return array of entries in the row +791 * @throws MatrixIndexException if the specified row index is not valid +792 */ +793 public BigDecimal[] getRow(int row) throws MatrixIndexException { +794 MatrixUtils.checkRowIndex(this, row); +795 final int ncols = this.getColumnDimension(); +796 final BigDecimal[] out = new BigDecimal[ncols]; +797 System.arraycopy(data[row], 0, out, 0, ncols); +798 return out; +799 } +800 +801 /** +802 * Returns the entries in row number <code>row</code> as an array +803 * of double values. +804 * <p> +805 * Row indices start at 0. A <code>MatrixIndexException</code> is thrown +806 * unless <code>0 <= row < rowDimension.</code></p> +807 * +808 * @param row the row to be fetched +809 * @return array of entries in the row +810 * @throws MatrixIndexException if the specified row index is not valid +811 */ +812 public double[] getRowAsDoubleArray(int row) throws MatrixIndexException { +813 MatrixUtils.checkRowIndex(this, row); +814 final int ncols = this.getColumnDimension(); +815 final double[] out = new double[ncols]; +816 for (int i=0;i<ncols;i++) { +817 out[i] = data[row][i].doubleValue(); +818 } +819 return out; +820 } +821 +822 /** +823 * Returns the entries in column number <code>col</code> as an array. +824 * <p> +825 * Column indices start at 0. A <code>MatrixIndexException</code> is thrown +826 * unless <code>0 <= column < columnDimension.</code></p> +827 * +828 * @param col the column to be fetched +829 * @return array of entries in the column +830 * @throws MatrixIndexException if the specified column index is not valid +831 */ +832 public BigDecimal[] getColumn(int col) throws MatrixIndexException { +833 MatrixUtils.checkColumnIndex(this, col); +834 final int nRows = this.getRowDimension(); +835 final BigDecimal[] out = new BigDecimal[nRows]; +836 for (int i = 0; i < nRows; i++) { +837 out[i] = data[i][col]; +838 } +839 return out; +840 } +841 +842 /** +843 * Returns the entries in column number <code>col</code> as an array +844 * of double values. +845 * <p> +846 * Column indices start at 0. A <code>MatrixIndexException</code> is thrown +847 * unless <code>0 <= column < columnDimension.</code></p> +848 * +849 * @param col the column to be fetched +850 * @return array of entries in the column +851 * @throws MatrixIndexException if the specified column index is not valid +852 */ +853 public double[] getColumnAsDoubleArray(int col) throws MatrixIndexException { +854 MatrixUtils.checkColumnIndex(this, col); +855 final int nrows = this.getRowDimension(); +856 final double[] out = new double[nrows]; +857 for (int i=0;i<nrows;i++) { +858 out[i] = data[i][col].doubleValue(); +859 } +860 return out; +861 } +862 +863 /** +864 * Returns the entry in the specified row and column. +865 * <p> +866 * Row and column indices start at 0 and must satisfy +867 * <ul> +868 * <li><code>0 <= row < rowDimension</code></li> +869 * <li><code> 0 <= column < columnDimension</code></li> +870 * </ul> +871 * otherwise a <code>MatrixIndexException</code> is thrown.</p> +872 * +873 * @param row row location of entry to be fetched +874 * @param column column location of entry to be fetched +875 * @return matrix entry in row,column +876 * @throws MatrixIndexException if the row or column index is not valid +877 */ +878 public BigDecimal getEntry(int row, int column) +879 throws MatrixIndexException { +880 try { +881 return data[row][column]; +882 } catch (ArrayIndexOutOfBoundsException e) { +883 throw new MatrixIndexException( +884 "no entry at indices ({0}, {1}) in a {2}x{3} matrix", +885 row, column, getRowDimension(), getColumnDimension()); +886 } +887 } +888 +889 /** +890 * Returns the entry in the specified row and column as a double. +891 * <p> +892 * Row and column indices start at 0 and must satisfy +893 * <ul> +894 * <li><code>0 <= row < rowDimension</code></li> +895 * <li><code> 0 <= column < columnDimension</code></li> +896 * </ul> +897 * otherwise a <code>MatrixIndexException</code> is thrown.</p> +898 * +899 * @param row row location of entry to be fetched +900 * @param column column location of entry to be fetched +901 * @return matrix entry in row,column +902 * @throws MatrixIndexException if the row +903 * or column index is not valid +904 */ +905 public double getEntryAsDouble(int row, int column) throws MatrixIndexException { +906 return getEntry(row,column).doubleValue(); +907 } +908 +909 /** +910 * Returns the transpose matrix. +911 * +912 * @return transpose matrix +913 */ +914 public BigMatrix transpose() { +915 final int nRows = this.getRowDimension(); +916 final int nCols = this.getColumnDimension(); +917 final BigDecimal[][] outData = new BigDecimal[nCols][nRows]; +918 for (int row = 0; row < nRows; row++) { +919 final BigDecimal[] dataRow = data[row]; +920 for (int col = 0; col < nCols; col++) { +921 outData[col][row] = dataRow[col]; +922 } +923 } +924 return new BigMatrixImpl(outData, false); +925 } +926 +927 /** +928 * Returns the inverse matrix if this matrix is invertible. +929 * +930 * @return inverse matrix +931 * @throws InvalidMatrixException if this is not invertible +932 */ +933 public BigMatrix inverse() throws InvalidMatrixException { +934 return solve(MatrixUtils.createBigIdentityMatrix(getRowDimension())); +935 } +936 +937 /** +938 * Returns the determinant of this matrix. +939 * +940 * @return determinant +941 * @throws InvalidMatrixException if matrix is not square +942 */ +943 public BigDecimal getDeterminant() throws InvalidMatrixException { +944 if (!isSquare()) { +945 throw new NonSquareMatrixException(getRowDimension(), getColumnDimension()); +946 } +947 if (isSingular()) { // note: this has side effect of attempting LU decomp if lu == null +948 return ZERO; +949 } else { +950 BigDecimal det = (parity == 1) ? ONE : ONE.negate(); +951 for (int i = 0; i < getRowDimension(); i++) { +952 det = det.multiply(lu[i][i]); +953 } +954 return det; +955 } +956 } +957 +958 /** +959 * Is this a square matrix? +960 * @return true if the matrix is square (rowDimension = columnDimension) +961 */ +962 public boolean isSquare() { +963 return getColumnDimension() == getRowDimension(); +964 } +965 +966 /** +967 * Is this a singular matrix? +968 * @return true if the matrix is singular +969 */ +970 public boolean isSingular() { +971 if (lu == null) { +972 try { +973 luDecompose(); +974 return false; +975 } catch (InvalidMatrixException ex) { +976 return true; +977 } +978 } else { // LU decomp must have been successfully performed +979 return false; // so the matrix is not singular +980 } +981 } +982 +983 /** +984 * Returns the number of rows in the matrix. +985 * +986 * @return rowDimension +987 */ +988 public int getRowDimension() { +989 return data.length; +990 } +991 +992 /** +993 * Returns the number of columns in the matrix. +994 * +995 * @return columnDimension +996 */ +997 public int getColumnDimension() { +998 return data[0].length; +999 } +1000 +1001 /** +1002 * Returns the <a href="http://mathworld.wolfram.com/MatrixTrace.html"> +1003 * trace</a> of the matrix (the sum of the elements on the main diagonal). +1004 * +1005 * @return trace +1006 * +1007 * @throws IllegalArgumentException if this matrix is not square. +1008 */ +1009 public BigDecimal getTrace() throws IllegalArgumentException { +1010 if (!isSquare()) { +1011 throw new NonSquareMatrixException(getRowDimension(), getColumnDimension()); +1012 } +1013 BigDecimal trace = data[0][0]; +1014 for (int i = 1; i < this.getRowDimension(); i++) { +1015 trace = trace.add(data[i][i]); +1016 } +1017 return trace; +1018 } +1019 +1020 /** +1021 * Returns the result of multiplying this by the vector <code>v</code>. +1022 * +1023 * @param v the vector to operate on +1024 * @return this*v +1025 * @throws IllegalArgumentException if columnDimension != v.size() +1026 */ +1027 public BigDecimal[] operate(BigDecimal[] v) throws IllegalArgumentException { +1028 if (v.length != getColumnDimension()) { +1029 throw MathRuntimeException.createIllegalArgumentException( +1030 "vector length mismatch: got {0} but expected {1}", +1031 v.length, getColumnDimension() ); +1032 } +1033 final int nRows = this.getRowDimension(); +1034 final int nCols = this.getColumnDimension(); +1035 final BigDecimal[] out = new BigDecimal[nRows]; +1036 for (int row = 0; row < nRows; row++) { +1037 BigDecimal sum = ZERO; +1038 for (int i = 0; i < nCols; i++) { +1039 sum = sum.add(data[row][i].multiply(v[i])); +1040 } +1041 out[row] = sum; +1042 } +1043 return out; +1044 } +1045 +1046 /** +1047 * Returns the result of multiplying this by the vector <code>v</code>. +1048 * +1049 * @param v the vector to operate on +1050 * @return this*v +1051 * @throws IllegalArgumentException if columnDimension != v.size() +1052 */ +1053 public BigDecimal[] operate(double[] v) throws IllegalArgumentException { +1054 final BigDecimal bd[] = new BigDecimal[v.length]; +1055 for (int i = 0; i < bd.length; i++) { +1056 bd[i] = new BigDecimal(v[i]); +1057 } +1058 return operate(bd); +1059 } +1060 +1061 /** +1062 * Returns the (row) vector result of premultiplying this by the vector <code>v</code>. +1063 * +1064 * @param v the row vector to premultiply by +1065 * @return v*this +1066 * @throws IllegalArgumentException if rowDimension != v.size() +1067 */ +1068 public BigDecimal[] preMultiply(BigDecimal[] v) throws IllegalArgumentException { +1069 final int nRows = this.getRowDimension(); +1070 if (v.length != nRows) { +1071 throw MathRuntimeException.createIllegalArgumentException( +1072 "vector length mismatch: got {0} but expected {1}", +1073 v.length, nRows ); +1074 } +1075 final int nCols = this.getColumnDimension(); +1076 final BigDecimal[] out = new BigDecimal[nCols]; +1077 for (int col = 0; col < nCols; col++) { +1078 BigDecimal sum = ZERO; +1079 for (int i = 0; i < nRows; i++) { +1080 sum = sum.add(data[i][col].multiply(v[i])); +1081 } +1082 out[col] = sum; +1083 } +1084 return out; +1085 } +1086 +1087 /** +1088 * Returns a matrix of (column) solution vectors for linear systems with +1089 * coefficient matrix = this and constant vectors = columns of +1090 * <code>b</code>. +1091 * +1092 * @param b array of constants forming RHS of linear systems to +1093 * to solve +1094 * @return solution array +1095 * @throws IllegalArgumentException if this.rowDimension != row dimension +1096 * @throws InvalidMatrixException if this matrix is not square or is singular +1097 */ +1098 public BigDecimal[] solve(BigDecimal[] b) throws IllegalArgumentException, InvalidMatrixException { +1099 final int nRows = this.getRowDimension(); +1100 if (b.length != nRows) { +1101 throw MathRuntimeException.createIllegalArgumentException( +1102 "vector length mismatch: got {0} but expected {1}", +1103 b.length, nRows); +1104 } +1105 final BigMatrix bMatrix = new BigMatrixImpl(b); +1106 final BigDecimal[][] solution = ((BigMatrixImpl) (solve(bMatrix))).getDataRef(); +1107 final BigDecimal[] out = new BigDecimal[nRows]; +1108 for (int row = 0; row < nRows; row++) { +1109 out[row] = solution[row][0]; +1110 } +1111 return out; +1112 } +1113 +1114 /** +1115 * Returns a matrix of (column) solution vectors for linear systems with +1116 * coefficient matrix = this and constant vectors = columns of +1117 * <code>b</code>. +1118 * +1119 * @param b array of constants forming RHS of linear systems to +1120 * to solve +1121 * @return solution array +1122 * @throws IllegalArgumentException if this.rowDimension != row dimension +1123 * @throws InvalidMatrixException if this matrix is not square or is singular +1124 */ +1125 public BigDecimal[] solve(double[] b) throws IllegalArgumentException, InvalidMatrixException { +1126 final BigDecimal bd[] = new BigDecimal[b.length]; +1127 for (int i = 0; i < bd.length; i++) { +1128 bd[i] = new BigDecimal(b[i]); +1129 } +1130 return solve(bd); +1131 } +1132 +1133 /** +1134 * Returns a matrix of (column) solution vectors for linear systems with +1135 * coefficient matrix = this and constant vectors = columns of +1136 * <code>b</code>. +1137 * +1138 * @param b matrix of constant vectors forming RHS of linear systems to +1139 * to solve +1140 * @return matrix of solution vectors +1141 * @throws IllegalArgumentException if this.rowDimension != row dimension +1142 * @throws InvalidMatrixException if this matrix is not square or is singular +1143 */ +1144 public BigMatrix solve(BigMatrix b) throws IllegalArgumentException, InvalidMatrixException { +1145 if (b.getRowDimension() != getRowDimension()) { +1146 throw MathRuntimeException.createIllegalArgumentException( +1147 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +1148 b.getRowDimension(), b.getColumnDimension(), getRowDimension(), "n"); +1149 } +1150 if (!isSquare()) { +1151 throw new NonSquareMatrixException(getRowDimension(), getColumnDimension()); +1152 } +1153 if (this.isSingular()) { // side effect: compute LU decomp +1154 throw new SingularMatrixException(); +1155 } +1156 +1157 final int nCol = this.getColumnDimension(); +1158 final int nColB = b.getColumnDimension(); +1159 final int nRowB = b.getRowDimension(); +1160 +1161 // Apply permutations to b +1162 final BigDecimal[][] bp = new BigDecimal[nRowB][nColB]; +1163 for (int row = 0; row < nRowB; row++) { +1164 final BigDecimal[] bpRow = bp[row]; +1165 for (int col = 0; col < nColB; col++) { +1166 bpRow[col] = b.getEntry(permutation[row], col); +1167 } +1168 } +1169 +1170 // Solve LY = b +1171 for (int col = 0; col < nCol; col++) { +1172 for (int i = col + 1; i < nCol; i++) { +1173 final BigDecimal[] bpI = bp[i]; +1174 final BigDecimal[] luI = lu[i]; +1175 for (int j = 0; j < nColB; j++) { +1176 bpI[j] = bpI[j].subtract(bp[col][j].multiply(luI[col])); +1177 } +1178 } +1179 } +1180 +1181 // Solve UX = Y +1182 for (int col = nCol - 1; col >= 0; col--) { +1183 final BigDecimal[] bpCol = bp[col]; +1184 final BigDecimal luDiag = lu[col][col]; +1185 for (int j = 0; j < nColB; j++) { +1186 bpCol[j] = bpCol[j].divide(luDiag, scale, roundingMode); +1187 } +1188 for (int i = 0; i < col; i++) { +1189 final BigDecimal[] bpI = bp[i]; +1190 final BigDecimal[] luI = lu[i]; +1191 for (int j = 0; j < nColB; j++) { +1192 bpI[j] = bpI[j].subtract(bp[col][j].multiply(luI[col])); +1193 } +1194 } +1195 } +1196 +1197 return new BigMatrixImpl(bp, false); +1198 +1199 } +1200 +1201 /** +1202 * Computes a new +1203 * <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf"> +1204 * LU decompostion</a> for this matrix, storing the result for use by other methods. +1205 * <p> +1206 * <strong>Implementation Note</strong>:<br> +1207 * Uses <a href="http://www.damtp.cam.ac.uk/user/fdl/people/sd/lectures/nummeth98/linear.htm"> +1208 * Crout's algortithm</a>, with partial pivoting.</p> +1209 * <p> +1210 * <strong>Usage Note</strong>:<br> +1211 * This method should rarely be invoked directly. Its only use is +1212 * to force recomputation of the LU decomposition when changes have been +1213 * made to the underlying data using direct array references. Changes +1214 * made using setXxx methods will trigger recomputation when needed +1215 * automatically.</p> +1216 * +1217 * @throws InvalidMatrixException if the matrix is non-square or singular. +1218 */ +1219 public void luDecompose() throws InvalidMatrixException { +1220 +1221 final int nRows = this.getRowDimension(); +1222 final int nCols = this.getColumnDimension(); +1223 if (nRows != nCols) { +1224 throw new NonSquareMatrixException(getRowDimension(), getColumnDimension()); +1225 } +1226 lu = this.getData(); +1227 +1228 // Initialize permutation array and parity +1229 permutation = new int[nRows]; +1230 for (int row = 0; row < nRows; row++) { +1231 permutation[row] = row; +1232 } +1233 parity = 1; +1234 +1235 // Loop over columns +1236 for (int col = 0; col < nCols; col++) { +1237 +1238 BigDecimal sum = ZERO; +1239 +1240 // upper +1241 for (int row = 0; row < col; row++) { +1242 final BigDecimal[] luRow = lu[row]; +1243 sum = luRow[col]; +1244 for (int i = 0; i < row; i++) { +1245 sum = sum.subtract(luRow[i].multiply(lu[i][col])); +1246 } +1247 luRow[col] = sum; +1248 } +1249 +1250 // lower +1251 int max = col; // permutation row +1252 BigDecimal largest = ZERO; +1253 for (int row = col; row < nRows; row++) { +1254 final BigDecimal[] luRow = lu[row]; +1255 sum = luRow[col]; +1256 for (int i = 0; i < col; i++) { +1257 sum = sum.subtract(luRow[i].multiply(lu[i][col])); +1258 } +1259 luRow[col] = sum; +1260 +1261 // maintain best permutation choice +1262 if (sum.abs().compareTo(largest) == 1) { +1263 largest = sum.abs(); +1264 max = row; +1265 } +1266 } +1267 +1268 // Singularity check +1269 if (lu[max][col].abs().compareTo(TOO_SMALL) <= 0) { +1270 lu = null; +1271 throw new SingularMatrixException(); +1272 } +1273 +1274 // Pivot if necessary +1275 if (max != col) { +1276 BigDecimal tmp = ZERO; +1277 for (int i = 0; i < nCols; i++) { +1278 tmp = lu[max][i]; +1279 lu[max][i] = lu[col][i]; +1280 lu[col][i] = tmp; +1281 } +1282 int temp = permutation[max]; +1283 permutation[max] = permutation[col]; +1284 permutation[col] = temp; +1285 parity = -parity; +1286 } +1287 +1288 // Divide the lower elements by the "winning" diagonal elt. +1289 final BigDecimal luDiag = lu[col][col]; +1290 for (int row = col + 1; row < nRows; row++) { +1291 final BigDecimal[] luRow = lu[row]; +1292 luRow[col] = luRow[col].divide(luDiag, scale, roundingMode); +1293 } +1294 +1295 } +1296 +1297 } +1298 +1299 /** +1300 * Get a string representation for this matrix. +1301 * @return a string representation for this matrix +1302 */ +1303 @Override +1304 public String toString() { +1305 StringBuffer res = new StringBuffer(); +1306 res.append("BigMatrixImpl{"); +1307 if (data != null) { +1308 for (int i = 0; i < data.length; i++) { +1309 if (i > 0) { +1310 res.append(","); +1311 } +1312 res.append("{"); +1313 for (int j = 0; j < data[0].length; j++) { +1314 if (j > 0) { +1315 res.append(","); +1316 } +1317 res.append(data[i][j]); +1318 } +1319 res.append("}"); +1320 } +1321 } +1322 res.append("}"); +1323 return res.toString(); +1324 } +1325 +1326 /** +1327 * Returns true iff <code>object</code> is a +1328 * <code>BigMatrixImpl</code> instance with the same dimensions as this +1329 * and all corresponding matrix entries are equal. BigDecimal.equals +1330 * is used to compare corresponding entries. +1331 * +1332 * @param object the object to test equality against. +1333 * @return true if object equals this +1334 */ +1335 @Override +1336 public boolean equals(Object object) { +1337 if (object == this ) { +1338 return true; +1339 } +1340 if (object instanceof BigMatrixImpl == false) { +1341 return false; +1342 } +1343 final BigMatrix m = (BigMatrix) object; +1344 final int nRows = getRowDimension(); +1345 final int nCols = getColumnDimension(); +1346 if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows) { +1347 return false; +1348 } +1349 for (int row = 0; row < nRows; row++) { +1350 final BigDecimal[] dataRow = data[row]; +1351 for (int col = 0; col < nCols; col++) { +1352 if (!dataRow[col].equals(m.getEntry(row, col))) { +1353 return false; +1354 } +1355 } +1356 } +1357 return true; +1358 } +1359 +1360 /** +1361 * Computes a hashcode for the matrix. +1362 * +1363 * @return hashcode for matrix +1364 */ +1365 @Override +1366 public int hashCode() { +1367 int ret = 7; +1368 final int nRows = getRowDimension(); +1369 final int nCols = getColumnDimension(); +1370 ret = ret * 31 + nRows; +1371 ret = ret * 31 + nCols; +1372 for (int row = 0; row < nRows; row++) { +1373 final BigDecimal[] dataRow = data[row]; +1374 for (int col = 0; col < nCols; col++) { +1375 ret = ret * 31 + (11 * (row+1) + 17 * (col+1)) * +1376 dataRow[col].hashCode(); +1377 } +1378 } +1379 return ret; +1380 } +1381 +1382 //------------------------ Protected methods +1383 +1384 /** +1385 * Returns the LU decomposition as a BigMatrix. +1386 * Returns a fresh copy of the cached LU matrix if this has been computed; +1387 * otherwise the composition is computed and cached for use by other methods. +1388 * Since a copy is returned in either case, changes to the returned matrix do not +1389 * affect the LU decomposition property. +1390 * <p> +1391 * The matrix returned is a compact representation of the LU decomposition. +1392 * Elements below the main diagonal correspond to entries of the "L" matrix; +1393 * elements on and above the main diagonal correspond to entries of the "U" +1394 * matrix.</p> +1395 * <p> +1396 * Example: <pre> +1397 * +1398 * Returned matrix L U +1399 * 2 3 1 1 0 0 2 3 1 +1400 * 5 4 6 5 1 0 0 4 6 +1401 * 1 7 8 1 7 1 0 0 8 +1402 * </pre> +1403 * +1404 * The L and U matrices satisfy the matrix equation LU = permuteRows(this), <br> +1405 * where permuteRows reorders the rows of the matrix to follow the order determined +1406 * by the <a href=#getPermutation()>permutation</a> property.</p> +1407 * +1408 * @return LU decomposition matrix +1409 * @throws InvalidMatrixException if the matrix is non-square or singular. +1410 */ +1411 protected BigMatrix getLUMatrix() throws InvalidMatrixException { +1412 if (lu == null) { +1413 luDecompose(); +1414 } +1415 return new BigMatrixImpl(lu); +1416 } +1417 +1418 /** +1419 * Returns the permutation associated with the lu decomposition. +1420 * The entries of the array represent a permutation of the numbers 0, ... , nRows - 1. +1421 * <p> +1422 * Example: +1423 * permutation = [1, 2, 0] means current 2nd row is first, current third row is second +1424 * and current first row is last.</p> +1425 * <p> +1426 * Returns a fresh copy of the array.</p> +1427 * +1428 * @return the permutation +1429 */ +1430 protected int[] getPermutation() { +1431 final int[] out = new int[permutation.length]; +1432 System.arraycopy(permutation, 0, out, 0, permutation.length); +1433 return out; +1434 } +1435 +1436 //------------------------ Private methods +1437 +1438 /** +1439 * Returns a fresh copy of the underlying data array. +1440 * +1441 * @return a copy of the underlying data array. +1442 */ +1443 private BigDecimal[][] copyOut() { +1444 final int nRows = this.getRowDimension(); +1445 final BigDecimal[][] out = new BigDecimal[nRows][this.getColumnDimension()]; +1446 // can't copy 2-d array in one shot, otherwise get row references +1447 for (int i = 0; i < nRows; i++) { +1448 System.arraycopy(data[i], 0, out[i], 0, data[i].length); +1449 } +1450 return out; +1451 } +1452 +1453 /** +1454 * Replaces data with a fresh copy of the input array. +1455 * <p> +1456 * Verifies that the input array is rectangular and non-empty.</p> +1457 * +1458 * @param in data to copy in +1459 * @throws IllegalArgumentException if input array is emtpy or not +1460 * rectangular +1461 * @throws NullPointerException if input array is null +1462 */ +1463 private void copyIn(BigDecimal[][] in) { +1464 setSubMatrix(in,0,0); +1465 } +1466 +1467 /** +1468 * Replaces data with a fresh copy of the input array. +1469 * +1470 * @param in data to copy in +1471 */ +1472 private void copyIn(double[][] in) { +1473 final int nRows = in.length; +1474 final int nCols = in[0].length; +1475 data = new BigDecimal[nRows][nCols]; +1476 for (int i = 0; i < nRows; i++) { +1477 final BigDecimal[] dataI = data[i]; +1478 final double[] inI = in[i]; +1479 for (int j = 0; j < nCols; j++) { +1480 dataI[j] = new BigDecimal(inI[j]); +1481 } +1482 } +1483 lu = null; +1484 } +1485 +1486 /** +1487 * Replaces data with BigDecimals represented by the strings in the input +1488 * array. +1489 * +1490 * @param in data to copy in +1491 */ +1492 private void copyIn(String[][] in) { +1493 final int nRows = in.length; +1494 final int nCols = in[0].length; +1495 data = new BigDecimal[nRows][nCols]; +1496 for (int i = 0; i < nRows; i++) { +1497 final BigDecimal[] dataI = data[i]; +1498 final String[] inI = in[i]; +1499 for (int j = 0; j < nCols; j++) { +1500 dataI[j] = new BigDecimal(inI[j]); +1501 } +1502 } +1503 lu = null; +1504 } +1505 +1506 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/BlockFieldMatrix.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/BlockFieldMatrix.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1733 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.Field; +023 import org.apache.commons.math.FieldElement; +024 import org.apache.commons.math.MathRuntimeException; +025 +026 /** +027 * Cache-friendly implementation of FieldMatrix using a flat arrays to store +028 * square blocks of the matrix. +029 * <p> +030 * This implementation is specially designed to be cache-friendly. Square blocks are +031 * stored as small arrays and allow efficient traversal of data both in row major direction +032 * and columns major direction, one block at a time. This greatly increases performances +033 * for algorithms that use crossed directions loops like multiplication or transposition. +034 * </p> +035 * <p> +036 * The size of square blocks is a static parameter. It may be tuned according to the cache +037 * size of the target computer processor. As a rule of thumbs, it should be the largest +038 * value that allows three blocks to be simultaneously cached (this is necessary for example +039 * for matrix multiplication). The default value is to use 36x36 blocks. +040 * </p> +041 * <p> +042 * The regular blocks represent {@link #BLOCK_SIZE} x {@link #BLOCK_SIZE} squares. Blocks +043 * at right hand side and bottom side which may be smaller to fit matrix dimensions. The square +044 * blocks are flattened in row major order in single dimension arrays which are therefore +045 * {@link #BLOCK_SIZE}<sup>2</sup> elements long for regular blocks. The blocks are themselves +046 * organized in row major order. +047 * </p> +048 * <p> +049 * As an example, for a block size of 36x36, a 100x60 matrix would be stored in 6 blocks. +050 * Block 0 would be a Field[1296] array holding the upper left 36x36 square, block 1 would be +051 * a Field[1296] array holding the upper center 36x36 square, block 2 would be a Field[1008] +052 * array holding the upper right 36x28 rectangle, block 3 would be a Field[864] array holding +053 * the lower left 24x36 rectangle, block 4 would be a Field[864] array holding the lower center +054 * 24x36 rectangle and block 5 would be a Field[672] array holding the lower right 24x28 +055 * rectangle. +056 * </p> +057 * <p> +058 * The layout complexity overhead versus simple mapping of matrices to java +059 * arrays is negligible for small matrices (about 1%). The gain from cache efficiency leads +060 * to up to 3-fold improvements for matrices of moderate to large size. +061 * </p> +062 * @param <T> the type of the field elements +063 * @version $Revision: 825919 $ $Date: 2009-10-16 10:51:55 -0400 (Fri, 16 Oct 2009) $ +064 * @since 2.0 +065 */ +066 public class BlockFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMatrix<T> implements Serializable { +067 +068 /** Block size. */ +069 public static final int BLOCK_SIZE = 36; +070 +071 /** Serializable version identifier */ +072 private static final long serialVersionUID = -4602336630143123183L; +073 +074 /** Blocks of matrix entries. */ +075 private final T blocks[][]; +076 +077 /** Number of rows of the matrix. */ +078 private final int rows; +079 +080 /** Number of columns of the matrix. */ +081 private final int columns; +082 +083 /** Number of block rows of the matrix. */ +084 private final int blockRows; +085 +086 /** Number of block columns of the matrix. */ +087 private final int blockColumns; +088 +089 /** +090 * Create a new matrix with the supplied row and column dimensions. +091 * +092 * @param field field to which the elements belong +093 * @param rows the number of rows in the new matrix +094 * @param columns the number of columns in the new matrix +095 * @throws IllegalArgumentException if row or column dimension is not +096 * positive +097 */ +098 public BlockFieldMatrix(final Field<T> field, final int rows, final int columns) +099 throws IllegalArgumentException { +100 +101 super(field, rows, columns); +102 this.rows = rows; +103 this.columns = columns; +104 +105 // number of blocks +106 blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; +107 blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; +108 +109 // allocate storage blocks, taking care of smaller ones at right and bottom +110 blocks = createBlocksLayout(field, rows, columns); +111 +112 } +113 +114 /** +115 * Create a new dense matrix copying entries from raw layout data. +116 * <p>The input array <em>must</em> already be in raw layout.</p> +117 * <p>Calling this constructor is equivalent to call: +118 * <pre>matrix = new BlockFieldMatrix<T>(getField(), rawData.length, rawData[0].length, +119 * toBlocksLayout(rawData), false);</pre> +120 * </p> +121 * @param rawData data for new matrix, in raw layout +122 * +123 * @exception IllegalArgumentException if <code>blockData</code> shape is +124 * inconsistent with block layout +125 * @see #BlockFieldMatrix(int, int, FieldElement[][], boolean) +126 */ +127 public BlockFieldMatrix(final T[][] rawData) +128 throws IllegalArgumentException { +129 this(rawData.length, rawData[0].length, toBlocksLayout(rawData), false); +130 } +131 +132 /** +133 * Create a new dense matrix copying entries from block layout data. +134 * <p>The input array <em>must</em> already be in blocks layout.</p> +135 * @param rows the number of rows in the new matrix +136 * @param columns the number of columns in the new matrix +137 * @param blockData data for new matrix +138 * @param copyArray if true, the input array will be copied, otherwise +139 * it will be referenced +140 * +141 * @exception IllegalArgumentException if <code>blockData</code> shape is +142 * inconsistent with block layout +143 * @see #createBlocksLayout(Field, int, int) +144 * @see #toBlocksLayout(FieldElement[][]) +145 * @see #BlockFieldMatrix(FieldElement[][]) +146 */ +147 public BlockFieldMatrix(final int rows, final int columns, +148 final T[][] blockData, final boolean copyArray) +149 throws IllegalArgumentException { +150 +151 super(extractField(blockData), rows, columns); +152 this.rows = rows; +153 this.columns = columns; +154 +155 // number of blocks +156 blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; +157 blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; +158 +159 if (copyArray) { +160 // allocate storage blocks, taking care of smaller ones at right and bottom +161 blocks = buildArray(getField(), blockRows * blockColumns, -1); +162 } else { +163 // reference existing array +164 blocks = blockData; +165 } +166 +167 int index = 0; +168 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +169 final int iHeight = blockHeight(iBlock); +170 for (int jBlock = 0; jBlock < blockColumns; ++jBlock, ++index) { +171 if (blockData[index].length != iHeight * blockWidth(jBlock)) { +172 throw MathRuntimeException.createIllegalArgumentException( +173 "wrong array shape (block length = {0}, expected {1})", +174 blockData[index].length, iHeight * blockWidth(jBlock)); +175 } +176 if (copyArray) { +177 blocks[index] = blockData[index].clone(); +178 } +179 } +180 } +181 +182 } +183 +184 /** +185 * Convert a data array from raw layout to blocks layout. +186 * <p> +187 * Raw layout is the straightforward layout where element at row i and +188 * column j is in array element <code>rawData[i][j]</code>. Blocks layout +189 * is the layout used in {@link BlockFieldMatrix} instances, where the matrix +190 * is split in square blocks (except at right and bottom side where blocks may +191 * be rectangular to fit matrix size) and each block is stored in a flattened +192 * one-dimensional array. +193 * </p> +194 * <p> +195 * This method creates an array in blocks layout from an input array in raw layout. +196 * It can be used to provide the array argument of the {@link +197 * #BlockFieldMatrix(int, int, FieldElement[][], boolean)} +198 * constructor. +199 * </p> +200 * @param <T> the type of the field elements +201 * @param rawData data array in raw layout +202 * @return a new data array containing the same entries but in blocks layout +203 * @exception IllegalArgumentException if <code>rawData</code> is not rectangular +204 * (not all rows have the same length) +205 * @see #createBlocksLayout(Field, int, int) +206 * @see #BlockFieldMatrix(int, int, FieldElement[][], boolean) +207 */ +208 public static <T extends FieldElement<T>> T[][] toBlocksLayout(final T[][] rawData) +209 throws IllegalArgumentException { +210 +211 final int rows = rawData.length; +212 final int columns = rawData[0].length; +213 final int blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; +214 final int blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; +215 +216 // safety checks +217 for (int i = 0; i < rawData.length; ++i) { +218 final int length = rawData[i].length; +219 if (length != columns) { +220 throw MathRuntimeException.createIllegalArgumentException( +221 "some rows have length {0} while others have length {1}", +222 columns, length); +223 } +224 } +225 +226 // convert array +227 final Field<T> field = extractField(rawData); +228 final T[][] blocks = buildArray(field, blockRows * blockColumns, -1); +229 int blockIndex = 0; +230 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +231 final int pStart = iBlock * BLOCK_SIZE; +232 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +233 final int iHeight = pEnd - pStart; +234 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +235 final int qStart = jBlock * BLOCK_SIZE; +236 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +237 final int jWidth = qEnd - qStart; +238 +239 // allocate new block +240 final T[] block = buildArray(field, iHeight * jWidth); +241 blocks[blockIndex] = block; +242 +243 // copy data +244 int index = 0; +245 for (int p = pStart; p < pEnd; ++p) { +246 System.arraycopy(rawData[p], qStart, block, index, jWidth); +247 index += jWidth; +248 } +249 +250 ++blockIndex; +251 +252 } +253 } +254 +255 return blocks; +256 +257 } +258 +259 /** +260 * Create a data array in blocks layout. +261 * <p> +262 * This method can be used to create the array argument of the {@link +263 * #BlockFieldMatrix(int, int, FieldElement[][], boolean)} +264 * constructor. +265 * </p> +266 * @param <T> the type of the field elements +267 * @param field field to which the elements belong +268 * @param rows the number of rows in the new matrix +269 * @param columns the number of columns in the new matrix +270 * @return a new data array in blocks layout +271 * @see #toBlocksLayout(FieldElement[][]) +272 * @see #BlockFieldMatrix(int, int, FieldElement[][], boolean) +273 */ +274 public static <T extends FieldElement<T>> T[][] createBlocksLayout(final Field<T> field, +275 final int rows, final int columns) { +276 +277 final int blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; +278 final int blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; +279 +280 final T[][] blocks = buildArray(field, blockRows * blockColumns, -1); +281 int blockIndex = 0; +282 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +283 final int pStart = iBlock * BLOCK_SIZE; +284 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +285 final int iHeight = pEnd - pStart; +286 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +287 final int qStart = jBlock * BLOCK_SIZE; +288 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +289 final int jWidth = qEnd - qStart; +290 blocks[blockIndex] = buildArray(field, iHeight * jWidth); +291 ++blockIndex; +292 } +293 } +294 +295 return blocks; +296 +297 } +298 +299 /** {@inheritDoc} */ +300 @Override +301 public FieldMatrix<T> createMatrix(final int rowDimension, final int columnDimension) +302 throws IllegalArgumentException { +303 return new BlockFieldMatrix<T>(getField(), rowDimension, columnDimension); +304 } +305 +306 /** {@inheritDoc} */ +307 @Override +308 public FieldMatrix<T> copy() { +309 +310 // create an empty matrix +311 BlockFieldMatrix<T> copied = new BlockFieldMatrix<T>(getField(), rows, columns); +312 +313 // copy the blocks +314 for (int i = 0; i < blocks.length; ++i) { +315 System.arraycopy(blocks[i], 0, copied.blocks[i], 0, blocks[i].length); +316 } +317 +318 return copied; +319 +320 } +321 +322 /** {@inheritDoc} */ +323 @Override +324 public FieldMatrix<T> add(final FieldMatrix<T> m) +325 throws IllegalArgumentException { +326 try { +327 return add((BlockFieldMatrix<T>) m); +328 } catch (ClassCastException cce) { +329 +330 // safety check +331 checkAdditionCompatible(m); +332 +333 final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, columns); +334 +335 // perform addition block-wise, to ensure good cache behavior +336 int blockIndex = 0; +337 for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { +338 for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { +339 +340 // perform addition on the current block +341 final T[] outBlock = out.blocks[blockIndex]; +342 final T[] tBlock = blocks[blockIndex]; +343 final int pStart = iBlock * BLOCK_SIZE; +344 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +345 final int qStart = jBlock * BLOCK_SIZE; +346 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +347 int k = 0; +348 for (int p = pStart; p < pEnd; ++p) { +349 for (int q = qStart; q < qEnd; ++q) { +350 outBlock[k] = tBlock[k].add(m.getEntry(p, q)); +351 ++k; +352 } +353 } +354 +355 // go to next block +356 ++blockIndex; +357 +358 } +359 } +360 +361 return out; +362 +363 } +364 } +365 +366 /** +367 * Compute the sum of this and <code>m</code>. +368 * +369 * @param m matrix to be added +370 * @return this + m +371 * @throws IllegalArgumentException if m is not the same size as this +372 */ +373 public BlockFieldMatrix<T> add(final BlockFieldMatrix<T> m) +374 throws IllegalArgumentException { +375 +376 // safety check +377 checkAdditionCompatible(m); +378 +379 final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, columns); +380 +381 // perform addition block-wise, to ensure good cache behavior +382 for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { +383 final T[] outBlock = out.blocks[blockIndex]; +384 final T[] tBlock = blocks[blockIndex]; +385 final T[] mBlock = m.blocks[blockIndex]; +386 for (int k = 0; k < outBlock.length; ++k) { +387 outBlock[k] = tBlock[k].add(mBlock[k]); +388 } +389 } +390 +391 return out; +392 +393 } +394 +395 /** {@inheritDoc} */ +396 @Override +397 public FieldMatrix<T> subtract(final FieldMatrix<T> m) +398 throws IllegalArgumentException { +399 try { +400 return subtract((BlockFieldMatrix<T>) m); +401 } catch (ClassCastException cce) { +402 +403 // safety check +404 checkSubtractionCompatible(m); +405 +406 final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, columns); +407 +408 // perform subtraction block-wise, to ensure good cache behavior +409 int blockIndex = 0; +410 for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { +411 for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { +412 +413 // perform subtraction on the current block +414 final T[] outBlock = out.blocks[blockIndex]; +415 final T[] tBlock = blocks[blockIndex]; +416 final int pStart = iBlock * BLOCK_SIZE; +417 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +418 final int qStart = jBlock * BLOCK_SIZE; +419 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +420 int k = 0; +421 for (int p = pStart; p < pEnd; ++p) { +422 for (int q = qStart; q < qEnd; ++q) { +423 outBlock[k] = tBlock[k].subtract(m.getEntry(p, q)); +424 ++k; +425 } +426 } +427 +428 // go to next block +429 ++blockIndex; +430 +431 } +432 } +433 +434 return out; +435 +436 } +437 } +438 +439 /** +440 * Compute this minus <code>m</code>. +441 * +442 * @param m matrix to be subtracted +443 * @return this - m +444 * @throws IllegalArgumentException if m is not the same size as this +445 */ +446 public BlockFieldMatrix<T> subtract(final BlockFieldMatrix<T> m) +447 throws IllegalArgumentException { +448 +449 // safety check +450 checkSubtractionCompatible(m); +451 +452 final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, columns); +453 +454 // perform subtraction block-wise, to ensure good cache behavior +455 for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { +456 final T[] outBlock = out.blocks[blockIndex]; +457 final T[] tBlock = blocks[blockIndex]; +458 final T[] mBlock = m.blocks[blockIndex]; +459 for (int k = 0; k < outBlock.length; ++k) { +460 outBlock[k] = tBlock[k].subtract(mBlock[k]); +461 } +462 } +463 +464 return out; +465 +466 } +467 +468 /** {@inheritDoc} */ +469 @Override +470 public FieldMatrix<T> scalarAdd(final T d) +471 throws IllegalArgumentException { +472 +473 final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, columns); +474 +475 // perform subtraction block-wise, to ensure good cache behavior +476 for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { +477 final T[] outBlock = out.blocks[blockIndex]; +478 final T[] tBlock = blocks[blockIndex]; +479 for (int k = 0; k < outBlock.length; ++k) { +480 outBlock[k] = tBlock[k].add(d); +481 } +482 } +483 +484 return out; +485 +486 } +487 +488 /** {@inheritDoc} */ +489 @Override +490 public FieldMatrix<T> scalarMultiply(final T d) +491 throws IllegalArgumentException { +492 +493 final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, columns); +494 +495 // perform subtraction block-wise, to ensure good cache behavior +496 for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { +497 final T[] outBlock = out.blocks[blockIndex]; +498 final T[] tBlock = blocks[blockIndex]; +499 for (int k = 0; k < outBlock.length; ++k) { +500 outBlock[k] = tBlock[k].multiply(d); +501 } +502 } +503 +504 return out; +505 +506 } +507 +508 /** {@inheritDoc} */ +509 @Override +510 public FieldMatrix<T> multiply(final FieldMatrix<T> m) +511 throws IllegalArgumentException { +512 try { +513 return multiply((BlockFieldMatrix<T>) m); +514 } catch (ClassCastException cce) { +515 +516 // safety check +517 checkMultiplicationCompatible(m); +518 +519 final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, m.getColumnDimension()); +520 final T zero = getField().getZero(); +521 +522 // perform multiplication block-wise, to ensure good cache behavior +523 int blockIndex = 0; +524 for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { +525 +526 final int pStart = iBlock * BLOCK_SIZE; +527 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +528 +529 for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { +530 +531 final int qStart = jBlock * BLOCK_SIZE; +532 final int qEnd = Math.min(qStart + BLOCK_SIZE, m.getColumnDimension()); +533 +534 // select current block +535 final T[] outBlock = out.blocks[blockIndex]; +536 +537 // perform multiplication on current block +538 for (int kBlock = 0; kBlock < blockColumns; ++kBlock) { +539 final int kWidth = blockWidth(kBlock); +540 final T[] tBlock = blocks[iBlock * blockColumns + kBlock]; +541 final int rStart = kBlock * BLOCK_SIZE; +542 int k = 0; +543 for (int p = pStart; p < pEnd; ++p) { +544 final int lStart = (p - pStart) * kWidth; +545 final int lEnd = lStart + kWidth; +546 for (int q = qStart; q < qEnd; ++q) { +547 T sum = zero; +548 int r = rStart; +549 for (int l = lStart; l < lEnd; ++l) { +550 sum = sum.add(tBlock[l].multiply(m.getEntry(r, q))); +551 ++r; +552 } +553 outBlock[k] = outBlock[k].add(sum); +554 ++k; +555 } +556 } +557 } +558 +559 // go to next block +560 ++blockIndex; +561 +562 } +563 } +564 +565 return out; +566 +567 } +568 } +569 +570 /** +571 * Returns the result of postmultiplying this by m. +572 * +573 * @param m matrix to postmultiply by +574 * @return this * m +575 * @throws IllegalArgumentException +576 * if columnDimension(this) != rowDimension(m) +577 */ +578 public BlockFieldMatrix<T> multiply(BlockFieldMatrix<T> m) throws IllegalArgumentException { +579 +580 // safety check +581 checkMultiplicationCompatible(m); +582 +583 final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, m.columns); +584 final T zero = getField().getZero(); +585 +586 // perform multiplication block-wise, to ensure good cache behavior +587 int blockIndex = 0; +588 for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { +589 +590 final int pStart = iBlock * BLOCK_SIZE; +591 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +592 +593 for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { +594 final int jWidth = out.blockWidth(jBlock); +595 final int jWidth2 = jWidth + jWidth; +596 final int jWidth3 = jWidth2 + jWidth; +597 final int jWidth4 = jWidth3 + jWidth; +598 +599 // select current block +600 final T[] outBlock = out.blocks[blockIndex]; +601 +602 // perform multiplication on current block +603 for (int kBlock = 0; kBlock < blockColumns; ++kBlock) { +604 final int kWidth = blockWidth(kBlock); +605 final T[] tBlock = blocks[iBlock * blockColumns + kBlock]; +606 final T[] mBlock = m.blocks[kBlock * m.blockColumns + jBlock]; +607 int k = 0; +608 for (int p = pStart; p < pEnd; ++p) { +609 final int lStart = (p - pStart) * kWidth; +610 final int lEnd = lStart + kWidth; +611 for (int nStart = 0; nStart < jWidth; ++nStart) { +612 T sum = zero; +613 int l = lStart; +614 int n = nStart; +615 while (l < lEnd - 3) { +616 sum = sum. +617 add(tBlock[l].multiply(mBlock[n])). +618 add(tBlock[l + 1].multiply(mBlock[n + jWidth])). +619 add(tBlock[l + 2].multiply(mBlock[n + jWidth2])). +620 add(tBlock[l + 3].multiply(mBlock[n + jWidth3])); +621 l += 4; +622 n += jWidth4; +623 } +624 while (l < lEnd) { +625 sum = sum.add(tBlock[l++].multiply(mBlock[n])); +626 n += jWidth; +627 } +628 outBlock[k] = outBlock[k].add(sum); +629 ++k; +630 } +631 } +632 } +633 +634 // go to next block +635 ++blockIndex; +636 +637 } +638 } +639 +640 return out; +641 +642 } +643 +644 /** {@inheritDoc} */ +645 @Override +646 public T[][] getData() { +647 +648 final T[][] data = buildArray(getField(), getRowDimension(), getColumnDimension()); +649 final int lastColumns = columns - (blockColumns - 1) * BLOCK_SIZE; +650 +651 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +652 final int pStart = iBlock * BLOCK_SIZE; +653 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +654 int regularPos = 0; +655 int lastPos = 0; +656 for (int p = pStart; p < pEnd; ++p) { +657 final T[] dataP = data[p]; +658 int blockIndex = iBlock * blockColumns; +659 int dataPos = 0; +660 for (int jBlock = 0; jBlock < blockColumns - 1; ++jBlock) { +661 System.arraycopy(blocks[blockIndex++], regularPos, dataP, dataPos, BLOCK_SIZE); +662 dataPos += BLOCK_SIZE; +663 } +664 System.arraycopy(blocks[blockIndex], lastPos, dataP, dataPos, lastColumns); +665 regularPos += BLOCK_SIZE; +666 lastPos += lastColumns; +667 } +668 } +669 +670 return data; +671 +672 } +673 +674 /** {@inheritDoc} */ +675 @Override +676 public FieldMatrix<T> getSubMatrix(final int startRow, final int endRow, +677 final int startColumn, final int endColumn) +678 throws MatrixIndexException { +679 +680 // safety checks +681 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +682 +683 // create the output matrix +684 final BlockFieldMatrix<T> out = +685 new BlockFieldMatrix<T>(getField(), endRow - startRow + 1, endColumn - startColumn + 1); +686 +687 // compute blocks shifts +688 final int blockStartRow = startRow / BLOCK_SIZE; +689 final int rowsShift = startRow % BLOCK_SIZE; +690 final int blockStartColumn = startColumn / BLOCK_SIZE; +691 final int columnsShift = startColumn % BLOCK_SIZE; +692 +693 // perform extraction block-wise, to ensure good cache behavior +694 int pBlock = blockStartRow; +695 for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { +696 final int iHeight = out.blockHeight(iBlock); +697 int qBlock = blockStartColumn; +698 for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { +699 final int jWidth = out.blockWidth(jBlock); +700 +701 // handle one block of the output matrix +702 final int outIndex = iBlock * out.blockColumns + jBlock; +703 final T[] outBlock = out.blocks[outIndex]; +704 final int index = pBlock * blockColumns + qBlock; +705 final int width = blockWidth(qBlock); +706 +707 final int heightExcess = iHeight + rowsShift - BLOCK_SIZE; +708 final int widthExcess = jWidth + columnsShift - BLOCK_SIZE; +709 if (heightExcess > 0) { +710 // the submatrix block spans on two blocks rows from the original matrix +711 if (widthExcess > 0) { +712 // the submatrix block spans on two blocks columns from the original matrix +713 final int width2 = blockWidth(qBlock + 1); +714 copyBlockPart(blocks[index], width, +715 rowsShift, BLOCK_SIZE, +716 columnsShift, BLOCK_SIZE, +717 outBlock, jWidth, 0, 0); +718 copyBlockPart(blocks[index + 1], width2, +719 rowsShift, BLOCK_SIZE, +720 0, widthExcess, +721 outBlock, jWidth, 0, jWidth - widthExcess); +722 copyBlockPart(blocks[index + blockColumns], width, +723 0, heightExcess, +724 columnsShift, BLOCK_SIZE, +725 outBlock, jWidth, iHeight - heightExcess, 0); +726 copyBlockPart(blocks[index + blockColumns + 1], width2, +727 0, heightExcess, +728 0, widthExcess, +729 outBlock, jWidth, iHeight - heightExcess, jWidth - widthExcess); +730 } else { +731 // the submatrix block spans on one block column from the original matrix +732 copyBlockPart(blocks[index], width, +733 rowsShift, BLOCK_SIZE, +734 columnsShift, jWidth + columnsShift, +735 outBlock, jWidth, 0, 0); +736 copyBlockPart(blocks[index + blockColumns], width, +737 0, heightExcess, +738 columnsShift, jWidth + columnsShift, +739 outBlock, jWidth, iHeight - heightExcess, 0); +740 } +741 } else { +742 // the submatrix block spans on one block row from the original matrix +743 if (widthExcess > 0) { +744 // the submatrix block spans on two blocks columns from the original matrix +745 final int width2 = blockWidth(qBlock + 1); +746 copyBlockPart(blocks[index], width, +747 rowsShift, iHeight + rowsShift, +748 columnsShift, BLOCK_SIZE, +749 outBlock, jWidth, 0, 0); +750 copyBlockPart(blocks[index + 1], width2, +751 rowsShift, iHeight + rowsShift, +752 0, widthExcess, +753 outBlock, jWidth, 0, jWidth - widthExcess); +754 } else { +755 // the submatrix block spans on one block column from the original matrix +756 copyBlockPart(blocks[index], width, +757 rowsShift, iHeight + rowsShift, +758 columnsShift, jWidth + columnsShift, +759 outBlock, jWidth, 0, 0); +760 } +761 } +762 +763 ++qBlock; +764 } +765 +766 ++pBlock; +767 +768 } +769 +770 return out; +771 +772 } +773 +774 /** +775 * Copy a part of a block into another one +776 * <p>This method can be called only when the specified part fits in both +777 * blocks, no verification is done here.</p> +778 * @param srcBlock source block +779 * @param srcWidth source block width ({@link #BLOCK_SIZE} or smaller) +780 * @param srcStartRow start row in the source block +781 * @param srcEndRow end row (exclusive) in the source block +782 * @param srcStartColumn start column in the source block +783 * @param srcEndColumn end column (exclusive) in the source block +784 * @param dstBlock destination block +785 * @param dstWidth destination block width ({@link #BLOCK_SIZE} or smaller) +786 * @param dstStartRow start row in the destination block +787 * @param dstStartColumn start column in the destination block +788 */ +789 private void copyBlockPart(final T[] srcBlock, final int srcWidth, +790 final int srcStartRow, final int srcEndRow, +791 final int srcStartColumn, final int srcEndColumn, +792 final T[] dstBlock, final int dstWidth, +793 final int dstStartRow, final int dstStartColumn) { +794 final int length = srcEndColumn - srcStartColumn; +795 int srcPos = srcStartRow * srcWidth + srcStartColumn; +796 int dstPos = dstStartRow * dstWidth + dstStartColumn; +797 for (int srcRow = srcStartRow; srcRow < srcEndRow; ++srcRow) { +798 System.arraycopy(srcBlock, srcPos, dstBlock, dstPos, length); +799 srcPos += srcWidth; +800 dstPos += dstWidth; +801 } +802 } +803 +804 /** {@inheritDoc} */ +805 @Override +806 public void setSubMatrix(final T[][] subMatrix, final int row, final int column) +807 throws MatrixIndexException { +808 +809 // safety checks +810 final int refLength = subMatrix[0].length; +811 if (refLength < 1) { +812 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column"); +813 } +814 final int endRow = row + subMatrix.length - 1; +815 final int endColumn = column + refLength - 1; +816 checkSubMatrixIndex(row, endRow, column, endColumn); +817 for (final T[] subRow : subMatrix) { +818 if (subRow.length != refLength) { +819 throw MathRuntimeException.createIllegalArgumentException( +820 "some rows have length {0} while others have length {1}", +821 refLength, subRow.length); +822 } +823 } +824 +825 // compute blocks bounds +826 final int blockStartRow = row / BLOCK_SIZE; +827 final int blockEndRow = (endRow + BLOCK_SIZE) / BLOCK_SIZE; +828 final int blockStartColumn = column / BLOCK_SIZE; +829 final int blockEndColumn = (endColumn + BLOCK_SIZE) / BLOCK_SIZE; +830 +831 // perform copy block-wise, to ensure good cache behavior +832 for (int iBlock = blockStartRow; iBlock < blockEndRow; ++iBlock) { +833 final int iHeight = blockHeight(iBlock); +834 final int firstRow = iBlock * BLOCK_SIZE; +835 final int iStart = Math.max(row, firstRow); +836 final int iEnd = Math.min(endRow + 1, firstRow + iHeight); +837 +838 for (int jBlock = blockStartColumn; jBlock < blockEndColumn; ++jBlock) { +839 final int jWidth = blockWidth(jBlock); +840 final int firstColumn = jBlock * BLOCK_SIZE; +841 final int jStart = Math.max(column, firstColumn); +842 final int jEnd = Math.min(endColumn + 1, firstColumn + jWidth); +843 final int jLength = jEnd - jStart; +844 +845 // handle one block, row by row +846 final T[] block = blocks[iBlock * blockColumns + jBlock]; +847 for (int i = iStart; i < iEnd; ++i) { +848 System.arraycopy(subMatrix[i - row], jStart - column, +849 block, (i - firstRow) * jWidth + (jStart - firstColumn), +850 jLength); +851 } +852 +853 } +854 } +855 } +856 +857 /** {@inheritDoc} */ +858 @Override +859 public FieldMatrix<T> getRowMatrix(final int row) +860 throws MatrixIndexException { +861 +862 checkRowIndex(row); +863 final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), 1, columns); +864 +865 // perform copy block-wise, to ensure good cache behavior +866 final int iBlock = row / BLOCK_SIZE; +867 final int iRow = row - iBlock * BLOCK_SIZE; +868 int outBlockIndex = 0; +869 int outIndex = 0; +870 T[] outBlock = out.blocks[outBlockIndex]; +871 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +872 final int jWidth = blockWidth(jBlock); +873 final T[] block = blocks[iBlock * blockColumns + jBlock]; +874 final int available = outBlock.length - outIndex; +875 if (jWidth > available) { +876 System.arraycopy(block, iRow * jWidth, outBlock, outIndex, available); +877 outBlock = out.blocks[++outBlockIndex]; +878 System.arraycopy(block, iRow * jWidth, outBlock, 0, jWidth - available); +879 outIndex = jWidth - available; +880 } else { +881 System.arraycopy(block, iRow * jWidth, outBlock, outIndex, jWidth); +882 outIndex += jWidth; +883 } +884 } +885 +886 return out; +887 +888 } +889 +890 /** {@inheritDoc} */ +891 @Override +892 public void setRowMatrix(final int row, final FieldMatrix<T> matrix) +893 throws MatrixIndexException, InvalidMatrixException { +894 try { +895 setRowMatrix(row, (BlockFieldMatrix<T>) matrix); +896 } catch (ClassCastException cce) { +897 super.setRowMatrix(row, matrix); +898 } +899 } +900 +901 /** +902 * Sets the entries in row number <code>row</code> +903 * as a row matrix. Row indices start at 0. +904 * +905 * @param row the row to be set +906 * @param matrix row matrix (must have one row and the same number of columns +907 * as the instance) +908 * @throws MatrixIndexException if the specified row index is invalid +909 * @throws InvalidMatrixException if the matrix dimensions do not match one +910 * instance row +911 */ +912 public void setRowMatrix(final int row, final BlockFieldMatrix<T> matrix) +913 throws MatrixIndexException, InvalidMatrixException { +914 +915 checkRowIndex(row); +916 final int nCols = getColumnDimension(); +917 if ((matrix.getRowDimension() != 1) || +918 (matrix.getColumnDimension() != nCols)) { +919 throw new InvalidMatrixException( +920 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +921 matrix.getRowDimension(), matrix.getColumnDimension(), +922 1, nCols); +923 } +924 +925 // perform copy block-wise, to ensure good cache behavior +926 final int iBlock = row / BLOCK_SIZE; +927 final int iRow = row - iBlock * BLOCK_SIZE; +928 int mBlockIndex = 0; +929 int mIndex = 0; +930 T[] mBlock = matrix.blocks[mBlockIndex]; +931 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +932 final int jWidth = blockWidth(jBlock); +933 final T[] block = blocks[iBlock * blockColumns + jBlock]; +934 final int available = mBlock.length - mIndex; +935 if (jWidth > available) { +936 System.arraycopy(mBlock, mIndex, block, iRow * jWidth, available); +937 mBlock = matrix.blocks[++mBlockIndex]; +938 System.arraycopy(mBlock, 0, block, iRow * jWidth, jWidth - available); +939 mIndex = jWidth - available; +940 } else { +941 System.arraycopy(mBlock, mIndex, block, iRow * jWidth, jWidth); +942 mIndex += jWidth; +943 } +944 } +945 +946 } +947 +948 /** {@inheritDoc} */ +949 @Override +950 public FieldMatrix<T> getColumnMatrix(final int column) +951 throws MatrixIndexException { +952 +953 checkColumnIndex(column); +954 final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, 1); +955 +956 // perform copy block-wise, to ensure good cache behavior +957 final int jBlock = column / BLOCK_SIZE; +958 final int jColumn = column - jBlock * BLOCK_SIZE; +959 final int jWidth = blockWidth(jBlock); +960 int outBlockIndex = 0; +961 int outIndex = 0; +962 T[] outBlock = out.blocks[outBlockIndex]; +963 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +964 final int iHeight = blockHeight(iBlock); +965 final T[] block = blocks[iBlock * blockColumns + jBlock]; +966 for (int i = 0; i < iHeight; ++i) { +967 if (outIndex >= outBlock.length) { +968 outBlock = out.blocks[++outBlockIndex]; +969 outIndex = 0; +970 } +971 outBlock[outIndex++] = block[i * jWidth + jColumn]; +972 } +973 } +974 +975 return out; +976 +977 } +978 +979 /** {@inheritDoc} */ +980 @Override +981 public void setColumnMatrix(final int column, final FieldMatrix<T> matrix) +982 throws MatrixIndexException, InvalidMatrixException { +983 try { +984 setColumnMatrix(column, (BlockFieldMatrix<T>) matrix); +985 } catch (ClassCastException cce) { +986 super.setColumnMatrix(column, matrix); +987 } +988 } +989 +990 /** +991 * Sets the entries in column number <code>column</code> +992 * as a column matrix. Column indices start at 0. +993 * +994 * @param column the column to be set +995 * @param matrix column matrix (must have one column and the same number of rows +996 * as the instance) +997 * @throws MatrixIndexException if the specified column index is invalid +998 * @throws InvalidMatrixException if the matrix dimensions do not match one +999 * instance column +1000 */ +1001 void setColumnMatrix(final int column, final BlockFieldMatrix<T> matrix) +1002 throws MatrixIndexException, InvalidMatrixException { +1003 +1004 checkColumnIndex(column); +1005 final int nRows = getRowDimension(); +1006 if ((matrix.getRowDimension() != nRows) || +1007 (matrix.getColumnDimension() != 1)) { +1008 throw new InvalidMatrixException( +1009 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +1010 matrix.getRowDimension(), matrix.getColumnDimension(), +1011 nRows, 1); +1012 } +1013 +1014 // perform copy block-wise, to ensure good cache behavior +1015 final int jBlock = column / BLOCK_SIZE; +1016 final int jColumn = column - jBlock * BLOCK_SIZE; +1017 final int jWidth = blockWidth(jBlock); +1018 int mBlockIndex = 0; +1019 int mIndex = 0; +1020 T[] mBlock = matrix.blocks[mBlockIndex]; +1021 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1022 final int iHeight = blockHeight(iBlock); +1023 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1024 for (int i = 0; i < iHeight; ++i) { +1025 if (mIndex >= mBlock.length) { +1026 mBlock = matrix.blocks[++mBlockIndex]; +1027 mIndex = 0; +1028 } +1029 block[i * jWidth + jColumn] = mBlock[mIndex++]; +1030 } +1031 } +1032 +1033 } +1034 +1035 /** {@inheritDoc} */ +1036 @Override +1037 public FieldVector<T> getRowVector(final int row) +1038 throws MatrixIndexException { +1039 +1040 checkRowIndex(row); +1041 final T[] outData = buildArray(getField(), columns); +1042 +1043 // perform copy block-wise, to ensure good cache behavior +1044 final int iBlock = row / BLOCK_SIZE; +1045 final int iRow = row - iBlock * BLOCK_SIZE; +1046 int outIndex = 0; +1047 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1048 final int jWidth = blockWidth(jBlock); +1049 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1050 System.arraycopy(block, iRow * jWidth, outData, outIndex, jWidth); +1051 outIndex += jWidth; +1052 } +1053 +1054 return new ArrayFieldVector<T>(outData, false); +1055 +1056 } +1057 +1058 /** {@inheritDoc} */ +1059 @Override +1060 public void setRowVector(final int row, final FieldVector<T> vector) +1061 throws MatrixIndexException, InvalidMatrixException { +1062 try { +1063 setRow(row, ((ArrayFieldVector<T>) vector).getDataRef()); +1064 } catch (ClassCastException cce) { +1065 super.setRowVector(row, vector); +1066 } +1067 } +1068 +1069 /** {@inheritDoc} */ +1070 @Override +1071 public FieldVector<T> getColumnVector(final int column) +1072 throws MatrixIndexException { +1073 +1074 checkColumnIndex(column); +1075 final T[] outData = buildArray(getField(), rows); +1076 +1077 // perform copy block-wise, to ensure good cache behavior +1078 final int jBlock = column / BLOCK_SIZE; +1079 final int jColumn = column - jBlock * BLOCK_SIZE; +1080 final int jWidth = blockWidth(jBlock); +1081 int outIndex = 0; +1082 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1083 final int iHeight = blockHeight(iBlock); +1084 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1085 for (int i = 0; i < iHeight; ++i) { +1086 outData[outIndex++] = block[i * jWidth + jColumn]; +1087 } +1088 } +1089 +1090 return new ArrayFieldVector<T>(outData, false); +1091 +1092 } +1093 +1094 /** {@inheritDoc} */ +1095 @Override +1096 public void setColumnVector(final int column, final FieldVector<T> vector) +1097 throws MatrixIndexException, InvalidMatrixException { +1098 try { +1099 setColumn(column, ((ArrayFieldVector<T>) vector).getDataRef()); +1100 } catch (ClassCastException cce) { +1101 super.setColumnVector(column, vector); +1102 } +1103 } +1104 +1105 /** {@inheritDoc} */ +1106 @Override +1107 public T[] getRow(final int row) +1108 throws MatrixIndexException { +1109 +1110 checkRowIndex(row); +1111 final T[] out = buildArray(getField(), columns); +1112 +1113 // perform copy block-wise, to ensure good cache behavior +1114 final int iBlock = row / BLOCK_SIZE; +1115 final int iRow = row - iBlock * BLOCK_SIZE; +1116 int outIndex = 0; +1117 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1118 final int jWidth = blockWidth(jBlock); +1119 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1120 System.arraycopy(block, iRow * jWidth, out, outIndex, jWidth); +1121 outIndex += jWidth; +1122 } +1123 +1124 return out; +1125 +1126 } +1127 +1128 /** {@inheritDoc} */ +1129 @Override +1130 public void setRow(final int row, final T[] array) +1131 throws MatrixIndexException, InvalidMatrixException { +1132 +1133 checkRowIndex(row); +1134 final int nCols = getColumnDimension(); +1135 if (array.length != nCols) { +1136 throw new InvalidMatrixException( +1137 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +1138 1, array.length, 1, nCols); +1139 } +1140 +1141 // perform copy block-wise, to ensure good cache behavior +1142 final int iBlock = row / BLOCK_SIZE; +1143 final int iRow = row - iBlock * BLOCK_SIZE; +1144 int outIndex = 0; +1145 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1146 final int jWidth = blockWidth(jBlock); +1147 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1148 System.arraycopy(array, outIndex, block, iRow * jWidth, jWidth); +1149 outIndex += jWidth; +1150 } +1151 +1152 } +1153 +1154 /** {@inheritDoc} */ +1155 @Override +1156 public T[] getColumn(final int column) +1157 throws MatrixIndexException { +1158 +1159 checkColumnIndex(column); +1160 final T[] out = buildArray(getField(), rows); +1161 +1162 // perform copy block-wise, to ensure good cache behavior +1163 final int jBlock = column / BLOCK_SIZE; +1164 final int jColumn = column - jBlock * BLOCK_SIZE; +1165 final int jWidth = blockWidth(jBlock); +1166 int outIndex = 0; +1167 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1168 final int iHeight = blockHeight(iBlock); +1169 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1170 for (int i = 0; i < iHeight; ++i) { +1171 out[outIndex++] = block[i * jWidth + jColumn]; +1172 } +1173 } +1174 +1175 return out; +1176 +1177 } +1178 +1179 /** {@inheritDoc} */ +1180 @Override +1181 public void setColumn(final int column, final T[] array) +1182 throws MatrixIndexException, InvalidMatrixException { +1183 +1184 checkColumnIndex(column); +1185 final int nRows = getRowDimension(); +1186 if (array.length != nRows) { +1187 throw new InvalidMatrixException( +1188 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +1189 array.length, 1, nRows, 1); +1190 } +1191 +1192 // perform copy block-wise, to ensure good cache behavior +1193 final int jBlock = column / BLOCK_SIZE; +1194 final int jColumn = column - jBlock * BLOCK_SIZE; +1195 final int jWidth = blockWidth(jBlock); +1196 int outIndex = 0; +1197 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1198 final int iHeight = blockHeight(iBlock); +1199 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1200 for (int i = 0; i < iHeight; ++i) { +1201 block[i * jWidth + jColumn] = array[outIndex++]; +1202 } +1203 } +1204 +1205 } +1206 +1207 /** {@inheritDoc} */ +1208 @Override +1209 public T getEntry(final int row, final int column) +1210 throws MatrixIndexException { +1211 try { +1212 final int iBlock = row / BLOCK_SIZE; +1213 final int jBlock = column / BLOCK_SIZE; +1214 final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + +1215 (column - jBlock * BLOCK_SIZE); +1216 return blocks[iBlock * blockColumns + jBlock][k]; +1217 } catch (ArrayIndexOutOfBoundsException e) { +1218 throw new MatrixIndexException( +1219 "no entry at indices ({0}, {1}) in a {2}x{3} matrix", +1220 row, column, getRowDimension(), getColumnDimension()); +1221 } +1222 } +1223 +1224 /** {@inheritDoc} */ +1225 @Override +1226 public void setEntry(final int row, final int column, final T value) +1227 throws MatrixIndexException { +1228 try { +1229 final int iBlock = row / BLOCK_SIZE; +1230 final int jBlock = column / BLOCK_SIZE; +1231 final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + +1232 (column - jBlock * BLOCK_SIZE); +1233 blocks[iBlock * blockColumns + jBlock][k] = value; +1234 } catch (ArrayIndexOutOfBoundsException e) { +1235 throw new MatrixIndexException( +1236 "no entry at indices ({0}, {1}) in a {2}x{3} matrix", +1237 row, column, getRowDimension(), getColumnDimension()); +1238 } +1239 } +1240 +1241 /** {@inheritDoc} */ +1242 @Override +1243 public void addToEntry(final int row, final int column, final T increment) +1244 throws MatrixIndexException { +1245 try { +1246 final int iBlock = row / BLOCK_SIZE; +1247 final int jBlock = column / BLOCK_SIZE; +1248 final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + +1249 (column - jBlock * BLOCK_SIZE); +1250 final T[] blockIJ = blocks[iBlock * blockColumns + jBlock]; +1251 blockIJ[k] = blockIJ[k].add(increment); +1252 } catch (ArrayIndexOutOfBoundsException e) { +1253 throw new MatrixIndexException( +1254 "no entry at indices ({0}, {1}) in a {2}x{3} matrix", +1255 row, column, getRowDimension(), getColumnDimension()); +1256 } +1257 } +1258 +1259 /** {@inheritDoc} */ +1260 @Override +1261 public void multiplyEntry(final int row, final int column, final T factor) +1262 throws MatrixIndexException { +1263 try { +1264 final int iBlock = row / BLOCK_SIZE; +1265 final int jBlock = column / BLOCK_SIZE; +1266 final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + +1267 (column - jBlock * BLOCK_SIZE); +1268 final T[] blockIJ = blocks[iBlock * blockColumns + jBlock]; +1269 blockIJ[k] = blockIJ[k].multiply(factor); +1270 } catch (ArrayIndexOutOfBoundsException e) { +1271 throw new MatrixIndexException( +1272 "no entry at indices ({0}, {1}) in a {2}x{3} matrix", +1273 row, column, getRowDimension(), getColumnDimension()); +1274 } +1275 } +1276 +1277 /** {@inheritDoc} */ +1278 @Override +1279 public FieldMatrix<T> transpose() { +1280 +1281 final int nRows = getRowDimension(); +1282 final int nCols = getColumnDimension(); +1283 final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), nCols, nRows); +1284 +1285 // perform transpose block-wise, to ensure good cache behavior +1286 int blockIndex = 0; +1287 for (int iBlock = 0; iBlock < blockColumns; ++iBlock) { +1288 for (int jBlock = 0; jBlock < blockRows; ++jBlock) { +1289 +1290 // transpose current block +1291 final T[] outBlock = out.blocks[blockIndex]; +1292 final T[] tBlock = blocks[jBlock * blockColumns + iBlock]; +1293 final int pStart = iBlock * BLOCK_SIZE; +1294 final int pEnd = Math.min(pStart + BLOCK_SIZE, columns); +1295 final int qStart = jBlock * BLOCK_SIZE; +1296 final int qEnd = Math.min(qStart + BLOCK_SIZE, rows); +1297 int k = 0; +1298 for (int p = pStart; p < pEnd; ++p) { +1299 final int lInc = pEnd - pStart; +1300 int l = p - pStart; +1301 for (int q = qStart; q < qEnd; ++q) { +1302 outBlock[k] = tBlock[l]; +1303 ++k; +1304 l+= lInc; +1305 } +1306 } +1307 +1308 // go to next block +1309 ++blockIndex; +1310 +1311 } +1312 } +1313 +1314 return out; +1315 +1316 } +1317 +1318 /** {@inheritDoc} */ +1319 @Override +1320 public int getRowDimension() { +1321 return rows; +1322 } +1323 +1324 /** {@inheritDoc} */ +1325 @Override +1326 public int getColumnDimension() { +1327 return columns; +1328 } +1329 +1330 /** {@inheritDoc} */ +1331 @Override +1332 public T[] operate(final T[] v) +1333 throws IllegalArgumentException { +1334 +1335 if (v.length != columns) { +1336 throw MathRuntimeException.createIllegalArgumentException( +1337 "vector length mismatch: got {0} but expected {1}", +1338 v.length, columns); +1339 } +1340 final T[] out = buildArray(getField(), rows); +1341 final T zero = getField().getZero(); +1342 +1343 // perform multiplication block-wise, to ensure good cache behavior +1344 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1345 final int pStart = iBlock * BLOCK_SIZE; +1346 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +1347 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1348 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1349 final int qStart = jBlock * BLOCK_SIZE; +1350 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +1351 int k = 0; +1352 for (int p = pStart; p < pEnd; ++p) { +1353 T sum = zero; +1354 int q = qStart; +1355 while (q < qEnd - 3) { +1356 sum = sum. +1357 add(block[k].multiply(v[q])). +1358 add(block[k + 1].multiply(v[q + 1])). +1359 add(block[k + 2].multiply(v[q + 2])). +1360 add(block[k + 3].multiply(v[q + 3])); +1361 k += 4; +1362 q += 4; +1363 } +1364 while (q < qEnd) { +1365 sum = sum.add(block[k++].multiply(v[q++])); +1366 } +1367 out[p] = out[p].add(sum); +1368 } +1369 } +1370 } +1371 +1372 return out; +1373 +1374 } +1375 +1376 /** {@inheritDoc} */ +1377 @Override +1378 public T[] preMultiply(final T[] v) +1379 throws IllegalArgumentException { +1380 +1381 if (v.length != rows) { +1382 throw MathRuntimeException.createIllegalArgumentException( +1383 "vector length mismatch: got {0} but expected {1}", +1384 v.length, rows); +1385 } +1386 final T[] out = buildArray(getField(), columns); +1387 final T zero = getField().getZero(); +1388 +1389 // perform multiplication block-wise, to ensure good cache behavior +1390 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1391 final int jWidth = blockWidth(jBlock); +1392 final int jWidth2 = jWidth + jWidth; +1393 final int jWidth3 = jWidth2 + jWidth; +1394 final int jWidth4 = jWidth3 + jWidth; +1395 final int qStart = jBlock * BLOCK_SIZE; +1396 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +1397 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1398 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1399 final int pStart = iBlock * BLOCK_SIZE; +1400 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +1401 for (int q = qStart; q < qEnd; ++q) { +1402 int k = q - qStart; +1403 T sum = zero; +1404 int p = pStart; +1405 while (p < pEnd - 3) { +1406 sum = sum. +1407 add(block[k].multiply(v[p])). +1408 add(block[k + jWidth].multiply(v[p + 1])). +1409 add(block[k + jWidth2].multiply(v[p + 2])). +1410 add(block[k + jWidth3].multiply(v[p + 3])); +1411 k += jWidth4; +1412 p += 4; +1413 } +1414 while (p < pEnd) { +1415 sum = sum.add(block[k].multiply(v[p++])); +1416 k += jWidth; +1417 } +1418 out[q] = out[q].add(sum); +1419 } +1420 } +1421 } +1422 +1423 return out; +1424 +1425 } +1426 +1427 /** {@inheritDoc} */ +1428 @Override +1429 public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor) +1430 throws MatrixVisitorException { +1431 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +1432 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1433 final int pStart = iBlock * BLOCK_SIZE; +1434 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +1435 for (int p = pStart; p < pEnd; ++p) { +1436 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1437 final int jWidth = blockWidth(jBlock); +1438 final int qStart = jBlock * BLOCK_SIZE; +1439 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +1440 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1441 int k = (p - pStart) * jWidth; +1442 for (int q = qStart; q < qEnd; ++q) { +1443 block[k] = visitor.visit(p, q, block[k]); +1444 ++k; +1445 } +1446 } +1447 } +1448 } +1449 return visitor.end(); +1450 } +1451 +1452 /** {@inheritDoc} */ +1453 @Override +1454 public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor) +1455 throws MatrixVisitorException { +1456 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +1457 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1458 final int pStart = iBlock * BLOCK_SIZE; +1459 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +1460 for (int p = pStart; p < pEnd; ++p) { +1461 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1462 final int jWidth = blockWidth(jBlock); +1463 final int qStart = jBlock * BLOCK_SIZE; +1464 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +1465 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1466 int k = (p - pStart) * jWidth; +1467 for (int q = qStart; q < qEnd; ++q) { +1468 visitor.visit(p, q, block[k]); +1469 ++k; +1470 } +1471 } +1472 } +1473 } +1474 return visitor.end(); +1475 } +1476 +1477 /** {@inheritDoc} */ +1478 @Override +1479 public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor, +1480 final int startRow, final int endRow, +1481 final int startColumn, final int endColumn) +1482 throws MatrixIndexException, MatrixVisitorException { +1483 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +1484 visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); +1485 for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { +1486 final int p0 = iBlock * BLOCK_SIZE; +1487 final int pStart = Math.max(startRow, p0); +1488 final int pEnd = Math.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); +1489 for (int p = pStart; p < pEnd; ++p) { +1490 for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { +1491 final int jWidth = blockWidth(jBlock); +1492 final int q0 = jBlock * BLOCK_SIZE; +1493 final int qStart = Math.max(startColumn, q0); +1494 final int qEnd = Math.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); +1495 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1496 int k = (p - p0) * jWidth + qStart - q0; +1497 for (int q = qStart; q < qEnd; ++q) { +1498 block[k] = visitor.visit(p, q, block[k]); +1499 ++k; +1500 } +1501 } +1502 } +1503 } +1504 return visitor.end(); +1505 } +1506 +1507 /** {@inheritDoc} */ +1508 @Override +1509 public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor, +1510 final int startRow, final int endRow, +1511 final int startColumn, final int endColumn) +1512 throws MatrixIndexException, MatrixVisitorException { +1513 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +1514 visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); +1515 for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { +1516 final int p0 = iBlock * BLOCK_SIZE; +1517 final int pStart = Math.max(startRow, p0); +1518 final int pEnd = Math.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); +1519 for (int p = pStart; p < pEnd; ++p) { +1520 for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { +1521 final int jWidth = blockWidth(jBlock); +1522 final int q0 = jBlock * BLOCK_SIZE; +1523 final int qStart = Math.max(startColumn, q0); +1524 final int qEnd = Math.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); +1525 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1526 int k = (p - p0) * jWidth + qStart - q0; +1527 for (int q = qStart; q < qEnd; ++q) { +1528 visitor.visit(p, q, block[k]); +1529 ++k; +1530 } +1531 } +1532 } +1533 } +1534 return visitor.end(); +1535 } +1536 +1537 /** {@inheritDoc} */ +1538 @Override +1539 public T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor) +1540 throws MatrixVisitorException { +1541 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +1542 int blockIndex = 0; +1543 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1544 final int pStart = iBlock * BLOCK_SIZE; +1545 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +1546 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1547 final int qStart = jBlock * BLOCK_SIZE; +1548 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +1549 final T[] block = blocks[blockIndex]; +1550 int k = 0; +1551 for (int p = pStart; p < pEnd; ++p) { +1552 for (int q = qStart; q < qEnd; ++q) { +1553 block[k] = visitor.visit(p, q, block[k]); +1554 ++k; +1555 } +1556 } +1557 ++blockIndex; +1558 } +1559 } +1560 return visitor.end(); +1561 } +1562 +1563 /** {@inheritDoc} */ +1564 @Override +1565 public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor) +1566 throws MatrixVisitorException { +1567 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +1568 int blockIndex = 0; +1569 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1570 final int pStart = iBlock * BLOCK_SIZE; +1571 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +1572 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1573 final int qStart = jBlock * BLOCK_SIZE; +1574 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +1575 final T[] block = blocks[blockIndex]; +1576 int k = 0; +1577 for (int p = pStart; p < pEnd; ++p) { +1578 for (int q = qStart; q < qEnd; ++q) { +1579 visitor.visit(p, q, block[k]); +1580 ++k; +1581 } +1582 } +1583 ++blockIndex; +1584 } +1585 } +1586 return visitor.end(); +1587 } +1588 +1589 /** {@inheritDoc} */ +1590 @Override +1591 public T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor, +1592 final int startRow, final int endRow, +1593 final int startColumn, final int endColumn) +1594 throws MatrixIndexException, MatrixVisitorException { +1595 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +1596 visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); +1597 for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { +1598 final int p0 = iBlock * BLOCK_SIZE; +1599 final int pStart = Math.max(startRow, p0); +1600 final int pEnd = Math.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); +1601 for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { +1602 final int jWidth = blockWidth(jBlock); +1603 final int q0 = jBlock * BLOCK_SIZE; +1604 final int qStart = Math.max(startColumn, q0); +1605 final int qEnd = Math.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); +1606 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1607 for (int p = pStart; p < pEnd; ++p) { +1608 int k = (p - p0) * jWidth + qStart - q0; +1609 for (int q = qStart; q < qEnd; ++q) { +1610 block[k] = visitor.visit(p, q, block[k]); +1611 ++k; +1612 } +1613 } +1614 } +1615 } +1616 return visitor.end(); +1617 } +1618 +1619 /** {@inheritDoc} */ +1620 @Override +1621 public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor, +1622 final int startRow, final int endRow, +1623 final int startColumn, final int endColumn) +1624 throws MatrixIndexException, MatrixVisitorException { +1625 checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); +1626 visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); +1627 for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { +1628 final int p0 = iBlock * BLOCK_SIZE; +1629 final int pStart = Math.max(startRow, p0); +1630 final int pEnd = Math.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); +1631 for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { +1632 final int jWidth = blockWidth(jBlock); +1633 final int q0 = jBlock * BLOCK_SIZE; +1634 final int qStart = Math.max(startColumn, q0); +1635 final int qEnd = Math.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); +1636 final T[] block = blocks[iBlock * blockColumns + jBlock]; +1637 for (int p = pStart; p < pEnd; ++p) { +1638 int k = (p - p0) * jWidth + qStart - q0; +1639 for (int q = qStart; q < qEnd; ++q) { +1640 visitor.visit(p, q, block[k]); +1641 ++k; +1642 } +1643 } +1644 } +1645 } +1646 return visitor.end(); +1647 } +1648 +1649 /** +1650 * Get the height of a block. +1651 * @param blockRow row index (in block sense) of the block +1652 * @return height (number of rows) of the block +1653 */ +1654 private int blockHeight(final int blockRow) { +1655 return (blockRow == blockRows - 1) ? rows - blockRow * BLOCK_SIZE : BLOCK_SIZE; +1656 } +1657 +1658 /** +1659 * Get the width of a block. +1660 * @param blockColumn column index (in block sense) of the block +1661 * @return width (number of columns) of the block +1662 */ +1663 private int blockWidth(final int blockColumn) { +1664 return (blockColumn == blockColumns - 1) ? columns - blockColumn * BLOCK_SIZE : BLOCK_SIZE; +1665 } +1666 +1667 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/BlockRealMatrix.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/BlockRealMatrix.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1753 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.io.Serializable; +021 import java.util.Arrays; +022 +023 import org.apache.commons.math.MathRuntimeException; +024 +025 /** +026 * Cache-friendly implementation of RealMatrix using a flat arrays to store +027 * square blocks of the matrix. +028 * <p> +029 * This implementation is specially designed to be cache-friendly. Square blocks are +030 * stored as small arrays and allow efficient traversal of data both in row major direction +031 * and columns major direction, one block at a time. This greatly increases performances +032 * for algorithms that use crossed directions loops like multiplication or transposition. +033 * </p> +034 * <p> +035 * The size of square blocks is a static parameter. It may be tuned according to the cache +036 * size of the target computer processor. As a rule of thumbs, it should be the largest +037 * value that allows three blocks to be simultaneously cached (this is necessary for example +038 * for matrix multiplication). The default value is to use 52x52 blocks which is well suited +039 * for processors with 64k L1 cache (one block holds 2704 values or 21632 bytes). This value +040 * could be lowered to 36x36 for processors with 32k L1 cache. +041 * </p> +042 * <p> +043 * The regular blocks represent {@link #BLOCK_SIZE} x {@link #BLOCK_SIZE} squares. Blocks +044 * at right hand side and bottom side which may be smaller to fit matrix dimensions. The square +045 * blocks are flattened in row major order in single dimension arrays which are therefore +046 * {@link #BLOCK_SIZE}<sup>2</sup> elements long for regular blocks. The blocks are themselves +047 * organized in row major order. +048 * </p> +049 * <p> +050 * As an example, for a block size of 52x52, a 100x60 matrix would be stored in 4 blocks. +051 * Block 0 would be a double[2704] array holding the upper left 52x52 square, block 1 would be +052 * a double[416] array holding the upper right 52x8 rectangle, block 2 would be a double[2496] +053 * array holding the lower left 48x52 rectangle and block 3 would be a double[384] array +054 * holding the lower right 48x8 rectangle. +055 * </p> +056 * <p> +057 * The layout complexity overhead versus simple mapping of matrices to java +058 * arrays is negligible for small matrices (about 1%). The gain from cache efficiency leads +059 * to up to 3-fold improvements for matrices of moderate to large size. +060 * </p> +061 * @version $Revision: 825919 $ $Date: 2009-10-16 10:51:55 -0400 (Fri, 16 Oct 2009) $ +062 * @since 2.0 +063 */ +064 public class BlockRealMatrix extends AbstractRealMatrix implements Serializable { +065 +066 /** Block size. */ +067 public static final int BLOCK_SIZE = 52; +068 +069 /** Serializable version identifier */ +070 private static final long serialVersionUID = 4991895511313664478L; +071 +072 /** Blocks of matrix entries. */ +073 private final double blocks[][]; +074 +075 /** Number of rows of the matrix. */ +076 private final int rows; +077 +078 /** Number of columns of the matrix. */ +079 private final int columns; +080 +081 /** Number of block rows of the matrix. */ +082 private final int blockRows; +083 +084 /** Number of block columns of the matrix. */ +085 private final int blockColumns; +086 +087 /** +088 * Create a new matrix with the supplied row and column dimensions. +089 * +090 * @param rows the number of rows in the new matrix +091 * @param columns the number of columns in the new matrix +092 * @throws IllegalArgumentException if row or column dimension is not +093 * positive +094 */ +095 public BlockRealMatrix(final int rows, final int columns) +096 throws IllegalArgumentException { +097 +098 super(rows, columns); +099 this.rows = rows; +100 this.columns = columns; +101 +102 // number of blocks +103 blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; +104 blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; +105 +106 // allocate storage blocks, taking care of smaller ones at right and bottom +107 blocks = createBlocksLayout(rows, columns); +108 +109 } +110 +111 /** +112 * Create a new dense matrix copying entries from raw layout data. +113 * <p>The input array <em>must</em> already be in raw layout.</p> +114 * <p>Calling this constructor is equivalent to call: +115 * <pre>matrix = new BlockRealMatrix(rawData.length, rawData[0].length, +116 * toBlocksLayout(rawData), false);</pre> +117 * </p> +118 * @param rawData data for new matrix, in raw layout +119 * +120 * @exception IllegalArgumentException if <code>blockData</code> shape is +121 * inconsistent with block layout +122 * @see #BlockRealMatrix(int, int, double[][], boolean) +123 */ +124 public BlockRealMatrix(final double[][] rawData) +125 throws IllegalArgumentException { +126 this(rawData.length, rawData[0].length, toBlocksLayout(rawData), false); +127 } +128 +129 /** +130 * Create a new dense matrix copying entries from block layout data. +131 * <p>The input array <em>must</em> already be in blocks layout.</p> +132 * @param rows the number of rows in the new matrix +133 * @param columns the number of columns in the new matrix +134 * @param blockData data for new matrix +135 * @param copyArray if true, the input array will be copied, otherwise +136 * it will be referenced +137 * +138 * @exception IllegalArgumentException if <code>blockData</code> shape is +139 * inconsistent with block layout +140 * @see #createBlocksLayout(int, int) +141 * @see #toBlocksLayout(double[][]) +142 * @see #BlockRealMatrix(double[][]) +143 */ +144 public BlockRealMatrix(final int rows, final int columns, +145 final double[][] blockData, final boolean copyArray) +146 throws IllegalArgumentException { +147 +148 super(rows, columns); +149 this.rows = rows; +150 this.columns = columns; +151 +152 // number of blocks +153 blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; +154 blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; +155 +156 if (copyArray) { +157 // allocate storage blocks, taking care of smaller ones at right and bottom +158 blocks = new double[blockRows * blockColumns][]; +159 } else { +160 // reference existing array +161 blocks = blockData; +162 } +163 +164 int index = 0; +165 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +166 final int iHeight = blockHeight(iBlock); +167 for (int jBlock = 0; jBlock < blockColumns; ++jBlock, ++index) { +168 if (blockData[index].length != iHeight * blockWidth(jBlock)) { +169 throw MathRuntimeException.createIllegalArgumentException( +170 "wrong array shape (block length = {0}, expected {1})", +171 blockData[index].length, iHeight * blockWidth(jBlock)); +172 } +173 if (copyArray) { +174 blocks[index] = blockData[index].clone(); +175 } +176 } +177 } +178 +179 } +180 +181 /** +182 * Convert a data array from raw layout to blocks layout. +183 * <p> +184 * Raw layout is the straightforward layout where element at row i and +185 * column j is in array element <code>rawData[i][j]</code>. Blocks layout +186 * is the layout used in {@link BlockRealMatrix} instances, where the matrix +187 * is split in square blocks (except at right and bottom side where blocks may +188 * be rectangular to fit matrix size) and each block is stored in a flattened +189 * one-dimensional array. +190 * </p> +191 * <p> +192 * This method creates an array in blocks layout from an input array in raw layout. +193 * It can be used to provide the array argument of the {@link +194 * #BlockRealMatrix(int, int, double[][], boolean)} constructor. +195 * </p> +196 * @param rawData data array in raw layout +197 * @return a new data array containing the same entries but in blocks layout +198 * @exception IllegalArgumentException if <code>rawData</code> is not rectangular +199 * (not all rows have the same length) +200 * @see #createBlocksLayout(int, int) +201 * @see #BlockRealMatrix(int, int, double[][], boolean) +202 */ +203 public static double[][] toBlocksLayout(final double[][] rawData) +204 throws IllegalArgumentException { +205 +206 final int rows = rawData.length; +207 final int columns = rawData[0].length; +208 final int blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; +209 final int blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; +210 +211 // safety checks +212 for (int i = 0; i < rawData.length; ++i) { +213 final int length = rawData[i].length; +214 if (length != columns) { +215 throw MathRuntimeException.createIllegalArgumentException( +216 "some rows have length {0} while others have length {1}", +217 columns, length); +218 } +219 } +220 +221 // convert array +222 final double[][] blocks = new double[blockRows * blockColumns][]; +223 int blockIndex = 0; +224 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +225 final int pStart = iBlock * BLOCK_SIZE; +226 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +227 final int iHeight = pEnd - pStart; +228 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +229 final int qStart = jBlock * BLOCK_SIZE; +230 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +231 final int jWidth = qEnd - qStart; +232 +233 // allocate new block +234 final double[] block = new double[iHeight * jWidth]; +235 blocks[blockIndex] = block; +236 +237 // copy data +238 int index = 0; +239 for (int p = pStart; p < pEnd; ++p) { +240 System.arraycopy(rawData[p], qStart, block, index, jWidth); +241 index += jWidth; +242 } +243 +244 ++blockIndex; +245 +246 } +247 } +248 +249 return blocks; +250 +251 } +252 +253 /** +254 * Create a data array in blocks layout. +255 * <p> +256 * This method can be used to create the array argument of the {@link +257 * #BlockRealMatrix(int, int, double[][], boolean)} constructor. +258 * </p> +259 * @param rows the number of rows in the new matrix +260 * @param columns the number of columns in the new matrix +261 * @return a new data array in blocks layout +262 * @see #toBlocksLayout(double[][]) +263 * @see #BlockRealMatrix(int, int, double[][], boolean) +264 */ +265 public static double[][] createBlocksLayout(final int rows, final int columns) { +266 +267 final int blockRows = (rows + BLOCK_SIZE - 1) / BLOCK_SIZE; +268 final int blockColumns = (columns + BLOCK_SIZE - 1) / BLOCK_SIZE; +269 +270 final double[][] blocks = new double[blockRows * blockColumns][]; +271 int blockIndex = 0; +272 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +273 final int pStart = iBlock * BLOCK_SIZE; +274 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +275 final int iHeight = pEnd - pStart; +276 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +277 final int qStart = jBlock * BLOCK_SIZE; +278 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +279 final int jWidth = qEnd - qStart; +280 blocks[blockIndex] = new double[iHeight * jWidth]; +281 ++blockIndex; +282 } +283 } +284 +285 return blocks; +286 +287 } +288 +289 /** {@inheritDoc} */ +290 @Override +291 public BlockRealMatrix createMatrix(final int rowDimension, final int columnDimension) +292 throws IllegalArgumentException { +293 return new BlockRealMatrix(rowDimension, columnDimension); +294 } +295 +296 /** {@inheritDoc} */ +297 @Override +298 public BlockRealMatrix copy() { +299 +300 // create an empty matrix +301 BlockRealMatrix copied = new BlockRealMatrix(rows, columns); +302 +303 // copy the blocks +304 for (int i = 0; i < blocks.length; ++i) { +305 System.arraycopy(blocks[i], 0, copied.blocks[i], 0, blocks[i].length); +306 } +307 +308 return copied; +309 +310 } +311 +312 /** {@inheritDoc} */ +313 @Override +314 public BlockRealMatrix add(final RealMatrix m) +315 throws IllegalArgumentException { +316 try { +317 return add((BlockRealMatrix) m); +318 } catch (ClassCastException cce) { +319 +320 // safety check +321 MatrixUtils.checkAdditionCompatible(this, m); +322 +323 final BlockRealMatrix out = new BlockRealMatrix(rows, columns); +324 +325 // perform addition block-wise, to ensure good cache behavior +326 int blockIndex = 0; +327 for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { +328 for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { +329 +330 // perform addition on the current block +331 final double[] outBlock = out.blocks[blockIndex]; +332 final double[] tBlock = blocks[blockIndex]; +333 final int pStart = iBlock * BLOCK_SIZE; +334 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +335 final int qStart = jBlock * BLOCK_SIZE; +336 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +337 int k = 0; +338 for (int p = pStart; p < pEnd; ++p) { +339 for (int q = qStart; q < qEnd; ++q) { +340 outBlock[k] = tBlock[k] + m.getEntry(p, q); +341 ++k; +342 } +343 } +344 +345 // go to next block +346 ++blockIndex; +347 +348 } +349 } +350 +351 return out; +352 +353 } +354 } +355 +356 /** +357 * Compute the sum of this and <code>m</code>. +358 * +359 * @param m matrix to be added +360 * @return this + m +361 * @throws IllegalArgumentException if m is not the same size as this +362 */ +363 public BlockRealMatrix add(final BlockRealMatrix m) +364 throws IllegalArgumentException { +365 +366 // safety check +367 MatrixUtils.checkAdditionCompatible(this, m); +368 +369 final BlockRealMatrix out = new BlockRealMatrix(rows, columns); +370 +371 // perform addition block-wise, to ensure good cache behavior +372 for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { +373 final double[] outBlock = out.blocks[blockIndex]; +374 final double[] tBlock = blocks[blockIndex]; +375 final double[] mBlock = m.blocks[blockIndex]; +376 for (int k = 0; k < outBlock.length; ++k) { +377 outBlock[k] = tBlock[k] + mBlock[k]; +378 } +379 } +380 +381 return out; +382 +383 } +384 +385 /** {@inheritDoc} */ +386 @Override +387 public BlockRealMatrix subtract(final RealMatrix m) +388 throws IllegalArgumentException { +389 try { +390 return subtract((BlockRealMatrix) m); +391 } catch (ClassCastException cce) { +392 +393 // safety check +394 MatrixUtils.checkSubtractionCompatible(this, m); +395 +396 final BlockRealMatrix out = new BlockRealMatrix(rows, columns); +397 +398 // perform subtraction block-wise, to ensure good cache behavior +399 int blockIndex = 0; +400 for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { +401 for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { +402 +403 // perform subtraction on the current block +404 final double[] outBlock = out.blocks[blockIndex]; +405 final double[] tBlock = blocks[blockIndex]; +406 final int pStart = iBlock * BLOCK_SIZE; +407 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +408 final int qStart = jBlock * BLOCK_SIZE; +409 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +410 int k = 0; +411 for (int p = pStart; p < pEnd; ++p) { +412 for (int q = qStart; q < qEnd; ++q) { +413 outBlock[k] = tBlock[k] - m.getEntry(p, q); +414 ++k; +415 } +416 } +417 +418 // go to next block +419 ++blockIndex; +420 +421 } +422 } +423 +424 return out; +425 +426 } +427 } +428 +429 /** +430 * Compute this minus <code>m</code>. +431 * +432 * @param m matrix to be subtracted +433 * @return this - m +434 * @throws IllegalArgumentException if m is not the same size as this +435 */ +436 public BlockRealMatrix subtract(final BlockRealMatrix m) +437 throws IllegalArgumentException { +438 +439 // safety check +440 MatrixUtils.checkSubtractionCompatible(this, m); +441 +442 final BlockRealMatrix out = new BlockRealMatrix(rows, columns); +443 +444 // perform subtraction block-wise, to ensure good cache behavior +445 for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { +446 final double[] outBlock = out.blocks[blockIndex]; +447 final double[] tBlock = blocks[blockIndex]; +448 final double[] mBlock = m.blocks[blockIndex]; +449 for (int k = 0; k < outBlock.length; ++k) { +450 outBlock[k] = tBlock[k] - mBlock[k]; +451 } +452 } +453 +454 return out; +455 +456 } +457 +458 /** {@inheritDoc} */ +459 @Override +460 public BlockRealMatrix scalarAdd(final double d) +461 throws IllegalArgumentException { +462 +463 final BlockRealMatrix out = new BlockRealMatrix(rows, columns); +464 +465 // perform subtraction block-wise, to ensure good cache behavior +466 for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { +467 final double[] outBlock = out.blocks[blockIndex]; +468 final double[] tBlock = blocks[blockIndex]; +469 for (int k = 0; k < outBlock.length; ++k) { +470 outBlock[k] = tBlock[k] + d; +471 } +472 } +473 +474 return out; +475 +476 } +477 +478 /** {@inheritDoc} */ +479 @Override +480 public RealMatrix scalarMultiply(final double d) +481 throws IllegalArgumentException { +482 +483 final BlockRealMatrix out = new BlockRealMatrix(rows, columns); +484 +485 // perform subtraction block-wise, to ensure good cache behavior +486 for (int blockIndex = 0; blockIndex < out.blocks.length; ++blockIndex) { +487 final double[] outBlock = out.blocks[blockIndex]; +488 final double[] tBlock = blocks[blockIndex]; +489 for (int k = 0; k < outBlock.length; ++k) { +490 outBlock[k] = tBlock[k] * d; +491 } +492 } +493 +494 return out; +495 +496 } +497 +498 /** {@inheritDoc} */ +499 @Override +500 public BlockRealMatrix multiply(final RealMatrix m) +501 throws IllegalArgumentException { +502 try { +503 return multiply((BlockRealMatrix) m); +504 } catch (ClassCastException cce) { +505 +506 // safety check +507 MatrixUtils.checkMultiplicationCompatible(this, m); +508 +509 final BlockRealMatrix out = new BlockRealMatrix(rows, m.getColumnDimension()); +510 +511 // perform multiplication block-wise, to ensure good cache behavior +512 int blockIndex = 0; +513 for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { +514 +515 final int pStart = iBlock * BLOCK_SIZE; +516 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +517 +518 for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { +519 +520 final int qStart = jBlock * BLOCK_SIZE; +521 final int qEnd = Math.min(qStart + BLOCK_SIZE, m.getColumnDimension()); +522 +523 // select current block +524 final double[] outBlock = out.blocks[blockIndex]; +525 +526 // perform multiplication on current block +527 for (int kBlock = 0; kBlock < blockColumns; ++kBlock) { +528 final int kWidth = blockWidth(kBlock); +529 final double[] tBlock = blocks[iBlock * blockColumns + kBlock]; +530 final int rStart = kBlock * BLOCK_SIZE; +531 int k = 0; +532 for (int p = pStart; p < pEnd; ++p) { +533 final int lStart = (p - pStart) * kWidth; +534 final int lEnd = lStart + kWidth; +535 for (int q = qStart; q < qEnd; ++q) { +536 double sum = 0; +537 int r = rStart; +538 for (int l = lStart; l < lEnd; ++l) { +539 sum += tBlock[l] * m.getEntry(r, q); +540 ++r; +541 } +542 outBlock[k] += sum; +543 ++k; +544 } +545 } +546 } +547 +548 // go to next block +549 ++blockIndex; +550 +551 } +552 } +553 +554 return out; +555 +556 } +557 } +558 +559 /** +560 * Returns the result of postmultiplying this by m. +561 * +562 * @param m matrix to postmultiply by +563 * @return this * m +564 * @throws IllegalArgumentException +565 * if columnDimension(this) != rowDimension(m) +566 */ +567 public BlockRealMatrix multiply(BlockRealMatrix m) throws IllegalArgumentException { +568 +569 // safety check +570 MatrixUtils.checkMultiplicationCompatible(this, m); +571 +572 final BlockRealMatrix out = new BlockRealMatrix(rows, m.columns); +573 +574 // perform multiplication block-wise, to ensure good cache behavior +575 int blockIndex = 0; +576 for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { +577 +578 final int pStart = iBlock * BLOCK_SIZE; +579 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +580 +581 for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { +582 final int jWidth = out.blockWidth(jBlock); +583 final int jWidth2 = jWidth + jWidth; +584 final int jWidth3 = jWidth2 + jWidth; +585 final int jWidth4 = jWidth3 + jWidth; +586 +587 // select current block +588 final double[] outBlock = out.blocks[blockIndex]; +589 +590 // perform multiplication on current block +591 for (int kBlock = 0; kBlock < blockColumns; ++kBlock) { +592 final int kWidth = blockWidth(kBlock); +593 final double[] tBlock = blocks[iBlock * blockColumns + kBlock]; +594 final double[] mBlock = m.blocks[kBlock * m.blockColumns + jBlock]; +595 int k = 0; +596 for (int p = pStart; p < pEnd; ++p) { +597 final int lStart = (p - pStart) * kWidth; +598 final int lEnd = lStart + kWidth; +599 for (int nStart = 0; nStart < jWidth; ++nStart) { +600 double sum = 0; +601 int l = lStart; +602 int n = nStart; +603 while (l < lEnd - 3) { +604 sum += tBlock[l] * mBlock[n] + +605 tBlock[l + 1] * mBlock[n + jWidth] + +606 tBlock[l + 2] * mBlock[n + jWidth2] + +607 tBlock[l + 3] * mBlock[n + jWidth3]; +608 l += 4; +609 n += jWidth4; +610 } +611 while (l < lEnd) { +612 sum += tBlock[l++] * mBlock[n]; +613 n += jWidth; +614 } +615 outBlock[k] += sum; +616 ++k; +617 } +618 } +619 } +620 +621 // go to next block +622 ++blockIndex; +623 +624 } +625 } +626 +627 return out; +628 +629 } +630 +631 /** {@inheritDoc} */ +632 @Override +633 public double[][] getData() { +634 +635 final double[][] data = new double[getRowDimension()][getColumnDimension()]; +636 final int lastColumns = columns - (blockColumns - 1) * BLOCK_SIZE; +637 +638 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +639 final int pStart = iBlock * BLOCK_SIZE; +640 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +641 int regularPos = 0; +642 int lastPos = 0; +643 for (int p = pStart; p < pEnd; ++p) { +644 final double[] dataP = data[p]; +645 int blockIndex = iBlock * blockColumns; +646 int dataPos = 0; +647 for (int jBlock = 0; jBlock < blockColumns - 1; ++jBlock) { +648 System.arraycopy(blocks[blockIndex++], regularPos, dataP, dataPos, BLOCK_SIZE); +649 dataPos += BLOCK_SIZE; +650 } +651 System.arraycopy(blocks[blockIndex], lastPos, dataP, dataPos, lastColumns); +652 regularPos += BLOCK_SIZE; +653 lastPos += lastColumns; +654 } +655 } +656 +657 return data; +658 +659 } +660 +661 /** {@inheritDoc} */ +662 @Override +663 public double getNorm() { +664 final double[] colSums = new double[BLOCK_SIZE]; +665 double maxColSum = 0; +666 for (int jBlock = 0; jBlock < blockColumns; jBlock++) { +667 final int jWidth = blockWidth(jBlock); +668 Arrays.fill(colSums, 0, jWidth, 0.0); +669 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +670 final int iHeight = blockHeight(iBlock); +671 final double[] block = blocks[iBlock * blockColumns + jBlock]; +672 for (int j = 0; j < jWidth; ++j) { +673 double sum = 0; +674 for (int i = 0; i < iHeight; ++i) { +675 sum += Math.abs(block[i * jWidth + j]); +676 } +677 colSums[j] += sum; +678 } +679 } +680 for (int j = 0; j < jWidth; ++j) { +681 maxColSum = Math.max(maxColSum, colSums[j]); +682 } +683 } +684 return maxColSum; +685 } +686 +687 /** {@inheritDoc} */ +688 @Override +689 public double getFrobeniusNorm() { +690 double sum2 = 0; +691 for (int blockIndex = 0; blockIndex < blocks.length; ++blockIndex) { +692 for (final double entry : blocks[blockIndex]) { +693 sum2 += entry * entry; +694 } +695 } +696 return Math.sqrt(sum2); +697 } +698 +699 /** {@inheritDoc} */ +700 @Override +701 public BlockRealMatrix getSubMatrix(final int startRow, final int endRow, +702 final int startColumn, final int endColumn) +703 throws MatrixIndexException { +704 +705 // safety checks +706 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +707 +708 // create the output matrix +709 final BlockRealMatrix out = +710 new BlockRealMatrix(endRow - startRow + 1, endColumn - startColumn + 1); +711 +712 // compute blocks shifts +713 final int blockStartRow = startRow / BLOCK_SIZE; +714 final int rowsShift = startRow % BLOCK_SIZE; +715 final int blockStartColumn = startColumn / BLOCK_SIZE; +716 final int columnsShift = startColumn % BLOCK_SIZE; +717 +718 // perform extraction block-wise, to ensure good cache behavior +719 int pBlock = blockStartRow; +720 for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { +721 final int iHeight = out.blockHeight(iBlock); +722 int qBlock = blockStartColumn; +723 for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { +724 final int jWidth = out.blockWidth(jBlock); +725 +726 // handle one block of the output matrix +727 final int outIndex = iBlock * out.blockColumns + jBlock; +728 final double[] outBlock = out.blocks[outIndex]; +729 final int index = pBlock * blockColumns + qBlock; +730 final int width = blockWidth(qBlock); +731 +732 final int heightExcess = iHeight + rowsShift - BLOCK_SIZE; +733 final int widthExcess = jWidth + columnsShift - BLOCK_SIZE; +734 if (heightExcess > 0) { +735 // the submatrix block spans on two blocks rows from the original matrix +736 if (widthExcess > 0) { +737 // the submatrix block spans on two blocks columns from the original matrix +738 final int width2 = blockWidth(qBlock + 1); +739 copyBlockPart(blocks[index], width, +740 rowsShift, BLOCK_SIZE, +741 columnsShift, BLOCK_SIZE, +742 outBlock, jWidth, 0, 0); +743 copyBlockPart(blocks[index + 1], width2, +744 rowsShift, BLOCK_SIZE, +745 0, widthExcess, +746 outBlock, jWidth, 0, jWidth - widthExcess); +747 copyBlockPart(blocks[index + blockColumns], width, +748 0, heightExcess, +749 columnsShift, BLOCK_SIZE, +750 outBlock, jWidth, iHeight - heightExcess, 0); +751 copyBlockPart(blocks[index + blockColumns + 1], width2, +752 0, heightExcess, +753 0, widthExcess, +754 outBlock, jWidth, iHeight - heightExcess, jWidth - widthExcess); +755 } else { +756 // the submatrix block spans on one block column from the original matrix +757 copyBlockPart(blocks[index], width, +758 rowsShift, BLOCK_SIZE, +759 columnsShift, jWidth + columnsShift, +760 outBlock, jWidth, 0, 0); +761 copyBlockPart(blocks[index + blockColumns], width, +762 0, heightExcess, +763 columnsShift, jWidth + columnsShift, +764 outBlock, jWidth, iHeight - heightExcess, 0); +765 } +766 } else { +767 // the submatrix block spans on one block row from the original matrix +768 if (widthExcess > 0) { +769 // the submatrix block spans on two blocks columns from the original matrix +770 final int width2 = blockWidth(qBlock + 1); +771 copyBlockPart(blocks[index], width, +772 rowsShift, iHeight + rowsShift, +773 columnsShift, BLOCK_SIZE, +774 outBlock, jWidth, 0, 0); +775 copyBlockPart(blocks[index + 1], width2, +776 rowsShift, iHeight + rowsShift, +777 0, widthExcess, +778 outBlock, jWidth, 0, jWidth - widthExcess); +779 } else { +780 // the submatrix block spans on one block column from the original matrix +781 copyBlockPart(blocks[index], width, +782 rowsShift, iHeight + rowsShift, +783 columnsShift, jWidth + columnsShift, +784 outBlock, jWidth, 0, 0); +785 } +786 } +787 +788 ++qBlock; +789 +790 } +791 +792 ++pBlock; +793 +794 } +795 +796 return out; +797 +798 } +799 +800 /** +801 * Copy a part of a block into another one +802 * <p>This method can be called only when the specified part fits in both +803 * blocks, no verification is done here.</p> +804 * @param srcBlock source block +805 * @param srcWidth source block width ({@link #BLOCK_SIZE} or smaller) +806 * @param srcStartRow start row in the source block +807 * @param srcEndRow end row (exclusive) in the source block +808 * @param srcStartColumn start column in the source block +809 * @param srcEndColumn end column (exclusive) in the source block +810 * @param dstBlock destination block +811 * @param dstWidth destination block width ({@link #BLOCK_SIZE} or smaller) +812 * @param dstStartRow start row in the destination block +813 * @param dstStartColumn start column in the destination block +814 */ +815 private void copyBlockPart(final double[] srcBlock, final int srcWidth, +816 final int srcStartRow, final int srcEndRow, +817 final int srcStartColumn, final int srcEndColumn, +818 final double[] dstBlock, final int dstWidth, +819 final int dstStartRow, final int dstStartColumn) { +820 final int length = srcEndColumn - srcStartColumn; +821 int srcPos = srcStartRow * srcWidth + srcStartColumn; +822 int dstPos = dstStartRow * dstWidth + dstStartColumn; +823 for (int srcRow = srcStartRow; srcRow < srcEndRow; ++srcRow) { +824 System.arraycopy(srcBlock, srcPos, dstBlock, dstPos, length); +825 srcPos += srcWidth; +826 dstPos += dstWidth; +827 } +828 } +829 +830 /** {@inheritDoc} */ +831 @Override +832 public void setSubMatrix(final double[][] subMatrix, final int row, final int column) +833 throws MatrixIndexException { +834 +835 // safety checks +836 final int refLength = subMatrix[0].length; +837 if (refLength < 1) { +838 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column"); +839 } +840 final int endRow = row + subMatrix.length - 1; +841 final int endColumn = column + refLength - 1; +842 MatrixUtils.checkSubMatrixIndex(this, row, endRow, column, endColumn); +843 for (final double[] subRow : subMatrix) { +844 if (subRow.length != refLength) { +845 throw MathRuntimeException.createIllegalArgumentException( +846 "some rows have length {0} while others have length {1}", +847 refLength, subRow.length); +848 } +849 } +850 +851 // compute blocks bounds +852 final int blockStartRow = row / BLOCK_SIZE; +853 final int blockEndRow = (endRow + BLOCK_SIZE) / BLOCK_SIZE; +854 final int blockStartColumn = column / BLOCK_SIZE; +855 final int blockEndColumn = (endColumn + BLOCK_SIZE) / BLOCK_SIZE; +856 +857 // perform copy block-wise, to ensure good cache behavior +858 for (int iBlock = blockStartRow; iBlock < blockEndRow; ++iBlock) { +859 final int iHeight = blockHeight(iBlock); +860 final int firstRow = iBlock * BLOCK_SIZE; +861 final int iStart = Math.max(row, firstRow); +862 final int iEnd = Math.min(endRow + 1, firstRow + iHeight); +863 +864 for (int jBlock = blockStartColumn; jBlock < blockEndColumn; ++jBlock) { +865 final int jWidth = blockWidth(jBlock); +866 final int firstColumn = jBlock * BLOCK_SIZE; +867 final int jStart = Math.max(column, firstColumn); +868 final int jEnd = Math.min(endColumn + 1, firstColumn + jWidth); +869 final int jLength = jEnd - jStart; +870 +871 // handle one block, row by row +872 final double[] block = blocks[iBlock * blockColumns + jBlock]; +873 for (int i = iStart; i < iEnd; ++i) { +874 System.arraycopy(subMatrix[i - row], jStart - column, +875 block, (i - firstRow) * jWidth + (jStart - firstColumn), +876 jLength); +877 } +878 +879 } +880 } +881 } +882 +883 /** {@inheritDoc} */ +884 @Override +885 public BlockRealMatrix getRowMatrix(final int row) +886 throws MatrixIndexException { +887 +888 MatrixUtils.checkRowIndex(this, row); +889 final BlockRealMatrix out = new BlockRealMatrix(1, columns); +890 +891 // perform copy block-wise, to ensure good cache behavior +892 final int iBlock = row / BLOCK_SIZE; +893 final int iRow = row - iBlock * BLOCK_SIZE; +894 int outBlockIndex = 0; +895 int outIndex = 0; +896 double[] outBlock = out.blocks[outBlockIndex]; +897 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +898 final int jWidth = blockWidth(jBlock); +899 final double[] block = blocks[iBlock * blockColumns + jBlock]; +900 final int available = outBlock.length - outIndex; +901 if (jWidth > available) { +902 System.arraycopy(block, iRow * jWidth, outBlock, outIndex, available); +903 outBlock = out.blocks[++outBlockIndex]; +904 System.arraycopy(block, iRow * jWidth, outBlock, 0, jWidth - available); +905 outIndex = jWidth - available; +906 } else { +907 System.arraycopy(block, iRow * jWidth, outBlock, outIndex, jWidth); +908 outIndex += jWidth; +909 } +910 } +911 +912 return out; +913 +914 } +915 +916 /** {@inheritDoc} */ +917 @Override +918 public void setRowMatrix(final int row, final RealMatrix matrix) +919 throws MatrixIndexException, InvalidMatrixException { +920 try { +921 setRowMatrix(row, (BlockRealMatrix) matrix); +922 } catch (ClassCastException cce) { +923 super.setRowMatrix(row, matrix); +924 } +925 } +926 +927 /** +928 * Sets the entries in row number <code>row</code> +929 * as a row matrix. Row indices start at 0. +930 * +931 * @param row the row to be set +932 * @param matrix row matrix (must have one row and the same number of columns +933 * as the instance) +934 * @throws MatrixIndexException if the specified row index is invalid +935 * @throws InvalidMatrixException if the matrix dimensions do not match one +936 * instance row +937 */ +938 public void setRowMatrix(final int row, final BlockRealMatrix matrix) +939 throws MatrixIndexException, InvalidMatrixException { +940 +941 MatrixUtils.checkRowIndex(this, row); +942 final int nCols = getColumnDimension(); +943 if ((matrix.getRowDimension() != 1) || +944 (matrix.getColumnDimension() != nCols)) { +945 throw new InvalidMatrixException( +946 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +947 matrix.getRowDimension(), matrix.getColumnDimension(), +948 1, nCols); +949 } +950 +951 // perform copy block-wise, to ensure good cache behavior +952 final int iBlock = row / BLOCK_SIZE; +953 final int iRow = row - iBlock * BLOCK_SIZE; +954 int mBlockIndex = 0; +955 int mIndex = 0; +956 double[] mBlock = matrix.blocks[mBlockIndex]; +957 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +958 final int jWidth = blockWidth(jBlock); +959 final double[] block = blocks[iBlock * blockColumns + jBlock]; +960 final int available = mBlock.length - mIndex; +961 if (jWidth > available) { +962 System.arraycopy(mBlock, mIndex, block, iRow * jWidth, available); +963 mBlock = matrix.blocks[++mBlockIndex]; +964 System.arraycopy(mBlock, 0, block, iRow * jWidth, jWidth - available); +965 mIndex = jWidth - available; +966 } else { +967 System.arraycopy(mBlock, mIndex, block, iRow * jWidth, jWidth); +968 mIndex += jWidth; +969 } +970 } +971 +972 } +973 +974 /** {@inheritDoc} */ +975 @Override +976 public BlockRealMatrix getColumnMatrix(final int column) +977 throws MatrixIndexException { +978 +979 MatrixUtils.checkColumnIndex(this, column); +980 final BlockRealMatrix out = new BlockRealMatrix(rows, 1); +981 +982 // perform copy block-wise, to ensure good cache behavior +983 final int jBlock = column / BLOCK_SIZE; +984 final int jColumn = column - jBlock * BLOCK_SIZE; +985 final int jWidth = blockWidth(jBlock); +986 int outBlockIndex = 0; +987 int outIndex = 0; +988 double[] outBlock = out.blocks[outBlockIndex]; +989 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +990 final int iHeight = blockHeight(iBlock); +991 final double[] block = blocks[iBlock * blockColumns + jBlock]; +992 for (int i = 0; i < iHeight; ++i) { +993 if (outIndex >= outBlock.length) { +994 outBlock = out.blocks[++outBlockIndex]; +995 outIndex = 0; +996 } +997 outBlock[outIndex++] = block[i * jWidth + jColumn]; +998 } +999 } +1000 +1001 return out; +1002 +1003 } +1004 +1005 /** {@inheritDoc} */ +1006 @Override +1007 public void setColumnMatrix(final int column, final RealMatrix matrix) +1008 throws MatrixIndexException, InvalidMatrixException { +1009 try { +1010 setColumnMatrix(column, (BlockRealMatrix) matrix); +1011 } catch (ClassCastException cce) { +1012 super.setColumnMatrix(column, matrix); +1013 } +1014 } +1015 +1016 /** +1017 * Sets the entries in column number <code>column</code> +1018 * as a column matrix. Column indices start at 0. +1019 * +1020 * @param column the column to be set +1021 * @param matrix column matrix (must have one column and the same number of rows +1022 * as the instance) +1023 * @throws MatrixIndexException if the specified column index is invalid +1024 * @throws InvalidMatrixException if the matrix dimensions do not match one +1025 * instance column +1026 */ +1027 void setColumnMatrix(final int column, final BlockRealMatrix matrix) +1028 throws MatrixIndexException, InvalidMatrixException { +1029 +1030 MatrixUtils.checkColumnIndex(this, column); +1031 final int nRows = getRowDimension(); +1032 if ((matrix.getRowDimension() != nRows) || +1033 (matrix.getColumnDimension() != 1)) { +1034 throw new InvalidMatrixException( +1035 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +1036 matrix.getRowDimension(), matrix.getColumnDimension(), +1037 nRows, 1); +1038 } +1039 +1040 // perform copy block-wise, to ensure good cache behavior +1041 final int jBlock = column / BLOCK_SIZE; +1042 final int jColumn = column - jBlock * BLOCK_SIZE; +1043 final int jWidth = blockWidth(jBlock); +1044 int mBlockIndex = 0; +1045 int mIndex = 0; +1046 double[] mBlock = matrix.blocks[mBlockIndex]; +1047 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1048 final int iHeight = blockHeight(iBlock); +1049 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1050 for (int i = 0; i < iHeight; ++i) { +1051 if (mIndex >= mBlock.length) { +1052 mBlock = matrix.blocks[++mBlockIndex]; +1053 mIndex = 0; +1054 } +1055 block[i * jWidth + jColumn] = mBlock[mIndex++]; +1056 } +1057 } +1058 +1059 } +1060 +1061 /** {@inheritDoc} */ +1062 @Override +1063 public RealVector getRowVector(final int row) +1064 throws MatrixIndexException { +1065 +1066 MatrixUtils.checkRowIndex(this, row); +1067 final double[] outData = new double[columns]; +1068 +1069 // perform copy block-wise, to ensure good cache behavior +1070 final int iBlock = row / BLOCK_SIZE; +1071 final int iRow = row - iBlock * BLOCK_SIZE; +1072 int outIndex = 0; +1073 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1074 final int jWidth = blockWidth(jBlock); +1075 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1076 System.arraycopy(block, iRow * jWidth, outData, outIndex, jWidth); +1077 outIndex += jWidth; +1078 } +1079 +1080 return new ArrayRealVector(outData, false); +1081 +1082 } +1083 +1084 /** {@inheritDoc} */ +1085 @Override +1086 public void setRowVector(final int row, final RealVector vector) +1087 throws MatrixIndexException, InvalidMatrixException { +1088 try { +1089 setRow(row, ((ArrayRealVector) vector).getDataRef()); +1090 } catch (ClassCastException cce) { +1091 super.setRowVector(row, vector); +1092 } +1093 } +1094 +1095 /** {@inheritDoc} */ +1096 @Override +1097 public RealVector getColumnVector(final int column) +1098 throws MatrixIndexException { +1099 +1100 MatrixUtils.checkColumnIndex(this, column); +1101 final double[] outData = new double[rows]; +1102 +1103 // perform copy block-wise, to ensure good cache behavior +1104 final int jBlock = column / BLOCK_SIZE; +1105 final int jColumn = column - jBlock * BLOCK_SIZE; +1106 final int jWidth = blockWidth(jBlock); +1107 int outIndex = 0; +1108 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1109 final int iHeight = blockHeight(iBlock); +1110 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1111 for (int i = 0; i < iHeight; ++i) { +1112 outData[outIndex++] = block[i * jWidth + jColumn]; +1113 } +1114 } +1115 +1116 return new ArrayRealVector(outData, false); +1117 +1118 } +1119 +1120 /** {@inheritDoc} */ +1121 @Override +1122 public void setColumnVector(final int column, final RealVector vector) +1123 throws MatrixIndexException, InvalidMatrixException { +1124 try { +1125 setColumn(column, ((ArrayRealVector) vector).getDataRef()); +1126 } catch (ClassCastException cce) { +1127 super.setColumnVector(column, vector); +1128 } +1129 } +1130 +1131 /** {@inheritDoc} */ +1132 @Override +1133 public double[] getRow(final int row) +1134 throws MatrixIndexException { +1135 +1136 MatrixUtils.checkRowIndex(this, row); +1137 final double[] out = new double[columns]; +1138 +1139 // perform copy block-wise, to ensure good cache behavior +1140 final int iBlock = row / BLOCK_SIZE; +1141 final int iRow = row - iBlock * BLOCK_SIZE; +1142 int outIndex = 0; +1143 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1144 final int jWidth = blockWidth(jBlock); +1145 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1146 System.arraycopy(block, iRow * jWidth, out, outIndex, jWidth); +1147 outIndex += jWidth; +1148 } +1149 +1150 return out; +1151 +1152 } +1153 +1154 /** {@inheritDoc} */ +1155 @Override +1156 public void setRow(final int row, final double[] array) +1157 throws MatrixIndexException, InvalidMatrixException { +1158 +1159 MatrixUtils.checkRowIndex(this, row); +1160 final int nCols = getColumnDimension(); +1161 if (array.length != nCols) { +1162 throw new InvalidMatrixException( +1163 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +1164 1, array.length, 1, nCols); +1165 } +1166 +1167 // perform copy block-wise, to ensure good cache behavior +1168 final int iBlock = row / BLOCK_SIZE; +1169 final int iRow = row - iBlock * BLOCK_SIZE; +1170 int outIndex = 0; +1171 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1172 final int jWidth = blockWidth(jBlock); +1173 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1174 System.arraycopy(array, outIndex, block, iRow * jWidth, jWidth); +1175 outIndex += jWidth; +1176 } +1177 +1178 } +1179 +1180 /** {@inheritDoc} */ +1181 @Override +1182 public double[] getColumn(final int column) +1183 throws MatrixIndexException { +1184 +1185 MatrixUtils.checkColumnIndex(this, column); +1186 final double[] out = new double[rows]; +1187 +1188 // perform copy block-wise, to ensure good cache behavior +1189 final int jBlock = column / BLOCK_SIZE; +1190 final int jColumn = column - jBlock * BLOCK_SIZE; +1191 final int jWidth = blockWidth(jBlock); +1192 int outIndex = 0; +1193 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1194 final int iHeight = blockHeight(iBlock); +1195 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1196 for (int i = 0; i < iHeight; ++i) { +1197 out[outIndex++] = block[i * jWidth + jColumn]; +1198 } +1199 } +1200 +1201 return out; +1202 +1203 } +1204 +1205 /** {@inheritDoc} */ +1206 @Override +1207 public void setColumn(final int column, final double[] array) +1208 throws MatrixIndexException, InvalidMatrixException { +1209 +1210 MatrixUtils.checkColumnIndex(this, column); +1211 final int nRows = getRowDimension(); +1212 if (array.length != nRows) { +1213 throw new InvalidMatrixException( +1214 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +1215 array.length, 1, nRows, 1); +1216 } +1217 +1218 // perform copy block-wise, to ensure good cache behavior +1219 final int jBlock = column / BLOCK_SIZE; +1220 final int jColumn = column - jBlock * BLOCK_SIZE; +1221 final int jWidth = blockWidth(jBlock); +1222 int outIndex = 0; +1223 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1224 final int iHeight = blockHeight(iBlock); +1225 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1226 for (int i = 0; i < iHeight; ++i) { +1227 block[i * jWidth + jColumn] = array[outIndex++]; +1228 } +1229 } +1230 +1231 } +1232 +1233 /** {@inheritDoc} */ +1234 @Override +1235 public double getEntry(final int row, final int column) +1236 throws MatrixIndexException { +1237 try { +1238 final int iBlock = row / BLOCK_SIZE; +1239 final int jBlock = column / BLOCK_SIZE; +1240 final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + +1241 (column - jBlock * BLOCK_SIZE); +1242 return blocks[iBlock * blockColumns + jBlock][k]; +1243 } catch (ArrayIndexOutOfBoundsException e) { +1244 throw new MatrixIndexException( +1245 "no entry at indices ({0}, {1}) in a {2}x{3} matrix", +1246 row, column, getRowDimension(), getColumnDimension()); +1247 } +1248 } +1249 +1250 /** {@inheritDoc} */ +1251 @Override +1252 public void setEntry(final int row, final int column, final double value) +1253 throws MatrixIndexException { +1254 try { +1255 final int iBlock = row / BLOCK_SIZE; +1256 final int jBlock = column / BLOCK_SIZE; +1257 final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + +1258 (column - jBlock * BLOCK_SIZE); +1259 blocks[iBlock * blockColumns + jBlock][k] = value; +1260 } catch (ArrayIndexOutOfBoundsException e) { +1261 throw new MatrixIndexException( +1262 "no entry at indices ({0}, {1}) in a {2}x{3} matrix", +1263 row, column, getRowDimension(), getColumnDimension()); +1264 } +1265 } +1266 +1267 /** {@inheritDoc} */ +1268 @Override +1269 public void addToEntry(final int row, final int column, final double increment) +1270 throws MatrixIndexException { +1271 try { +1272 final int iBlock = row / BLOCK_SIZE; +1273 final int jBlock = column / BLOCK_SIZE; +1274 final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + +1275 (column - jBlock * BLOCK_SIZE); +1276 blocks[iBlock * blockColumns + jBlock][k] += increment; +1277 } catch (ArrayIndexOutOfBoundsException e) { +1278 throw new MatrixIndexException( +1279 "no entry at indices ({0}, {1}) in a {2}x{3} matrix", +1280 row, column, getRowDimension(), getColumnDimension()); +1281 } +1282 } +1283 +1284 /** {@inheritDoc} */ +1285 @Override +1286 public void multiplyEntry(final int row, final int column, final double factor) +1287 throws MatrixIndexException { +1288 try { +1289 final int iBlock = row / BLOCK_SIZE; +1290 final int jBlock = column / BLOCK_SIZE; +1291 final int k = (row - iBlock * BLOCK_SIZE) * blockWidth(jBlock) + +1292 (column - jBlock * BLOCK_SIZE); +1293 blocks[iBlock * blockColumns + jBlock][k] *= factor; +1294 } catch (ArrayIndexOutOfBoundsException e) { +1295 throw new MatrixIndexException( +1296 "no entry at indices ({0}, {1}) in a {2}x{3} matrix", +1297 row, column, getRowDimension(), getColumnDimension()); +1298 } +1299 } +1300 +1301 /** {@inheritDoc} */ +1302 @Override +1303 public BlockRealMatrix transpose() { +1304 +1305 final int nRows = getRowDimension(); +1306 final int nCols = getColumnDimension(); +1307 final BlockRealMatrix out = new BlockRealMatrix(nCols, nRows); +1308 +1309 // perform transpose block-wise, to ensure good cache behavior +1310 int blockIndex = 0; +1311 for (int iBlock = 0; iBlock < blockColumns; ++iBlock) { +1312 for (int jBlock = 0; jBlock < blockRows; ++jBlock) { +1313 +1314 // transpose current block +1315 final double[] outBlock = out.blocks[blockIndex]; +1316 final double[] tBlock = blocks[jBlock * blockColumns + iBlock]; +1317 final int pStart = iBlock * BLOCK_SIZE; +1318 final int pEnd = Math.min(pStart + BLOCK_SIZE, columns); +1319 final int qStart = jBlock * BLOCK_SIZE; +1320 final int qEnd = Math.min(qStart + BLOCK_SIZE, rows); +1321 int k = 0; +1322 for (int p = pStart; p < pEnd; ++p) { +1323 final int lInc = pEnd - pStart; +1324 int l = p - pStart; +1325 for (int q = qStart; q < qEnd; ++q) { +1326 outBlock[k] = tBlock[l]; +1327 ++k; +1328 l+= lInc; +1329 } +1330 } +1331 +1332 // go to next block +1333 ++blockIndex; +1334 +1335 } +1336 } +1337 +1338 return out; +1339 +1340 } +1341 +1342 /** {@inheritDoc} */ +1343 @Override +1344 public int getRowDimension() { +1345 return rows; +1346 } +1347 +1348 /** {@inheritDoc} */ +1349 @Override +1350 public int getColumnDimension() { +1351 return columns; +1352 } +1353 +1354 /** {@inheritDoc} */ +1355 @Override +1356 public double[] operate(final double[] v) +1357 throws IllegalArgumentException { +1358 +1359 if (v.length != columns) { +1360 throw MathRuntimeException.createIllegalArgumentException( +1361 "vector length mismatch: got {0} but expected {1}", +1362 v.length, columns); +1363 } +1364 final double[] out = new double[rows]; +1365 +1366 // perform multiplication block-wise, to ensure good cache behavior +1367 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1368 final int pStart = iBlock * BLOCK_SIZE; +1369 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +1370 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1371 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1372 final int qStart = jBlock * BLOCK_SIZE; +1373 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +1374 int k = 0; +1375 for (int p = pStart; p < pEnd; ++p) { +1376 double sum = 0; +1377 int q = qStart; +1378 while (q < qEnd - 3) { +1379 sum += block[k] * v[q] + +1380 block[k + 1] * v[q + 1] + +1381 block[k + 2] * v[q + 2] + +1382 block[k + 3] * v[q + 3]; +1383 k += 4; +1384 q += 4; +1385 } +1386 while (q < qEnd) { +1387 sum += block[k++] * v[q++]; +1388 } +1389 out[p] += sum; +1390 } +1391 } +1392 } +1393 +1394 return out; +1395 +1396 } +1397 +1398 /** {@inheritDoc} */ +1399 @Override +1400 public double[] preMultiply(final double[] v) +1401 throws IllegalArgumentException { +1402 +1403 if (v.length != rows) { +1404 throw MathRuntimeException.createIllegalArgumentException( +1405 "vector length mismatch: got {0} but expected {1}", +1406 v.length, rows); +1407 } +1408 final double[] out = new double[columns]; +1409 +1410 // perform multiplication block-wise, to ensure good cache behavior +1411 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1412 final int jWidth = blockWidth(jBlock); +1413 final int jWidth2 = jWidth + jWidth; +1414 final int jWidth3 = jWidth2 + jWidth; +1415 final int jWidth4 = jWidth3 + jWidth; +1416 final int qStart = jBlock * BLOCK_SIZE; +1417 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +1418 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1419 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1420 final int pStart = iBlock * BLOCK_SIZE; +1421 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +1422 for (int q = qStart; q < qEnd; ++q) { +1423 int k = q - qStart; +1424 double sum = 0; +1425 int p = pStart; +1426 while (p < pEnd - 3) { +1427 sum += block[k] * v[p] + +1428 block[k + jWidth] * v[p + 1] + +1429 block[k + jWidth2] * v[p + 2] + +1430 block[k + jWidth3] * v[p + 3]; +1431 k += jWidth4; +1432 p += 4; +1433 } +1434 while (p < pEnd) { +1435 sum += block[k] * v[p++]; +1436 k += jWidth; +1437 } +1438 out[q] += sum; +1439 } +1440 } +1441 } +1442 +1443 return out; +1444 +1445 } +1446 +1447 /** {@inheritDoc} */ +1448 @Override +1449 public double walkInRowOrder(final RealMatrixChangingVisitor visitor) +1450 throws MatrixVisitorException { +1451 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +1452 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1453 final int pStart = iBlock * BLOCK_SIZE; +1454 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +1455 for (int p = pStart; p < pEnd; ++p) { +1456 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1457 final int jWidth = blockWidth(jBlock); +1458 final int qStart = jBlock * BLOCK_SIZE; +1459 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +1460 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1461 int k = (p - pStart) * jWidth; +1462 for (int q = qStart; q < qEnd; ++q) { +1463 block[k] = visitor.visit(p, q, block[k]); +1464 ++k; +1465 } +1466 } +1467 } +1468 } +1469 return visitor.end(); +1470 } +1471 +1472 /** {@inheritDoc} */ +1473 @Override +1474 public double walkInRowOrder(final RealMatrixPreservingVisitor visitor) +1475 throws MatrixVisitorException { +1476 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +1477 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1478 final int pStart = iBlock * BLOCK_SIZE; +1479 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +1480 for (int p = pStart; p < pEnd; ++p) { +1481 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1482 final int jWidth = blockWidth(jBlock); +1483 final int qStart = jBlock * BLOCK_SIZE; +1484 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +1485 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1486 int k = (p - pStart) * jWidth; +1487 for (int q = qStart; q < qEnd; ++q) { +1488 visitor.visit(p, q, block[k]); +1489 ++k; +1490 } +1491 } +1492 } +1493 } +1494 return visitor.end(); +1495 } +1496 +1497 /** {@inheritDoc} */ +1498 @Override +1499 public double walkInRowOrder(final RealMatrixChangingVisitor visitor, +1500 final int startRow, final int endRow, +1501 final int startColumn, final int endColumn) +1502 throws MatrixIndexException, MatrixVisitorException { +1503 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +1504 visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); +1505 for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { +1506 final int p0 = iBlock * BLOCK_SIZE; +1507 final int pStart = Math.max(startRow, p0); +1508 final int pEnd = Math.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); +1509 for (int p = pStart; p < pEnd; ++p) { +1510 for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { +1511 final int jWidth = blockWidth(jBlock); +1512 final int q0 = jBlock * BLOCK_SIZE; +1513 final int qStart = Math.max(startColumn, q0); +1514 final int qEnd = Math.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); +1515 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1516 int k = (p - p0) * jWidth + qStart - q0; +1517 for (int q = qStart; q < qEnd; ++q) { +1518 block[k] = visitor.visit(p, q, block[k]); +1519 ++k; +1520 } +1521 } +1522 } +1523 } +1524 return visitor.end(); +1525 } +1526 +1527 /** {@inheritDoc} */ +1528 @Override +1529 public double walkInRowOrder(final RealMatrixPreservingVisitor visitor, +1530 final int startRow, final int endRow, +1531 final int startColumn, final int endColumn) +1532 throws MatrixIndexException, MatrixVisitorException { +1533 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +1534 visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); +1535 for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { +1536 final int p0 = iBlock * BLOCK_SIZE; +1537 final int pStart = Math.max(startRow, p0); +1538 final int pEnd = Math.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); +1539 for (int p = pStart; p < pEnd; ++p) { +1540 for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { +1541 final int jWidth = blockWidth(jBlock); +1542 final int q0 = jBlock * BLOCK_SIZE; +1543 final int qStart = Math.max(startColumn, q0); +1544 final int qEnd = Math.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); +1545 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1546 int k = (p - p0) * jWidth + qStart - q0; +1547 for (int q = qStart; q < qEnd; ++q) { +1548 visitor.visit(p, q, block[k]); +1549 ++k; +1550 } +1551 } +1552 } +1553 } +1554 return visitor.end(); +1555 } +1556 +1557 /** {@inheritDoc} */ +1558 @Override +1559 public double walkInOptimizedOrder(final RealMatrixChangingVisitor visitor) +1560 throws MatrixVisitorException { +1561 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +1562 int blockIndex = 0; +1563 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1564 final int pStart = iBlock * BLOCK_SIZE; +1565 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +1566 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1567 final int qStart = jBlock * BLOCK_SIZE; +1568 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +1569 final double[] block = blocks[blockIndex]; +1570 int k = 0; +1571 for (int p = pStart; p < pEnd; ++p) { +1572 for (int q = qStart; q < qEnd; ++q) { +1573 block[k] = visitor.visit(p, q, block[k]); +1574 ++k; +1575 } +1576 } +1577 ++blockIndex; +1578 } +1579 } +1580 return visitor.end(); +1581 } +1582 +1583 /** {@inheritDoc} */ +1584 @Override +1585 public double walkInOptimizedOrder(final RealMatrixPreservingVisitor visitor) +1586 throws MatrixVisitorException { +1587 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +1588 int blockIndex = 0; +1589 for (int iBlock = 0; iBlock < blockRows; ++iBlock) { +1590 final int pStart = iBlock * BLOCK_SIZE; +1591 final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); +1592 for (int jBlock = 0; jBlock < blockColumns; ++jBlock) { +1593 final int qStart = jBlock * BLOCK_SIZE; +1594 final int qEnd = Math.min(qStart + BLOCK_SIZE, columns); +1595 final double[] block = blocks[blockIndex]; +1596 int k = 0; +1597 for (int p = pStart; p < pEnd; ++p) { +1598 for (int q = qStart; q < qEnd; ++q) { +1599 visitor.visit(p, q, block[k]); +1600 ++k; +1601 } +1602 } +1603 ++blockIndex; +1604 } +1605 } +1606 return visitor.end(); +1607 } +1608 +1609 /** {@inheritDoc} */ +1610 @Override +1611 public double walkInOptimizedOrder(final RealMatrixChangingVisitor visitor, +1612 final int startRow, final int endRow, +1613 final int startColumn, final int endColumn) +1614 throws MatrixIndexException, MatrixVisitorException { +1615 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +1616 visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); +1617 for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { +1618 final int p0 = iBlock * BLOCK_SIZE; +1619 final int pStart = Math.max(startRow, p0); +1620 final int pEnd = Math.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); +1621 for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { +1622 final int jWidth = blockWidth(jBlock); +1623 final int q0 = jBlock * BLOCK_SIZE; +1624 final int qStart = Math.max(startColumn, q0); +1625 final int qEnd = Math.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); +1626 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1627 for (int p = pStart; p < pEnd; ++p) { +1628 int k = (p - p0) * jWidth + qStart - q0; +1629 for (int q = qStart; q < qEnd; ++q) { +1630 block[k] = visitor.visit(p, q, block[k]); +1631 ++k; +1632 } +1633 } +1634 } +1635 } +1636 return visitor.end(); +1637 } +1638 +1639 /** {@inheritDoc} */ +1640 @Override +1641 public double walkInOptimizedOrder(final RealMatrixPreservingVisitor visitor, +1642 final int startRow, final int endRow, +1643 final int startColumn, final int endColumn) +1644 throws MatrixIndexException, MatrixVisitorException { +1645 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +1646 visitor.start(rows, columns, startRow, endRow, startColumn, endColumn); +1647 for (int iBlock = startRow / BLOCK_SIZE; iBlock < 1 + endRow / BLOCK_SIZE; ++iBlock) { +1648 final int p0 = iBlock * BLOCK_SIZE; +1649 final int pStart = Math.max(startRow, p0); +1650 final int pEnd = Math.min((iBlock + 1) * BLOCK_SIZE, 1 + endRow); +1651 for (int jBlock = startColumn / BLOCK_SIZE; jBlock < 1 + endColumn / BLOCK_SIZE; ++jBlock) { +1652 final int jWidth = blockWidth(jBlock); +1653 final int q0 = jBlock * BLOCK_SIZE; +1654 final int qStart = Math.max(startColumn, q0); +1655 final int qEnd = Math.min((jBlock + 1) * BLOCK_SIZE, 1 + endColumn); +1656 final double[] block = blocks[iBlock * blockColumns + jBlock]; +1657 for (int p = pStart; p < pEnd; ++p) { +1658 int k = (p - p0) * jWidth + qStart - q0; +1659 for (int q = qStart; q < qEnd; ++q) { +1660 visitor.visit(p, q, block[k]); +1661 ++k; +1662 } +1663 } +1664 } +1665 } +1666 return visitor.end(); +1667 } +1668 +1669 /** +1670 * Get the height of a block. +1671 * @param blockRow row index (in block sense) of the block +1672 * @return height (number of rows) of the block +1673 */ +1674 private int blockHeight(final int blockRow) { +1675 return (blockRow == blockRows - 1) ? rows - blockRow * BLOCK_SIZE : BLOCK_SIZE; +1676 } +1677 +1678 /** +1679 * Get the width of a block. +1680 * @param blockColumn column index (in block sense) of the block +1681 * @return width (number of columns) of the block +1682 */ +1683 private int blockWidth(final int blockColumn) { +1684 return (blockColumn == blockColumns - 1) ? columns - blockColumn * BLOCK_SIZE : BLOCK_SIZE; +1685 } +1686 +1687 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/CholeskyDecomposition.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/CholeskyDecomposition.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,137 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 +021 /** +022 * An interface to classes that implement an algorithm to calculate the +023 * Cholesky decomposition of a real symmetric positive-definite matrix. +024 * <p>This interface is based on the class with similar name from the +025 * <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> library, with the +026 * following changes:</p> +027 * <ul> +028 * <li>a {@link #getLT() getLT} method has been added,</li> +029 * <li>the <code>isspd</code> method has been removed, the constructors of +030 * implementation classes being expected to throw {@link +031 * NotPositiveDefiniteMatrixException} when a matrix cannot be decomposed,</li> +032 * <li>a {@link #getDeterminant() getDeterminant} method has been added,</li> +033 * <li>the <code>solve</code> method has been replaced by a {@link +034 * #getSolver() getSolver} method and the equivalent method provided by +035 * the returned {@link DecompositionSolver}.</li> +036 * </ul> +037 * +038 * @see <a href="http://mathworld.wolfram.com/CholeskyDecomposition.html">MathWorld</a> +039 * @see <a href="http://en.wikipedia.org/wiki/Cholesky_decomposition">Wikipedia</a> +040 * @version $Revision: 826627 $ $Date: 2009-10-19 06:27:47 -0400 (Mon, 19 Oct 2009) $ +041 * @since 2.0 +042 */ +043 public interface CholeskyDecomposition { +044 +045 /** +046 * Returns the matrix L of the decomposition. +047 * <p>L is an lower-triangular matrix</p> +048 * @return the L matrix +049 */ +050 RealMatrix getL(); +051 +052 /** +053 * Returns the transpose of the matrix L of the decomposition. +054 * <p>L<sup>T</sup> is an upper-triangular matrix</p> +055 * @return the transpose of the matrix L of the decomposition +056 */ +057 RealMatrix getLT(); +058 +059 /** +060 * Return the determinant of the matrix +061 * @return determinant of the matrix +062 */ +063 double getDeterminant(); +064 +065 /** +066 * Get a solver for finding the A × X = B solution in least square sense. +067 * @return a solver +068 */ +069 DecompositionSolver getSolver(); +070 +071 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/CholeskyDecompositionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/CholeskyDecompositionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,420 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.MathRuntimeException; +021 +022 +023 /** +024 * Calculates the Cholesky decomposition of a matrix. +025 * <p>The Cholesky decomposition of a real symmetric positive-definite +026 * matrix A consists of a lower triangular matrix L with same size that +027 * satisfy: A = LL<sup>T</sup>Q = I). In a sense, this is the square root of A.</p> +028 * +029 * @see <a href="http://mathworld.wolfram.com/CholeskyDecomposition.html">MathWorld</a> +030 * @see <a href="http://en.wikipedia.org/wiki/Cholesky_decomposition">Wikipedia</a> +031 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +032 * @since 2.0 +033 */ +034 public class CholeskyDecompositionImpl implements CholeskyDecomposition { +035 +036 /** Default threshold above which off-diagonal elements are considered too different +037 * and matrix not symmetric. */ +038 public static final double DEFAULT_RELATIVE_SYMMETRY_THRESHOLD = 1.0e-15; +039 +040 /** Default threshold below which diagonal elements are considered null +041 * and matrix not positive definite. */ +042 public static final double DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD = 1.0e-10; +043 +044 /** Row-oriented storage for L<sup>T</sup> matrix data. */ +045 private double[][] lTData; +046 +047 /** Cached value of L. */ +048 private RealMatrix cachedL; +049 +050 /** Cached value of LT. */ +051 private RealMatrix cachedLT; +052 +053 /** +054 * Calculates the Cholesky decomposition of the given matrix. +055 * <p> +056 * Calling this constructor is equivalent to call {@link +057 * #CholeskyDecompositionImpl(RealMatrix, double, double)} with the +058 * thresholds set to the default values {@link +059 * #DEFAULT_RELATIVE_SYMMETRY_THRESHOLD} and {@link +060 * #DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD} +061 * </p> +062 * @param matrix the matrix to decompose +063 * @exception NonSquareMatrixException if matrix is not square +064 * @exception NotSymmetricMatrixException if matrix is not symmetric +065 * @exception NotPositiveDefiniteMatrixException if the matrix is not +066 * strictly positive definite +067 * @see #CholeskyDecompositionImpl(RealMatrix, double, double) +068 * @see #DEFAULT_RELATIVE_SYMMETRY_THRESHOLD +069 * @see #DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD +070 */ +071 public CholeskyDecompositionImpl(final RealMatrix matrix) +072 throws NonSquareMatrixException, +073 NotSymmetricMatrixException, NotPositiveDefiniteMatrixException { +074 this(matrix, DEFAULT_RELATIVE_SYMMETRY_THRESHOLD, +075 DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD); +076 } +077 +078 /** +079 * Calculates the Cholesky decomposition of the given matrix. +080 * @param matrix the matrix to decompose +081 * @param relativeSymmetryThreshold threshold above which off-diagonal +082 * elements are considered too different and matrix not symmetric +083 * @param absolutePositivityThreshold threshold below which diagonal +084 * elements are considered null and matrix not positive definite +085 * @exception NonSquareMatrixException if matrix is not square +086 * @exception NotSymmetricMatrixException if matrix is not symmetric +087 * @exception NotPositiveDefiniteMatrixException if the matrix is not +088 * strictly positive definite +089 * @see #CholeskyDecompositionImpl(RealMatrix) +090 * @see #DEFAULT_RELATIVE_SYMMETRY_THRESHOLD +091 * @see #DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD +092 */ +093 public CholeskyDecompositionImpl(final RealMatrix matrix, +094 final double relativeSymmetryThreshold, +095 final double absolutePositivityThreshold) +096 throws NonSquareMatrixException, +097 NotSymmetricMatrixException, NotPositiveDefiniteMatrixException { +098 +099 if (!matrix.isSquare()) { +100 throw new NonSquareMatrixException(matrix.getRowDimension(), +101 matrix.getColumnDimension()); +102 } +103 +104 final int order = matrix.getRowDimension(); +105 lTData = matrix.getData(); +106 cachedL = null; +107 cachedLT = null; +108 +109 // check the matrix before transformation +110 for (int i = 0; i < order; ++i) { +111 +112 final double[] lI = lTData[i]; +113 +114 // check off-diagonal elements (and reset them to 0) +115 for (int j = i + 1; j < order; ++j) { +116 final double[] lJ = lTData[j]; +117 final double lIJ = lI[j]; +118 final double lJI = lJ[i]; +119 final double maxDelta = +120 relativeSymmetryThreshold * Math.max(Math.abs(lIJ), Math.abs(lJI)); +121 if (Math.abs(lIJ - lJI) > maxDelta) { +122 throw new NotSymmetricMatrixException(); +123 } +124 lJ[i] = 0; +125 } +126 } +127 +128 // transform the matrix +129 for (int i = 0; i < order; ++i) { +130 +131 final double[] ltI = lTData[i]; +132 +133 // check diagonal element +134 if (ltI[i] < absolutePositivityThreshold) { +135 throw new NotPositiveDefiniteMatrixException(); +136 } +137 +138 ltI[i] = Math.sqrt(ltI[i]); +139 final double inverse = 1.0 / ltI[i]; +140 +141 for (int q = order - 1; q > i; --q) { +142 ltI[q] *= inverse; +143 final double[] ltQ = lTData[q]; +144 for (int p = q; p < order; ++p) { +145 ltQ[p] -= ltI[q] * ltI[p]; +146 } +147 } +148 +149 } +150 +151 } +152 +153 /** {@inheritDoc} */ +154 public RealMatrix getL() { +155 if (cachedL == null) { +156 cachedL = getLT().transpose(); +157 } +158 return cachedL; +159 } +160 +161 /** {@inheritDoc} */ +162 public RealMatrix getLT() { +163 +164 if (cachedLT == null) { +165 cachedLT = MatrixUtils.createRealMatrix(lTData); +166 } +167 +168 // return the cached matrix +169 return cachedLT; +170 +171 } +172 +173 /** {@inheritDoc} */ +174 public double getDeterminant() { +175 double determinant = 1.0; +176 for (int i = 0; i < lTData.length; ++i) { +177 double lTii = lTData[i][i]; +178 determinant *= lTii * lTii; +179 } +180 return determinant; +181 } +182 +183 /** {@inheritDoc} */ +184 public DecompositionSolver getSolver() { +185 return new Solver(lTData); +186 } +187 +188 /** Specialized solver. */ +189 private static class Solver implements DecompositionSolver { +190 +191 /** Row-oriented storage for L<sup>T</sup> matrix data. */ +192 private final double[][] lTData; +193 +194 /** +195 * Build a solver from decomposed matrix. +196 * @param lTData row-oriented storage for L<sup>T</sup> matrix data +197 */ +198 private Solver(final double[][] lTData) { +199 this.lTData = lTData; +200 } +201 +202 /** {@inheritDoc} */ +203 public boolean isNonSingular() { +204 // if we get this far, the matrix was positive definite, hence non-singular +205 return true; +206 } +207 +208 /** {@inheritDoc} */ +209 public double[] solve(double[] b) +210 throws IllegalArgumentException, InvalidMatrixException { +211 +212 final int m = lTData.length; +213 if (b.length != m) { +214 throw MathRuntimeException.createIllegalArgumentException( +215 "vector length mismatch: got {0} but expected {1}", +216 b.length, m); +217 } +218 +219 final double[] x = b.clone(); +220 +221 // Solve LY = b +222 for (int j = 0; j < m; j++) { +223 final double[] lJ = lTData[j]; +224 x[j] /= lJ[j]; +225 final double xJ = x[j]; +226 for (int i = j + 1; i < m; i++) { +227 x[i] -= xJ * lJ[i]; +228 } +229 } +230 +231 // Solve LTX = Y +232 for (int j = m - 1; j >= 0; j--) { +233 x[j] /= lTData[j][j]; +234 final double xJ = x[j]; +235 for (int i = 0; i < j; i++) { +236 x[i] -= xJ * lTData[i][j]; +237 } +238 } +239 +240 return x; +241 +242 } +243 +244 /** {@inheritDoc} */ +245 public RealVector solve(RealVector b) +246 throws IllegalArgumentException, InvalidMatrixException { +247 try { +248 return solve((ArrayRealVector) b); +249 } catch (ClassCastException cce) { +250 +251 final int m = lTData.length; +252 if (b.getDimension() != m) { +253 throw MathRuntimeException.createIllegalArgumentException( +254 "vector length mismatch: got {0} but expected {1}", +255 b.getDimension(), m); +256 } +257 +258 final double[] x = b.getData(); +259 +260 // Solve LY = b +261 for (int j = 0; j < m; j++) { +262 final double[] lJ = lTData[j]; +263 x[j] /= lJ[j]; +264 final double xJ = x[j]; +265 for (int i = j + 1; i < m; i++) { +266 x[i] -= xJ * lJ[i]; +267 } +268 } +269 +270 // Solve LTX = Y +271 for (int j = m - 1; j >= 0; j--) { +272 x[j] /= lTData[j][j]; +273 final double xJ = x[j]; +274 for (int i = 0; i < j; i++) { +275 x[i] -= xJ * lTData[i][j]; +276 } +277 } +278 +279 return new ArrayRealVector(x, false); +280 +281 } +282 } +283 +284 /** Solve the linear equation A × X = B. +285 * <p>The A matrix is implicit here. It is </p> +286 * @param b right-hand side of the equation A × X = B +287 * @return a vector X such that A × X = B +288 * @exception IllegalArgumentException if matrices dimensions don't match +289 * @exception InvalidMatrixException if decomposed matrix is singular +290 */ +291 public ArrayRealVector solve(ArrayRealVector b) +292 throws IllegalArgumentException, InvalidMatrixException { +293 return new ArrayRealVector(solve(b.getDataRef()), false); +294 } +295 +296 /** {@inheritDoc} */ +297 public RealMatrix solve(RealMatrix b) +298 throws IllegalArgumentException, InvalidMatrixException { +299 +300 final int m = lTData.length; +301 if (b.getRowDimension() != m) { +302 throw MathRuntimeException.createIllegalArgumentException( +303 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +304 b.getRowDimension(), b.getColumnDimension(), m, "n"); +305 } +306 +307 final int nColB = b.getColumnDimension(); +308 double[][] x = b.getData(); +309 +310 // Solve LY = b +311 for (int j = 0; j < m; j++) { +312 final double[] lJ = lTData[j]; +313 final double lJJ = lJ[j]; +314 final double[] xJ = x[j]; +315 for (int k = 0; k < nColB; ++k) { +316 xJ[k] /= lJJ; +317 } +318 for (int i = j + 1; i < m; i++) { +319 final double[] xI = x[i]; +320 final double lJI = lJ[i]; +321 for (int k = 0; k < nColB; ++k) { +322 xI[k] -= xJ[k] * lJI; +323 } +324 } +325 } +326 +327 // Solve LTX = Y +328 for (int j = m - 1; j >= 0; j--) { +329 final double lJJ = lTData[j][j]; +330 final double[] xJ = x[j]; +331 for (int k = 0; k < nColB; ++k) { +332 xJ[k] /= lJJ; +333 } +334 for (int i = 0; i < j; i++) { +335 final double[] xI = x[i]; +336 final double lIJ = lTData[i][j]; +337 for (int k = 0; k < nColB; ++k) { +338 xI[k] -= xJ[k] * lIJ; +339 } +340 } +341 } +342 +343 return new Array2DRowRealMatrix(x, false); +344 +345 } +346 +347 /** {@inheritDoc} */ +348 public RealMatrix getInverse() throws InvalidMatrixException { +349 return solve(MatrixUtils.createRealIdentityMatrix(lTData.length)); +350 } +351 +352 } +353 +354 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/DecompositionSolver.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/DecompositionSolver.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,150 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 +021 +022 /** +023 * Interface handling decomposition algorithms that can solve A × X = B. +024 * <p>Decomposition algorithms decompose an A matrix has a product of several specific +025 * matrices from which they can solve A × X = B in least squares sense: they find X +026 * such that ||A × X - B|| is minimal.</p> +027 * <p>Some solvers like {@link LUDecomposition} can only find the solution for +028 * square matrices and when the solution is an exact linear solution, i.e. when +029 * ||A × X - B|| is exactly 0. Other solvers can also find solutions +030 * with non-square matrix A and with non-null minimal norm. If an exact linear +031 * solution exists it is also the minimal norm solution.</p> +032 * +033 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +034 * @since 2.0 +035 */ +036 public interface DecompositionSolver { +037 +038 /** Solve the linear equation A × X = B for matrices A. +039 * <p>The A matrix is implicit, it is provided by the underlying +040 * decomposition algorithm.</p> +041 * @param b right-hand side of the equation A × X = B +042 * @return a vector X that minimizes the two norm of A × X - B +043 * @exception IllegalArgumentException if matrices dimensions don't match +044 * @exception InvalidMatrixException if decomposed matrix is singular +045 */ +046 double[] solve(final double[] b) +047 throws IllegalArgumentException, InvalidMatrixException; +048 +049 /** Solve the linear equation A × X = B for matrices A. +050 * <p>The A matrix is implicit, it is provided by the underlying +051 * decomposition algorithm.</p> +052 * @param b right-hand side of the equation A × X = B +053 * @return a vector X that minimizes the two norm of A × X - B +054 * @exception IllegalArgumentException if matrices dimensions don't match +055 * @exception InvalidMatrixException if decomposed matrix is singular +056 */ +057 RealVector solve(final RealVector b) +058 throws IllegalArgumentException, InvalidMatrixException; +059 +060 /** Solve the linear equation A × X = B for matrices A. +061 * <p>The A matrix is implicit, it is provided by the underlying +062 * decomposition algorithm.</p> +063 * @param b right-hand side of the equation A × X = B +064 * @return a matrix X that minimizes the two norm of A × X - B +065 * @exception IllegalArgumentException if matrices dimensions don't match +066 * @exception InvalidMatrixException if decomposed matrix is singular +067 */ +068 RealMatrix solve(final RealMatrix b) +069 throws IllegalArgumentException, InvalidMatrixException; +070 +071 /** +072 * Check if the decomposed matrix is non-singular. +073 * @return true if the decomposed matrix is non-singular +074 */ +075 boolean isNonSingular(); +076 +077 /** Get the inverse (or pseudo-inverse) of the decomposed matrix. +078 * @return inverse matrix +079 * @throws InvalidMatrixException if decomposed matrix is singular +080 */ +081 RealMatrix getInverse() +082 throws InvalidMatrixException; +083 +084 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/DefaultFieldMatrixChangingVisitor.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/DefaultFieldMatrixChangingVisitor.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,128 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.FieldElement; +021 +022 /** +023 * Default implementation of the {@link FieldMatrixChangingVisitor} interface. +024 * <p> +025 * This class is a convenience to create custom visitors without defining all +026 * methods. This class provides default implementations that do nothing. +027 * </p> +028 * +029 * @param <T> the type of the field elements +030 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +031 * @since 2.0 +032 */ +033 public class DefaultFieldMatrixChangingVisitor<T extends FieldElement<T>> +034 implements FieldMatrixChangingVisitor<T> { +035 +036 /** Zero element of the field. */ +037 private final T zero; +038 +039 /** Build a new instance. +040 * @param zero additive identity of the field +041 */ +042 public DefaultFieldMatrixChangingVisitor(final T zero) { +043 this.zero = zero; +044 } +045 +046 /** {@inheritDoc} */ +047 public void start(int rows, int columns, +048 int startRow, int endRow, int startColumn, int endColumn) { +049 } +050 +051 /** {@inheritDoc} */ +052 public T visit(int row, int column, T value) +053 throws MatrixVisitorException { +054 return value; +055 } +056 +057 /** {@inheritDoc} */ +058 public T end() { +059 return zero; +060 } +061 +062 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/DefaultFieldMatrixPreservingVisitor.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/DefaultFieldMatrixPreservingVisitor.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,127 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.FieldElement; +021 +022 /** +023 * Default implementation of the {@link FieldMatrixPreservingVisitor} interface. +024 * <p> +025 * This class is a convenience to create custom visitors without defining all +026 * methods. This class provides default implementations that do nothing. +027 * </p> +028 * +029 * @param <T> the type of the field elements +030 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +031 * @since 2.0 +032 */ +033 public class DefaultFieldMatrixPreservingVisitor<T extends FieldElement<T>> +034 implements FieldMatrixPreservingVisitor<T> { +035 +036 /** Zero element of the field. */ +037 private final T zero; +038 +039 /** Build a new instance. +040 * @param zero additive identity of the field +041 */ +042 public DefaultFieldMatrixPreservingVisitor(final T zero) { +043 this.zero = zero; +044 } +045 +046 /** {@inheritDoc} */ +047 public void start(int rows, int columns, +048 int startRow, int endRow, int startColumn, int endColumn) { +049 } +050 +051 /** {@inheritDoc} */ +052 public void visit(int row, int column, T value) +053 throws MatrixVisitorException { +054 } +055 +056 /** {@inheritDoc} */ +057 public T end() { +058 return zero; +059 } +060 +061 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/DefaultRealMatrixChangingVisitor.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/DefaultRealMatrixChangingVisitor.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,114 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 /** +021 * Default implementation of the {@link RealMatrixChangingVisitor} interface. +022 * <p> +023 * This class is a convenience to create custom visitors without defining all +024 * methods. This class provides default implementations that do nothing. +025 * </p> +026 * +027 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +028 * @since 2.0 +029 */ +030 public class DefaultRealMatrixChangingVisitor implements RealMatrixChangingVisitor { +031 +032 /** {@inheritDoc} */ +033 public void start(int rows, int columns, +034 int startRow, int endRow, int startColumn, int endColumn) { +035 } +036 +037 /** {@inheritDoc} */ +038 public double visit(int row, int column, double value) +039 throws MatrixVisitorException { +040 return value; +041 } +042 +043 /** {@inheritDoc} */ +044 public double end() { +045 return 0; +046 } +047 +048 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/DefaultRealMatrixPreservingVisitor.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/DefaultRealMatrixPreservingVisitor.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,113 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 /** +021 * Default implementation of the {@link RealMatrixPreservingVisitor} interface. +022 * <p> +023 * This class is a convenience to create custom visitors without defining all +024 * methods. This class provides default implementations that do nothing. +025 * </p> +026 * +027 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +028 * @since 2.0 +029 */ +030 public class DefaultRealMatrixPreservingVisitor implements RealMatrixPreservingVisitor { +031 +032 /** {@inheritDoc} */ +033 public void start(int rows, int columns, +034 int startRow, int endRow, int startColumn, int endColumn) { +035 } +036 +037 /** {@inheritDoc} */ +038 public void visit(int row, int column, double value) +039 throws MatrixVisitorException { +040 } +041 +042 /** {@inheritDoc} */ +043 public double end() { +044 return 0; +045 } +046 +047 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/EigenDecomposition.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/EigenDecomposition.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,197 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 +021 /** +022 * An interface to classes that implement an algorithm to calculate the +023 * eigen decomposition of a real matrix. +024 * <p>The eigen decomposition of matrix A is a set of two matrices: +025 * V and D such that A = V × D × V<sup>T</sup>. +026 * A, V and D are all m × m matrices.</p> +027 * <p>This interface is similar in spirit to the <code>EigenvalueDecomposition</code> +028 * class from the <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> +029 * library, with the following changes:</p> +030 * <ul> +031 * <li>a {@link #getVT() getVt} method has been added,</li> +032 * <li>two {@link #getRealEigenvalue(int) getRealEigenvalue} and {@link #getImagEigenvalue(int) +033 * getImagEigenvalue} methods to pick up a single eigenvalue have been added,</li> +034 * <li>a {@link #getEigenvector(int) getEigenvector} method to pick up a single +035 * eigenvector has been added,</li> +036 * <li>a {@link #getDeterminant() getDeterminant} method has been added.</li> +037 * <li>a {@link #getSolver() getSolver} method has been added.</li> +038 * </ul> +039 * @see <a href="http://mathworld.wolfram.com/EigenDecomposition.html">MathWorld</a> +040 * @see <a href="http://en.wikipedia.org/wiki/Eigendecomposition_of_a_matrix">Wikipedia</a> +041 * @version $Revision: 826627 $ $Date: 2009-10-19 06:27:47 -0400 (Mon, 19 Oct 2009) $ +042 * @since 2.0 +043 */ +044 public interface EigenDecomposition { +045 +046 /** +047 * Returns the matrix V of the decomposition. +048 * <p>V is an orthogonal matrix, i.e. its transpose is also its inverse.</p> +049 * <p>The columns of V are the eigenvectors of the original matrix.</p> +050 * @return the V matrix +051 */ +052 RealMatrix getV(); +053 +054 /** +055 * Returns the block diagonal matrix D of the decomposition. +056 * <p>D is a block diagonal matrix.</p> +057 * <p>Real eigenvalues are on the diagonal while complex values are on +058 * 2x2 blocks { {real +imaginary}, {-imaginary, real} }.</p> +059 * @return the D matrix +060 * @see #getRealEigenvalues() +061 * @see #getImagEigenvalues() +062 */ +063 RealMatrix getD(); +064 +065 /** +066 * Returns the transpose of the matrix V of the decomposition. +067 * <p>V is an orthogonal matrix, i.e. its transpose is also its inverse.</p> +068 * <p>The columns of V are the eigenvectors of the original matrix.</p> +069 * @return the transpose of the V matrix +070 */ +071 RealMatrix getVT(); +072 +073 /** +074 * Returns a copy of the real parts of the eigenvalues of the original matrix. +075 * @return a copy of the real parts of the eigenvalues of the original matrix +076 * @see #getD() +077 * @see #getRealEigenvalue(int) +078 * @see #getImagEigenvalues() +079 */ +080 double[] getRealEigenvalues(); +081 +082 /** +083 * Returns the real part of the i<sup>th</sup> eigenvalue of the original matrix. +084 * @param i index of the eigenvalue (counting from 0) +085 * @return real part of the i<sup>th</sup> eigenvalue of the original matrix +086 * @see #getD() +087 * @see #getRealEigenvalues() +088 * @see #getImagEigenvalue(int) +089 */ +090 double getRealEigenvalue(int i); +091 +092 /** +093 * Returns a copy of the imaginary parts of the eigenvalues of the original matrix. +094 * @return a copy of the imaginary parts of the eigenvalues of the original matrix +095 * @see #getD() +096 * @see #getImagEigenvalue(int) +097 * @see #getRealEigenvalues() +098 */ +099 double[] getImagEigenvalues(); +100 +101 /** +102 * Returns the imaginary part of the i<sup>th</sup> eigenvalue of the original matrix. +103 * @param i index of the eigenvalue (counting from 0) +104 * @return imaginary part of the i<sup>th</sup> eigenvalue of the original matrix +105 * @see #getD() +106 * @see #getImagEigenvalues() +107 * @see #getRealEigenvalue(int) +108 */ +109 double getImagEigenvalue(int i); +110 +111 /** +112 * Returns a copy of the i<sup>th</sup> eigenvector of the original matrix. +113 * @param i index of the eigenvector (counting from 0) +114 * @return copy of the i<sup>th</sup> eigenvector of the original matrix +115 * @see #getD() +116 */ +117 RealVector getEigenvector(int i); +118 +119 /** +120 * Return the determinant of the matrix +121 * @return determinant of the matrix +122 */ +123 double getDeterminant(); +124 +125 /** +126 * Get a solver for finding the A × X = B solution in exact linear sense. +127 * @return a solver +128 */ +129 DecompositionSolver getSolver(); +130 +131 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/EigenDecompositionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/EigenDecompositionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,683 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.MaxIterationsExceededException; +022 import org.apache.commons.math.util.MathUtils; +023 +024 /** +025 * Calculates the eigen decomposition of a real <strong>symmetric</strong> +026 * matrix. +027 * <p> +028 * The eigen decomposition of matrix A is a set of two matrices: V and D such +029 * that A = V D V<sup>T</sup>. A, V and D are all m × m matrices. +030 * </p> +031 * <p> +032 * As of 2.0, this class supports only <strong>symmetric</strong> matrices, and +033 * hence computes only real realEigenvalues. This implies the D matrix returned +034 * by {@link #getD()} is always diagonal and the imaginary values returned +035 * {@link #getImagEigenvalue(int)} and {@link #getImagEigenvalues()} are always +036 * null. +037 * </p> +038 * <p> +039 * When called with a {@link RealMatrix} argument, this implementation only uses +040 * the upper part of the matrix, the part below the diagonal is not accessed at +041 * all. +042 * </p> +043 * <p> +044 * This implementation is based on the paper by A. Drubrulle, R.S. Martin and +045 * J.H. Wilkinson 'The Implicit QL Algorithm' in Wilksinson and Reinsch (1971) +046 * Handbook for automatic computation, vol. 2, Linear algebra, Springer-Verlag, +047 * New-York +048 * </p> +049 * @version $Revision: 912413 $ $Date: 2010-02-21 16:46:12 -0500 (Sun, 21 Feb 2010) $ +050 * @since 2.0 +051 */ +052 public class EigenDecompositionImpl implements EigenDecomposition { +053 +054 /** Maximum number of iterations accepted in the implicit QL transformation */ +055 private byte maxIter = 30; +056 +057 /** Main diagonal of the tridiagonal matrix. */ +058 private double[] main; +059 +060 /** Secondary diagonal of the tridiagonal matrix. */ +061 private double[] secondary; +062 +063 /** +064 * Transformer to tridiagonal (may be null if matrix is already +065 * tridiagonal). +066 */ +067 private TriDiagonalTransformer transformer; +068 +069 /** Real part of the realEigenvalues. */ +070 private double[] realEigenvalues; +071 +072 /** Imaginary part of the realEigenvalues. */ +073 private double[] imagEigenvalues; +074 +075 /** Eigenvectors. */ +076 private ArrayRealVector[] eigenvectors; +077 +078 /** Cached value of V. */ +079 private RealMatrix cachedV; +080 +081 /** Cached value of D. */ +082 private RealMatrix cachedD; +083 +084 /** Cached value of Vt. */ +085 private RealMatrix cachedVt; +086 +087 /** +088 * Calculates the eigen decomposition of the given symmetric matrix. +089 * @param matrix The <strong>symmetric</strong> matrix to decompose. +090 * @param splitTolerance dummy parameter, present for backward compatibility only. +091 * @exception InvalidMatrixException (wrapping a +092 * {@link org.apache.commons.math.ConvergenceException} if algorithm +093 * fails to converge +094 */ +095 public EigenDecompositionImpl(final RealMatrix matrix,final double splitTolerance) +096 throws InvalidMatrixException { +097 if (isSymmetric(matrix)) { +098 transformToTridiagonal(matrix); +099 findEigenVectors(transformer.getQ().getData()); +100 } else { +101 // as of 2.0, non-symmetric matrices (i.e. complex eigenvalues) are +102 // NOT supported +103 // see issue https://issues.apache.org/jira/browse/MATH-235 +104 throw new InvalidMatrixException( +105 "eigen decomposition of assymetric matrices not supported yet"); +106 } +107 } +108 +109 /** +110 * Calculates the eigen decomposition of the symmetric tridiagonal +111 * matrix. The Householder matrix is assumed to be the identity matrix. +112 * @param main Main diagonal of the symmetric triadiagonal form +113 * @param secondary Secondary of the tridiagonal form +114 * @param splitTolerance dummy parameter, present for backward compatibility only. +115 * @exception InvalidMatrixException (wrapping a +116 * {@link org.apache.commons.math.ConvergenceException} if algorithm +117 * fails to converge +118 */ +119 public EigenDecompositionImpl(final double[] main,final double[] secondary, +120 final double splitTolerance) +121 throws InvalidMatrixException { +122 this.main = main.clone(); +123 this.secondary = secondary.clone(); +124 transformer = null; +125 final int size=main.length; +126 double[][] z = new double[size][size]; +127 for (int i=0;i<size;i++) { +128 z[i][i]=1.0; +129 } +130 findEigenVectors(z); +131 } +132 +133 /** +134 * Check if a matrix is symmetric. +135 * @param matrix +136 * matrix to check +137 * @return true if matrix is symmetric +138 */ +139 private boolean isSymmetric(final RealMatrix matrix) { +140 final int rows = matrix.getRowDimension(); +141 final int columns = matrix.getColumnDimension(); +142 final double eps = 10 * rows * columns * MathUtils.EPSILON; +143 for (int i = 0; i < rows; ++i) { +144 for (int j = i + 1; j < columns; ++j) { +145 final double mij = matrix.getEntry(i, j); +146 final double mji = matrix.getEntry(j, i); +147 if (Math.abs(mij - mji) > (Math.max(Math.abs(mij), Math +148 .abs(mji)) * eps)) { +149 return false; +150 } +151 } +152 } +153 return true; +154 } +155 +156 /** {@inheritDoc} */ +157 public RealMatrix getV() throws InvalidMatrixException { +158 +159 if (cachedV == null) { +160 final int m = eigenvectors.length; +161 cachedV = MatrixUtils.createRealMatrix(m, m); +162 for (int k = 0; k < m; ++k) { +163 cachedV.setColumnVector(k, eigenvectors[k]); +164 } +165 } +166 // return the cached matrix +167 return cachedV; +168 +169 } +170 +171 /** {@inheritDoc} */ +172 public RealMatrix getD() throws InvalidMatrixException { +173 if (cachedD == null) { +174 // cache the matrix for subsequent calls +175 cachedD = MatrixUtils.createRealDiagonalMatrix(realEigenvalues); +176 } +177 return cachedD; +178 } +179 +180 /** {@inheritDoc} */ +181 public RealMatrix getVT() throws InvalidMatrixException { +182 +183 if (cachedVt == null) { +184 final int m = eigenvectors.length; +185 cachedVt = MatrixUtils.createRealMatrix(m, m); +186 for (int k = 0; k < m; ++k) { +187 cachedVt.setRowVector(k, eigenvectors[k]); +188 } +189 +190 } +191 +192 // return the cached matrix +193 return cachedVt; +194 } +195 +196 /** {@inheritDoc} */ +197 public double[] getRealEigenvalues() throws InvalidMatrixException { +198 return realEigenvalues.clone(); +199 } +200 +201 /** {@inheritDoc} */ +202 public double getRealEigenvalue(final int i) throws InvalidMatrixException, +203 ArrayIndexOutOfBoundsException { +204 return realEigenvalues[i]; +205 } +206 +207 /** {@inheritDoc} */ +208 public double[] getImagEigenvalues() throws InvalidMatrixException { +209 return imagEigenvalues.clone(); +210 } +211 +212 /** {@inheritDoc} */ +213 public double getImagEigenvalue(final int i) throws InvalidMatrixException, +214 ArrayIndexOutOfBoundsException { +215 return imagEigenvalues[i]; +216 } +217 +218 /** {@inheritDoc} */ +219 public RealVector getEigenvector(final int i) +220 throws InvalidMatrixException, ArrayIndexOutOfBoundsException { +221 return eigenvectors[i].copy(); +222 } +223 +224 /** +225 * Return the determinant of the matrix +226 * @return determinant of the matrix +227 */ +228 public double getDeterminant() { +229 double determinant = 1; +230 for (double lambda : realEigenvalues) { +231 determinant *= lambda; +232 } +233 return determinant; +234 } +235 +236 /** {@inheritDoc} */ +237 public DecompositionSolver getSolver() { +238 return new Solver(realEigenvalues, imagEigenvalues, eigenvectors); +239 } +240 +241 /** Specialized solver. */ +242 private static class Solver implements DecompositionSolver { +243 +244 /** Real part of the realEigenvalues. */ +245 private double[] realEigenvalues; +246 +247 /** Imaginary part of the realEigenvalues. */ +248 private double[] imagEigenvalues; +249 +250 /** Eigenvectors. */ +251 private final ArrayRealVector[] eigenvectors; +252 +253 /** +254 * Build a solver from decomposed matrix. +255 * @param realEigenvalues +256 * real parts of the eigenvalues +257 * @param imagEigenvalues +258 * imaginary parts of the eigenvalues +259 * @param eigenvectors +260 * eigenvectors +261 */ +262 private Solver(final double[] realEigenvalues, +263 final double[] imagEigenvalues, +264 final ArrayRealVector[] eigenvectors) { +265 this.realEigenvalues = realEigenvalues; +266 this.imagEigenvalues = imagEigenvalues; +267 this.eigenvectors = eigenvectors; +268 } +269 +270 /** +271 * Solve the linear equation A × X = B for symmetric matrices A. +272 * <p> +273 * This method only find exact linear solutions, i.e. solutions for +274 * which ||A × X - B|| is exactly 0. +275 * </p> +276 * @param b +277 * right-hand side of the equation A × X = B +278 * @return a vector X that minimizes the two norm of A × X - B +279 * @exception IllegalArgumentException +280 * if matrices dimensions don't match +281 * @exception InvalidMatrixException +282 * if decomposed matrix is singular +283 */ +284 public double[] solve(final double[] b) +285 throws IllegalArgumentException, InvalidMatrixException { +286 +287 if (!isNonSingular()) { +288 throw new SingularMatrixException(); +289 } +290 +291 final int m = realEigenvalues.length; +292 if (b.length != m) { +293 throw MathRuntimeException.createIllegalArgumentException( +294 "vector length mismatch: got {0} but expected {1}", +295 b.length, m); +296 } +297 +298 final double[] bp = new double[m]; +299 for (int i = 0; i < m; ++i) { +300 final ArrayRealVector v = eigenvectors[i]; +301 final double[] vData = v.getDataRef(); +302 final double s = v.dotProduct(b) / realEigenvalues[i]; +303 for (int j = 0; j < m; ++j) { +304 bp[j] += s * vData[j]; +305 } +306 } +307 +308 return bp; +309 +310 } +311 +312 /** +313 * Solve the linear equation A × X = B for symmetric matrices A. +314 * <p> +315 * This method only find exact linear solutions, i.e. solutions for +316 * which ||A × X - B|| is exactly 0. +317 * </p> +318 * @param b +319 * right-hand side of the equation A × X = B +320 * @return a vector X that minimizes the two norm of A × X - B +321 * @exception IllegalArgumentException +322 * if matrices dimensions don't match +323 * @exception InvalidMatrixException +324 * if decomposed matrix is singular +325 */ +326 public RealVector solve(final RealVector b) +327 throws IllegalArgumentException, InvalidMatrixException { +328 +329 if (!isNonSingular()) { +330 throw new SingularMatrixException(); +331 } +332 +333 final int m = realEigenvalues.length; +334 if (b.getDimension() != m) { +335 throw MathRuntimeException.createIllegalArgumentException( +336 "vector length mismatch: got {0} but expected {1}", b +337 .getDimension(), m); +338 } +339 +340 final double[] bp = new double[m]; +341 for (int i = 0; i < m; ++i) { +342 final ArrayRealVector v = eigenvectors[i]; +343 final double[] vData = v.getDataRef(); +344 final double s = v.dotProduct(b) / realEigenvalues[i]; +345 for (int j = 0; j < m; ++j) { +346 bp[j] += s * vData[j]; +347 } +348 } +349 +350 return new ArrayRealVector(bp, false); +351 +352 } +353 +354 /** +355 * Solve the linear equation A × X = B for symmetric matrices A. +356 * <p> +357 * This method only find exact linear solutions, i.e. solutions for +358 * which ||A × X - B|| is exactly 0. +359 * </p> +360 * @param b +361 * right-hand side of the equation A × X = B +362 * @return a matrix X that minimizes the two norm of A × X - B +363 * @exception IllegalArgumentException +364 * if matrices dimensions don't match +365 * @exception InvalidMatrixException +366 * if decomposed matrix is singular +367 */ +368 public RealMatrix solve(final RealMatrix b) +369 throws IllegalArgumentException, InvalidMatrixException { +370 +371 if (!isNonSingular()) { +372 throw new SingularMatrixException(); +373 } +374 +375 final int m = realEigenvalues.length; +376 if (b.getRowDimension() != m) { +377 throw MathRuntimeException +378 .createIllegalArgumentException( +379 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +380 b.getRowDimension(), b.getColumnDimension(), m, +381 "n"); +382 } +383 +384 final int nColB = b.getColumnDimension(); +385 final double[][] bp = new double[m][nColB]; +386 for (int k = 0; k < nColB; ++k) { +387 for (int i = 0; i < m; ++i) { +388 final ArrayRealVector v = eigenvectors[i]; +389 final double[] vData = v.getDataRef(); +390 double s = 0; +391 for (int j = 0; j < m; ++j) { +392 s += v.getEntry(j) * b.getEntry(j, k); +393 } +394 s /= realEigenvalues[i]; +395 for (int j = 0; j < m; ++j) { +396 bp[j][k] += s * vData[j]; +397 } +398 } +399 } +400 +401 return MatrixUtils.createRealMatrix(bp); +402 +403 } +404 +405 /** +406 * Check if the decomposed matrix is non-singular. +407 * @return true if the decomposed matrix is non-singular +408 */ +409 public boolean isNonSingular() { +410 for (int i = 0; i < realEigenvalues.length; ++i) { +411 if ((realEigenvalues[i] == 0) && (imagEigenvalues[i] == 0)) { +412 return false; +413 } +414 } +415 return true; +416 } +417 +418 /** +419 * Get the inverse of the decomposed matrix. +420 * @return inverse matrix +421 * @throws InvalidMatrixException +422 * if decomposed matrix is singular +423 */ +424 public RealMatrix getInverse() throws InvalidMatrixException { +425 +426 if (!isNonSingular()) { +427 throw new SingularMatrixException(); +428 } +429 +430 final int m = realEigenvalues.length; +431 final double[][] invData = new double[m][m]; +432 +433 for (int i = 0; i < m; ++i) { +434 final double[] invI = invData[i]; +435 for (int j = 0; j < m; ++j) { +436 double invIJ = 0; +437 for (int k = 0; k < m; ++k) { +438 final double[] vK = eigenvectors[k].getDataRef(); +439 invIJ += vK[i] * vK[j] / realEigenvalues[k]; +440 } +441 invI[j] = invIJ; +442 } +443 } +444 return MatrixUtils.createRealMatrix(invData); +445 +446 } +447 +448 } +449 +450 /** +451 * Transform matrix to tridiagonal. +452 * @param matrix +453 * matrix to transform +454 */ +455 private void transformToTridiagonal(final RealMatrix matrix) { +456 +457 // transform the matrix to tridiagonal +458 transformer = new TriDiagonalTransformer(matrix); +459 main = transformer.getMainDiagonalRef(); +460 secondary = transformer.getSecondaryDiagonalRef(); +461 +462 } +463 +464 /** +465 * Find eigenvalues and eigenvectors (Dubrulle et al., 1971) +466 * @param householderMatrix Householder matrix of the transformation +467 * to tri-diagonal form. +468 */ +469 private void findEigenVectors(double[][] householderMatrix) { +470 +471 double[][]z = householderMatrix.clone(); +472 final int n = main.length; +473 realEigenvalues = new double[n]; +474 imagEigenvalues = new double[n]; +475 double[] e = new double[n]; +476 for (int i = 0; i < n - 1; i++) { +477 realEigenvalues[i] = main[i]; +478 e[i] = secondary[i]; +479 } +480 realEigenvalues[n - 1] = main[n - 1]; +481 e[n - 1] = 0.0; +482 +483 // Determine the largest main and secondary value in absolute term. +484 double maxAbsoluteValue=0.0; +485 for (int i = 0; i < n; i++) { +486 if (Math.abs(realEigenvalues[i])>maxAbsoluteValue) { +487 maxAbsoluteValue=Math.abs(realEigenvalues[i]); +488 } +489 if (Math.abs(e[i])>maxAbsoluteValue) { +490 maxAbsoluteValue=Math.abs(e[i]); +491 } +492 } +493 // Make null any main and secondary value too small to be significant +494 if (maxAbsoluteValue!=0.0) { +495 for (int i=0; i < n; i++) { +496 if (Math.abs(realEigenvalues[i])<=MathUtils.EPSILON*maxAbsoluteValue) { +497 realEigenvalues[i]=0.0; +498 } +499 if (Math.abs(e[i])<=MathUtils.EPSILON*maxAbsoluteValue) { +500 e[i]=0.0; +501 } +502 } +503 } +504 +505 for (int j = 0; j < n; j++) { +506 int its = 0; +507 int m; +508 do { +509 for (m = j; m < n - 1; m++) { +510 double delta = Math.abs(realEigenvalues[m]) + Math.abs(realEigenvalues[m + 1]); +511 if (Math.abs(e[m]) + delta == delta) { +512 break; +513 } +514 } +515 if (m != j) { +516 if (its == maxIter) +517 throw new InvalidMatrixException( +518 new MaxIterationsExceededException(maxIter)); +519 its++; +520 double q = (realEigenvalues[j + 1] - realEigenvalues[j]) / (2 * e[j]); +521 double t = Math.sqrt(1 + q * q); +522 if (q < 0.0) { +523 q = realEigenvalues[m] - realEigenvalues[j] + e[j] / (q - t); +524 } else { +525 q = realEigenvalues[m] - realEigenvalues[j] + e[j] / (q + t); +526 } +527 double u = 0.0; +528 double s = 1.0; +529 double c = 1.0; +530 int i; +531 for (i = m - 1; i >= j; i--) { +532 double p = s * e[i]; +533 double h = c * e[i]; +534 if (Math.abs(p) >= Math.abs(q)) { +535 c = q / p; +536 t = Math.sqrt(c * c + 1.0); +537 e[i + 1] = p * t; +538 s = 1.0 / t; +539 c = c * s; +540 } else { +541 s = p / q; +542 t = Math.sqrt(s * s + 1.0); +543 e[i + 1] = q * t; +544 c = 1.0 / t; +545 s = s * c; +546 } +547 if (e[i + 1] == 0.0) { +548 realEigenvalues[i + 1] -= u; +549 e[m] = 0.0; +550 break; +551 } +552 q = realEigenvalues[i + 1] - u; +553 t = (realEigenvalues[i] - q) * s + 2.0 * c * h; +554 u = s * t; +555 realEigenvalues[i + 1] = q + u; +556 q = c * t - h; +557 for (int ia = 0; ia < n; ia++) { +558 p = z[ia][i + 1]; +559 z[ia][i + 1] = s * z[ia][i] + c * p; +560 z[ia][i] = c * z[ia][i] - s * p; +561 } +562 } +563 if (e[i + 1] == 0.0 && i >= j) +564 continue; +565 realEigenvalues[j] -= u; +566 e[j] = q; +567 e[m] = 0.0; +568 } +569 } while (m != j); +570 } +571 +572 //Sort the eigen values (and vectors) in increase order +573 for (int i = 0; i < n; i++) { +574 int k = i; +575 double p = realEigenvalues[i]; +576 for (int j = i + 1; j < n; j++) { +577 if (realEigenvalues[j] > p) { +578 k = j; +579 p = realEigenvalues[j]; +580 } +581 } +582 if (k != i) { +583 realEigenvalues[k] = realEigenvalues[i]; +584 realEigenvalues[i] = p; +585 for (int j = 0; j < n; j++) { +586 p = z[j][i]; +587 z[j][i] = z[j][k]; +588 z[j][k] = p; +589 } +590 } +591 } +592 +593 // Determine the largest eigen value in absolute term. +594 maxAbsoluteValue=0.0; +595 for (int i = 0; i < n; i++) { +596 if (Math.abs(realEigenvalues[i])>maxAbsoluteValue) { +597 maxAbsoluteValue=Math.abs(realEigenvalues[i]); +598 } +599 } +600 // Make null any eigen value too small to be significant +601 if (maxAbsoluteValue!=0.0) { +602 for (int i=0; i < n; i++) { +603 if (Math.abs(realEigenvalues[i])<MathUtils.EPSILON*maxAbsoluteValue) { +604 realEigenvalues[i]=0.0; +605 } +606 } +607 } +608 eigenvectors = new ArrayRealVector[n]; +609 double[] tmp = new double[n]; +610 for (int i = 0; i < n; i++) { +611 for (int j = 0; j < n; j++) { +612 tmp[j] = z[j][i]; +613 } +614 eigenvectors[i] = new ArrayRealVector(tmp); +615 } +616 } +617 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/FieldDecompositionSolver.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/FieldDecompositionSolver.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,152 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.FieldElement; +021 +022 +023 /** +024 * Interface handling decomposition algorithms that can solve A × X = B. +025 * <p>Decomposition algorithms decompose an A matrix has a product of several specific +026 * matrices from which they can solve A × X = B in least squares sense: they find X +027 * such that ||A × X - B|| is minimal.</p> +028 * <p>Some solvers like {@link LUDecomposition} can only find the solution for +029 * square matrices and when the solution is an exact linear solution, i.e. when +030 * ||A × X - B|| is exactly 0. Other solvers can also find solutions +031 * with non-square matrix A and with non-null minimal norm. If an exact linear +032 * solution exists it is also the minimal norm solution.</p> +033 * +034 * @param <T> the type of the field elements +035 * @version $Revision: 781122 $ $Date: 2009-06-02 14:53:23 -0400 (Tue, 02 Jun 2009) $ +036 * @since 2.0 +037 */ +038 public interface FieldDecompositionSolver<T extends FieldElement<T>> { +039 +040 /** Solve the linear equation A × X = B for matrices A. +041 * <p>The A matrix is implicit, it is provided by the underlying +042 * decomposition algorithm.</p> +043 * @param b right-hand side of the equation A × X = B +044 * @return a vector X that minimizes the two norm of A × X - B +045 * @exception IllegalArgumentException if matrices dimensions don't match +046 * @exception InvalidMatrixException if decomposed matrix is singular +047 */ +048 T[] solve(final T[] b) +049 throws IllegalArgumentException, InvalidMatrixException; +050 +051 /** Solve the linear equation A × X = B for matrices A. +052 * <p>The A matrix is implicit, it is provided by the underlying +053 * decomposition algorithm.</p> +054 * @param b right-hand side of the equation A × X = B +055 * @return a vector X that minimizes the two norm of A × X - B +056 * @exception IllegalArgumentException if matrices dimensions don't match +057 * @exception InvalidMatrixException if decomposed matrix is singular +058 */ +059 FieldVector<T> solve(final FieldVector<T> b) +060 throws IllegalArgumentException, InvalidMatrixException; +061 +062 /** Solve the linear equation A × X = B for matrices A. +063 * <p>The A matrix is implicit, it is provided by the underlying +064 * decomposition algorithm.</p> +065 * @param b right-hand side of the equation A × X = B +066 * @return a matrix X that minimizes the two norm of A × X - B +067 * @exception IllegalArgumentException if matrices dimensions don't match +068 * @exception InvalidMatrixException if decomposed matrix is singular +069 */ +070 FieldMatrix<T> solve(final FieldMatrix<T> b) +071 throws IllegalArgumentException, InvalidMatrixException; +072 +073 /** +074 * Check if the decomposed matrix is non-singular. +075 * @return true if the decomposed matrix is non-singular +076 */ +077 boolean isNonSingular(); +078 +079 /** Get the inverse (or pseudo-inverse) of the decomposed matrix. +080 * @return inverse matrix +081 * @throws InvalidMatrixException if decomposed matrix is singular +082 */ +083 FieldMatrix<T> getInverse() +084 throws InvalidMatrixException; +085 +086 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/FieldLUDecomposition.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/FieldLUDecomposition.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,160 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.FieldElement; +021 +022 /** +023 * An interface to classes that implement an algorithm to calculate the +024 * LU-decomposition of a real matrix. +025 * <p>The LU-decomposition of matrix A is a set of three matrices: P, L and U +026 * such that P×A = L×U. P is a rows permutation matrix that is used +027 * to rearrange the rows of A before so that it can be decomposed. L is a lower +028 * triangular matrix with unit diagonal terms and U is an upper triangular matrix.</p> +029 * <p>This interface is based on the class with similar name from the +030 * <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> library.</p> +031 * <ul> +032 * <li>a {@link #getP() getP} method has been added,</li> +033 * <li>the <code>det</code> method has been renamed as {@link #getDeterminant() +034 * getDeterminant},</li> +035 * <li>the <code>getDoublePivot</code> method has been removed (but the int based +036 * {@link #getPivot() getPivot} method has been kept),</li> +037 * <li>the <code>solve</code> and <code>isNonSingular</code> methods have been replaced +038 * by a {@link #getSolver() getSolver} method and the equivalent methods provided by +039 * the returned {@link DecompositionSolver}.</li> +040 * </ul> +041 * +042 * @param <T> the type of the field elements +043 * @see <a href="http://mathworld.wolfram.com/LUDecomposition.html">MathWorld</a> +044 * @see <a href="http://en.wikipedia.org/wiki/LU_decomposition">Wikipedia</a> +045 * @version $Revision: 826627 $ $Date: 2009-10-19 06:27:47 -0400 (Mon, 19 Oct 2009) $ +046 * @since 2.0 +047 */ +048 public interface FieldLUDecomposition<T extends FieldElement<T>> { +049 +050 /** +051 * Returns the matrix L of the decomposition. +052 * <p>L is an lower-triangular matrix</p> +053 * @return the L matrix (or null if decomposed matrix is singular) +054 */ +055 FieldMatrix<T> getL(); +056 +057 /** +058 * Returns the matrix U of the decomposition. +059 * <p>U is an upper-triangular matrix</p> +060 * @return the U matrix (or null if decomposed matrix is singular) +061 */ +062 FieldMatrix<T> getU(); +063 +064 /** +065 * Returns the P rows permutation matrix. +066 * <p>P is a sparse matrix with exactly one element set to 1.0 in +067 * each row and each column, all other elements being set to 0.0.</p> +068 * <p>The positions of the 1 elements are given by the {@link #getPivot() +069 * pivot permutation vector}.</p> +070 * @return the P rows permutation matrix (or null if decomposed matrix is singular) +071 * @see #getPivot() +072 */ +073 FieldMatrix<T> getP(); +074 +075 /** +076 * Returns the pivot permutation vector. +077 * @return the pivot permutation vector +078 * @see #getP() +079 */ +080 int[] getPivot(); +081 +082 /** +083 * Return the determinant of the matrix +084 * @return determinant of the matrix +085 */ +086 T getDeterminant(); +087 +088 /** +089 * Get a solver for finding the A × X = B solution in exact linear sense. +090 * @return a solver +091 */ +092 FieldDecompositionSolver<T> getSolver(); +093 +094 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/FieldLUDecompositionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/FieldLUDecompositionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,499 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.lang.reflect.Array; +021 +022 import org.apache.commons.math.Field; +023 import org.apache.commons.math.FieldElement; +024 import org.apache.commons.math.MathRuntimeException; +025 +026 /** +027 * Calculates the LUP-decomposition of a square matrix. +028 * <p>The LUP-decomposition of a matrix A consists of three matrices +029 * L, U and P that satisfy: PA = LU, L is lower triangular, and U is +030 * upper triangular and P is a permutation matrix. All matrices are +031 * m×m.</p> +032 * <p>Since {@link FieldElement field elements} do not provide an ordering +033 * operator, the permutation matrix is computed here only in order to avoid +034 * a zero pivot element, no attempt is done to get the largest pivot element.</p> +035 * +036 * @param <T> the type of the field elements +037 * @version $Revision: 903046 $ $Date: 2010-01-25 21:07:26 -0500 (Mon, 25 Jan 2010) $ +038 * @since 2.0 +039 */ +040 public class FieldLUDecompositionImpl<T extends FieldElement<T>> implements FieldLUDecomposition<T> { +041 +042 /** Field to which the elements belong. */ +043 private final Field<T> field; +044 +045 /** Entries of LU decomposition. */ +046 private T lu[][]; +047 +048 /** Pivot permutation associated with LU decomposition */ +049 private int[] pivot; +050 +051 /** Parity of the permutation associated with the LU decomposition */ +052 private boolean even; +053 +054 /** Singularity indicator. */ +055 private boolean singular; +056 +057 /** Cached value of L. */ +058 private FieldMatrix<T> cachedL; +059 +060 /** Cached value of U. */ +061 private FieldMatrix<T> cachedU; +062 +063 /** Cached value of P. */ +064 private FieldMatrix<T> cachedP; +065 +066 /** +067 * Calculates the LU-decomposition of the given matrix. +068 * @param matrix The matrix to decompose. +069 * @exception NonSquareMatrixException if matrix is not square +070 */ +071 public FieldLUDecompositionImpl(FieldMatrix<T> matrix) +072 throws NonSquareMatrixException { +073 +074 if (!matrix.isSquare()) { +075 throw new NonSquareMatrixException(matrix.getRowDimension(), matrix.getColumnDimension()); +076 } +077 +078 final int m = matrix.getColumnDimension(); +079 field = matrix.getField(); +080 lu = matrix.getData(); +081 pivot = new int[m]; +082 cachedL = null; +083 cachedU = null; +084 cachedP = null; +085 +086 // Initialize permutation array and parity +087 for (int row = 0; row < m; row++) { +088 pivot[row] = row; +089 } +090 even = true; +091 singular = false; +092 +093 // Loop over columns +094 for (int col = 0; col < m; col++) { +095 +096 T sum = field.getZero(); +097 +098 // upper +099 for (int row = 0; row < col; row++) { +100 final T[] luRow = lu[row]; +101 sum = luRow[col]; +102 for (int i = 0; i < row; i++) { +103 sum = sum.subtract(luRow[i].multiply(lu[i][col])); +104 } +105 luRow[col] = sum; +106 } +107 +108 // lower +109 int nonZero = col; // permutation row +110 for (int row = col; row < m; row++) { +111 final T[] luRow = lu[row]; +112 sum = luRow[col]; +113 for (int i = 0; i < col; i++) { +114 sum = sum.subtract(luRow[i].multiply(lu[i][col])); +115 } +116 luRow[col] = sum; +117 +118 if (lu[nonZero][col].equals(field.getZero())) { +119 // try to select a better permutation choice +120 ++nonZero; +121 } +122 } +123 +124 // Singularity check +125 if (nonZero >= m) { +126 singular = true; +127 return; +128 } +129 +130 // Pivot if necessary +131 if (nonZero != col) { +132 T tmp = field.getZero(); +133 for (int i = 0; i < m; i++) { +134 tmp = lu[nonZero][i]; +135 lu[nonZero][i] = lu[col][i]; +136 lu[col][i] = tmp; +137 } +138 int temp = pivot[nonZero]; +139 pivot[nonZero] = pivot[col]; +140 pivot[col] = temp; +141 even = !even; +142 } +143 +144 // Divide the lower elements by the "winning" diagonal elt. +145 final T luDiag = lu[col][col]; +146 for (int row = col + 1; row < m; row++) { +147 final T[] luRow = lu[row]; +148 luRow[col] = luRow[col].divide(luDiag); +149 } +150 } +151 +152 } +153 +154 /** {@inheritDoc} */ +155 public FieldMatrix<T> getL() { +156 if ((cachedL == null) && !singular) { +157 final int m = pivot.length; +158 cachedL = new Array2DRowFieldMatrix<T>(field, m, m); +159 for (int i = 0; i < m; ++i) { +160 final T[] luI = lu[i]; +161 for (int j = 0; j < i; ++j) { +162 cachedL.setEntry(i, j, luI[j]); +163 } +164 cachedL.setEntry(i, i, field.getOne()); +165 } +166 } +167 return cachedL; +168 } +169 +170 /** {@inheritDoc} */ +171 public FieldMatrix<T> getU() { +172 if ((cachedU == null) && !singular) { +173 final int m = pivot.length; +174 cachedU = new Array2DRowFieldMatrix<T>(field, m, m); +175 for (int i = 0; i < m; ++i) { +176 final T[] luI = lu[i]; +177 for (int j = i; j < m; ++j) { +178 cachedU.setEntry(i, j, luI[j]); +179 } +180 } +181 } +182 return cachedU; +183 } +184 +185 /** {@inheritDoc} */ +186 public FieldMatrix<T> getP() { +187 if ((cachedP == null) && !singular) { +188 final int m = pivot.length; +189 cachedP = new Array2DRowFieldMatrix<T>(field, m, m); +190 for (int i = 0; i < m; ++i) { +191 cachedP.setEntry(i, pivot[i], field.getOne()); +192 } +193 } +194 return cachedP; +195 } +196 +197 /** {@inheritDoc} */ +198 public int[] getPivot() { +199 return pivot.clone(); +200 } +201 +202 /** {@inheritDoc} */ +203 public T getDeterminant() { +204 if (singular) { +205 return field.getZero(); +206 } else { +207 final int m = pivot.length; +208 T determinant = even ? field.getOne() : field.getZero().subtract(field.getOne()); +209 for (int i = 0; i < m; i++) { +210 determinant = determinant.multiply(lu[i][i]); +211 } +212 return determinant; +213 } +214 } +215 +216 /** {@inheritDoc} */ +217 public FieldDecompositionSolver<T> getSolver() { +218 return new Solver<T>(field, lu, pivot, singular); +219 } +220 +221 /** Specialized solver. */ +222 private static class Solver<T extends FieldElement<T>> implements FieldDecompositionSolver<T> { +223 +224 /** Serializable version identifier. */ +225 private static final long serialVersionUID = -6353105415121373022L; +226 +227 /** Field to which the elements belong. */ +228 private final Field<T> field; +229 +230 /** Entries of LU decomposition. */ +231 private final T lu[][]; +232 +233 /** Pivot permutation associated with LU decomposition. */ +234 private final int[] pivot; +235 +236 /** Singularity indicator. */ +237 private final boolean singular; +238 +239 /** +240 * Build a solver from decomposed matrix. +241 * @param field field to which the matrix elements belong +242 * @param lu entries of LU decomposition +243 * @param pivot pivot permutation associated with LU decomposition +244 * @param singular singularity indicator +245 */ +246 private Solver(final Field<T> field, final T[][] lu, +247 final int[] pivot, final boolean singular) { +248 this.field = field; +249 this.lu = lu; +250 this.pivot = pivot; +251 this.singular = singular; +252 } +253 +254 /** {@inheritDoc} */ +255 public boolean isNonSingular() { +256 return !singular; +257 } +258 +259 /** {@inheritDoc} */ +260 public T[] solve(T[] b) +261 throws IllegalArgumentException, InvalidMatrixException { +262 +263 final int m = pivot.length; +264 if (b.length != m) { +265 throw MathRuntimeException.createIllegalArgumentException( +266 "vector length mismatch: got {0} but expected {1}", +267 b.length, m); +268 } +269 if (singular) { +270 throw new SingularMatrixException(); +271 } +272 +273 @SuppressWarnings("unchecked") // field is of type T +274 final T[] bp = (T[]) Array.newInstance(field.getZero().getClass(), m); +275 +276 // Apply permutations to b +277 for (int row = 0; row < m; row++) { +278 bp[row] = b[pivot[row]]; +279 } +280 +281 // Solve LY = b +282 for (int col = 0; col < m; col++) { +283 final T bpCol = bp[col]; +284 for (int i = col + 1; i < m; i++) { +285 bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col])); +286 } +287 } +288 +289 // Solve UX = Y +290 for (int col = m - 1; col >= 0; col--) { +291 bp[col] = bp[col].divide(lu[col][col]); +292 final T bpCol = bp[col]; +293 for (int i = 0; i < col; i++) { +294 bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col])); +295 } +296 } +297 +298 return bp; +299 +300 } +301 +302 /** {@inheritDoc} */ +303 public FieldVector<T> solve(FieldVector<T> b) +304 throws IllegalArgumentException, InvalidMatrixException { +305 try { +306 return solve((ArrayFieldVector<T>) b); +307 } catch (ClassCastException cce) { +308 +309 final int m = pivot.length; +310 if (b.getDimension() != m) { +311 throw MathRuntimeException.createIllegalArgumentException( +312 "vector length mismatch: got {0} but expected {1}", +313 b.getDimension(), m); +314 } +315 if (singular) { +316 throw new SingularMatrixException(); +317 } +318 +319 @SuppressWarnings("unchecked") // field is of type T +320 final T[] bp = (T[]) Array.newInstance(field.getZero().getClass(), m); +321 +322 // Apply permutations to b +323 for (int row = 0; row < m; row++) { +324 bp[row] = b.getEntry(pivot[row]); +325 } +326 +327 // Solve LY = b +328 for (int col = 0; col < m; col++) { +329 final T bpCol = bp[col]; +330 for (int i = col + 1; i < m; i++) { +331 bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col])); +332 } +333 } +334 +335 // Solve UX = Y +336 for (int col = m - 1; col >= 0; col--) { +337 bp[col] = bp[col].divide(lu[col][col]); +338 final T bpCol = bp[col]; +339 for (int i = 0; i < col; i++) { +340 bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col])); +341 } +342 } +343 +344 return new ArrayFieldVector<T>(bp, false); +345 +346 } +347 } +348 +349 /** Solve the linear equation A × X = B. +350 * <p>The A matrix is implicit here. It is </p> +351 * @param b right-hand side of the equation A × X = B +352 * @return a vector X such that A × X = B +353 * @exception IllegalArgumentException if matrices dimensions don't match +354 * @exception InvalidMatrixException if decomposed matrix is singular +355 */ +356 public ArrayFieldVector<T> solve(ArrayFieldVector<T> b) +357 throws IllegalArgumentException, InvalidMatrixException { +358 return new ArrayFieldVector<T>(solve(b.getDataRef()), false); +359 } +360 +361 /** {@inheritDoc} */ +362 public FieldMatrix<T> solve(FieldMatrix<T> b) +363 throws IllegalArgumentException, InvalidMatrixException { +364 +365 final int m = pivot.length; +366 if (b.getRowDimension() != m) { +367 throw MathRuntimeException.createIllegalArgumentException( +368 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +369 b.getRowDimension(), b.getColumnDimension(), m, "n"); +370 } +371 if (singular) { +372 throw new SingularMatrixException(); +373 } +374 +375 final int nColB = b.getColumnDimension(); +376 +377 // Apply permutations to b +378 @SuppressWarnings("unchecked") // field is of type T +379 final T[][] bp = (T[][]) Array.newInstance(field.getZero().getClass(), new int[] { m, nColB }); +380 for (int row = 0; row < m; row++) { +381 final T[] bpRow = bp[row]; +382 final int pRow = pivot[row]; +383 for (int col = 0; col < nColB; col++) { +384 bpRow[col] = b.getEntry(pRow, col); +385 } +386 } +387 +388 // Solve LY = b +389 for (int col = 0; col < m; col++) { +390 final T[] bpCol = bp[col]; +391 for (int i = col + 1; i < m; i++) { +392 final T[] bpI = bp[i]; +393 final T luICol = lu[i][col]; +394 for (int j = 0; j < nColB; j++) { +395 bpI[j] = bpI[j].subtract(bpCol[j].multiply(luICol)); +396 } +397 } +398 } +399 +400 // Solve UX = Y +401 for (int col = m - 1; col >= 0; col--) { +402 final T[] bpCol = bp[col]; +403 final T luDiag = lu[col][col]; +404 for (int j = 0; j < nColB; j++) { +405 bpCol[j] = bpCol[j].divide(luDiag); +406 } +407 for (int i = 0; i < col; i++) { +408 final T[] bpI = bp[i]; +409 final T luICol = lu[i][col]; +410 for (int j = 0; j < nColB; j++) { +411 bpI[j] = bpI[j].subtract(bpCol[j].multiply(luICol)); +412 } +413 } +414 } +415 +416 return new Array2DRowFieldMatrix<T>(bp, false); +417 +418 } +419 +420 /** {@inheritDoc} */ +421 public FieldMatrix<T> getInverse() throws InvalidMatrixException { +422 final int m = pivot.length; +423 final T one = field.getOne(); +424 FieldMatrix<T> identity = new Array2DRowFieldMatrix<T>(field, m, m); +425 for (int i = 0; i < m; ++i) { +426 identity.setEntry(i, i, one); +427 } +428 return solve(identity); +429 } +430 +431 } +432 +433 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/FieldMatrix.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/FieldMatrix.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,863 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 +021 import org.apache.commons.math.Field; +022 import org.apache.commons.math.FieldElement; +023 +024 /** +025 * Interface defining field-valued matrix with basic algebraic operations. +026 * <p> +027 * Matrix element indexing is 0-based -- e.g., <code>getEntry(0, 0)</code> +028 * returns the element in the first row, first column of the matrix.</p> +029 * +030 * @param <T> the type of the field elements +031 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +032 */ +033 public interface FieldMatrix<T extends FieldElement<T>> extends AnyMatrix { +034 +035 /** +036 * Get the type of field elements of the matrix. +037 * @return type of field elements of the matrix +038 */ +039 Field<T> getField(); +040 +041 /** +042 * Create a new FieldMatrix<T> of the same type as the instance with the supplied +043 * row and column dimensions. +044 * +045 * @param rowDimension the number of rows in the new matrix +046 * @param columnDimension the number of columns in the new matrix +047 * @return a new matrix of the same type as the instance +048 * @throws IllegalArgumentException if row or column dimension is not positive +049 * @since 2.0 +050 */ +051 FieldMatrix<T> createMatrix(final int rowDimension, final int columnDimension); +052 +053 /** +054 * Returns a (deep) copy of this. +055 * +056 * @return matrix copy +057 */ +058 FieldMatrix<T> copy(); +059 +060 /** +061 * Compute the sum of this and m. +062 * +063 * @param m matrix to be added +064 * @return this + m +065 * @throws IllegalArgumentException if m is not the same size as this +066 */ +067 FieldMatrix<T> add(FieldMatrix<T> m) throws IllegalArgumentException; +068 +069 /** +070 * Compute this minus m. +071 * +072 * @param m matrix to be subtracted +073 * @return this + m +074 * @throws IllegalArgumentException if m is not the same size as this +075 */ +076 FieldMatrix<T> subtract(FieldMatrix<T> m) throws IllegalArgumentException; +077 +078 /** +079 * Returns the result of adding d to each entry of this. +080 * +081 * @param d value to be added to each entry +082 * @return d + this +083 */ +084 FieldMatrix<T> scalarAdd(T d); +085 +086 /** +087 * Returns the result multiplying each entry of this by d. +088 * +089 * @param d value to multiply all entries by +090 * @return d * this +091 */ +092 FieldMatrix<T> scalarMultiply(T d); +093 +094 /** +095 * Returns the result of postmultiplying this by m. +096 * +097 * @param m matrix to postmultiply by +098 * @return this * m +099 * @throws IllegalArgumentException +100 * if columnDimension(this) != rowDimension(m) +101 */ +102 FieldMatrix<T> multiply(FieldMatrix<T> m) throws IllegalArgumentException; +103 +104 /** +105 * Returns the result premultiplying this by <code>m</code>. +106 * @param m matrix to premultiply by +107 * @return m * this +108 * @throws IllegalArgumentException +109 * if rowDimension(this) != columnDimension(m) +110 */ +111 FieldMatrix<T> preMultiply(FieldMatrix<T> m) throws IllegalArgumentException; +112 +113 /** +114 * Returns matrix entries as a two-dimensional array. +115 * +116 * @return 2-dimensional array of entries +117 */ +118 T[][] getData(); +119 +120 /** +121 * Gets a submatrix. Rows and columns are indicated +122 * counting from 0 to n-1. +123 * +124 * @param startRow Initial row index +125 * @param endRow Final row index (inclusive) +126 * @param startColumn Initial column index +127 * @param endColumn Final column index (inclusive) +128 * @return The subMatrix containing the data of the +129 * specified rows and columns +130 * @exception MatrixIndexException if the indices are not valid +131 */ +132 FieldMatrix<T> getSubMatrix(int startRow, int endRow, int startColumn, int endColumn) +133 throws MatrixIndexException; +134 +135 /** +136 * Gets a submatrix. Rows and columns are indicated +137 * counting from 0 to n-1. +138 * +139 * @param selectedRows Array of row indices. +140 * @param selectedColumns Array of column indices. +141 * @return The subMatrix containing the data in the +142 * specified rows and columns +143 * @exception MatrixIndexException if row or column selections are not valid +144 */ +145 FieldMatrix<T> getSubMatrix(int[] selectedRows, int[] selectedColumns) +146 throws MatrixIndexException; +147 +148 /** +149 * Copy a submatrix. Rows and columns are indicated +150 * counting from 0 to n-1. +151 * +152 * @param startRow Initial row index +153 * @param endRow Final row index (inclusive) +154 * @param startColumn Initial column index +155 * @param endColumn Final column index (inclusive) +156 * @param destination The arrays where the submatrix data should be copied +157 * (if larger than rows/columns counts, only the upper-left part will be used) +158 * @exception MatrixIndexException if the indices are not valid +159 * @exception IllegalArgumentException if the destination array is too small +160 */ +161 void copySubMatrix(int startRow, int endRow, int startColumn, int endColumn, +162 T[][] destination) +163 throws MatrixIndexException, IllegalArgumentException; +164 +165 /** +166 * Copy a submatrix. Rows and columns are indicated +167 * counting from 0 to n-1. +168 * +169 * @param selectedRows Array of row indices. +170 * @param selectedColumns Array of column indices. +171 * @param destination The arrays where the submatrix data should be copied +172 * (if larger than rows/columns counts, only the upper-left part will be used) +173 * @exception MatrixIndexException if the indices are not valid +174 * @exception IllegalArgumentException if the destination array is too small +175 */ +176 void copySubMatrix(int[] selectedRows, int[] selectedColumns, T[][] destination) +177 throws MatrixIndexException, IllegalArgumentException; +178 +179 /** +180 * Replace the submatrix starting at <code>row, column</code> using data in +181 * the input <code>subMatrix</code> array. Indexes are 0-based. +182 * <p> +183 * Example:<br> +184 * Starting with <pre> +185 * 1 2 3 4 +186 * 5 6 7 8 +187 * 9 0 1 2 +188 * </pre> +189 * and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking +190 * <code>setSubMatrix(subMatrix,1,1))</code> will result in <pre> +191 * 1 2 3 4 +192 * 5 3 4 8 +193 * 9 5 6 2 +194 * </pre></p> +195 * +196 * @param subMatrix array containing the submatrix replacement data +197 * @param row row coordinate of the top, left element to be replaced +198 * @param column column coordinate of the top, left element to be replaced +199 * @throws MatrixIndexException if subMatrix does not fit into this +200 * matrix from element in (row, column) +201 * @throws IllegalArgumentException if <code>subMatrix</code> is not rectangular +202 * (not all rows have the same length) or empty +203 * @throws NullPointerException if <code>subMatrix</code> is null +204 * @since 2.0 +205 */ +206 void setSubMatrix(T[][] subMatrix, int row, int column) +207 throws MatrixIndexException; +208 +209 /** +210 * Returns the entries in row number <code>row</code> +211 * as a row matrix. Row indices start at 0. +212 * +213 * @param row the row to be fetched +214 * @return row matrix +215 * @throws MatrixIndexException if the specified row index is invalid +216 */ +217 FieldMatrix<T> getRowMatrix(int row) throws MatrixIndexException; +218 +219 /** +220 * Sets the entries in row number <code>row</code> +221 * as a row matrix. Row indices start at 0. +222 * +223 * @param row the row to be set +224 * @param matrix row matrix (must have one row and the same number of columns +225 * as the instance) +226 * @throws MatrixIndexException if the specified row index is invalid +227 * @throws InvalidMatrixException if the matrix dimensions do not match one +228 * instance row +229 */ +230 void setRowMatrix(int row, FieldMatrix<T> matrix) +231 throws MatrixIndexException, InvalidMatrixException; +232 +233 /** +234 * Returns the entries in column number <code>column</code> +235 * as a column matrix. Column indices start at 0. +236 * +237 * @param column the column to be fetched +238 * @return column matrix +239 * @throws MatrixIndexException if the specified column index is invalid +240 */ +241 FieldMatrix<T> getColumnMatrix(int column) throws MatrixIndexException; +242 +243 /** +244 * Sets the entries in column number <code>column</code> +245 * as a column matrix. Column indices start at 0. +246 * +247 * @param column the column to be set +248 * @param matrix column matrix (must have one column and the same number of rows +249 * as the instance) +250 * @throws MatrixIndexException if the specified column index is invalid +251 * @throws InvalidMatrixException if the matrix dimensions do not match one +252 * instance column +253 */ +254 void setColumnMatrix(int column, FieldMatrix<T> matrix) +255 throws MatrixIndexException, InvalidMatrixException; +256 +257 /** +258 * Returns the entries in row number <code>row</code> +259 * as a vector. Row indices start at 0. +260 * +261 * @param row the row to be fetched +262 * @return row vector +263 * @throws MatrixIndexException if the specified row index is invalid +264 */ +265 FieldVector<T> getRowVector(int row) throws MatrixIndexException; +266 +267 /** +268 * Sets the entries in row number <code>row</code> +269 * as a vector. Row indices start at 0. +270 * +271 * @param row the row to be set +272 * @param vector row vector (must have the same number of columns +273 * as the instance) +274 * @throws MatrixIndexException if the specified row index is invalid +275 * @throws InvalidMatrixException if the vector dimension does not match one +276 * instance row +277 */ +278 void setRowVector(int row, FieldVector<T> vector) +279 throws MatrixIndexException, InvalidMatrixException; +280 +281 /** +282 * Returns the entries in column number <code>column</code> +283 * as a vector. Column indices start at 0. +284 * +285 * @param column the column to be fetched +286 * @return column vector +287 * @throws MatrixIndexException if the specified column index is invalid +288 */ +289 FieldVector<T> getColumnVector(int column) throws MatrixIndexException; +290 +291 /** +292 * Sets the entries in column number <code>column</code> +293 * as a vector. Column indices start at 0. +294 * +295 * @param column the column to be set +296 * @param vector column vector (must have the same number of rows as the instance) +297 * @throws MatrixIndexException if the specified column index is invalid +298 * @throws InvalidMatrixException if the vector dimension does not match one +299 * instance column +300 */ +301 void setColumnVector(int column, FieldVector<T> vector) +302 throws MatrixIndexException, InvalidMatrixException; +303 +304 /** +305 * Returns the entries in row number <code>row</code> as an array. +306 * <p> +307 * Row indices start at 0. A <code>MatrixIndexException</code> is thrown +308 * unless <code>0 <= row < rowDimension.</code></p> +309 * +310 * @param row the row to be fetched +311 * @return array of entries in the row +312 * @throws MatrixIndexException if the specified row index is not valid +313 */ +314 T[] getRow(int row) throws MatrixIndexException; +315 +316 /** +317 * Sets the entries in row number <code>row</code> +318 * as a row matrix. Row indices start at 0. +319 * +320 * @param row the row to be set +321 * @param array row matrix (must have the same number of columns as the instance) +322 * @throws MatrixIndexException if the specified row index is invalid +323 * @throws InvalidMatrixException if the array size does not match one +324 * instance row +325 */ +326 void setRow(int row, T[] array) +327 throws MatrixIndexException, InvalidMatrixException; +328 +329 /** +330 * Returns the entries in column number <code>col</code> as an array. +331 * <p> +332 * Column indices start at 0. A <code>MatrixIndexException</code> is thrown +333 * unless <code>0 <= column < columnDimension.</code></p> +334 * +335 * @param column the column to be fetched +336 * @return array of entries in the column +337 * @throws MatrixIndexException if the specified column index is not valid +338 */ +339 T[] getColumn(int column) throws MatrixIndexException; +340 +341 /** +342 * Sets the entries in column number <code>column</code> +343 * as a column matrix. Column indices start at 0. +344 * +345 * @param column the column to be set +346 * @param array column array (must have the same number of rows as the instance) +347 * @throws MatrixIndexException if the specified column index is invalid +348 * @throws InvalidMatrixException if the array size does not match one +349 * instance column +350 */ +351 void setColumn(int column, T[] array) +352 throws MatrixIndexException, InvalidMatrixException; +353 +354 /** +355 * Returns the entry in the specified row and column. +356 * <p> +357 * Row and column indices start at 0 and must satisfy +358 * <ul> +359 * <li><code>0 <= row < rowDimension</code></li> +360 * <li><code> 0 <= column < columnDimension</code></li> +361 * </ul> +362 * otherwise a <code>MatrixIndexException</code> is thrown.</p> +363 * +364 * @param row row location of entry to be fetched +365 * @param column column location of entry to be fetched +366 * @return matrix entry in row,column +367 * @throws MatrixIndexException if the row or column index is not valid +368 */ +369 T getEntry(int row, int column) throws MatrixIndexException; +370 +371 /** +372 * Set the entry in the specified row and column. +373 * <p> +374 * Row and column indices start at 0 and must satisfy +375 * <ul> +376 * <li><code>0 <= row < rowDimension</code></li> +377 * <li><code> 0 <= column < columnDimension</code></li> +378 * </ul> +379 * otherwise a <code>MatrixIndexException</code> is thrown.</p> +380 * +381 * @param row row location of entry to be set +382 * @param column column location of entry to be set +383 * @param value matrix entry to be set in row,column +384 * @throws MatrixIndexException if the row or column index is not valid +385 * @since 2.0 +386 */ +387 void setEntry(int row, int column, T value) throws MatrixIndexException; +388 +389 /** +390 * Change an entry in the specified row and column. +391 * <p> +392 * Row and column indices start at 0 and must satisfy +393 * <ul> +394 * <li><code>0 <= row < rowDimension</code></li> +395 * <li><code> 0 <= column < columnDimension</code></li> +396 * </ul> +397 * otherwise a <code>MatrixIndexException</code> is thrown.</p> +398 * +399 * @param row row location of entry to be set +400 * @param column column location of entry to be set +401 * @param increment value to add to the current matrix entry in row,column +402 * @throws MatrixIndexException if the row or column index is not valid +403 * @since 2.0 +404 */ +405 void addToEntry(int row, int column, T increment) throws MatrixIndexException; +406 +407 /** +408 * Change an entry in the specified row and column. +409 * <p> +410 * Row and column indices start at 0 and must satisfy +411 * <ul> +412 * <li><code>0 <= row < rowDimension</code></li> +413 * <li><code> 0 <= column < columnDimension</code></li> +414 * </ul> +415 * otherwise a <code>MatrixIndexException</code> is thrown.</p> +416 * +417 * @param row row location of entry to be set +418 * @param column column location of entry to be set +419 * @param factor multiplication factor for the current matrix entry in row,column +420 * @throws MatrixIndexException if the row or column index is not valid +421 * @since 2.0 +422 */ +423 void multiplyEntry(int row, int column, T factor) throws MatrixIndexException; +424 +425 /** +426 * Returns the transpose of this matrix. +427 * +428 * @return transpose matrix +429 */ +430 FieldMatrix<T> transpose(); +431 +432 /** +433 * Returns the <a href="http://mathworld.wolfram.com/MatrixTrace.html"> +434 * trace</a> of the matrix (the sum of the elements on the main diagonal). +435 * +436 * @return trace +437 * @throws NonSquareMatrixException if the matrix is not square +438 */ +439 T getTrace() throws NonSquareMatrixException; +440 +441 /** +442 * Returns the result of multiplying this by the vector <code>v</code>. +443 * +444 * @param v the vector to operate on +445 * @return this*v +446 * @throws IllegalArgumentException if columnDimension != v.size() +447 */ +448 T[] operate(T[] v) throws IllegalArgumentException; +449 +450 /** +451 * Returns the result of multiplying this by the vector <code>v</code>. +452 * +453 * @param v the vector to operate on +454 * @return this*v +455 * @throws IllegalArgumentException if columnDimension != v.size() +456 */ +457 FieldVector<T> operate(FieldVector<T> v) throws IllegalArgumentException; +458 +459 /** +460 * Returns the (row) vector result of premultiplying this by the vector <code>v</code>. +461 * +462 * @param v the row vector to premultiply by +463 * @return v*this +464 * @throws IllegalArgumentException if rowDimension != v.size() +465 */ +466 T[] preMultiply(T[] v) throws IllegalArgumentException; +467 +468 /** +469 * Returns the (row) vector result of premultiplying this by the vector <code>v</code>. +470 * +471 * @param v the row vector to premultiply by +472 * @return v*this +473 * @throws IllegalArgumentException if rowDimension != v.size() +474 */ +475 FieldVector<T> preMultiply(FieldVector<T> v) throws IllegalArgumentException; +476 +477 /** +478 * Visit (and possibly change) all matrix entries in row order. +479 * <p>Row order starts at upper left and iterating through all elements +480 * of a row from left to right before going to the leftmost element +481 * of the next row.</p> +482 * @param visitor visitor used to process all matrix entries +483 * @exception MatrixVisitorException if the visitor cannot process an entry +484 * @see #walkInRowOrder(FieldMatrixPreservingVisitor) +485 * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) +486 * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) +487 * @see #walkInColumnOrder(FieldMatrixChangingVisitor) +488 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) +489 * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) +490 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) +491 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) +492 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) +493 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) +494 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) +495 * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end +496 * of the walk +497 */ +498 T walkInRowOrder(FieldMatrixChangingVisitor<T> visitor) +499 throws MatrixVisitorException; +500 +501 /** +502 * Visit (but don't change) all matrix entries in row order. +503 * <p>Row order starts at upper left and iterating through all elements +504 * of a row from left to right before going to the leftmost element +505 * of the next row.</p> +506 * @param visitor visitor used to process all matrix entries +507 * @exception MatrixVisitorException if the visitor cannot process an entry +508 * @see #walkInRowOrder(FieldMatrixChangingVisitor) +509 * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) +510 * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) +511 * @see #walkInColumnOrder(FieldMatrixChangingVisitor) +512 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) +513 * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) +514 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) +515 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) +516 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) +517 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) +518 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) +519 * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end +520 * of the walk +521 */ +522 T walkInRowOrder(FieldMatrixPreservingVisitor<T> visitor) +523 throws MatrixVisitorException; +524 +525 /** +526 * Visit (and possibly change) some matrix entries in row order. +527 * <p>Row order starts at upper left and iterating through all elements +528 * of a row from left to right before going to the leftmost element +529 * of the next row.</p> +530 * @param visitor visitor used to process all matrix entries +531 * @param startRow Initial row index +532 * @param endRow Final row index (inclusive) +533 * @param startColumn Initial column index +534 * @param endColumn Final column index +535 * @exception MatrixVisitorException if the visitor cannot process an entry +536 * @exception MatrixIndexException if the indices are not valid +537 * @see #walkInRowOrder(FieldMatrixChangingVisitor) +538 * @see #walkInRowOrder(FieldMatrixPreservingVisitor) +539 * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) +540 * @see #walkInColumnOrder(FieldMatrixChangingVisitor) +541 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) +542 * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) +543 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) +544 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) +545 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) +546 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) +547 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) +548 * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end +549 * of the walk +550 */ +551 T walkInRowOrder(FieldMatrixChangingVisitor<T> visitor, +552 int startRow, int endRow, int startColumn, int endColumn) +553 throws MatrixIndexException, MatrixVisitorException; +554 +555 /** +556 * Visit (but don't change) some matrix entries in row order. +557 * <p>Row order starts at upper left and iterating through all elements +558 * of a row from left to right before going to the leftmost element +559 * of the next row.</p> +560 * @param visitor visitor used to process all matrix entries +561 * @param startRow Initial row index +562 * @param endRow Final row index (inclusive) +563 * @param startColumn Initial column index +564 * @param endColumn Final column index +565 * @exception MatrixVisitorException if the visitor cannot process an entry +566 * @exception MatrixIndexException if the indices are not valid +567 * @see #walkInRowOrder(FieldMatrixChangingVisitor) +568 * @see #walkInRowOrder(FieldMatrixPreservingVisitor) +569 * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) +570 * @see #walkInColumnOrder(FieldMatrixChangingVisitor) +571 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) +572 * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) +573 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) +574 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) +575 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) +576 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) +577 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) +578 * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end +579 * of the walk +580 */ +581 T walkInRowOrder(FieldMatrixPreservingVisitor<T> visitor, +582 int startRow, int endRow, int startColumn, int endColumn) +583 throws MatrixIndexException, MatrixVisitorException; +584 +585 /** +586 * Visit (and possibly change) all matrix entries in column order. +587 * <p>Column order starts at upper left and iterating through all elements +588 * of a column from top to bottom before going to the topmost element +589 * of the next column.</p> +590 * @param visitor visitor used to process all matrix entries +591 * @exception MatrixVisitorException if the visitor cannot process an entry +592 * @see #walkInRowOrder(FieldMatrixChangingVisitor) +593 * @see #walkInRowOrder(FieldMatrixPreservingVisitor) +594 * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) +595 * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) +596 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) +597 * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) +598 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) +599 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) +600 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) +601 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) +602 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) +603 * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end +604 * of the walk +605 */ +606 T walkInColumnOrder(FieldMatrixChangingVisitor<T> visitor) +607 throws MatrixVisitorException; +608 +609 /** +610 * Visit (but don't change) all matrix entries in column order. +611 * <p>Column order starts at upper left and iterating through all elements +612 * of a column from top to bottom before going to the topmost element +613 * of the next column.</p> +614 * @param visitor visitor used to process all matrix entries +615 * @exception MatrixVisitorException if the visitor cannot process an entry +616 * @see #walkInRowOrder(FieldMatrixChangingVisitor) +617 * @see #walkInRowOrder(FieldMatrixPreservingVisitor) +618 * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) +619 * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) +620 * @see #walkInColumnOrder(FieldMatrixChangingVisitor) +621 * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) +622 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) +623 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) +624 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) +625 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) +626 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) +627 * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end +628 * of the walk +629 */ +630 T walkInColumnOrder(FieldMatrixPreservingVisitor<T> visitor) +631 throws MatrixVisitorException; +632 +633 /** +634 * Visit (and possibly change) some matrix entries in column order. +635 * <p>Column order starts at upper left and iterating through all elements +636 * of a column from top to bottom before going to the topmost element +637 * of the next column.</p> +638 * @param visitor visitor used to process all matrix entries +639 * @param startRow Initial row index +640 * @param endRow Final row index (inclusive) +641 * @param startColumn Initial column index +642 * @param endColumn Final column index +643 * @exception MatrixVisitorException if the visitor cannot process an entry +644 * @exception MatrixIndexException if the indices are not valid +645 * @see #walkInRowOrder(FieldMatrixChangingVisitor) +646 * @see #walkInRowOrder(FieldMatrixPreservingVisitor) +647 * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) +648 * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) +649 * @see #walkInColumnOrder(FieldMatrixChangingVisitor) +650 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) +651 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) +652 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) +653 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) +654 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) +655 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) +656 * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end +657 * of the walk +658 */ +659 T walkInColumnOrder(FieldMatrixChangingVisitor<T> visitor, +660 int startRow, int endRow, int startColumn, int endColumn) +661 throws MatrixIndexException, MatrixVisitorException; +662 +663 /** +664 * Visit (but don't change) some matrix entries in column order. +665 * <p>Column order starts at upper left and iterating through all elements +666 * of a column from top to bottom before going to the topmost element +667 * of the next column.</p> +668 * @param visitor visitor used to process all matrix entries +669 * @param startRow Initial row index +670 * @param endRow Final row index (inclusive) +671 * @param startColumn Initial column index +672 * @param endColumn Final column index +673 * @exception MatrixVisitorException if the visitor cannot process an entry +674 * @exception MatrixIndexException if the indices are not valid +675 * @see #walkInRowOrder(FieldMatrixChangingVisitor) +676 * @see #walkInRowOrder(FieldMatrixPreservingVisitor) +677 * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) +678 * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) +679 * @see #walkInColumnOrder(FieldMatrixChangingVisitor) +680 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) +681 * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) +682 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) +683 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) +684 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) +685 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) +686 * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end +687 * of the walk +688 */ +689 T walkInColumnOrder(FieldMatrixPreservingVisitor<T> visitor, +690 int startRow, int endRow, int startColumn, int endColumn) +691 throws MatrixIndexException, MatrixVisitorException; +692 +693 /** +694 * Visit (and possibly change) all matrix entries using the fastest possible order. +695 * <p>The fastest walking order depends on the exact matrix class. It may be +696 * different from traditional row or column orders.</p> +697 * @param visitor visitor used to process all matrix entries +698 * @exception MatrixVisitorException if the visitor cannot process an entry +699 * @see #walkInRowOrder(FieldMatrixChangingVisitor) +700 * @see #walkInRowOrder(FieldMatrixPreservingVisitor) +701 * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) +702 * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) +703 * @see #walkInColumnOrder(FieldMatrixChangingVisitor) +704 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) +705 * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) +706 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) +707 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) +708 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) +709 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) +710 * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end +711 * of the walk +712 */ +713 T walkInOptimizedOrder(FieldMatrixChangingVisitor<T> visitor) +714 throws MatrixVisitorException; +715 +716 /** +717 * Visit (but don't change) all matrix entries using the fastest possible order. +718 * <p>The fastest walking order depends on the exact matrix class. It may be +719 * different from traditional row or column orders.</p> +720 * @param visitor visitor used to process all matrix entries +721 * @exception MatrixVisitorException if the visitor cannot process an entry +722 * @see #walkInRowOrder(FieldMatrixChangingVisitor) +723 * @see #walkInRowOrder(FieldMatrixPreservingVisitor) +724 * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) +725 * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) +726 * @see #walkInColumnOrder(FieldMatrixChangingVisitor) +727 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) +728 * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) +729 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) +730 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) +731 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) +732 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) +733 * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end +734 * of the walk +735 */ +736 T walkInOptimizedOrder(FieldMatrixPreservingVisitor<T> visitor) +737 throws MatrixVisitorException; +738 +739 /** +740 * Visit (and possibly change) some matrix entries using the fastest possible order. +741 * <p>The fastest walking order depends on the exact matrix class. It may be +742 * different from traditional row or column orders.</p> +743 * @param visitor visitor used to process all matrix entries +744 * @param startRow Initial row index +745 * @param endRow Final row index (inclusive) +746 * @param startColumn Initial column index +747 * @param endColumn Final column index (inclusive) +748 * @exception MatrixVisitorException if the visitor cannot process an entry +749 * @exception MatrixIndexException if the indices are not valid +750 * @see #walkInRowOrder(FieldMatrixChangingVisitor) +751 * @see #walkInRowOrder(FieldMatrixPreservingVisitor) +752 * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) +753 * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) +754 * @see #walkInColumnOrder(FieldMatrixChangingVisitor) +755 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) +756 * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) +757 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) +758 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) +759 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) +760 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int) +761 * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end +762 * of the walk +763 */ +764 T walkInOptimizedOrder(FieldMatrixChangingVisitor<T> visitor, +765 int startRow, int endRow, int startColumn, int endColumn) +766 throws MatrixIndexException, MatrixVisitorException; +767 +768 /** +769 * Visit (but don't change) some matrix entries using the fastest possible order. +770 * <p>The fastest walking order depends on the exact matrix class. It may be +771 * different from traditional row or column orders.</p> +772 * @param visitor visitor used to process all matrix entries +773 * @param startRow Initial row index +774 * @param endRow Final row index (inclusive) +775 * @param startColumn Initial column index +776 * @param endColumn Final column index (inclusive) +777 * @exception MatrixVisitorException if the visitor cannot process an entry +778 * @exception MatrixIndexException if the indices are not valid +779 * @see #walkInRowOrder(FieldMatrixChangingVisitor) +780 * @see #walkInRowOrder(FieldMatrixPreservingVisitor) +781 * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int) +782 * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int) +783 * @see #walkInColumnOrder(FieldMatrixChangingVisitor) +784 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor) +785 * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int) +786 * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int) +787 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor) +788 * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor) +789 * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int) +790 * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end +791 * of the walk +792 */ +793 T walkInOptimizedOrder(FieldMatrixPreservingVisitor<T> visitor, +794 int startRow, int endRow, int startColumn, int endColumn) +795 throws MatrixIndexException, MatrixVisitorException; +796 +797 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/FieldMatrixChangingVisitor.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/FieldMatrixChangingVisitor.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,128 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.FieldElement; +021 +022 /** +023 * Interface defining a visitor for matrix entries. +024 * +025 * @param <T> the type of the field elements +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 * @since 2.0 +028 */ +029 public interface FieldMatrixChangingVisitor<T extends FieldElement<?>> { +030 +031 /** +032 * Start visiting a matrix. +033 * <p>This method is called once before any entry of the matrix is visited.</p> +034 * @param rows number of rows of the matrix +035 * @param columns number of columns of the matrix +036 * @param startRow Initial row index +037 * @param endRow Final row index (inclusive) +038 * @param startColumn Initial column index +039 * @param endColumn Final column index (inclusive) +040 */ +041 void start(int rows, int columns, +042 int startRow, int endRow, int startColumn, int endColumn); +043 +044 /** +045 * Visit one matrix entry. +046 * @param row row index of the entry +047 * @param column column index of the entry +048 * @param value current value of the entry +049 * @return the new value to be set for the entry +050 * @throws MatrixVisitorException if something wrong occurs +051 */ +052 T visit(int row, int column, T value) +053 throws MatrixVisitorException; +054 +055 /** +056 * End visiting a matrix. +057 * <p>This method is called once after all entries of the matrix have been visited.</p> +058 * @return the value that the <code>walkInXxxOrder</code> must return +059 */ +060 T end(); +061 +062 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/FieldMatrixPreservingVisitor.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/FieldMatrixPreservingVisitor.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,127 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.FieldElement; +021 +022 /** +023 * Interface defining a visitor for matrix entries. +024 * +025 * @param <T> the type of the field elements +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 * @since 2.0 +028 */ +029 public interface FieldMatrixPreservingVisitor<T extends FieldElement<?>> { +030 +031 /** +032 * Start visiting a matrix. +033 * <p>This method is called once before any entry of the matrix is visited.</p> +034 * @param rows number of rows of the matrix +035 * @param columns number of columns of the matrix +036 * @param startRow Initial row index +037 * @param endRow Final row index (inclusive) +038 * @param startColumn Initial column index +039 * @param endColumn Final column index (inclusive) +040 */ +041 void start(int rows, int columns, +042 int startRow, int endRow, int startColumn, int endColumn); +043 +044 /** +045 * Visit one matrix entry. +046 * @param row row index of the entry +047 * @param column column index of the entry +048 * @param value current value of the entry +049 * @throws MatrixVisitorException if something wrong occurs +050 */ +051 void visit(int row, int column, T value) +052 throws MatrixVisitorException; +053 +054 /** +055 * End visiting a matrix. +056 * <p>This method is called once after all entries of the matrix have been visited.</p> +057 * @return the value that the <code>walkInXxxOrder</code> must return +058 */ +059 T end(); +060 +061 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/FieldVector.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/FieldVector.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,424 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.linear; +018 +019 import org.apache.commons.math.Field; +020 import org.apache.commons.math.FieldElement; +021 +022 /** +023 * Interface defining a field-valued vector with basic algebraic operations. +024 * <p> +025 * vector element indexing is 0-based -- e.g., <code>getEntry(0)</code> +026 * returns the first element of the vector. +027 * </p> +028 * <p> +029 * The various <code>mapXxx</code> and <code>mapXxxToSelf</code> methods operate +030 * on vectors element-wise, i.e. they perform the same operation (adding a scalar, +031 * applying a function ...) on each element in turn. The <code>mapXxx</code> +032 * versions create a new vector to hold the result and do not change the instance. +033 * The <code>mapXxxToSelf</code> versions use the instance itself to store the +034 * results, so the instance is changed by these methods. In both cases, the result +035 * vector is returned by the methods, this allows to use the <i>fluent API</i> +036 * style, like this: +037 * </p> +038 * <pre> +039 * RealVector result = v.mapAddToSelf(3.0).mapTanToSelf().mapSquareToSelf(); +040 * </pre> +041 * +042 * @param <T> the type of the field elements +043 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +044 * @since 2.0 +045 */ +046 public interface FieldVector<T extends FieldElement<T>> { +047 +048 /** +049 * Get the type of field elements of the vector. +050 * @return type of field elements of the vector +051 */ +052 Field<T> getField(); +053 +054 /** +055 * Returns a (deep) copy of this. +056 * @return vector copy +057 */ +058 FieldVector<T> copy(); +059 +060 /** +061 * Compute the sum of this and v. +062 * @param v vector to be added +063 * @return this + v +064 * @throws IllegalArgumentException if v is not the same size as this +065 */ +066 FieldVector<T> add(FieldVector<T> v) +067 throws IllegalArgumentException; +068 +069 /** +070 * Compute the sum of this and v. +071 * @param v vector to be added +072 * @return this + v +073 * @throws IllegalArgumentException if v is not the same size as this +074 */ +075 FieldVector<T> add(T[] v) +076 throws IllegalArgumentException; +077 +078 /** +079 * Compute this minus v. +080 * @param v vector to be subtracted +081 * @return this + v +082 * @throws IllegalArgumentException if v is not the same size as this +083 */ +084 FieldVector<T> subtract(FieldVector<T> v) +085 throws IllegalArgumentException; +086 +087 /** +088 * Compute this minus v. +089 * @param v vector to be subtracted +090 * @return this + v +091 * @throws IllegalArgumentException if v is not the same size as this +092 */ +093 FieldVector<T> subtract(T[] v) +094 throws IllegalArgumentException; +095 +096 /** +097 * Map an addition operation to each entry. +098 * @param d value to be added to each entry +099 * @return this + d +100 */ +101 FieldVector<T> mapAdd(T d); +102 +103 /** +104 * Map an addition operation to each entry. +105 * <p>The instance <strong>is</strong> changed by this method.</p> +106 * @param d value to be added to each entry +107 * @return for convenience, return this +108 */ +109 FieldVector<T> mapAddToSelf(T d); +110 +111 /** +112 * Map a subtraction operation to each entry. +113 * @param d value to be subtracted to each entry +114 * @return this - d +115 */ +116 FieldVector<T> mapSubtract(T d); +117 +118 /** +119 * Map a subtraction operation to each entry. +120 * <p>The instance <strong>is</strong> changed by this method.</p> +121 * @param d value to be subtracted to each entry +122 * @return for convenience, return this +123 */ +124 FieldVector<T> mapSubtractToSelf(T d); +125 +126 /** +127 * Map a multiplication operation to each entry. +128 * @param d value to multiply all entries by +129 * @return this * d +130 */ +131 FieldVector<T> mapMultiply(T d); +132 +133 /** +134 * Map a multiplication operation to each entry. +135 * <p>The instance <strong>is</strong> changed by this method.</p> +136 * @param d value to multiply all entries by +137 * @return for convenience, return this +138 */ +139 FieldVector<T> mapMultiplyToSelf(T d); +140 +141 /** +142 * Map a division operation to each entry. +143 * @param d value to divide all entries by +144 * @return this / d +145 */ +146 FieldVector<T> mapDivide(T d); +147 +148 /** +149 * Map a division operation to each entry. +150 * <p>The instance <strong>is</strong> changed by this method.</p> +151 * @param d value to divide all entries by +152 * @return for convenience, return this +153 */ +154 FieldVector<T> mapDivideToSelf(T d); +155 +156 /** +157 * Map the 1/x function to each entry. +158 * @return a vector containing the result of applying the function to each entry +159 */ +160 FieldVector<T> mapInv(); +161 +162 /** +163 * Map the 1/x function to each entry. +164 * <p>The instance <strong>is</strong> changed by this method.</p> +165 * @return for convenience, return this +166 */ +167 FieldVector<T> mapInvToSelf(); +168 +169 /** +170 * Element-by-element multiplication. +171 * @param v vector by which instance elements must be multiplied +172 * @return a vector containing this[i] * v[i] for all i +173 * @throws IllegalArgumentException if v is not the same size as this +174 */ +175 FieldVector<T> ebeMultiply(FieldVector<T> v) throws IllegalArgumentException; +176 +177 /** +178 * Element-by-element multiplication. +179 * @param v vector by which instance elements must be multiplied +180 * @return a vector containing this[i] * v[i] for all i +181 * @throws IllegalArgumentException if v is not the same size as this +182 */ +183 FieldVector<T> ebeMultiply(T[] v) throws IllegalArgumentException; +184 +185 /** +186 * Element-by-element division. +187 * @param v vector by which instance elements must be divided +188 * @return a vector containing this[i] / v[i] for all i +189 * @throws IllegalArgumentException if v is not the same size as this +190 */ +191 FieldVector<T> ebeDivide(FieldVector<T> v) throws IllegalArgumentException; +192 +193 /** +194 * Element-by-element division. +195 * @param v vector by which instance elements must be divided +196 * @return a vector containing this[i] / v[i] for all i +197 * @throws IllegalArgumentException if v is not the same size as this +198 */ +199 FieldVector<T> ebeDivide(T[] v) throws IllegalArgumentException; +200 +201 /** +202 * Returns vector entries as a T array. +203 * @return T array of entries +204 */ +205 T[] getData(); +206 +207 /** +208 * Compute the dot product. +209 * @param v vector with which dot product should be computed +210 * @return the scalar dot product between instance and v +211 * @exception IllegalArgumentException if v is not the same size as this +212 */ +213 T dotProduct(FieldVector<T> v) +214 throws IllegalArgumentException; +215 +216 /** +217 * Compute the dot product. +218 * @param v vector with which dot product should be computed +219 * @return the scalar dot product between instance and v +220 * @exception IllegalArgumentException if v is not the same size as this +221 */ +222 T dotProduct(T[] v) +223 throws IllegalArgumentException; +224 +225 /** Find the orthogonal projection of this vector onto another vector. +226 * @param v vector onto which instance must be projected +227 * @return projection of the instance onto v +228 * @throws IllegalArgumentException if v is not the same size as this +229 */ +230 FieldVector<T> projection(FieldVector<T> v) +231 throws IllegalArgumentException; +232 +233 /** Find the orthogonal projection of this vector onto another vector. +234 * @param v vector onto which instance must be projected +235 * @return projection of the instance onto v +236 * @throws IllegalArgumentException if v is not the same size as this +237 */ +238 FieldVector<T> projection(T[] v) +239 throws IllegalArgumentException; +240 +241 /** +242 * Compute the outer product. +243 * @param v vector with which outer product should be computed +244 * @return the square matrix outer product between instance and v +245 * @exception IllegalArgumentException if v is not the same size as this +246 */ +247 FieldMatrix<T> outerProduct(FieldVector<T> v) +248 throws IllegalArgumentException; +249 +250 /** +251 * Compute the outer product. +252 * @param v vector with which outer product should be computed +253 * @return the square matrix outer product between instance and v +254 * @exception IllegalArgumentException if v is not the same size as this +255 */ +256 FieldMatrix<T> outerProduct(T[] v) +257 throws IllegalArgumentException; +258 +259 /** +260 * Returns the entry in the specified index. +261 * <p> +262 * The index start at 0 and must be lesser than the size, +263 * otherwise a {@link MatrixIndexException} is thrown. +264 * </p> +265 * @param index index location of entry to be fetched +266 * @return vector entry at index +267 * @throws MatrixIndexException if the index is not valid +268 * @see #setEntry(int, FieldElement) +269 */ +270 T getEntry(int index) +271 throws MatrixIndexException; +272 +273 /** +274 * Set a single element. +275 * @param index element index. +276 * @param value new value for the element. +277 * @exception MatrixIndexException if the index is +278 * inconsistent with vector size +279 * @see #getEntry(int) +280 */ +281 void setEntry(int index, T value) +282 throws MatrixIndexException; +283 +284 /** +285 * Returns the size of the vector. +286 * @return size +287 */ +288 int getDimension(); +289 +290 /** +291 * Construct a vector by appending a vector to this vector. +292 * @param v vector to append to this one. +293 * @return a new vector +294 */ +295 FieldVector<T> append(FieldVector<T> v); +296 +297 /** +298 * Construct a vector by appending a T to this vector. +299 * @param d T to append. +300 * @return a new vector +301 */ +302 FieldVector<T> append(T d); +303 +304 /** +305 * Construct a vector by appending a T array to this vector. +306 * @param a T array to append. +307 * @return a new vector +308 */ +309 FieldVector<T> append(T[] a); +310 +311 /** +312 * Get a subvector from consecutive elements. +313 * @param index index of first element. +314 * @param n number of elements to be retrieved. +315 * @return a vector containing n elements. +316 * @exception MatrixIndexException if the index is +317 * inconsistent with vector size +318 */ +319 FieldVector<T> getSubVector(int index, int n) +320 throws MatrixIndexException; +321 +322 /** +323 * Set a set of consecutive elements. +324 * @param index index of first element to be set. +325 * @param v vector containing the values to set. +326 * @exception MatrixIndexException if the index is +327 * inconsistent with vector size +328 * @see #setSubVector(int, FieldElement[]) +329 */ +330 void setSubVector(int index, FieldVector<T> v) +331 throws MatrixIndexException; +332 +333 /** +334 * Set a set of consecutive elements. +335 * @param index index of first element to be set. +336 * @param v vector containing the values to set. +337 * @exception MatrixIndexException if the index is +338 * inconsistent with vector size +339 * @see #setSubVector(int, FieldVector) +340 */ +341 void setSubVector(int index, T[] v) +342 throws MatrixIndexException; +343 +344 /** +345 * Set all elements to a single value. +346 * @param value single value to set for all elements +347 */ +348 void set(T value); +349 +350 /** +351 * Convert the vector to a T array. +352 * <p>The array is independent from vector data, it's elements +353 * are copied.</p> +354 * @return array containing a copy of vector elements +355 */ +356 T[] toArray(); +357 +358 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/InvalidMatrixException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/InvalidMatrixException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,119 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.MathRuntimeException; +021 +022 /** +023 * Thrown when a system attempts an operation on a matrix, and +024 * that matrix does not satisfy the preconditions for the +025 * aforementioned operation. +026 * @version $Revision: 746578 $ $Date: 2009-02-21 15:01:14 -0500 (Sat, 21 Feb 2009) $ +027 */ +028 public class InvalidMatrixException extends MathRuntimeException { +029 +030 /** Serializable version identifier. */ +031 private static final long serialVersionUID = 1135533765052675495L; +032 +033 /** +034 * Construct an exception with the given message. +035 * @param pattern format specifier +036 * @param arguments format arguments +037 * @since 2.0 +038 */ +039 public InvalidMatrixException(final String pattern, final Object ... arguments) { +040 super(pattern, arguments); +041 } +042 +043 /** +044 * Construct an exception with the given message. +045 * @param cause the exception or error that caused this exception +046 * to be thrown. +047 * @since 2.0 +048 */ +049 public InvalidMatrixException(final Throwable cause) { +050 super(cause); +051 } +052 +053 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/LUDecomposition.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/LUDecomposition.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,158 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 +021 /** +022 * An interface to classes that implement an algorithm to calculate the +023 * LU-decomposition of a real matrix. +024 * <p>The LU-decomposition of matrix A is a set of three matrices: P, L and U +025 * such that P×A = L×U. P is a rows permutation matrix that is used +026 * to rearrange the rows of A before so that it can be decomposed. L is a lower +027 * triangular matrix with unit diagonal terms and U is an upper triangular matrix.</p> +028 * <p>This interface is based on the class with similar name from the +029 * <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> library.</p> +030 * <ul> +031 * <li>a {@link #getP() getP} method has been added,</li> +032 * <li>the <code>det</code> method has been renamed as {@link #getDeterminant() +033 * getDeterminant},</li> +034 * <li>the <code>getDoublePivot</code> method has been removed (but the int based +035 * {@link #getPivot() getPivot} method has been kept),</li> +036 * <li>the <code>solve</code> and <code>isNonSingular</code> methods have been replaced +037 * by a {@link #getSolver() getSolver} method and the equivalent methods provided by +038 * the returned {@link DecompositionSolver}.</li> +039 * </ul> +040 * +041 * @see <a href="http://mathworld.wolfram.com/LUDecomposition.html">MathWorld</a> +042 * @see <a href="http://en.wikipedia.org/wiki/LU_decomposition">Wikipedia</a> +043 * @version $Revision: 826627 $ $Date: 2009-10-19 06:27:47 -0400 (Mon, 19 Oct 2009) $ +044 * @since 2.0 +045 */ +046 public interface LUDecomposition { +047 +048 /** +049 * Returns the matrix L of the decomposition. +050 * <p>L is an lower-triangular matrix</p> +051 * @return the L matrix (or null if decomposed matrix is singular) +052 */ +053 RealMatrix getL(); +054 +055 /** +056 * Returns the matrix U of the decomposition. +057 * <p>U is an upper-triangular matrix</p> +058 * @return the U matrix (or null if decomposed matrix is singular) +059 */ +060 RealMatrix getU(); +061 +062 /** +063 * Returns the P rows permutation matrix. +064 * <p>P is a sparse matrix with exactly one element set to 1.0 in +065 * each row and each column, all other elements being set to 0.0.</p> +066 * <p>The positions of the 1 elements are given by the {@link #getPivot() +067 * pivot permutation vector}.</p> +068 * @return the P rows permutation matrix (or null if decomposed matrix is singular) +069 * @see #getPivot() +070 */ +071 RealMatrix getP(); +072 +073 /** +074 * Returns the pivot permutation vector. +075 * @return the pivot permutation vector +076 * @see #getP() +077 */ +078 int[] getPivot(); +079 +080 /** +081 * Return the determinant of the matrix +082 * @return determinant of the matrix +083 */ +084 double getDeterminant(); +085 +086 /** +087 * Get a solver for finding the A × X = B solution in exact linear sense. +088 * @return a solver +089 */ +090 DecompositionSolver getSolver(); +091 +092 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/LUDecompositionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/LUDecompositionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,491 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.MathRuntimeException; +021 +022 /** +023 * Calculates the LUP-decomposition of a square matrix. +024 * <p>The LUP-decomposition of a matrix A consists of three matrices +025 * L, U and P that satisfy: PA = LU, L is lower triangular, and U is +026 * upper triangular and P is a permutation matrix. All matrices are +027 * m×m.</p> +028 * <p>As shown by the presence of the P matrix, this decomposition is +029 * implemented using partial pivoting.</p> +030 * +031 * @version $Revision: 885278 $ $Date: 2009-11-29 16:47:51 -0500 (Sun, 29 Nov 2009) $ +032 * @since 2.0 +033 */ +034 public class LUDecompositionImpl implements LUDecomposition { +035 +036 /** Default bound to determine effective singularity in LU decomposition */ +037 private static final double DEFAULT_TOO_SMALL = 10E-12; +038 +039 /** Message for vector length mismatch. */ +040 private static final String VECTOR_LENGTH_MISMATCH_MESSAGE = +041 "vector length mismatch: got {0} but expected {1}"; +042 +043 /** Entries of LU decomposition. */ +044 private double lu[][]; +045 +046 /** Pivot permutation associated with LU decomposition */ +047 private int[] pivot; +048 +049 /** Parity of the permutation associated with the LU decomposition */ +050 private boolean even; +051 +052 /** Singularity indicator. */ +053 private boolean singular; +054 +055 /** Cached value of L. */ +056 private RealMatrix cachedL; +057 +058 /** Cached value of U. */ +059 private RealMatrix cachedU; +060 +061 /** Cached value of P. */ +062 private RealMatrix cachedP; +063 +064 /** +065 * Calculates the LU-decomposition of the given matrix. +066 * @param matrix The matrix to decompose. +067 * @exception InvalidMatrixException if matrix is not square +068 */ +069 public LUDecompositionImpl(RealMatrix matrix) +070 throws InvalidMatrixException { +071 this(matrix, DEFAULT_TOO_SMALL); +072 } +073 +074 /** +075 * Calculates the LU-decomposition of the given matrix. +076 * @param matrix The matrix to decompose. +077 * @param singularityThreshold threshold (based on partial row norm) +078 * under which a matrix is considered singular +079 * @exception NonSquareMatrixException if matrix is not square +080 */ +081 public LUDecompositionImpl(RealMatrix matrix, double singularityThreshold) +082 throws NonSquareMatrixException { +083 +084 if (!matrix.isSquare()) { +085 throw new NonSquareMatrixException(matrix.getRowDimension(), matrix.getColumnDimension()); +086 } +087 +088 final int m = matrix.getColumnDimension(); +089 lu = matrix.getData(); +090 pivot = new int[m]; +091 cachedL = null; +092 cachedU = null; +093 cachedP = null; +094 +095 // Initialize permutation array and parity +096 for (int row = 0; row < m; row++) { +097 pivot[row] = row; +098 } +099 even = true; +100 singular = false; +101 +102 // Loop over columns +103 for (int col = 0; col < m; col++) { +104 +105 double sum = 0; +106 +107 // upper +108 for (int row = 0; row < col; row++) { +109 final double[] luRow = lu[row]; +110 sum = luRow[col]; +111 for (int i = 0; i < row; i++) { +112 sum -= luRow[i] * lu[i][col]; +113 } +114 luRow[col] = sum; +115 } +116 +117 // lower +118 int max = col; // permutation row +119 double largest = Double.NEGATIVE_INFINITY; +120 for (int row = col; row < m; row++) { +121 final double[] luRow = lu[row]; +122 sum = luRow[col]; +123 for (int i = 0; i < col; i++) { +124 sum -= luRow[i] * lu[i][col]; +125 } +126 luRow[col] = sum; +127 +128 // maintain best permutation choice +129 if (Math.abs(sum) > largest) { +130 largest = Math.abs(sum); +131 max = row; +132 } +133 } +134 +135 // Singularity check +136 if (Math.abs(lu[max][col]) < singularityThreshold) { +137 singular = true; +138 return; +139 } +140 +141 // Pivot if necessary +142 if (max != col) { +143 double tmp = 0; +144 final double[] luMax = lu[max]; +145 final double[] luCol = lu[col]; +146 for (int i = 0; i < m; i++) { +147 tmp = luMax[i]; +148 luMax[i] = luCol[i]; +149 luCol[i] = tmp; +150 } +151 int temp = pivot[max]; +152 pivot[max] = pivot[col]; +153 pivot[col] = temp; +154 even = !even; +155 } +156 +157 // Divide the lower elements by the "winning" diagonal elt. +158 final double luDiag = lu[col][col]; +159 for (int row = col + 1; row < m; row++) { +160 lu[row][col] /= luDiag; +161 } +162 } +163 +164 } +165 +166 /** {@inheritDoc} */ +167 public RealMatrix getL() { +168 if ((cachedL == null) && !singular) { +169 final int m = pivot.length; +170 cachedL = MatrixUtils.createRealMatrix(m, m); +171 for (int i = 0; i < m; ++i) { +172 final double[] luI = lu[i]; +173 for (int j = 0; j < i; ++j) { +174 cachedL.setEntry(i, j, luI[j]); +175 } +176 cachedL.setEntry(i, i, 1.0); +177 } +178 } +179 return cachedL; +180 } +181 +182 /** {@inheritDoc} */ +183 public RealMatrix getU() { +184 if ((cachedU == null) && !singular) { +185 final int m = pivot.length; +186 cachedU = MatrixUtils.createRealMatrix(m, m); +187 for (int i = 0; i < m; ++i) { +188 final double[] luI = lu[i]; +189 for (int j = i; j < m; ++j) { +190 cachedU.setEntry(i, j, luI[j]); +191 } +192 } +193 } +194 return cachedU; +195 } +196 +197 /** {@inheritDoc} */ +198 public RealMatrix getP() { +199 if ((cachedP == null) && !singular) { +200 final int m = pivot.length; +201 cachedP = MatrixUtils.createRealMatrix(m, m); +202 for (int i = 0; i < m; ++i) { +203 cachedP.setEntry(i, pivot[i], 1.0); +204 } +205 } +206 return cachedP; +207 } +208 +209 /** {@inheritDoc} */ +210 public int[] getPivot() { +211 return pivot.clone(); +212 } +213 +214 /** {@inheritDoc} */ +215 public double getDeterminant() { +216 if (singular) { +217 return 0; +218 } else { +219 final int m = pivot.length; +220 double determinant = even ? 1 : -1; +221 for (int i = 0; i < m; i++) { +222 determinant *= lu[i][i]; +223 } +224 return determinant; +225 } +226 } +227 +228 /** {@inheritDoc} */ +229 public DecompositionSolver getSolver() { +230 return new Solver(lu, pivot, singular); +231 } +232 +233 /** Specialized solver. */ +234 private static class Solver implements DecompositionSolver { +235 +236 /** Entries of LU decomposition. */ +237 private final double lu[][]; +238 +239 /** Pivot permutation associated with LU decomposition. */ +240 private final int[] pivot; +241 +242 /** Singularity indicator. */ +243 private final boolean singular; +244 +245 /** +246 * Build a solver from decomposed matrix. +247 * @param lu entries of LU decomposition +248 * @param pivot pivot permutation associated with LU decomposition +249 * @param singular singularity indicator +250 */ +251 private Solver(final double[][] lu, final int[] pivot, final boolean singular) { +252 this.lu = lu; +253 this.pivot = pivot; +254 this.singular = singular; +255 } +256 +257 /** {@inheritDoc} */ +258 public boolean isNonSingular() { +259 return !singular; +260 } +261 +262 /** {@inheritDoc} */ +263 public double[] solve(double[] b) +264 throws IllegalArgumentException, InvalidMatrixException { +265 +266 final int m = pivot.length; +267 if (b.length != m) { +268 throw MathRuntimeException.createIllegalArgumentException( +269 VECTOR_LENGTH_MISMATCH_MESSAGE, b.length, m); +270 } +271 if (singular) { +272 throw new SingularMatrixException(); +273 } +274 +275 final double[] bp = new double[m]; +276 +277 // Apply permutations to b +278 for (int row = 0; row < m; row++) { +279 bp[row] = b[pivot[row]]; +280 } +281 +282 // Solve LY = b +283 for (int col = 0; col < m; col++) { +284 final double bpCol = bp[col]; +285 for (int i = col + 1; i < m; i++) { +286 bp[i] -= bpCol * lu[i][col]; +287 } +288 } +289 +290 // Solve UX = Y +291 for (int col = m - 1; col >= 0; col--) { +292 bp[col] /= lu[col][col]; +293 final double bpCol = bp[col]; +294 for (int i = 0; i < col; i++) { +295 bp[i] -= bpCol * lu[i][col]; +296 } +297 } +298 +299 return bp; +300 +301 } +302 +303 /** {@inheritDoc} */ +304 public RealVector solve(RealVector b) +305 throws IllegalArgumentException, InvalidMatrixException { +306 try { +307 return solve((ArrayRealVector) b); +308 } catch (ClassCastException cce) { +309 +310 final int m = pivot.length; +311 if (b.getDimension() != m) { +312 throw MathRuntimeException.createIllegalArgumentException( +313 VECTOR_LENGTH_MISMATCH_MESSAGE, b.getDimension(), m); +314 } +315 if (singular) { +316 throw new SingularMatrixException(); +317 } +318 +319 final double[] bp = new double[m]; +320 +321 // Apply permutations to b +322 for (int row = 0; row < m; row++) { +323 bp[row] = b.getEntry(pivot[row]); +324 } +325 +326 // Solve LY = b +327 for (int col = 0; col < m; col++) { +328 final double bpCol = bp[col]; +329 for (int i = col + 1; i < m; i++) { +330 bp[i] -= bpCol * lu[i][col]; +331 } +332 } +333 +334 // Solve UX = Y +335 for (int col = m - 1; col >= 0; col--) { +336 bp[col] /= lu[col][col]; +337 final double bpCol = bp[col]; +338 for (int i = 0; i < col; i++) { +339 bp[i] -= bpCol * lu[i][col]; +340 } +341 } +342 +343 return new ArrayRealVector(bp, false); +344 +345 } +346 } +347 +348 /** Solve the linear equation A × X = B. +349 * <p>The A matrix is implicit here. It is </p> +350 * @param b right-hand side of the equation A × X = B +351 * @return a vector X such that A × X = B +352 * @exception IllegalArgumentException if matrices dimensions don't match +353 * @exception InvalidMatrixException if decomposed matrix is singular +354 */ +355 public ArrayRealVector solve(ArrayRealVector b) +356 throws IllegalArgumentException, InvalidMatrixException { +357 return new ArrayRealVector(solve(b.getDataRef()), false); +358 } +359 +360 /** {@inheritDoc} */ +361 public RealMatrix solve(RealMatrix b) +362 throws IllegalArgumentException, InvalidMatrixException { +363 +364 final int m = pivot.length; +365 if (b.getRowDimension() != m) { +366 throw MathRuntimeException.createIllegalArgumentException( +367 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +368 b.getRowDimension(), b.getColumnDimension(), m, "n"); +369 } +370 if (singular) { +371 throw new SingularMatrixException(); +372 } +373 +374 final int nColB = b.getColumnDimension(); +375 +376 // Apply permutations to b +377 final double[][] bp = new double[m][nColB]; +378 for (int row = 0; row < m; row++) { +379 final double[] bpRow = bp[row]; +380 final int pRow = pivot[row]; +381 for (int col = 0; col < nColB; col++) { +382 bpRow[col] = b.getEntry(pRow, col); +383 } +384 } +385 +386 // Solve LY = b +387 for (int col = 0; col < m; col++) { +388 final double[] bpCol = bp[col]; +389 for (int i = col + 1; i < m; i++) { +390 final double[] bpI = bp[i]; +391 final double luICol = lu[i][col]; +392 for (int j = 0; j < nColB; j++) { +393 bpI[j] -= bpCol[j] * luICol; +394 } +395 } +396 } +397 +398 // Solve UX = Y +399 for (int col = m - 1; col >= 0; col--) { +400 final double[] bpCol = bp[col]; +401 final double luDiag = lu[col][col]; +402 for (int j = 0; j < nColB; j++) { +403 bpCol[j] /= luDiag; +404 } +405 for (int i = 0; i < col; i++) { +406 final double[] bpI = bp[i]; +407 final double luICol = lu[i][col]; +408 for (int j = 0; j < nColB; j++) { +409 bpI[j] -= bpCol[j] * luICol; +410 } +411 } +412 } +413 +414 return new Array2DRowRealMatrix(bp, false); +415 +416 } +417 +418 /** {@inheritDoc} */ +419 public RealMatrix getInverse() throws InvalidMatrixException { +420 return solve(MatrixUtils.createRealIdentityMatrix(pivot.length)); +421 } +422 +423 } +424 +425 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/MatrixIndexException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/MatrixIndexException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,107 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.MathRuntimeException; +021 +022 /** +023 * Thrown when an operation addresses a matrix coordinate (row, col) +024 * which is outside of the dimensions of a matrix. +025 * @version $Revision: 746578 $ $Date: 2009-02-21 15:01:14 -0500 (Sat, 21 Feb 2009) $ +026 */ +027 public class MatrixIndexException extends MathRuntimeException { +028 +029 /** Serializable version identifier */ +030 private static final long serialVersionUID = -2382324504109300625L; +031 +032 /** +033 * Constructs a new instance with specified formatted detail message. +034 * @param pattern format specifier +035 * @param arguments format arguments +036 */ +037 public MatrixIndexException(final String pattern, final Object ... arguments) { +038 super(pattern, arguments); +039 } +040 +041 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/MatrixUtils.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/MatrixUtils.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1022 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.io.IOException; +021 import java.io.ObjectInputStream; +022 import java.io.ObjectOutputStream; +023 import java.lang.reflect.Array; +024 import java.math.BigDecimal; +025 import java.util.Arrays; +026 +027 import org.apache.commons.math.Field; +028 import org.apache.commons.math.FieldElement; +029 import org.apache.commons.math.MathRuntimeException; +030 import org.apache.commons.math.fraction.BigFraction; +031 import org.apache.commons.math.fraction.Fraction; +032 +033 /** +034 * A collection of static methods that operate on or return matrices. +035 * +036 * @version $Revision: 903046 $ $Date: 2010-01-25 21:07:26 -0500 (Mon, 25 Jan 2010) $ +037 */ +038 public class MatrixUtils { +039 +040 /** +041 * Private constructor. +042 */ +043 private MatrixUtils() { +044 super(); +045 } +046 +047 /** +048 * Returns a {@link RealMatrix} with specified dimensions. +049 * <p>The type of matrix returned depends on the dimension. Below +050 * 2<sup>12</sup> elements (i.e. 4096 elements or 64×64 for a +051 * square matrix) which can be stored in a 32kB array, a {@link +052 * Array2DRowRealMatrix} instance is built. Above this threshold a {@link +053 * BlockRealMatrix} instance is built.</p> +054 * <p>The matrix elements are all set to 0.0.</p> +055 * @param rows number of rows of the matrix +056 * @param columns number of columns of the matrix +057 * @return RealMatrix with specified dimensions +058 * @see #createRealMatrix(double[][]) +059 */ +060 public static RealMatrix createRealMatrix(final int rows, final int columns) { +061 return (rows * columns <= 4096) ? +062 new Array2DRowRealMatrix(rows, columns) : new BlockRealMatrix(rows, columns); +063 } +064 +065 /** +066 * Returns a {@link FieldMatrix} with specified dimensions. +067 * <p>The type of matrix returned depends on the dimension. Below +068 * 2<sup>12</sup> elements (i.e. 4096 elements or 64×64 for a +069 * square matrix), a {@link FieldMatrix} instance is built. Above +070 * this threshold a {@link BlockFieldMatrix} instance is built.</p> +071 * <p>The matrix elements are all set to field.getZero().</p> +072 * @param <T> the type of the field elements +073 * @param field field to which the matrix elements belong +074 * @param rows number of rows of the matrix +075 * @param columns number of columns of the matrix +076 * @return FieldMatrix with specified dimensions +077 * @see #createFieldMatrix(FieldElement[][]) +078 * @since 2.0 +079 */ +080 public static <T extends FieldElement<T>> FieldMatrix<T> createFieldMatrix(final Field<T> field, +081 final int rows, +082 final int columns) { +083 return (rows * columns <= 4096) ? +084 new Array2DRowFieldMatrix<T>(field, rows, columns) : new BlockFieldMatrix<T>(field, rows, columns); +085 } +086 +087 /** +088 * Returns a {@link RealMatrix} whose entries are the the values in the +089 * the input array. +090 * <p>The type of matrix returned depends on the dimension. Below +091 * 2<sup>12</sup> elements (i.e. 4096 elements or 64×64 for a +092 * square matrix) which can be stored in a 32kB array, a {@link +093 * Array2DRowRealMatrix} instance is built. Above this threshold a {@link +094 * BlockRealMatrix} instance is built.</p> +095 * <p>The input array is copied, not referenced.</p> +096 * +097 * @param data input array +098 * @return RealMatrix containing the values of the array +099 * @throws IllegalArgumentException if <code>data</code> is not rectangular +100 * (not all rows have the same length) or empty +101 * @throws NullPointerException if either <code>data</code> or +102 * <code>data[0]</code> is null +103 * @see #createRealMatrix(int, int) +104 */ +105 public static RealMatrix createRealMatrix(double[][] data) { +106 return (data.length * data[0].length <= 4096) ? +107 new Array2DRowRealMatrix(data) : new BlockRealMatrix(data); +108 } +109 +110 /** +111 * Returns a {@link FieldMatrix} whose entries are the the values in the +112 * the input array. +113 * <p>The type of matrix returned depends on the dimension. Below +114 * 2<sup>12</sup> elements (i.e. 4096 elements or 64×64 for a +115 * square matrix), a {@link FieldMatrix} instance is built. Above +116 * this threshold a {@link BlockFieldMatrix} instance is built.</p> +117 * <p>The input array is copied, not referenced.</p> +118 * @param <T> the type of the field elements +119 * @param data input array +120 * @return RealMatrix containing the values of the array +121 * @throws IllegalArgumentException if <code>data</code> is not rectangular +122 * (not all rows have the same length) or empty +123 * @throws NullPointerException if either <code>data</code> or +124 * <code>data[0]</code> is null +125 * @see #createFieldMatrix(Field, int, int) +126 * @since 2.0 +127 */ +128 public static <T extends FieldElement<T>> FieldMatrix<T> createFieldMatrix(T[][] data) { +129 return (data.length * data[0].length <= 4096) ? +130 new Array2DRowFieldMatrix<T>(data) : new BlockFieldMatrix<T>(data); +131 } +132 +133 /** +134 * Returns <code>dimension x dimension</code> identity matrix. +135 * +136 * @param dimension dimension of identity matrix to generate +137 * @return identity matrix +138 * @throws IllegalArgumentException if dimension is not positive +139 * @since 1.1 +140 */ +141 public static RealMatrix createRealIdentityMatrix(int dimension) { +142 final RealMatrix m = createRealMatrix(dimension, dimension); +143 for (int i = 0; i < dimension; ++i) { +144 m.setEntry(i, i, 1.0); +145 } +146 return m; +147 } +148 +149 /** +150 * Returns <code>dimension x dimension</code> identity matrix. +151 * +152 * @param <T> the type of the field elements +153 * @param field field to which the elements belong +154 * @param dimension dimension of identity matrix to generate +155 * @return identity matrix +156 * @throws IllegalArgumentException if dimension is not positive +157 * @since 2.0 +158 */ +159 public static <T extends FieldElement<T>> FieldMatrix<T> +160 createFieldIdentityMatrix(final Field<T> field, final int dimension) { +161 final T zero = field.getZero(); +162 final T one = field.getOne(); +163 @SuppressWarnings("unchecked") // zero is type T +164 final T[][] d = (T[][]) Array.newInstance(zero.getClass(), new int[] { dimension, dimension }); +165 for (int row = 0; row < dimension; row++) { +166 final T[] dRow = d[row]; +167 Arrays.fill(dRow, zero); +168 dRow[row] = one; +169 } +170 return new Array2DRowFieldMatrix<T>(d, false); +171 } +172 +173 /** +174 * Returns <code>dimension x dimension</code> identity matrix. +175 * +176 * @param dimension dimension of identity matrix to generate +177 * @return identity matrix +178 * @throws IllegalArgumentException if dimension is not positive +179 * @since 1.1 +180 * @deprecated since 2.0, replaced by {@link #createFieldIdentityMatrix(Field, int)} +181 */ +182 @Deprecated +183 public static BigMatrix createBigIdentityMatrix(int dimension) { +184 final BigDecimal[][] d = new BigDecimal[dimension][dimension]; +185 for (int row = 0; row < dimension; row++) { +186 final BigDecimal[] dRow = d[row]; +187 Arrays.fill(dRow, BigMatrixImpl.ZERO); +188 dRow[row] = BigMatrixImpl.ONE; +189 } +190 return new BigMatrixImpl(d, false); +191 } +192 +193 /** +194 * Returns a diagonal matrix with specified elements. +195 * +196 * @param diagonal diagonal elements of the matrix (the array elements +197 * will be copied) +198 * @return diagonal matrix +199 * @since 2.0 +200 */ +201 public static RealMatrix createRealDiagonalMatrix(final double[] diagonal) { +202 final RealMatrix m = createRealMatrix(diagonal.length, diagonal.length); +203 for (int i = 0; i < diagonal.length; ++i) { +204 m.setEntry(i, i, diagonal[i]); +205 } +206 return m; +207 } +208 +209 /** +210 * Returns a diagonal matrix with specified elements. +211 * +212 * @param <T> the type of the field elements +213 * @param diagonal diagonal elements of the matrix (the array elements +214 * will be copied) +215 * @return diagonal matrix +216 * @since 2.0 +217 */ +218 public static <T extends FieldElement<T>> FieldMatrix<T> +219 createFieldDiagonalMatrix(final T[] diagonal) { +220 final FieldMatrix<T> m = +221 createFieldMatrix(diagonal[0].getField(), diagonal.length, diagonal.length); +222 for (int i = 0; i < diagonal.length; ++i) { +223 m.setEntry(i, i, diagonal[i]); +224 } +225 return m; +226 } +227 +228 /** +229 * Returns a {@link BigMatrix} whose entries are the the values in the +230 * the input array. The input array is copied, not referenced. +231 * +232 * @param data input array +233 * @return RealMatrix containing the values of the array +234 * @throws IllegalArgumentException if <code>data</code> is not rectangular +235 * (not all rows have the same length) or empty +236 * @throws NullPointerException if data is null +237 * @deprecated since 2.0 replaced by {@link #createFieldMatrix(FieldElement[][])} +238 */ +239 @Deprecated +240 public static BigMatrix createBigMatrix(double[][] data) { +241 return new BigMatrixImpl(data); +242 } +243 +244 /** +245 * Returns a {@link BigMatrix} whose entries are the the values in the +246 * the input array. The input array is copied, not referenced. +247 * +248 * @param data input array +249 * @return RealMatrix containing the values of the array +250 * @throws IllegalArgumentException if <code>data</code> is not rectangular +251 * (not all rows have the same length) or empty +252 * @throws NullPointerException if data is null +253 * @deprecated since 2.0 replaced by {@link #createFieldMatrix(FieldElement[][])} +254 */ +255 @Deprecated +256 public static BigMatrix createBigMatrix(BigDecimal[][] data) { +257 return new BigMatrixImpl(data); +258 } +259 +260 /** +261 * Returns a {@link BigMatrix} whose entries are the the values in the +262 * the input array. +263 * <p>If an array is built specially in order to be embedded in a +264 * BigMatrix and not used directly, the <code>copyArray</code> may be +265 * set to <code>false</code. This will prevent the copying and improve +266 * performance as no new array will be built and no data will be copied.</p> +267 * @param data data for new matrix +268 * @param copyArray if true, the input array will be copied, otherwise +269 * it will be referenced +270 * @return BigMatrix containing the values of the array +271 * @throws IllegalArgumentException if <code>data</code> is not rectangular +272 * (not all rows have the same length) or empty +273 * @throws NullPointerException if <code>data</code> is null +274 * @see #createRealMatrix(double[][]) +275 * @deprecated since 2.0 replaced by {@link #createFieldMatrix(FieldElement[][])} +276 */ +277 @Deprecated +278 public static BigMatrix createBigMatrix(BigDecimal[][] data, boolean copyArray) { +279 return new BigMatrixImpl(data, copyArray); +280 } +281 +282 /** +283 * Returns a {@link BigMatrix} whose entries are the the values in the +284 * the input array. The input array is copied, not referenced. +285 * +286 * @param data input array +287 * @return RealMatrix containing the values of the array +288 * @throws IllegalArgumentException if <code>data</code> is not rectangular +289 * (not all rows have the same length) or empty +290 * @throws NullPointerException if data is null +291 * @deprecated since 2.0 replaced by {@link #createFieldMatrix(FieldElement[][])} +292 */ +293 @Deprecated +294 public static BigMatrix createBigMatrix(String[][] data) { +295 return new BigMatrixImpl(data); +296 } +297 +298 /** +299 * Creates a {@link RealVector} using the data from the input array. +300 * +301 * @param data the input data +302 * @return a data.length RealVector +303 * @throws IllegalArgumentException if <code>data</code> is empty +304 * @throws NullPointerException if <code>data</code>is null +305 */ +306 public static RealVector createRealVector(double[] data) { +307 return new ArrayRealVector(data, true); +308 } +309 +310 /** +311 * Creates a {@link FieldVector} using the data from the input array. +312 * +313 * @param <T> the type of the field elements +314 * @param data the input data +315 * @return a data.length FieldVector +316 * @throws IllegalArgumentException if <code>data</code> is empty +317 * @throws NullPointerException if <code>data</code>is null +318 */ +319 public static <T extends FieldElement<T>> FieldVector<T> createFieldVector(final T[] data) { +320 return new ArrayFieldVector<T>(data, true); +321 } +322 +323 /** +324 * Creates a row {@link RealMatrix} using the data from the input +325 * array. +326 * +327 * @param rowData the input row data +328 * @return a 1 x rowData.length RealMatrix +329 * @throws IllegalArgumentException if <code>rowData</code> is empty +330 * @throws NullPointerException if <code>rowData</code>is null +331 */ +332 public static RealMatrix createRowRealMatrix(double[] rowData) { +333 final int nCols = rowData.length; +334 final RealMatrix m = createRealMatrix(1, nCols); +335 for (int i = 0; i < nCols; ++i) { +336 m.setEntry(0, i, rowData[i]); +337 } +338 return m; +339 } +340 +341 /** +342 * Creates a row {@link FieldMatrix} using the data from the input +343 * array. +344 * +345 * @param <T> the type of the field elements +346 * @param rowData the input row data +347 * @return a 1 x rowData.length FieldMatrix +348 * @throws IllegalArgumentException if <code>rowData</code> is empty +349 * @throws NullPointerException if <code>rowData</code>is null +350 */ +351 public static <T extends FieldElement<T>> FieldMatrix<T> +352 createRowFieldMatrix(final T[] rowData) { +353 final int nCols = rowData.length; +354 if (nCols == 0) { +355 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column"); +356 } +357 final FieldMatrix<T> m = createFieldMatrix(rowData[0].getField(), 1, nCols); +358 for (int i = 0; i < nCols; ++i) { +359 m.setEntry(0, i, rowData[i]); +360 } +361 return m; +362 } +363 +364 /** +365 * Creates a row {@link BigMatrix} using the data from the input +366 * array. +367 * +368 * @param rowData the input row data +369 * @return a 1 x rowData.length BigMatrix +370 * @throws IllegalArgumentException if <code>rowData</code> is empty +371 * @throws NullPointerException if <code>rowData</code>is null +372 * @deprecated since 2.0 replaced by {@link #createRowFieldMatrix(FieldElement[])} +373 */ +374 @Deprecated +375 public static BigMatrix createRowBigMatrix(double[] rowData) { +376 final int nCols = rowData.length; +377 final BigDecimal[][] data = new BigDecimal[1][nCols]; +378 for (int i = 0; i < nCols; ++i) { +379 data[0][i] = new BigDecimal(rowData[i]); +380 } +381 return new BigMatrixImpl(data, false); +382 } +383 +384 /** +385 * Creates a row {@link BigMatrix} using the data from the input +386 * array. +387 * +388 * @param rowData the input row data +389 * @return a 1 x rowData.length BigMatrix +390 * @throws IllegalArgumentException if <code>rowData</code> is empty +391 * @throws NullPointerException if <code>rowData</code>is null +392 * @deprecated since 2.0 replaced by {@link #createRowFieldMatrix(FieldElement[])} +393 */ +394 @Deprecated +395 public static BigMatrix createRowBigMatrix(BigDecimal[] rowData) { +396 final int nCols = rowData.length; +397 final BigDecimal[][] data = new BigDecimal[1][nCols]; +398 System.arraycopy(rowData, 0, data[0], 0, nCols); +399 return new BigMatrixImpl(data, false); +400 } +401 +402 /** +403 * Creates a row {@link BigMatrix} using the data from the input +404 * array. +405 * +406 * @param rowData the input row data +407 * @return a 1 x rowData.length BigMatrix +408 * @throws IllegalArgumentException if <code>rowData</code> is empty +409 * @throws NullPointerException if <code>rowData</code>is null +410 * @deprecated since 2.0 replaced by {@link #createRowFieldMatrix(FieldElement[])} +411 */ +412 @Deprecated +413 public static BigMatrix createRowBigMatrix(String[] rowData) { +414 final int nCols = rowData.length; +415 final BigDecimal[][] data = new BigDecimal[1][nCols]; +416 for (int i = 0; i < nCols; ++i) { +417 data[0][i] = new BigDecimal(rowData[i]); +418 } +419 return new BigMatrixImpl(data, false); +420 } +421 +422 /** +423 * Creates a column {@link RealMatrix} using the data from the input +424 * array. +425 * +426 * @param columnData the input column data +427 * @return a columnData x 1 RealMatrix +428 * @throws IllegalArgumentException if <code>columnData</code> is empty +429 * @throws NullPointerException if <code>columnData</code>is null +430 */ +431 public static RealMatrix createColumnRealMatrix(double[] columnData) { +432 final int nRows = columnData.length; +433 final RealMatrix m = createRealMatrix(nRows, 1); +434 for (int i = 0; i < nRows; ++i) { +435 m.setEntry(i, 0, columnData[i]); +436 } +437 return m; +438 } +439 +440 /** +441 * Creates a column {@link FieldMatrix} using the data from the input +442 * array. +443 * +444 * @param <T> the type of the field elements +445 * @param columnData the input column data +446 * @return a columnData x 1 FieldMatrix +447 * @throws IllegalArgumentException if <code>columnData</code> is empty +448 * @throws NullPointerException if <code>columnData</code>is null +449 */ +450 public static <T extends FieldElement<T>> FieldMatrix<T> +451 createColumnFieldMatrix(final T[] columnData) { +452 final int nRows = columnData.length; +453 if (nRows == 0) { +454 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row"); +455 } +456 final FieldMatrix<T> m = createFieldMatrix(columnData[0].getField(), nRows, 1); +457 for (int i = 0; i < nRows; ++i) { +458 m.setEntry(i, 0, columnData[i]); +459 } +460 return m; +461 } +462 +463 /** +464 * Creates a column {@link BigMatrix} using the data from the input +465 * array. +466 * +467 * @param columnData the input column data +468 * @return a columnData x 1 BigMatrix +469 * @throws IllegalArgumentException if <code>columnData</code> is empty +470 * @throws NullPointerException if <code>columnData</code>is null +471 * @deprecated since 2.0 replaced by {@link #createColumnFieldMatrix(FieldElement[])} +472 */ +473 @Deprecated +474 public static BigMatrix createColumnBigMatrix(double[] columnData) { +475 final int nRows = columnData.length; +476 final BigDecimal[][] data = new BigDecimal[nRows][1]; +477 for (int row = 0; row < nRows; row++) { +478 data[row][0] = new BigDecimal(columnData[row]); +479 } +480 return new BigMatrixImpl(data, false); +481 } +482 +483 /** +484 * Creates a column {@link BigMatrix} using the data from the input +485 * array. +486 * +487 * @param columnData the input column data +488 * @return a columnData x 1 BigMatrix +489 * @throws IllegalArgumentException if <code>columnData</code> is empty +490 * @throws NullPointerException if <code>columnData</code>is null +491 * @deprecated since 2.0 replaced by {@link #createColumnFieldMatrix(FieldElement[])} +492 */ +493 @Deprecated +494 public static BigMatrix createColumnBigMatrix(BigDecimal[] columnData) { +495 final int nRows = columnData.length; +496 final BigDecimal[][] data = new BigDecimal[nRows][1]; +497 for (int row = 0; row < nRows; row++) { +498 data[row][0] = columnData[row]; +499 } +500 return new BigMatrixImpl(data, false); +501 } +502 +503 /** +504 * Creates a column {@link BigMatrix} using the data from the input +505 * array. +506 * +507 * @param columnData the input column data +508 * @return a columnData x 1 BigMatrix +509 * @throws IllegalArgumentException if <code>columnData</code> is empty +510 * @throws NullPointerException if <code>columnData</code>is null +511 * @deprecated since 2.0 replaced by {@link #createColumnFieldMatrix(FieldElement[])} +512 */ +513 @Deprecated +514 public static BigMatrix createColumnBigMatrix(String[] columnData) { +515 int nRows = columnData.length; +516 final BigDecimal[][] data = new BigDecimal[nRows][1]; +517 for (int row = 0; row < nRows; row++) { +518 data[row][0] = new BigDecimal(columnData[row]); +519 } +520 return new BigMatrixImpl(data, false); +521 } +522 +523 /** +524 * Check if a row index is valid. +525 * @param m matrix containing the submatrix +526 * @param row row index to check +527 * @exception MatrixIndexException if index is not valid +528 */ +529 public static void checkRowIndex(final AnyMatrix m, final int row) { +530 if (row < 0 || row >= m.getRowDimension()) { +531 throw new MatrixIndexException("row index {0} out of allowed range [{1}, {2}]", +532 row, 0, m.getRowDimension() - 1); +533 } +534 } +535 +536 /** +537 * Check if a column index is valid. +538 * @param m matrix containing the submatrix +539 * @param column column index to check +540 * @exception MatrixIndexException if index is not valid +541 */ +542 public static void checkColumnIndex(final AnyMatrix m, final int column) +543 throws MatrixIndexException { +544 if (column < 0 || column >= m.getColumnDimension()) { +545 throw new MatrixIndexException("column index {0} out of allowed range [{1}, {2}]", +546 column, 0, m.getColumnDimension() - 1); +547 } +548 } +549 +550 /** +551 * Check if submatrix ranges indices are valid. +552 * Rows and columns are indicated counting from 0 to n-1. +553 * +554 * @param m matrix containing the submatrix +555 * @param startRow Initial row index +556 * @param endRow Final row index +557 * @param startColumn Initial column index +558 * @param endColumn Final column index +559 * @exception MatrixIndexException if the indices are not valid +560 */ +561 public static void checkSubMatrixIndex(final AnyMatrix m, +562 final int startRow, final int endRow, +563 final int startColumn, final int endColumn) { +564 checkRowIndex(m, startRow); +565 checkRowIndex(m, endRow); +566 if (startRow > endRow) { +567 throw new MatrixIndexException("initial row {0} after final row {1}", +568 startRow, endRow); +569 } +570 +571 checkColumnIndex(m, startColumn); +572 checkColumnIndex(m, endColumn); +573 if (startColumn > endColumn) { +574 throw new MatrixIndexException("initial column {0} after final column {1}", +575 startColumn, endColumn); +576 } +577 +578 +579 } +580 +581 /** +582 * Check if submatrix ranges indices are valid. +583 * Rows and columns are indicated counting from 0 to n-1. +584 * +585 * @param m matrix containing the submatrix +586 * @param selectedRows Array of row indices. +587 * @param selectedColumns Array of column indices. +588 * @exception MatrixIndexException if row or column selections are not valid +589 */ +590 public static void checkSubMatrixIndex(final AnyMatrix m, +591 final int[] selectedRows, final int[] selectedColumns) +592 throws MatrixIndexException { +593 if (selectedRows.length * selectedColumns.length == 0) { +594 if (selectedRows.length == 0) { +595 throw new MatrixIndexException("empty selected row index array"); +596 } +597 throw new MatrixIndexException("empty selected column index array"); +598 } +599 +600 for (final int row : selectedRows) { +601 checkRowIndex(m, row); +602 } +603 for (final int column : selectedColumns) { +604 checkColumnIndex(m, column); +605 } +606 } +607 +608 /** +609 * Check if matrices are addition compatible +610 * @param left left hand side matrix +611 * @param right right hand side matrix +612 * @exception IllegalArgumentException if matrices are not addition compatible +613 */ +614 public static void checkAdditionCompatible(final AnyMatrix left, final AnyMatrix right) +615 throws IllegalArgumentException { +616 if ((left.getRowDimension() != right.getRowDimension()) || +617 (left.getColumnDimension() != right.getColumnDimension())) { +618 throw MathRuntimeException.createIllegalArgumentException( +619 "{0}x{1} and {2}x{3} matrices are not addition compatible", +620 left.getRowDimension(), left.getColumnDimension(), +621 right.getRowDimension(), right.getColumnDimension()); +622 } +623 } +624 +625 /** +626 * Check if matrices are subtraction compatible +627 * @param left left hand side matrix +628 * @param right right hand side matrix +629 * @exception IllegalArgumentException if matrices are not subtraction compatible +630 */ +631 public static void checkSubtractionCompatible(final AnyMatrix left, final AnyMatrix right) +632 throws IllegalArgumentException { +633 if ((left.getRowDimension() != right.getRowDimension()) || +634 (left.getColumnDimension() != right.getColumnDimension())) { +635 throw MathRuntimeException.createIllegalArgumentException( +636 "{0}x{1} and {2}x{3} matrices are not subtraction compatible", +637 left.getRowDimension(), left.getColumnDimension(), +638 right.getRowDimension(), right.getColumnDimension()); +639 } +640 } +641 +642 /** +643 * Check if matrices are multiplication compatible +644 * @param left left hand side matrix +645 * @param right right hand side matrix +646 * @exception IllegalArgumentException if matrices are not multiplication compatible +647 */ +648 public static void checkMultiplicationCompatible(final AnyMatrix left, final AnyMatrix right) +649 throws IllegalArgumentException { +650 if (left.getColumnDimension() != right.getRowDimension()) { +651 throw MathRuntimeException.createIllegalArgumentException( +652 "{0}x{1} and {2}x{3} matrices are not multiplication compatible", +653 left.getRowDimension(), left.getColumnDimension(), +654 right.getRowDimension(), right.getColumnDimension()); +655 } +656 } +657 +658 /** +659 * Convert a {@link FieldMatrix}/{@link Fraction} matrix to a {@link RealMatrix}. +660 * @param m matrix to convert +661 * @return converted matrix +662 */ +663 public static Array2DRowRealMatrix fractionMatrixToRealMatrix(final FieldMatrix<Fraction> m) { +664 final FractionMatrixConverter converter = new FractionMatrixConverter(); +665 m.walkInOptimizedOrder(converter); +666 return converter.getConvertedMatrix(); +667 } +668 +669 /** Converter for {@link FieldMatrix}/{@link Fraction}. */ +670 private static class FractionMatrixConverter extends DefaultFieldMatrixPreservingVisitor<Fraction> { +671 +672 /** Converted array. */ +673 private double[][] data; +674 +675 /** Simple constructor. */ +676 public FractionMatrixConverter() { +677 super(Fraction.ZERO); +678 } +679 +680 /** {@inheritDoc} */ +681 @Override +682 public void start(int rows, int columns, +683 int startRow, int endRow, int startColumn, int endColumn) { +684 data = new double[rows][columns]; +685 } +686 +687 /** {@inheritDoc} */ +688 @Override +689 public void visit(int row, int column, Fraction value) { +690 data[row][column] = value.doubleValue(); +691 } +692 +693 /** Get the converted matrix. +694 * @return converted matrix +695 */ +696 Array2DRowRealMatrix getConvertedMatrix() { +697 return new Array2DRowRealMatrix(data, false); +698 } +699 +700 } +701 +702 /** +703 * Convert a {@link FieldMatrix}/{@link BigFraction} matrix to a {@link RealMatrix}. +704 * @param m matrix to convert +705 * @return converted matrix +706 */ +707 public static Array2DRowRealMatrix bigFractionMatrixToRealMatrix(final FieldMatrix<BigFraction> m) { +708 final BigFractionMatrixConverter converter = new BigFractionMatrixConverter(); +709 m.walkInOptimizedOrder(converter); +710 return converter.getConvertedMatrix(); +711 } +712 +713 /** Converter for {@link FieldMatrix}/{@link BigFraction}. */ +714 private static class BigFractionMatrixConverter extends DefaultFieldMatrixPreservingVisitor<BigFraction> { +715 +716 /** Converted array. */ +717 private double[][] data; +718 +719 /** Simple constructor. */ +720 public BigFractionMatrixConverter() { +721 super(BigFraction.ZERO); +722 } +723 +724 /** {@inheritDoc} */ +725 @Override +726 public void start(int rows, int columns, +727 int startRow, int endRow, int startColumn, int endColumn) { +728 data = new double[rows][columns]; +729 } +730 +731 /** {@inheritDoc} */ +732 @Override +733 public void visit(int row, int column, BigFraction value) { +734 data[row][column] = value.doubleValue(); +735 } +736 +737 /** Get the converted matrix. +738 * @return converted matrix +739 */ +740 Array2DRowRealMatrix getConvertedMatrix() { +741 return new Array2DRowRealMatrix(data, false); +742 } +743 +744 } +745 +746 /** Serialize a {@link RealVector}. +747 * <p> +748 * This method is intended to be called from within a private +749 * <code>writeObject</code> method (after a call to +750 * <code>oos.defaultWriteObject()</code>) in a class that has a +751 * {@link RealVector} field, which should be declared <code>transient</code>. +752 * This way, the default handling does not serialize the vector (the {@link +753 * RealVector} interface is not serializable by default) but this method does +754 * serialize it specifically. +755 * </p> +756 * <p> +757 * The following example shows how a simple class with a name and a real vector +758 * should be written: +759 * <pre><code> +760 * public class NamedVector implements Serializable { +761 * +762 * private final String name; +763 * private final transient RealVector coefficients; +764 * +765 * // omitted constructors, getters ... +766 * +767 * private void writeObject(ObjectOutputStream oos) throws IOException { +768 * oos.defaultWriteObject(); // takes care of name field +769 * MatrixUtils.serializeRealVector(coefficients, oos); +770 * } +771 * +772 * private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { +773 * ois.defaultReadObject(); // takes care of name field +774 * MatrixUtils.deserializeRealVector(this, "coefficients", ois); +775 * } +776 * +777 * } +778 * </code></pre> +779 * </p> +780 * +781 * @param vector real vector to serialize +782 * @param oos stream where the real vector should be written +783 * @exception IOException if object cannot be written to stream +784 * @see #deserializeRealVector(Object, String, ObjectInputStream) +785 */ +786 public static void serializeRealVector(final RealVector vector, +787 final ObjectOutputStream oos) +788 throws IOException { +789 final int n = vector.getDimension(); +790 oos.writeInt(n); +791 for (int i = 0; i < n; ++i) { +792 oos.writeDouble(vector.getEntry(i)); +793 } +794 } +795 +796 /** Deserialize a {@link RealVector} field in a class. +797 * <p> +798 * This method is intended to be called from within a private +799 * <code>readObject</code> method (after a call to +800 * <code>ois.defaultReadObject()</code>) in a class that has a +801 * {@link RealVector} field, which should be declared <code>transient</code>. +802 * This way, the default handling does not deserialize the vector (the {@link +803 * RealVector} interface is not serializable by default) but this method does +804 * deserialize it specifically. +805 * </p> +806 * @param instance instance in which the field must be set up +807 * @param fieldName name of the field within the class (may be private and final) +808 * @param ois stream from which the real vector should be read +809 * @exception ClassNotFoundException if a class in the stream cannot be found +810 * @exception IOException if object cannot be read from the stream +811 * @see #serializeRealVector(RealVector, ObjectOutputStream) +812 */ +813 public static void deserializeRealVector(final Object instance, +814 final String fieldName, +815 final ObjectInputStream ois) +816 throws ClassNotFoundException, IOException { +817 try { +818 +819 // read the vector data +820 final int n = ois.readInt(); +821 final double[] data = new double[n]; +822 for (int i = 0; i < n; ++i) { +823 data[i] = ois.readDouble(); +824 } +825 +826 // create the instance +827 final RealVector vector = new ArrayRealVector(data, false); +828 +829 // set up the field +830 final java.lang.reflect.Field f = +831 instance.getClass().getDeclaredField(fieldName); +832 f.setAccessible(true); +833 f.set(instance, vector); +834 +835 } catch (NoSuchFieldException nsfe) { +836 IOException ioe = new IOException(); +837 ioe.initCause(nsfe); +838 throw ioe; +839 } catch (IllegalAccessException iae) { +840 IOException ioe = new IOException(); +841 ioe.initCause(iae); +842 throw ioe; +843 } +844 +845 } +846 +847 /** Serialize a {@link RealMatrix}. +848 * <p> +849 * This method is intended to be called from within a private +850 * <code>writeObject</code> method (after a call to +851 * <code>oos.defaultWriteObject()</code>) in a class that has a +852 * {@link RealMatrix} field, which should be declared <code>transient</code>. +853 * This way, the default handling does not serialize the matrix (the {@link +854 * RealMatrix} interface is not serializable by default) but this method does +855 * serialize it specifically. +856 * </p> +857 * <p> +858 * The following example shows how a simple class with a name and a real matrix +859 * should be written: +860 * <pre><code> +861 * public class NamedMatrix implements Serializable { +862 * +863 * private final String name; +864 * private final transient RealMatrix coefficients; +865 * +866 * // omitted constructors, getters ... +867 * +868 * private void writeObject(ObjectOutputStream oos) throws IOException { +869 * oos.defaultWriteObject(); // takes care of name field +870 * MatrixUtils.serializeRealMatrix(coefficients, oos); +871 * } +872 * +873 * private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { +874 * ois.defaultReadObject(); // takes care of name field +875 * MatrixUtils.deserializeRealMatrix(this, "coefficients", ois); +876 * } +877 * +878 * } +879 * </code></pre> +880 * </p> +881 * +882 * @param matrix real matrix to serialize +883 * @param oos stream where the real matrix should be written +884 * @exception IOException if object cannot be written to stream +885 * @see #deserializeRealMatrix(Object, String, ObjectInputStream) +886 */ +887 public static void serializeRealMatrix(final RealMatrix matrix, +888 final ObjectOutputStream oos) +889 throws IOException { +890 final int n = matrix.getRowDimension(); +891 final int m = matrix.getColumnDimension(); +892 oos.writeInt(n); +893 oos.writeInt(m); +894 for (int i = 0; i < n; ++i) { +895 for (int j = 0; j < m; ++j) { +896 oos.writeDouble(matrix.getEntry(i, j)); +897 } +898 } +899 } +900 +901 /** Deserialize a {@link RealMatrix} field in a class. +902 * <p> +903 * This method is intended to be called from within a private +904 * <code>readObject</code> method (after a call to +905 * <code>ois.defaultReadObject()</code>) in a class that has a +906 * {@link RealMatrix} field, which should be declared <code>transient</code>. +907 * This way, the default handling does not deserialize the matrix (the {@link +908 * RealMatrix} interface is not serializable by default) but this method does +909 * deserialize it specifically. +910 * </p> +911 * @param instance instance in which the field must be set up +912 * @param fieldName name of the field within the class (may be private and final) +913 * @param ois stream from which the real matrix should be read +914 * @exception ClassNotFoundException if a class in the stream cannot be found +915 * @exception IOException if object cannot be read from the stream +916 * @see #serializeRealMatrix(RealMatrix, ObjectOutputStream) +917 */ +918 public static void deserializeRealMatrix(final Object instance, +919 final String fieldName, +920 final ObjectInputStream ois) +921 throws ClassNotFoundException, IOException { +922 try { +923 +924 // read the matrix data +925 final int n = ois.readInt(); +926 final int m = ois.readInt(); +927 final double[][] data = new double[n][m]; +928 for (int i = 0; i < n; ++i) { +929 final double[] dataI = data[i]; +930 for (int j = 0; j < m; ++j) { +931 dataI[j] = ois.readDouble(); +932 } +933 } +934 +935 // create the instance +936 final RealMatrix matrix = new Array2DRowRealMatrix(data, false); +937 +938 // set up the field +939 final java.lang.reflect.Field f = +940 instance.getClass().getDeclaredField(fieldName); +941 f.setAccessible(true); +942 f.set(instance, matrix); +943 +944 } catch (NoSuchFieldException nsfe) { +945 IOException ioe = new IOException(); +946 ioe.initCause(nsfe); +947 throw ioe; +948 } catch (IllegalAccessException iae) { +949 IOException ioe = new IOException(); +950 ioe.initCause(iae); +951 throw ioe; +952 } +953 +954 } +955 +956 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/MatrixVisitorException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/MatrixVisitorException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,106 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.MathRuntimeException; +021 +022 /** +023 * Thrown when a visitor encounters an error while processing a matrix entry. +024 * @version $Revision: 729673 $ $Date: 2008-12-27 15:55:12 -0500 (Sat, 27 Dec 2008) $ +025 */ +026 public class MatrixVisitorException extends MathRuntimeException { +027 +028 /** Serializable version identifier */ +029 private static final long serialVersionUID = 3814333035048617048L; +030 +031 /** +032 * Constructs a new instance with specified formatted detail message. +033 * @param pattern format specifier +034 * @param arguments format arguments +035 */ +036 public MatrixVisitorException(final String pattern, final Object[] arguments) { +037 super(pattern, arguments); +038 } +039 +040 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/NonSquareMatrixException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/NonSquareMatrixException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,107 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 +021 /** +022 * Thrown when an operation defined only for square matrices is applied to non-square ones. +023 * @version $Revision: 799857 $ $Date: 2009-08-01 09:07:12 -0400 (Sat, 01 Aug 2009) $ +024 * @since 2.0 +025 */ +026 public class NonSquareMatrixException extends InvalidMatrixException { +027 +028 /** Serializable version identifier. */ +029 private static final long serialVersionUID = 8996207526636673730L; +030 +031 /** +032 * Construct an exception with the given message. +033 * @param rows number of rows of the faulty matrix +034 * @param columns number of columns of the faulty matrix +035 */ +036 public NonSquareMatrixException(final int rows, final int columns) { +037 super("a {0}x{1} matrix was provided instead of a square matrix", +038 rows, columns); +039 } +040 +041 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/NotPositiveDefiniteMatrixException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/NotPositiveDefiniteMatrixException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,108 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.MathException; +021 +022 /** +023 * This class represents exceptions thrown when a matrix expected to +024 * be positive definite is not. +025 * +026 * @since 1.2 +027 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +028 */ +029 +030 public class NotPositiveDefiniteMatrixException extends MathException { +031 +032 /** Serializable version identifier */ +033 private static final long serialVersionUID = 4122929125438624648L; +034 +035 /** Simple constructor. +036 * build an exception with a default message. +037 */ +038 public NotPositiveDefiniteMatrixException() { +039 super("not positive definite matrix"); +040 } +041 +042 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/NotSymmetricMatrixException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/NotSymmetricMatrixException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,108 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.MathException; +021 +022 /** +023 * This class represents exceptions thrown when a matrix expected to +024 * be symmetric is not +025 * +026 * @since 2.0 +027 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +028 */ +029 +030 public class NotSymmetricMatrixException extends MathException { +031 +032 /** Serializable version identifier */ +033 private static final long serialVersionUID = -7012803946709786097L; +034 +035 /** Simple constructor. +036 * build an exception with a default message. +037 */ +038 public NotSymmetricMatrixException() { +039 super("not symmetric matrix"); +040 } +041 +042 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/OpenMapRealMatrix.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/OpenMapRealMatrix.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,358 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.util.OpenIntToDoubleHashMap; +023 +024 /** +025 * Sparse matrix implementation based on an open addressed map. +026 * +027 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +028 * @since 2.0 +029 */ +030 public class OpenMapRealMatrix extends AbstractRealMatrix implements SparseRealMatrix, Serializable { +031 +032 /** Serializable version identifier. */ +033 private static final long serialVersionUID = -5962461716457143437L; +034 +035 /** Number of rows of the matrix. */ +036 private final int rows; +037 +038 /** Number of columns of the matrix. */ +039 private final int columns; +040 +041 /** Storage for (sparse) matrix elements. */ +042 private final OpenIntToDoubleHashMap entries; +043 +044 /** +045 * Build a sparse matrix with the supplied row and column dimensions. +046 * @param rowDimension number of rows of the matrix +047 * @param columnDimension number of columns of the matrix +048 */ +049 public OpenMapRealMatrix(int rowDimension, int columnDimension) { +050 super(rowDimension, columnDimension); +051 this.rows = rowDimension; +052 this.columns = columnDimension; +053 this.entries = new OpenIntToDoubleHashMap(0.0); +054 } +055 +056 /** +057 * Build a matrix by copying another one. +058 * @param matrix matrix to copy +059 */ +060 public OpenMapRealMatrix(OpenMapRealMatrix matrix) { +061 this.rows = matrix.rows; +062 this.columns = matrix.columns; +063 this.entries = new OpenIntToDoubleHashMap(matrix.entries); +064 } +065 +066 /** {@inheritDoc} */ +067 @Override +068 public OpenMapRealMatrix copy() { +069 return new OpenMapRealMatrix(this); +070 } +071 +072 /** {@inheritDoc} */ +073 @Override +074 public OpenMapRealMatrix createMatrix(int rowDimension, int columnDimension) +075 throws IllegalArgumentException { +076 return new OpenMapRealMatrix(rowDimension, columnDimension); +077 } +078 +079 /** {@inheritDoc} */ +080 @Override +081 public int getColumnDimension() { +082 return columns; +083 } +084 +085 /** {@inheritDoc} */ +086 @Override +087 public OpenMapRealMatrix add(final RealMatrix m) +088 throws IllegalArgumentException { +089 try { +090 return add((OpenMapRealMatrix) m); +091 } catch (ClassCastException cce) { +092 return (OpenMapRealMatrix) super.add(m); +093 } +094 } +095 +096 /** +097 * Compute the sum of this and <code>m</code>. +098 * +099 * @param m matrix to be added +100 * @return this + m +101 * @throws IllegalArgumentException if m is not the same size as this +102 */ +103 public OpenMapRealMatrix add(OpenMapRealMatrix m) throws IllegalArgumentException { +104 +105 // safety check +106 MatrixUtils.checkAdditionCompatible(this, m); +107 +108 final OpenMapRealMatrix out = new OpenMapRealMatrix(this); +109 for (OpenIntToDoubleHashMap.Iterator iterator = m.entries.iterator(); iterator.hasNext();) { +110 iterator.advance(); +111 final int row = iterator.key() / columns; +112 final int col = iterator.key() - row * columns; +113 out.setEntry(row, col, getEntry(row, col) + iterator.value()); +114 } +115 +116 return out; +117 +118 } +119 +120 /** {@inheritDoc} */ +121 @Override +122 public OpenMapRealMatrix subtract(final RealMatrix m) +123 throws IllegalArgumentException { +124 try { +125 return subtract((OpenMapRealMatrix) m); +126 } catch (ClassCastException cce) { +127 return (OpenMapRealMatrix) super.subtract(m); +128 } +129 } +130 +131 /** +132 * Compute this minus <code>m</code>. +133 * +134 * @param m matrix to be subtracted +135 * @return this - m +136 * @throws IllegalArgumentException if m is not the same size as this +137 */ +138 public OpenMapRealMatrix subtract(OpenMapRealMatrix m) throws IllegalArgumentException { +139 +140 // safety check +141 MatrixUtils.checkAdditionCompatible(this, m); +142 +143 final OpenMapRealMatrix out = new OpenMapRealMatrix(this); +144 for (OpenIntToDoubleHashMap.Iterator iterator = m.entries.iterator(); iterator.hasNext();) { +145 iterator.advance(); +146 final int row = iterator.key() / columns; +147 final int col = iterator.key() - row * columns; +148 out.setEntry(row, col, getEntry(row, col) - iterator.value()); +149 } +150 +151 return out; +152 +153 } +154 +155 /** {@inheritDoc} */ +156 @Override +157 public RealMatrix multiply(final RealMatrix m) +158 throws IllegalArgumentException { +159 try { +160 return multiply((OpenMapRealMatrix) m); +161 } catch (ClassCastException cce) { +162 +163 // safety check +164 MatrixUtils.checkMultiplicationCompatible(this, m); +165 +166 final int outCols = m.getColumnDimension(); +167 final BlockRealMatrix out = new BlockRealMatrix(rows, outCols); +168 for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.hasNext();) { +169 iterator.advance(); +170 final double value = iterator.value(); +171 final int key = iterator.key(); +172 final int i = key / columns; +173 final int k = key % columns; +174 for (int j = 0; j < outCols; ++j) { +175 out.addToEntry(i, j, value * m.getEntry(k, j)); +176 } +177 } +178 +179 return out; +180 +181 } +182 } +183 +184 /** +185 * Returns the result of postmultiplying this by m. +186 * +187 * @param m matrix to postmultiply by +188 * @return this * m +189 * @throws IllegalArgumentException +190 * if columnDimension(this) != rowDimension(m) +191 */ +192 public OpenMapRealMatrix multiply(OpenMapRealMatrix m) throws IllegalArgumentException { +193 +194 // safety check +195 MatrixUtils.checkMultiplicationCompatible(this, m); +196 +197 final int outCols = m.getColumnDimension(); +198 OpenMapRealMatrix out = new OpenMapRealMatrix(rows, outCols); +199 for (OpenIntToDoubleHashMap.Iterator iterator = entries.iterator(); iterator.hasNext();) { +200 iterator.advance(); +201 final double value = iterator.value(); +202 final int key = iterator.key(); +203 final int i = key / columns; +204 final int k = key % columns; +205 for (int j = 0; j < outCols; ++j) { +206 final int rightKey = m.computeKey(k, j); +207 if (m.entries.containsKey(rightKey)) { +208 final int outKey = out.computeKey(i, j); +209 final double outValue = +210 out.entries.get(outKey) + value * m.entries.get(rightKey); +211 if (outValue == 0.0) { +212 out.entries.remove(outKey); +213 } else { +214 out.entries.put(outKey, outValue); +215 } +216 } +217 } +218 } +219 +220 return out; +221 +222 } +223 +224 /** {@inheritDoc} */ +225 @Override +226 public double getEntry(int row, int column) throws MatrixIndexException { +227 MatrixUtils.checkRowIndex(this, row); +228 MatrixUtils.checkColumnIndex(this, column); +229 return entries.get(computeKey(row, column)); +230 } +231 +232 /** {@inheritDoc} */ +233 @Override +234 public int getRowDimension() { +235 return rows; +236 } +237 +238 /** {@inheritDoc} */ +239 @Override +240 public void setEntry(int row, int column, double value) +241 throws MatrixIndexException { +242 MatrixUtils.checkRowIndex(this, row); +243 MatrixUtils.checkColumnIndex(this, column); +244 if (value == 0.0) { +245 entries.remove(computeKey(row, column)); +246 } else { +247 entries.put(computeKey(row, column), value); +248 } +249 } +250 +251 /** {@inheritDoc} */ +252 @Override +253 public void addToEntry(int row, int column, double increment) +254 throws MatrixIndexException { +255 MatrixUtils.checkRowIndex(this, row); +256 MatrixUtils.checkColumnIndex(this, column); +257 final int key = computeKey(row, column); +258 final double value = entries.get(key) + increment; +259 if (value == 0.0) { +260 entries.remove(key); +261 } else { +262 entries.put(key, value); +263 } +264 } +265 +266 /** {@inheritDoc} */ +267 @Override +268 public void multiplyEntry(int row, int column, double factor) +269 throws MatrixIndexException { +270 MatrixUtils.checkRowIndex(this, row); +271 MatrixUtils.checkColumnIndex(this, column); +272 final int key = computeKey(row, column); +273 final double value = entries.get(key) * factor; +274 if (value == 0.0) { +275 entries.remove(key); +276 } else { +277 entries.put(key, value); +278 } +279 } +280 +281 /** +282 * Compute the key to access a matrix element +283 * @param row row index of the matrix element +284 * @param column column index of the matrix element +285 * @return key within the map to access the matrix element +286 */ +287 private int computeKey(int row, int column) { +288 return row * columns + column; +289 } +290 +291 +292 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/OpenMapRealVector.OpenMapEntry.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/OpenMapRealVector.OpenMapEntry.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,968 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.linear; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.util.OpenIntToDoubleHashMap; +023 import org.apache.commons.math.util.OpenIntToDoubleHashMap.Iterator; +024 +025 /** +026 * This class implements the {@link RealVector} interface with a {@link OpenIntToDoubleHashMap} backing store. +027 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +028 * @since 2.0 +029 */ +030 public class OpenMapRealVector extends AbstractRealVector implements SparseRealVector, Serializable { +031 +032 /** Default Tolerance for having a value considered zero. */ +033 public static final double DEFAULT_ZERO_TOLERANCE = 1.0e-12; +034 +035 /** Serializable version identifier. */ +036 private static final long serialVersionUID = 8772222695580707260L; +037 +038 /** Entries of the vector. */ +039 private final OpenIntToDoubleHashMap entries; +040 +041 /** Dimension of the vector. */ +042 private final int virtualSize; +043 +044 /** Tolerance for having a value considered zero. */ +045 private double epsilon; +046 +047 /** +048 * Build a 0-length vector. +049 * <p>Zero-length vectors may be used to initialized construction of vectors +050 * by data gathering. We start with zero-length and use either the {@link +051 * #OpenMapRealVector(OpenMapRealVector, int)} constructor +052 * or one of the <code>append</code> method ({@link #append(double)}, {@link +053 * #append(double[])}, {@link #append(RealVector)}) to gather data +054 * into this vector.</p> +055 */ +056 public OpenMapRealVector() { +057 this(0, DEFAULT_ZERO_TOLERANCE); +058 } +059 +060 /** +061 * Construct a (dimension)-length vector of zeros. +062 * @param dimension size of the vector +063 */ +064 public OpenMapRealVector(int dimension) { +065 this(dimension, DEFAULT_ZERO_TOLERANCE); +066 } +067 +068 /** +069 * Construct a (dimension)-length vector of zeros, specifying zero tolerance. +070 * @param dimension Size of the vector +071 * @param epsilon The tolerance for having a value considered zero +072 */ +073 public OpenMapRealVector(int dimension, double epsilon) { +074 virtualSize = dimension; +075 entries = new OpenIntToDoubleHashMap(0.0); +076 this.epsilon = epsilon; +077 } +078 +079 /** +080 * Build a resized vector, for use with append. +081 * @param v The original vector +082 * @param resize The amount to resize it +083 */ +084 protected OpenMapRealVector(OpenMapRealVector v, int resize) { +085 virtualSize = v.getDimension() + resize; +086 entries = new OpenIntToDoubleHashMap(v.entries); +087 epsilon = v.epsilon; +088 } +089 +090 /** +091 * Build a vector with known the sparseness (for advanced use only). +092 * @param dimension The size of the vector +093 * @param expectedSize The expected number of non-zero entries +094 */ +095 public OpenMapRealVector(int dimension, int expectedSize) { +096 this(dimension, expectedSize, DEFAULT_ZERO_TOLERANCE); +097 } +098 +099 /** +100 * Build a vector with known the sparseness and zero tolerance setting (for advanced use only). +101 * @param dimension The size of the vector +102 * @param expectedSize The expected number of non-zero entries +103 * @param epsilon The tolerance for having a value considered zero +104 */ +105 public OpenMapRealVector(int dimension, int expectedSize, double epsilon) { +106 virtualSize = dimension; +107 entries = new OpenIntToDoubleHashMap(expectedSize, 0.0); +108 this.epsilon = epsilon; +109 } +110 +111 /** +112 * Create from a double array. +113 * Only non-zero entries will be stored +114 * @param values The set of values to create from +115 */ +116 public OpenMapRealVector(double[] values) { +117 this(values, DEFAULT_ZERO_TOLERANCE); +118 } +119 +120 /** +121 * Create from a double array, specifying zero tolerance. +122 * Only non-zero entries will be stored +123 * @param values The set of values to create from +124 * @param epsilon The tolerance for having a value considered zero +125 */ +126 public OpenMapRealVector(double[] values, double epsilon) { +127 virtualSize = values.length; +128 entries = new OpenIntToDoubleHashMap(0.0); +129 this.epsilon = epsilon; +130 for (int key = 0; key < values.length; key++) { +131 double value = values[key]; +132 if (!isDefaultValue(value)) { +133 entries.put(key, value); +134 } +135 } +136 } +137 +138 /** +139 * Create from a Double array. +140 * Only non-zero entries will be stored +141 * @param values The set of values to create from +142 */ +143 public OpenMapRealVector(Double[] values) { +144 this(values, DEFAULT_ZERO_TOLERANCE); +145 } +146 +147 /** +148 * Create from a Double array. +149 * Only non-zero entries will be stored +150 * @param values The set of values to create from +151 * @param epsilon The tolerance for having a value considered zero +152 */ +153 public OpenMapRealVector(Double[] values, double epsilon) { +154 virtualSize = values.length; +155 entries = new OpenIntToDoubleHashMap(0.0); +156 this.epsilon = epsilon; +157 for (int key = 0; key < values.length; key++) { +158 double value = values[key].doubleValue(); +159 if (!isDefaultValue(value)) { +160 entries.put(key, value); +161 } +162 } +163 } +164 +165 /** +166 * Copy constructor. +167 * @param v The instance to copy from +168 */ +169 public OpenMapRealVector(OpenMapRealVector v) { +170 virtualSize = v.getDimension(); +171 entries = new OpenIntToDoubleHashMap(v.getEntries()); +172 epsilon = v.epsilon; +173 } +174 +175 /** +176 * Generic copy constructor. +177 * @param v The instance to copy from +178 */ +179 public OpenMapRealVector(RealVector v) { +180 virtualSize = v.getDimension(); +181 entries = new OpenIntToDoubleHashMap(0.0); +182 epsilon = DEFAULT_ZERO_TOLERANCE; +183 for (int key = 0; key < virtualSize; key++) { +184 double value = v.getEntry(key); +185 if (!isDefaultValue(value)) { +186 entries.put(key, value); +187 } +188 } +189 } +190 +191 /** +192 * Get the entries of this instance. +193 * @return entries of this instance +194 */ +195 private OpenIntToDoubleHashMap getEntries() { +196 return entries; +197 } +198 +199 /** +200 * Determine if this value is within epsilon of zero. +201 * @param value The value to test +202 * @return <code>true</code> if this value is within epsilon to zero, <code>false</code> otherwise +203 * @since 2.1 +204 */ +205 protected boolean isDefaultValue(double value) { +206 return Math.abs(value) < epsilon; +207 } +208 +209 /** {@inheritDoc} */ +210 @Override +211 public RealVector add(RealVector v) throws IllegalArgumentException { +212 checkVectorDimensions(v.getDimension()); +213 if (v instanceof OpenMapRealVector) { +214 return add((OpenMapRealVector) v); +215 } else { +216 return super.add(v); +217 } +218 } +219 +220 /** +221 * Optimized method to add two OpenMapRealVectors. Copies the larger vector, iterates over the smaller. +222 * @param v Vector to add with +223 * @return The sum of <code>this</code> with <code>v</code> +224 * @throws IllegalArgumentException If the dimensions don't match +225 */ +226 public OpenMapRealVector add(OpenMapRealVector v) throws IllegalArgumentException{ +227 checkVectorDimensions(v.getDimension()); +228 boolean copyThis = entries.size() > v.entries.size(); +229 OpenMapRealVector res = copyThis ? this.copy() : v.copy(); +230 Iterator iter = copyThis ? v.entries.iterator() : entries.iterator(); +231 OpenIntToDoubleHashMap randomAccess = copyThis ? entries : v.entries; +232 while (iter.hasNext()) { +233 iter.advance(); +234 int key = iter.key(); +235 if (randomAccess.containsKey(key)) { +236 res.setEntry(key, randomAccess.get(key) + iter.value()); +237 } else { +238 res.setEntry(key, iter.value()); +239 } +240 } +241 return res; +242 } +243 +244 /** +245 * Optimized method to append a OpenMapRealVector. +246 * @param v vector to append +247 * @return The result of appending <code>v</code> to self +248 */ +249 public OpenMapRealVector append(OpenMapRealVector v) { +250 OpenMapRealVector res = new OpenMapRealVector(this, v.getDimension()); +251 Iterator iter = v.entries.iterator(); +252 while (iter.hasNext()) { +253 iter.advance(); +254 res.setEntry(iter.key() + virtualSize, iter.value()); +255 } +256 return res; +257 } +258 +259 /** {@inheritDoc} */ +260 public OpenMapRealVector append(RealVector v) { +261 if (v instanceof OpenMapRealVector) { +262 return append((OpenMapRealVector) v); +263 } +264 return append(v.getData()); +265 } +266 +267 /** {@inheritDoc} */ +268 public OpenMapRealVector append(double d) { +269 OpenMapRealVector res = new OpenMapRealVector(this, 1); +270 res.setEntry(virtualSize, d); +271 return res; +272 } +273 +274 /** {@inheritDoc} */ +275 public OpenMapRealVector append(double[] a) { +276 OpenMapRealVector res = new OpenMapRealVector(this, a.length); +277 for (int i = 0; i < a.length; i++) { +278 res.setEntry(i + virtualSize, a[i]); +279 } +280 return res; +281 } +282 +283 /** +284 * {@inheritDoc} +285 * @since 2.1 +286 */ +287 @Override +288 public OpenMapRealVector copy() { +289 return new OpenMapRealVector(this); +290 } +291 +292 /** +293 * Optimized method to compute the dot product with an OpenMapRealVector. +294 * Iterates over the smaller of the two. +295 * @param v The vector to compute the dot product with +296 * @return The dot product of <code>this</code> and <code>v</code> +297 * @throws IllegalArgumentException If the dimensions don't match +298 */ +299 public double dotProduct(OpenMapRealVector v) throws IllegalArgumentException { +300 checkVectorDimensions(v.getDimension()); +301 boolean thisIsSmaller = entries.size() < v.entries.size(); +302 Iterator iter = thisIsSmaller ? entries.iterator() : v.entries.iterator(); +303 OpenIntToDoubleHashMap larger = thisIsSmaller ? v.entries : entries; +304 double d = 0; +305 while(iter.hasNext()) { +306 iter.advance(); +307 d += iter.value() * larger.get(iter.key()); +308 } +309 return d; +310 } +311 +312 /** {@inheritDoc} */ +313 @Override +314 public double dotProduct(RealVector v) throws IllegalArgumentException { +315 if(v instanceof OpenMapRealVector) { +316 return dotProduct((OpenMapRealVector)v); +317 } else { +318 return super.dotProduct(v); +319 } +320 } +321 +322 /** {@inheritDoc} */ +323 public OpenMapRealVector ebeDivide(RealVector v) throws IllegalArgumentException { +324 checkVectorDimensions(v.getDimension()); +325 OpenMapRealVector res = new OpenMapRealVector(this); +326 Iterator iter = res.entries.iterator(); +327 while (iter.hasNext()) { +328 iter.advance(); +329 res.setEntry(iter.key(), iter.value() / v.getEntry(iter.key())); +330 } +331 return res; +332 } +333 +334 /** {@inheritDoc} */ +335 @Override +336 public OpenMapRealVector ebeDivide(double[] v) throws IllegalArgumentException { +337 checkVectorDimensions(v.length); +338 OpenMapRealVector res = new OpenMapRealVector(this); +339 Iterator iter = res.entries.iterator(); +340 while (iter.hasNext()) { +341 iter.advance(); +342 res.setEntry(iter.key(), iter.value() / v[iter.key()]); +343 } +344 return res; +345 } +346 +347 /** {@inheritDoc} */ +348 public OpenMapRealVector ebeMultiply(RealVector v) throws IllegalArgumentException { +349 checkVectorDimensions(v.getDimension()); +350 OpenMapRealVector res = new OpenMapRealVector(this); +351 Iterator iter = res.entries.iterator(); +352 while (iter.hasNext()) { +353 iter.advance(); +354 res.setEntry(iter.key(), iter.value() * v.getEntry(iter.key())); +355 } +356 return res; +357 } +358 +359 /** {@inheritDoc} */ +360 @Override +361 public OpenMapRealVector ebeMultiply(double[] v) throws IllegalArgumentException { +362 checkVectorDimensions(v.length); +363 OpenMapRealVector res = new OpenMapRealVector(this); +364 Iterator iter = res.entries.iterator(); +365 while (iter.hasNext()) { +366 iter.advance(); +367 res.setEntry(iter.key(), iter.value() * v[iter.key()]); +368 } +369 return res; +370 } +371 +372 /** {@inheritDoc} */ +373 public OpenMapRealVector getSubVector(int index, int n) throws MatrixIndexException { +374 checkIndex(index); +375 checkIndex(index + n - 1); +376 OpenMapRealVector res = new OpenMapRealVector(n); +377 int end = index + n; +378 Iterator iter = entries.iterator(); +379 while (iter.hasNext()) { +380 iter.advance(); +381 int key = iter.key(); +382 if (key >= index && key < end) { +383 res.setEntry(key - index, iter.value()); +384 } +385 } +386 return res; +387 } +388 +389 /** {@inheritDoc} */ +390 @Override +391 public double[] getData() { +392 double[] res = new double[virtualSize]; +393 Iterator iter = entries.iterator(); +394 while (iter.hasNext()) { +395 iter.advance(); +396 res[iter.key()] = iter.value(); +397 } +398 return res; +399 } +400 +401 /** {@inheritDoc} */ +402 public int getDimension() { +403 return virtualSize; +404 } +405 +406 /** +407 * Optimized method to compute distance. +408 * @param v The vector to compute distance to +409 * @return The distance from <code>this</code> and <code>v</code> +410 * @throws IllegalArgumentException If the dimensions don't match +411 */ +412 public double getDistance(OpenMapRealVector v) throws IllegalArgumentException { +413 Iterator iter = entries.iterator(); +414 double res = 0; +415 while (iter.hasNext()) { +416 iter.advance(); +417 int key = iter.key(); +418 double delta; +419 delta = iter.value() - v.getEntry(key); +420 res += delta * delta; +421 } +422 iter = v.getEntries().iterator(); +423 while (iter.hasNext()) { +424 iter.advance(); +425 int key = iter.key(); +426 if (!entries.containsKey(key)) { +427 final double value = iter.value(); +428 res += value * value; +429 } +430 } +431 return Math.sqrt(res); +432 } +433 +434 /** {@inheritDoc} */ +435 @Override +436 public double getDistance(RealVector v) throws IllegalArgumentException { +437 checkVectorDimensions(v.getDimension()); +438 if (v instanceof OpenMapRealVector) { +439 return getDistance((OpenMapRealVector) v); +440 } +441 return getDistance(v.getData()); +442 } +443 +444 /** {@inheritDoc} */ +445 @Override +446 public double getDistance(double[] v) throws IllegalArgumentException { +447 checkVectorDimensions(v.length); +448 double res = 0; +449 for (int i = 0; i < v.length; i++) { +450 double delta = entries.get(i) - v[i]; +451 res += delta * delta; +452 } +453 return Math.sqrt(res); +454 } +455 +456 /** {@inheritDoc} */ +457 public double getEntry(int index) throws MatrixIndexException { +458 checkIndex(index); +459 return entries.get(index); +460 } +461 +462 /** +463 * Distance between two vectors. +464 * <p>This method computes the distance consistent with +465 * L<sub>1</sub> norm, i.e. the sum of the absolute values of +466 * elements differences.</p> +467 * @param v vector to which distance is requested +468 * @return distance between two vectors. +469 */ +470 public double getL1Distance(OpenMapRealVector v) { +471 double max = 0; +472 Iterator iter = entries.iterator(); +473 while (iter.hasNext()) { +474 iter.advance(); +475 double delta = Math.abs(iter.value() - v.getEntry(iter.key())); +476 max += delta; +477 } +478 iter = v.getEntries().iterator(); +479 while (iter.hasNext()) { +480 iter.advance(); +481 int key = iter.key(); +482 if (!entries.containsKey(key)) { +483 double delta = Math.abs(iter.value()); +484 max += Math.abs(delta); +485 } +486 } +487 return max; +488 } +489 +490 /** {@inheritDoc} */ +491 @Override +492 public double getL1Distance(RealVector v) throws IllegalArgumentException { +493 checkVectorDimensions(v.getDimension()); +494 if (v instanceof OpenMapRealVector) { +495 return getL1Distance((OpenMapRealVector) v); +496 } +497 return getL1Distance(v.getData()); +498 } +499 +500 /** {@inheritDoc} */ +501 @Override +502 public double getL1Distance(double[] v) throws IllegalArgumentException { +503 checkVectorDimensions(v.length); +504 double max = 0; +505 for (int i = 0; i < v.length; i++) { +506 double delta = Math.abs(getEntry(i) - v[i]); +507 max += delta; +508 } +509 return max; +510 } +511 +512 /** +513 * Optimized method to compute LInfDistance. +514 * @param v The vector to compute from +515 * @return the LInfDistance +516 */ +517 private double getLInfDistance(OpenMapRealVector v) { +518 double max = 0; +519 Iterator iter = entries.iterator(); +520 while (iter.hasNext()) { +521 iter.advance(); +522 double delta = Math.abs(iter.value() - v.getEntry(iter.key())); +523 if (delta > max) { +524 max = delta; +525 } +526 } +527 iter = v.getEntries().iterator(); +528 while (iter.hasNext()) { +529 iter.advance(); +530 int key = iter.key(); +531 if (!entries.containsKey(key)) { +532 if (iter.value() > max) { +533 max = iter.value(); +534 } +535 } +536 } +537 return max; +538 } +539 +540 /** {@inheritDoc} */ +541 @Override +542 public double getLInfDistance(RealVector v) throws IllegalArgumentException { +543 checkVectorDimensions(v.getDimension()); +544 if (v instanceof OpenMapRealVector) { +545 return getLInfDistance((OpenMapRealVector) v); +546 } +547 return getLInfDistance(v.getData()); +548 } +549 +550 /** {@inheritDoc} */ +551 @Override +552 public double getLInfDistance(double[] v) throws IllegalArgumentException { +553 checkVectorDimensions(v.length); +554 double max = 0; +555 for (int i = 0; i < v.length; i++) { +556 double delta = Math.abs(getEntry(i) - v[i]); +557 if (delta > max) { +558 max = delta; +559 } +560 } +561 return max; +562 } +563 +564 /** {@inheritDoc} */ +565 public boolean isInfinite() { +566 boolean infiniteFound = false; +567 Iterator iter = entries.iterator(); +568 while (iter.hasNext()) { +569 iter.advance(); +570 final double value = iter.value(); +571 if (Double.isNaN(value)) { +572 return false; +573 } +574 if (Double.isInfinite(value)) { +575 infiniteFound = true; +576 } +577 } +578 return infiniteFound; +579 } +580 +581 /** {@inheritDoc} */ +582 public boolean isNaN() { +583 Iterator iter = entries.iterator(); +584 while (iter.hasNext()) { +585 iter.advance(); +586 if (Double.isNaN(iter.value())) { +587 return true; +588 } +589 } +590 return false; +591 } +592 +593 /** {@inheritDoc} */ +594 @Override +595 public OpenMapRealVector mapAdd(double d) { +596 return copy().mapAddToSelf(d); +597 } +598 +599 /** {@inheritDoc} */ +600 @Override +601 public OpenMapRealVector mapAddToSelf(double d) { +602 for (int i = 0; i < virtualSize; i++) { +603 setEntry(i, getEntry(i) + d); +604 } +605 return this; +606 } +607 +608 /** {@inheritDoc} */ +609 @Override +610 public RealMatrix outerProduct(double[] v) throws IllegalArgumentException { +611 checkVectorDimensions(v.length); +612 RealMatrix res = new OpenMapRealMatrix(virtualSize, virtualSize); +613 Iterator iter = entries.iterator(); +614 while (iter.hasNext()) { +615 iter.advance(); +616 int row = iter.key(); +617 double value = iter.value(); +618 for (int col = 0; col < virtualSize; col++) { +619 res.setEntry(row, col, value * v[col]); +620 } +621 } +622 return res; +623 } +624 +625 /** {@inheritDoc} */ +626 public RealVector projection(RealVector v) throws IllegalArgumentException { +627 checkVectorDimensions(v.getDimension()); +628 return v.mapMultiply(dotProduct(v) / v.dotProduct(v)); +629 } +630 +631 /** {@inheritDoc} */ +632 @Override +633 public OpenMapRealVector projection(double[] v) throws IllegalArgumentException { +634 checkVectorDimensions(v.length); +635 return (OpenMapRealVector) projection(new OpenMapRealVector(v)); +636 } +637 +638 /** {@inheritDoc} */ +639 public void setEntry(int index, double value) throws MatrixIndexException { +640 checkIndex(index); +641 if (!isDefaultValue(value)) { +642 entries.put(index, value); +643 } else if (entries.containsKey(index)) { +644 entries.remove(index); +645 } +646 } +647 +648 /** {@inheritDoc} */ +649 @Override +650 public void setSubVector(int index, RealVector v) throws MatrixIndexException { +651 checkIndex(index); +652 checkIndex(index + v.getDimension() - 1); +653 setSubVector(index, v.getData()); +654 } +655 +656 /** {@inheritDoc} */ +657 @Override +658 public void setSubVector(int index, double[] v) throws MatrixIndexException { +659 checkIndex(index); +660 checkIndex(index + v.length - 1); +661 for (int i = 0; i < v.length; i++) { +662 setEntry(i + index, v[i]); +663 } +664 } +665 +666 /** {@inheritDoc} */ +667 @Override +668 public void set(double value) { +669 for (int i = 0; i < virtualSize; i++) { +670 setEntry(i, value); +671 } +672 } +673 +674 /** +675 * Optimized method to subtract OpenMapRealVectors. +676 * @param v The vector to subtract from <code>this</code> +677 * @return The difference of <code>this</code> and <code>v</code> +678 * @throws IllegalArgumentException If the dimensions don't match +679 */ +680 public OpenMapRealVector subtract(OpenMapRealVector v) throws IllegalArgumentException{ +681 checkVectorDimensions(v.getDimension()); +682 OpenMapRealVector res = copy(); +683 Iterator iter = v.getEntries().iterator(); +684 while (iter.hasNext()) { +685 iter.advance(); +686 int key = iter.key(); +687 if (entries.containsKey(key)) { +688 res.setEntry(key, entries.get(key) - iter.value()); +689 } else { +690 res.setEntry(key, -iter.value()); +691 } +692 } +693 return res; +694 } +695 +696 /** {@inheritDoc} */ +697 @Override +698 public OpenMapRealVector subtract(RealVector v) throws IllegalArgumentException { +699 checkVectorDimensions(v.getDimension()); +700 if (v instanceof OpenMapRealVector) { +701 return subtract((OpenMapRealVector) v); +702 } +703 return subtract(v.getData()); +704 } +705 +706 /** {@inheritDoc} */ +707 @Override +708 public OpenMapRealVector subtract(double[] v) throws IllegalArgumentException { +709 checkVectorDimensions(v.length); +710 OpenMapRealVector res = new OpenMapRealVector(this); +711 for (int i = 0; i < v.length; i++) { +712 if (entries.containsKey(i)) { +713 res.setEntry(i, entries.get(i) - v[i]); +714 } else { +715 res.setEntry(i, -v[i]); +716 } +717 } +718 return res; +719 } +720 +721 +722 /** {@inheritDoc} */ +723 @Override +724 public OpenMapRealVector unitVector() { +725 OpenMapRealVector res = copy(); +726 res.unitize(); +727 return res; +728 } +729 +730 /** {@inheritDoc} */ +731 @Override +732 public void unitize() { +733 double norm = getNorm(); +734 if (isDefaultValue(norm)) { +735 throw MathRuntimeException.createArithmeticException("cannot normalize a zero norm vector"); +736 } +737 Iterator iter = entries.iterator(); +738 while (iter.hasNext()) { +739 iter.advance(); +740 entries.put(iter.key(), iter.value() / norm); +741 } +742 +743 } +744 +745 +746 /** {@inheritDoc} */ +747 @Override +748 public double[] toArray() { +749 return getData(); +750 } +751 +752 /** {@inheritDoc} +753 * <p> Implementation Note: This works on exact values, and as a result +754 * it is possible for {@code a.subtract(b)} to be the zero vector, while +755 * {@code a.hashCode() != b.hashCode()}.</p> +756 */ +757 @Override +758 public int hashCode() { +759 final int prime = 31; +760 int result = 1; +761 long temp; +762 temp = Double.doubleToLongBits(epsilon); +763 result = prime * result + (int) (temp ^ (temp >>> 32)); +764 result = prime * result + virtualSize; +765 Iterator iter = entries.iterator(); +766 while (iter.hasNext()) { +767 iter.advance(); +768 temp = Double.doubleToLongBits(iter.value()); +769 result = prime * result + (int) (temp ^ (temp >>32)); +770 } +771 return result; +772 } +773 +774 /** +775 * <p> Implementation Note: This performs an exact comparison, and as a result +776 * it is possible for {@code a.subtract(b}} to be the zero vector, while +777 * {@code a.equals(b) == false}.</p> +778 * {@inheritDoc} +779 */ +780 @Override +781 public boolean equals(Object obj) { +782 if (this == obj) { +783 return true; +784 } +785 if (!(obj instanceof OpenMapRealVector)) { +786 return false; +787 } +788 OpenMapRealVector other = (OpenMapRealVector) obj; +789 if (virtualSize != other.virtualSize) { +790 return false; +791 } +792 if (Double.doubleToLongBits(epsilon) != +793 Double.doubleToLongBits(other.epsilon)) { +794 return false; +795 } +796 Iterator iter = entries.iterator(); +797 while (iter.hasNext()) { +798 iter.advance(); +799 double test = other.getEntry(iter.key()); +800 if (Double.doubleToLongBits(test) != Double.doubleToLongBits(iter.value())) { +801 return false; +802 } +803 } +804 iter = other.getEntries().iterator(); +805 while (iter.hasNext()) { +806 iter.advance(); +807 double test = iter.value(); +808 if (Double.doubleToLongBits(test) != Double.doubleToLongBits(getEntry(iter.key()))) { +809 return false; +810 } +811 } +812 return true; +813 } +814 +815 /** +816 * +817 * @return the percentage of none zero elements as a decimal percent. +818 */ +819 public double getSparcity() { +820 return (double)entries.size()/(double)getDimension(); +821 } +822 +823 /** {@inheritDoc} */ +824 @Override +825 public java.util.Iterator<Entry> sparseIterator() { +826 return new OpenMapSparseIterator(); +827 } +828 +829 /** +830 * Implementation of <code>Entry</code> optimized for OpenMap. +831 * <p>This implementation does not allow arbitrary calls to <code>setIndex</code> +832 * since the order that entries are returned is undefined. +833 */ +834 protected class OpenMapEntry extends Entry { +835 +836 /** Iterator pointing to the entry. */ +837 private final Iterator iter; +838 +839 /** Build an entry from an iterator point to an element. +840 * @param iter iterator pointing to the entry +841 */ +842 protected OpenMapEntry(Iterator iter) { +843 this.iter = iter; +844 } +845 +846 /** {@inheritDoc} */ +847 @Override +848 public double getValue() { +849 return iter.value(); +850 } +851 +852 /** {@inheritDoc} */ +853 @Override +854 public void setValue(double value) { +855 entries.put(iter.key(), value); +856 } +857 +858 /** {@inheritDoc} */ +859 @Override +860 public int getIndex() { +861 return iter.key(); +862 } +863 +864 } +865 +866 /** +867 * Iterator class to do iteration over just the non-zero elements. +868 * <p>This implementation is fail-fast, so cannot be used to modify any zero element. +869 * +870 */ +871 protected class OpenMapSparseIterator implements java.util.Iterator<Entry> { +872 +873 /** Underlying iterator. */ +874 private final Iterator iter; +875 +876 /** Current entry. */ +877 private final Entry current; +878 +879 /** Simple constructor. */ +880 protected OpenMapSparseIterator() { +881 iter = entries.iterator(); +882 current = new OpenMapEntry(iter); +883 } +884 +885 /** {@inheritDoc} */ +886 public boolean hasNext() { +887 return iter.hasNext(); +888 } +889 +890 /** {@inheritDoc} */ +891 public Entry next() { +892 iter.advance(); +893 return current; +894 } +895 +896 /** {@inheritDoc} */ +897 public void remove() { +898 throw new UnsupportedOperationException("Not supported"); +899 } +900 +901 } +902 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/OpenMapRealVector.OpenMapSparseIterator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/OpenMapRealVector.OpenMapSparseIterator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,968 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.linear; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.util.OpenIntToDoubleHashMap; +023 import org.apache.commons.math.util.OpenIntToDoubleHashMap.Iterator; +024 +025 /** +026 * This class implements the {@link RealVector} interface with a {@link OpenIntToDoubleHashMap} backing store. +027 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +028 * @since 2.0 +029 */ +030 public class OpenMapRealVector extends AbstractRealVector implements SparseRealVector, Serializable { +031 +032 /** Default Tolerance for having a value considered zero. */ +033 public static final double DEFAULT_ZERO_TOLERANCE = 1.0e-12; +034 +035 /** Serializable version identifier. */ +036 private static final long serialVersionUID = 8772222695580707260L; +037 +038 /** Entries of the vector. */ +039 private final OpenIntToDoubleHashMap entries; +040 +041 /** Dimension of the vector. */ +042 private final int virtualSize; +043 +044 /** Tolerance for having a value considered zero. */ +045 private double epsilon; +046 +047 /** +048 * Build a 0-length vector. +049 * <p>Zero-length vectors may be used to initialized construction of vectors +050 * by data gathering. We start with zero-length and use either the {@link +051 * #OpenMapRealVector(OpenMapRealVector, int)} constructor +052 * or one of the <code>append</code> method ({@link #append(double)}, {@link +053 * #append(double[])}, {@link #append(RealVector)}) to gather data +054 * into this vector.</p> +055 */ +056 public OpenMapRealVector() { +057 this(0, DEFAULT_ZERO_TOLERANCE); +058 } +059 +060 /** +061 * Construct a (dimension)-length vector of zeros. +062 * @param dimension size of the vector +063 */ +064 public OpenMapRealVector(int dimension) { +065 this(dimension, DEFAULT_ZERO_TOLERANCE); +066 } +067 +068 /** +069 * Construct a (dimension)-length vector of zeros, specifying zero tolerance. +070 * @param dimension Size of the vector +071 * @param epsilon The tolerance for having a value considered zero +072 */ +073 public OpenMapRealVector(int dimension, double epsilon) { +074 virtualSize = dimension; +075 entries = new OpenIntToDoubleHashMap(0.0); +076 this.epsilon = epsilon; +077 } +078 +079 /** +080 * Build a resized vector, for use with append. +081 * @param v The original vector +082 * @param resize The amount to resize it +083 */ +084 protected OpenMapRealVector(OpenMapRealVector v, int resize) { +085 virtualSize = v.getDimension() + resize; +086 entries = new OpenIntToDoubleHashMap(v.entries); +087 epsilon = v.epsilon; +088 } +089 +090 /** +091 * Build a vector with known the sparseness (for advanced use only). +092 * @param dimension The size of the vector +093 * @param expectedSize The expected number of non-zero entries +094 */ +095 public OpenMapRealVector(int dimension, int expectedSize) { +096 this(dimension, expectedSize, DEFAULT_ZERO_TOLERANCE); +097 } +098 +099 /** +100 * Build a vector with known the sparseness and zero tolerance setting (for advanced use only). +101 * @param dimension The size of the vector +102 * @param expectedSize The expected number of non-zero entries +103 * @param epsilon The tolerance for having a value considered zero +104 */ +105 public OpenMapRealVector(int dimension, int expectedSize, double epsilon) { +106 virtualSize = dimension; +107 entries = new OpenIntToDoubleHashMap(expectedSize, 0.0); +108 this.epsilon = epsilon; +109 } +110 +111 /** +112 * Create from a double array. +113 * Only non-zero entries will be stored +114 * @param values The set of values to create from +115 */ +116 public OpenMapRealVector(double[] values) { +117 this(values, DEFAULT_ZERO_TOLERANCE); +118 } +119 +120 /** +121 * Create from a double array, specifying zero tolerance. +122 * Only non-zero entries will be stored +123 * @param values The set of values to create from +124 * @param epsilon The tolerance for having a value considered zero +125 */ +126 public OpenMapRealVector(double[] values, double epsilon) { +127 virtualSize = values.length; +128 entries = new OpenIntToDoubleHashMap(0.0); +129 this.epsilon = epsilon; +130 for (int key = 0; key < values.length; key++) { +131 double value = values[key]; +132 if (!isDefaultValue(value)) { +133 entries.put(key, value); +134 } +135 } +136 } +137 +138 /** +139 * Create from a Double array. +140 * Only non-zero entries will be stored +141 * @param values The set of values to create from +142 */ +143 public OpenMapRealVector(Double[] values) { +144 this(values, DEFAULT_ZERO_TOLERANCE); +145 } +146 +147 /** +148 * Create from a Double array. +149 * Only non-zero entries will be stored +150 * @param values The set of values to create from +151 * @param epsilon The tolerance for having a value considered zero +152 */ +153 public OpenMapRealVector(Double[] values, double epsilon) { +154 virtualSize = values.length; +155 entries = new OpenIntToDoubleHashMap(0.0); +156 this.epsilon = epsilon; +157 for (int key = 0; key < values.length; key++) { +158 double value = values[key].doubleValue(); +159 if (!isDefaultValue(value)) { +160 entries.put(key, value); +161 } +162 } +163 } +164 +165 /** +166 * Copy constructor. +167 * @param v The instance to copy from +168 */ +169 public OpenMapRealVector(OpenMapRealVector v) { +170 virtualSize = v.getDimension(); +171 entries = new OpenIntToDoubleHashMap(v.getEntries()); +172 epsilon = v.epsilon; +173 } +174 +175 /** +176 * Generic copy constructor. +177 * @param v The instance to copy from +178 */ +179 public OpenMapRealVector(RealVector v) { +180 virtualSize = v.getDimension(); +181 entries = new OpenIntToDoubleHashMap(0.0); +182 epsilon = DEFAULT_ZERO_TOLERANCE; +183 for (int key = 0; key < virtualSize; key++) { +184 double value = v.getEntry(key); +185 if (!isDefaultValue(value)) { +186 entries.put(key, value); +187 } +188 } +189 } +190 +191 /** +192 * Get the entries of this instance. +193 * @return entries of this instance +194 */ +195 private OpenIntToDoubleHashMap getEntries() { +196 return entries; +197 } +198 +199 /** +200 * Determine if this value is within epsilon of zero. +201 * @param value The value to test +202 * @return <code>true</code> if this value is within epsilon to zero, <code>false</code> otherwise +203 * @since 2.1 +204 */ +205 protected boolean isDefaultValue(double value) { +206 return Math.abs(value) < epsilon; +207 } +208 +209 /** {@inheritDoc} */ +210 @Override +211 public RealVector add(RealVector v) throws IllegalArgumentException { +212 checkVectorDimensions(v.getDimension()); +213 if (v instanceof OpenMapRealVector) { +214 return add((OpenMapRealVector) v); +215 } else { +216 return super.add(v); +217 } +218 } +219 +220 /** +221 * Optimized method to add two OpenMapRealVectors. Copies the larger vector, iterates over the smaller. +222 * @param v Vector to add with +223 * @return The sum of <code>this</code> with <code>v</code> +224 * @throws IllegalArgumentException If the dimensions don't match +225 */ +226 public OpenMapRealVector add(OpenMapRealVector v) throws IllegalArgumentException{ +227 checkVectorDimensions(v.getDimension()); +228 boolean copyThis = entries.size() > v.entries.size(); +229 OpenMapRealVector res = copyThis ? this.copy() : v.copy(); +230 Iterator iter = copyThis ? v.entries.iterator() : entries.iterator(); +231 OpenIntToDoubleHashMap randomAccess = copyThis ? entries : v.entries; +232 while (iter.hasNext()) { +233 iter.advance(); +234 int key = iter.key(); +235 if (randomAccess.containsKey(key)) { +236 res.setEntry(key, randomAccess.get(key) + iter.value()); +237 } else { +238 res.setEntry(key, iter.value()); +239 } +240 } +241 return res; +242 } +243 +244 /** +245 * Optimized method to append a OpenMapRealVector. +246 * @param v vector to append +247 * @return The result of appending <code>v</code> to self +248 */ +249 public OpenMapRealVector append(OpenMapRealVector v) { +250 OpenMapRealVector res = new OpenMapRealVector(this, v.getDimension()); +251 Iterator iter = v.entries.iterator(); +252 while (iter.hasNext()) { +253 iter.advance(); +254 res.setEntry(iter.key() + virtualSize, iter.value()); +255 } +256 return res; +257 } +258 +259 /** {@inheritDoc} */ +260 public OpenMapRealVector append(RealVector v) { +261 if (v instanceof OpenMapRealVector) { +262 return append((OpenMapRealVector) v); +263 } +264 return append(v.getData()); +265 } +266 +267 /** {@inheritDoc} */ +268 public OpenMapRealVector append(double d) { +269 OpenMapRealVector res = new OpenMapRealVector(this, 1); +270 res.setEntry(virtualSize, d); +271 return res; +272 } +273 +274 /** {@inheritDoc} */ +275 public OpenMapRealVector append(double[] a) { +276 OpenMapRealVector res = new OpenMapRealVector(this, a.length); +277 for (int i = 0; i < a.length; i++) { +278 res.setEntry(i + virtualSize, a[i]); +279 } +280 return res; +281 } +282 +283 /** +284 * {@inheritDoc} +285 * @since 2.1 +286 */ +287 @Override +288 public OpenMapRealVector copy() { +289 return new OpenMapRealVector(this); +290 } +291 +292 /** +293 * Optimized method to compute the dot product with an OpenMapRealVector. +294 * Iterates over the smaller of the two. +295 * @param v The vector to compute the dot product with +296 * @return The dot product of <code>this</code> and <code>v</code> +297 * @throws IllegalArgumentException If the dimensions don't match +298 */ +299 public double dotProduct(OpenMapRealVector v) throws IllegalArgumentException { +300 checkVectorDimensions(v.getDimension()); +301 boolean thisIsSmaller = entries.size() < v.entries.size(); +302 Iterator iter = thisIsSmaller ? entries.iterator() : v.entries.iterator(); +303 OpenIntToDoubleHashMap larger = thisIsSmaller ? v.entries : entries; +304 double d = 0; +305 while(iter.hasNext()) { +306 iter.advance(); +307 d += iter.value() * larger.get(iter.key()); +308 } +309 return d; +310 } +311 +312 /** {@inheritDoc} */ +313 @Override +314 public double dotProduct(RealVector v) throws IllegalArgumentException { +315 if(v instanceof OpenMapRealVector) { +316 return dotProduct((OpenMapRealVector)v); +317 } else { +318 return super.dotProduct(v); +319 } +320 } +321 +322 /** {@inheritDoc} */ +323 public OpenMapRealVector ebeDivide(RealVector v) throws IllegalArgumentException { +324 checkVectorDimensions(v.getDimension()); +325 OpenMapRealVector res = new OpenMapRealVector(this); +326 Iterator iter = res.entries.iterator(); +327 while (iter.hasNext()) { +328 iter.advance(); +329 res.setEntry(iter.key(), iter.value() / v.getEntry(iter.key())); +330 } +331 return res; +332 } +333 +334 /** {@inheritDoc} */ +335 @Override +336 public OpenMapRealVector ebeDivide(double[] v) throws IllegalArgumentException { +337 checkVectorDimensions(v.length); +338 OpenMapRealVector res = new OpenMapRealVector(this); +339 Iterator iter = res.entries.iterator(); +340 while (iter.hasNext()) { +341 iter.advance(); +342 res.setEntry(iter.key(), iter.value() / v[iter.key()]); +343 } +344 return res; +345 } +346 +347 /** {@inheritDoc} */ +348 public OpenMapRealVector ebeMultiply(RealVector v) throws IllegalArgumentException { +349 checkVectorDimensions(v.getDimension()); +350 OpenMapRealVector res = new OpenMapRealVector(this); +351 Iterator iter = res.entries.iterator(); +352 while (iter.hasNext()) { +353 iter.advance(); +354 res.setEntry(iter.key(), iter.value() * v.getEntry(iter.key())); +355 } +356 return res; +357 } +358 +359 /** {@inheritDoc} */ +360 @Override +361 public OpenMapRealVector ebeMultiply(double[] v) throws IllegalArgumentException { +362 checkVectorDimensions(v.length); +363 OpenMapRealVector res = new OpenMapRealVector(this); +364 Iterator iter = res.entries.iterator(); +365 while (iter.hasNext()) { +366 iter.advance(); +367 res.setEntry(iter.key(), iter.value() * v[iter.key()]); +368 } +369 return res; +370 } +371 +372 /** {@inheritDoc} */ +373 public OpenMapRealVector getSubVector(int index, int n) throws MatrixIndexException { +374 checkIndex(index); +375 checkIndex(index + n - 1); +376 OpenMapRealVector res = new OpenMapRealVector(n); +377 int end = index + n; +378 Iterator iter = entries.iterator(); +379 while (iter.hasNext()) { +380 iter.advance(); +381 int key = iter.key(); +382 if (key >= index && key < end) { +383 res.setEntry(key - index, iter.value()); +384 } +385 } +386 return res; +387 } +388 +389 /** {@inheritDoc} */ +390 @Override +391 public double[] getData() { +392 double[] res = new double[virtualSize]; +393 Iterator iter = entries.iterator(); +394 while (iter.hasNext()) { +395 iter.advance(); +396 res[iter.key()] = iter.value(); +397 } +398 return res; +399 } +400 +401 /** {@inheritDoc} */ +402 public int getDimension() { +403 return virtualSize; +404 } +405 +406 /** +407 * Optimized method to compute distance. +408 * @param v The vector to compute distance to +409 * @return The distance from <code>this</code> and <code>v</code> +410 * @throws IllegalArgumentException If the dimensions don't match +411 */ +412 public double getDistance(OpenMapRealVector v) throws IllegalArgumentException { +413 Iterator iter = entries.iterator(); +414 double res = 0; +415 while (iter.hasNext()) { +416 iter.advance(); +417 int key = iter.key(); +418 double delta; +419 delta = iter.value() - v.getEntry(key); +420 res += delta * delta; +421 } +422 iter = v.getEntries().iterator(); +423 while (iter.hasNext()) { +424 iter.advance(); +425 int key = iter.key(); +426 if (!entries.containsKey(key)) { +427 final double value = iter.value(); +428 res += value * value; +429 } +430 } +431 return Math.sqrt(res); +432 } +433 +434 /** {@inheritDoc} */ +435 @Override +436 public double getDistance(RealVector v) throws IllegalArgumentException { +437 checkVectorDimensions(v.getDimension()); +438 if (v instanceof OpenMapRealVector) { +439 return getDistance((OpenMapRealVector) v); +440 } +441 return getDistance(v.getData()); +442 } +443 +444 /** {@inheritDoc} */ +445 @Override +446 public double getDistance(double[] v) throws IllegalArgumentException { +447 checkVectorDimensions(v.length); +448 double res = 0; +449 for (int i = 0; i < v.length; i++) { +450 double delta = entries.get(i) - v[i]; +451 res += delta * delta; +452 } +453 return Math.sqrt(res); +454 } +455 +456 /** {@inheritDoc} */ +457 public double getEntry(int index) throws MatrixIndexException { +458 checkIndex(index); +459 return entries.get(index); +460 } +461 +462 /** +463 * Distance between two vectors. +464 * <p>This method computes the distance consistent with +465 * L<sub>1</sub> norm, i.e. the sum of the absolute values of +466 * elements differences.</p> +467 * @param v vector to which distance is requested +468 * @return distance between two vectors. +469 */ +470 public double getL1Distance(OpenMapRealVector v) { +471 double max = 0; +472 Iterator iter = entries.iterator(); +473 while (iter.hasNext()) { +474 iter.advance(); +475 double delta = Math.abs(iter.value() - v.getEntry(iter.key())); +476 max += delta; +477 } +478 iter = v.getEntries().iterator(); +479 while (iter.hasNext()) { +480 iter.advance(); +481 int key = iter.key(); +482 if (!entries.containsKey(key)) { +483 double delta = Math.abs(iter.value()); +484 max += Math.abs(delta); +485 } +486 } +487 return max; +488 } +489 +490 /** {@inheritDoc} */ +491 @Override +492 public double getL1Distance(RealVector v) throws IllegalArgumentException { +493 checkVectorDimensions(v.getDimension()); +494 if (v instanceof OpenMapRealVector) { +495 return getL1Distance((OpenMapRealVector) v); +496 } +497 return getL1Distance(v.getData()); +498 } +499 +500 /** {@inheritDoc} */ +501 @Override +502 public double getL1Distance(double[] v) throws IllegalArgumentException { +503 checkVectorDimensions(v.length); +504 double max = 0; +505 for (int i = 0; i < v.length; i++) { +506 double delta = Math.abs(getEntry(i) - v[i]); +507 max += delta; +508 } +509 return max; +510 } +511 +512 /** +513 * Optimized method to compute LInfDistance. +514 * @param v The vector to compute from +515 * @return the LInfDistance +516 */ +517 private double getLInfDistance(OpenMapRealVector v) { +518 double max = 0; +519 Iterator iter = entries.iterator(); +520 while (iter.hasNext()) { +521 iter.advance(); +522 double delta = Math.abs(iter.value() - v.getEntry(iter.key())); +523 if (delta > max) { +524 max = delta; +525 } +526 } +527 iter = v.getEntries().iterator(); +528 while (iter.hasNext()) { +529 iter.advance(); +530 int key = iter.key(); +531 if (!entries.containsKey(key)) { +532 if (iter.value() > max) { +533 max = iter.value(); +534 } +535 } +536 } +537 return max; +538 } +539 +540 /** {@inheritDoc} */ +541 @Override +542 public double getLInfDistance(RealVector v) throws IllegalArgumentException { +543 checkVectorDimensions(v.getDimension()); +544 if (v instanceof OpenMapRealVector) { +545 return getLInfDistance((OpenMapRealVector) v); +546 } +547 return getLInfDistance(v.getData()); +548 } +549 +550 /** {@inheritDoc} */ +551 @Override +552 public double getLInfDistance(double[] v) throws IllegalArgumentException { +553 checkVectorDimensions(v.length); +554 double max = 0; +555 for (int i = 0; i < v.length; i++) { +556 double delta = Math.abs(getEntry(i) - v[i]); +557 if (delta > max) { +558 max = delta; +559 } +560 } +561 return max; +562 } +563 +564 /** {@inheritDoc} */ +565 public boolean isInfinite() { +566 boolean infiniteFound = false; +567 Iterator iter = entries.iterator(); +568 while (iter.hasNext()) { +569 iter.advance(); +570 final double value = iter.value(); +571 if (Double.isNaN(value)) { +572 return false; +573 } +574 if (Double.isInfinite(value)) { +575 infiniteFound = true; +576 } +577 } +578 return infiniteFound; +579 } +580 +581 /** {@inheritDoc} */ +582 public boolean isNaN() { +583 Iterator iter = entries.iterator(); +584 while (iter.hasNext()) { +585 iter.advance(); +586 if (Double.isNaN(iter.value())) { +587 return true; +588 } +589 } +590 return false; +591 } +592 +593 /** {@inheritDoc} */ +594 @Override +595 public OpenMapRealVector mapAdd(double d) { +596 return copy().mapAddToSelf(d); +597 } +598 +599 /** {@inheritDoc} */ +600 @Override +601 public OpenMapRealVector mapAddToSelf(double d) { +602 for (int i = 0; i < virtualSize; i++) { +603 setEntry(i, getEntry(i) + d); +604 } +605 return this; +606 } +607 +608 /** {@inheritDoc} */ +609 @Override +610 public RealMatrix outerProduct(double[] v) throws IllegalArgumentException { +611 checkVectorDimensions(v.length); +612 RealMatrix res = new OpenMapRealMatrix(virtualSize, virtualSize); +613 Iterator iter = entries.iterator(); +614 while (iter.hasNext()) { +615 iter.advance(); +616 int row = iter.key(); +617 double value = iter.value(); +618 for (int col = 0; col < virtualSize; col++) { +619 res.setEntry(row, col, value * v[col]); +620 } +621 } +622 return res; +623 } +624 +625 /** {@inheritDoc} */ +626 public RealVector projection(RealVector v) throws IllegalArgumentException { +627 checkVectorDimensions(v.getDimension()); +628 return v.mapMultiply(dotProduct(v) / v.dotProduct(v)); +629 } +630 +631 /** {@inheritDoc} */ +632 @Override +633 public OpenMapRealVector projection(double[] v) throws IllegalArgumentException { +634 checkVectorDimensions(v.length); +635 return (OpenMapRealVector) projection(new OpenMapRealVector(v)); +636 } +637 +638 /** {@inheritDoc} */ +639 public void setEntry(int index, double value) throws MatrixIndexException { +640 checkIndex(index); +641 if (!isDefaultValue(value)) { +642 entries.put(index, value); +643 } else if (entries.containsKey(index)) { +644 entries.remove(index); +645 } +646 } +647 +648 /** {@inheritDoc} */ +649 @Override +650 public void setSubVector(int index, RealVector v) throws MatrixIndexException { +651 checkIndex(index); +652 checkIndex(index + v.getDimension() - 1); +653 setSubVector(index, v.getData()); +654 } +655 +656 /** {@inheritDoc} */ +657 @Override +658 public void setSubVector(int index, double[] v) throws MatrixIndexException { +659 checkIndex(index); +660 checkIndex(index + v.length - 1); +661 for (int i = 0; i < v.length; i++) { +662 setEntry(i + index, v[i]); +663 } +664 } +665 +666 /** {@inheritDoc} */ +667 @Override +668 public void set(double value) { +669 for (int i = 0; i < virtualSize; i++) { +670 setEntry(i, value); +671 } +672 } +673 +674 /** +675 * Optimized method to subtract OpenMapRealVectors. +676 * @param v The vector to subtract from <code>this</code> +677 * @return The difference of <code>this</code> and <code>v</code> +678 * @throws IllegalArgumentException If the dimensions don't match +679 */ +680 public OpenMapRealVector subtract(OpenMapRealVector v) throws IllegalArgumentException{ +681 checkVectorDimensions(v.getDimension()); +682 OpenMapRealVector res = copy(); +683 Iterator iter = v.getEntries().iterator(); +684 while (iter.hasNext()) { +685 iter.advance(); +686 int key = iter.key(); +687 if (entries.containsKey(key)) { +688 res.setEntry(key, entries.get(key) - iter.value()); +689 } else { +690 res.setEntry(key, -iter.value()); +691 } +692 } +693 return res; +694 } +695 +696 /** {@inheritDoc} */ +697 @Override +698 public OpenMapRealVector subtract(RealVector v) throws IllegalArgumentException { +699 checkVectorDimensions(v.getDimension()); +700 if (v instanceof OpenMapRealVector) { +701 return subtract((OpenMapRealVector) v); +702 } +703 return subtract(v.getData()); +704 } +705 +706 /** {@inheritDoc} */ +707 @Override +708 public OpenMapRealVector subtract(double[] v) throws IllegalArgumentException { +709 checkVectorDimensions(v.length); +710 OpenMapRealVector res = new OpenMapRealVector(this); +711 for (int i = 0; i < v.length; i++) { +712 if (entries.containsKey(i)) { +713 res.setEntry(i, entries.get(i) - v[i]); +714 } else { +715 res.setEntry(i, -v[i]); +716 } +717 } +718 return res; +719 } +720 +721 +722 /** {@inheritDoc} */ +723 @Override +724 public OpenMapRealVector unitVector() { +725 OpenMapRealVector res = copy(); +726 res.unitize(); +727 return res; +728 } +729 +730 /** {@inheritDoc} */ +731 @Override +732 public void unitize() { +733 double norm = getNorm(); +734 if (isDefaultValue(norm)) { +735 throw MathRuntimeException.createArithmeticException("cannot normalize a zero norm vector"); +736 } +737 Iterator iter = entries.iterator(); +738 while (iter.hasNext()) { +739 iter.advance(); +740 entries.put(iter.key(), iter.value() / norm); +741 } +742 +743 } +744 +745 +746 /** {@inheritDoc} */ +747 @Override +748 public double[] toArray() { +749 return getData(); +750 } +751 +752 /** {@inheritDoc} +753 * <p> Implementation Note: This works on exact values, and as a result +754 * it is possible for {@code a.subtract(b)} to be the zero vector, while +755 * {@code a.hashCode() != b.hashCode()}.</p> +756 */ +757 @Override +758 public int hashCode() { +759 final int prime = 31; +760 int result = 1; +761 long temp; +762 temp = Double.doubleToLongBits(epsilon); +763 result = prime * result + (int) (temp ^ (temp >>> 32)); +764 result = prime * result + virtualSize; +765 Iterator iter = entries.iterator(); +766 while (iter.hasNext()) { +767 iter.advance(); +768 temp = Double.doubleToLongBits(iter.value()); +769 result = prime * result + (int) (temp ^ (temp >>32)); +770 } +771 return result; +772 } +773 +774 /** +775 * <p> Implementation Note: This performs an exact comparison, and as a result +776 * it is possible for {@code a.subtract(b}} to be the zero vector, while +777 * {@code a.equals(b) == false}.</p> +778 * {@inheritDoc} +779 */ +780 @Override +781 public boolean equals(Object obj) { +782 if (this == obj) { +783 return true; +784 } +785 if (!(obj instanceof OpenMapRealVector)) { +786 return false; +787 } +788 OpenMapRealVector other = (OpenMapRealVector) obj; +789 if (virtualSize != other.virtualSize) { +790 return false; +791 } +792 if (Double.doubleToLongBits(epsilon) != +793 Double.doubleToLongBits(other.epsilon)) { +794 return false; +795 } +796 Iterator iter = entries.iterator(); +797 while (iter.hasNext()) { +798 iter.advance(); +799 double test = other.getEntry(iter.key()); +800 if (Double.doubleToLongBits(test) != Double.doubleToLongBits(iter.value())) { +801 return false; +802 } +803 } +804 iter = other.getEntries().iterator(); +805 while (iter.hasNext()) { +806 iter.advance(); +807 double test = iter.value(); +808 if (Double.doubleToLongBits(test) != Double.doubleToLongBits(getEntry(iter.key()))) { +809 return false; +810 } +811 } +812 return true; +813 } +814 +815 /** +816 * +817 * @return the percentage of none zero elements as a decimal percent. +818 */ +819 public double getSparcity() { +820 return (double)entries.size()/(double)getDimension(); +821 } +822 +823 /** {@inheritDoc} */ +824 @Override +825 public java.util.Iterator<Entry> sparseIterator() { +826 return new OpenMapSparseIterator(); +827 } +828 +829 /** +830 * Implementation of <code>Entry</code> optimized for OpenMap. +831 * <p>This implementation does not allow arbitrary calls to <code>setIndex</code> +832 * since the order that entries are returned is undefined. +833 */ +834 protected class OpenMapEntry extends Entry { +835 +836 /** Iterator pointing to the entry. */ +837 private final Iterator iter; +838 +839 /** Build an entry from an iterator point to an element. +840 * @param iter iterator pointing to the entry +841 */ +842 protected OpenMapEntry(Iterator iter) { +843 this.iter = iter; +844 } +845 +846 /** {@inheritDoc} */ +847 @Override +848 public double getValue() { +849 return iter.value(); +850 } +851 +852 /** {@inheritDoc} */ +853 @Override +854 public void setValue(double value) { +855 entries.put(iter.key(), value); +856 } +857 +858 /** {@inheritDoc} */ +859 @Override +860 public int getIndex() { +861 return iter.key(); +862 } +863 +864 } +865 +866 /** +867 * Iterator class to do iteration over just the non-zero elements. +868 * <p>This implementation is fail-fast, so cannot be used to modify any zero element. +869 * +870 */ +871 protected class OpenMapSparseIterator implements java.util.Iterator<Entry> { +872 +873 /** Underlying iterator. */ +874 private final Iterator iter; +875 +876 /** Current entry. */ +877 private final Entry current; +878 +879 /** Simple constructor. */ +880 protected OpenMapSparseIterator() { +881 iter = entries.iterator(); +882 current = new OpenMapEntry(iter); +883 } +884 +885 /** {@inheritDoc} */ +886 public boolean hasNext() { +887 return iter.hasNext(); +888 } +889 +890 /** {@inheritDoc} */ +891 public Entry next() { +892 iter.advance(); +893 return current; +894 } +895 +896 /** {@inheritDoc} */ +897 public void remove() { +898 throw new UnsupportedOperationException("Not supported"); +899 } +900 +901 } +902 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/OpenMapRealVector.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/OpenMapRealVector.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,968 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.linear; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.util.OpenIntToDoubleHashMap; +023 import org.apache.commons.math.util.OpenIntToDoubleHashMap.Iterator; +024 +025 /** +026 * This class implements the {@link RealVector} interface with a {@link OpenIntToDoubleHashMap} backing store. +027 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +028 * @since 2.0 +029 */ +030 public class OpenMapRealVector extends AbstractRealVector implements SparseRealVector, Serializable { +031 +032 /** Default Tolerance for having a value considered zero. */ +033 public static final double DEFAULT_ZERO_TOLERANCE = 1.0e-12; +034 +035 /** Serializable version identifier. */ +036 private static final long serialVersionUID = 8772222695580707260L; +037 +038 /** Entries of the vector. */ +039 private final OpenIntToDoubleHashMap entries; +040 +041 /** Dimension of the vector. */ +042 private final int virtualSize; +043 +044 /** Tolerance for having a value considered zero. */ +045 private double epsilon; +046 +047 /** +048 * Build a 0-length vector. +049 * <p>Zero-length vectors may be used to initialized construction of vectors +050 * by data gathering. We start with zero-length and use either the {@link +051 * #OpenMapRealVector(OpenMapRealVector, int)} constructor +052 * or one of the <code>append</code> method ({@link #append(double)}, {@link +053 * #append(double[])}, {@link #append(RealVector)}) to gather data +054 * into this vector.</p> +055 */ +056 public OpenMapRealVector() { +057 this(0, DEFAULT_ZERO_TOLERANCE); +058 } +059 +060 /** +061 * Construct a (dimension)-length vector of zeros. +062 * @param dimension size of the vector +063 */ +064 public OpenMapRealVector(int dimension) { +065 this(dimension, DEFAULT_ZERO_TOLERANCE); +066 } +067 +068 /** +069 * Construct a (dimension)-length vector of zeros, specifying zero tolerance. +070 * @param dimension Size of the vector +071 * @param epsilon The tolerance for having a value considered zero +072 */ +073 public OpenMapRealVector(int dimension, double epsilon) { +074 virtualSize = dimension; +075 entries = new OpenIntToDoubleHashMap(0.0); +076 this.epsilon = epsilon; +077 } +078 +079 /** +080 * Build a resized vector, for use with append. +081 * @param v The original vector +082 * @param resize The amount to resize it +083 */ +084 protected OpenMapRealVector(OpenMapRealVector v, int resize) { +085 virtualSize = v.getDimension() + resize; +086 entries = new OpenIntToDoubleHashMap(v.entries); +087 epsilon = v.epsilon; +088 } +089 +090 /** +091 * Build a vector with known the sparseness (for advanced use only). +092 * @param dimension The size of the vector +093 * @param expectedSize The expected number of non-zero entries +094 */ +095 public OpenMapRealVector(int dimension, int expectedSize) { +096 this(dimension, expectedSize, DEFAULT_ZERO_TOLERANCE); +097 } +098 +099 /** +100 * Build a vector with known the sparseness and zero tolerance setting (for advanced use only). +101 * @param dimension The size of the vector +102 * @param expectedSize The expected number of non-zero entries +103 * @param epsilon The tolerance for having a value considered zero +104 */ +105 public OpenMapRealVector(int dimension, int expectedSize, double epsilon) { +106 virtualSize = dimension; +107 entries = new OpenIntToDoubleHashMap(expectedSize, 0.0); +108 this.epsilon = epsilon; +109 } +110 +111 /** +112 * Create from a double array. +113 * Only non-zero entries will be stored +114 * @param values The set of values to create from +115 */ +116 public OpenMapRealVector(double[] values) { +117 this(values, DEFAULT_ZERO_TOLERANCE); +118 } +119 +120 /** +121 * Create from a double array, specifying zero tolerance. +122 * Only non-zero entries will be stored +123 * @param values The set of values to create from +124 * @param epsilon The tolerance for having a value considered zero +125 */ +126 public OpenMapRealVector(double[] values, double epsilon) { +127 virtualSize = values.length; +128 entries = new OpenIntToDoubleHashMap(0.0); +129 this.epsilon = epsilon; +130 for (int key = 0; key < values.length; key++) { +131 double value = values[key]; +132 if (!isDefaultValue(value)) { +133 entries.put(key, value); +134 } +135 } +136 } +137 +138 /** +139 * Create from a Double array. +140 * Only non-zero entries will be stored +141 * @param values The set of values to create from +142 */ +143 public OpenMapRealVector(Double[] values) { +144 this(values, DEFAULT_ZERO_TOLERANCE); +145 } +146 +147 /** +148 * Create from a Double array. +149 * Only non-zero entries will be stored +150 * @param values The set of values to create from +151 * @param epsilon The tolerance for having a value considered zero +152 */ +153 public OpenMapRealVector(Double[] values, double epsilon) { +154 virtualSize = values.length; +155 entries = new OpenIntToDoubleHashMap(0.0); +156 this.epsilon = epsilon; +157 for (int key = 0; key < values.length; key++) { +158 double value = values[key].doubleValue(); +159 if (!isDefaultValue(value)) { +160 entries.put(key, value); +161 } +162 } +163 } +164 +165 /** +166 * Copy constructor. +167 * @param v The instance to copy from +168 */ +169 public OpenMapRealVector(OpenMapRealVector v) { +170 virtualSize = v.getDimension(); +171 entries = new OpenIntToDoubleHashMap(v.getEntries()); +172 epsilon = v.epsilon; +173 } +174 +175 /** +176 * Generic copy constructor. +177 * @param v The instance to copy from +178 */ +179 public OpenMapRealVector(RealVector v) { +180 virtualSize = v.getDimension(); +181 entries = new OpenIntToDoubleHashMap(0.0); +182 epsilon = DEFAULT_ZERO_TOLERANCE; +183 for (int key = 0; key < virtualSize; key++) { +184 double value = v.getEntry(key); +185 if (!isDefaultValue(value)) { +186 entries.put(key, value); +187 } +188 } +189 } +190 +191 /** +192 * Get the entries of this instance. +193 * @return entries of this instance +194 */ +195 private OpenIntToDoubleHashMap getEntries() { +196 return entries; +197 } +198 +199 /** +200 * Determine if this value is within epsilon of zero. +201 * @param value The value to test +202 * @return <code>true</code> if this value is within epsilon to zero, <code>false</code> otherwise +203 * @since 2.1 +204 */ +205 protected boolean isDefaultValue(double value) { +206 return Math.abs(value) < epsilon; +207 } +208 +209 /** {@inheritDoc} */ +210 @Override +211 public RealVector add(RealVector v) throws IllegalArgumentException { +212 checkVectorDimensions(v.getDimension()); +213 if (v instanceof OpenMapRealVector) { +214 return add((OpenMapRealVector) v); +215 } else { +216 return super.add(v); +217 } +218 } +219 +220 /** +221 * Optimized method to add two OpenMapRealVectors. Copies the larger vector, iterates over the smaller. +222 * @param v Vector to add with +223 * @return The sum of <code>this</code> with <code>v</code> +224 * @throws IllegalArgumentException If the dimensions don't match +225 */ +226 public OpenMapRealVector add(OpenMapRealVector v) throws IllegalArgumentException{ +227 checkVectorDimensions(v.getDimension()); +228 boolean copyThis = entries.size() > v.entries.size(); +229 OpenMapRealVector res = copyThis ? this.copy() : v.copy(); +230 Iterator iter = copyThis ? v.entries.iterator() : entries.iterator(); +231 OpenIntToDoubleHashMap randomAccess = copyThis ? entries : v.entries; +232 while (iter.hasNext()) { +233 iter.advance(); +234 int key = iter.key(); +235 if (randomAccess.containsKey(key)) { +236 res.setEntry(key, randomAccess.get(key) + iter.value()); +237 } else { +238 res.setEntry(key, iter.value()); +239 } +240 } +241 return res; +242 } +243 +244 /** +245 * Optimized method to append a OpenMapRealVector. +246 * @param v vector to append +247 * @return The result of appending <code>v</code> to self +248 */ +249 public OpenMapRealVector append(OpenMapRealVector v) { +250 OpenMapRealVector res = new OpenMapRealVector(this, v.getDimension()); +251 Iterator iter = v.entries.iterator(); +252 while (iter.hasNext()) { +253 iter.advance(); +254 res.setEntry(iter.key() + virtualSize, iter.value()); +255 } +256 return res; +257 } +258 +259 /** {@inheritDoc} */ +260 public OpenMapRealVector append(RealVector v) { +261 if (v instanceof OpenMapRealVector) { +262 return append((OpenMapRealVector) v); +263 } +264 return append(v.getData()); +265 } +266 +267 /** {@inheritDoc} */ +268 public OpenMapRealVector append(double d) { +269 OpenMapRealVector res = new OpenMapRealVector(this, 1); +270 res.setEntry(virtualSize, d); +271 return res; +272 } +273 +274 /** {@inheritDoc} */ +275 public OpenMapRealVector append(double[] a) { +276 OpenMapRealVector res = new OpenMapRealVector(this, a.length); +277 for (int i = 0; i < a.length; i++) { +278 res.setEntry(i + virtualSize, a[i]); +279 } +280 return res; +281 } +282 +283 /** +284 * {@inheritDoc} +285 * @since 2.1 +286 */ +287 @Override +288 public OpenMapRealVector copy() { +289 return new OpenMapRealVector(this); +290 } +291 +292 /** +293 * Optimized method to compute the dot product with an OpenMapRealVector. +294 * Iterates over the smaller of the two. +295 * @param v The vector to compute the dot product with +296 * @return The dot product of <code>this</code> and <code>v</code> +297 * @throws IllegalArgumentException If the dimensions don't match +298 */ +299 public double dotProduct(OpenMapRealVector v) throws IllegalArgumentException { +300 checkVectorDimensions(v.getDimension()); +301 boolean thisIsSmaller = entries.size() < v.entries.size(); +302 Iterator iter = thisIsSmaller ? entries.iterator() : v.entries.iterator(); +303 OpenIntToDoubleHashMap larger = thisIsSmaller ? v.entries : entries; +304 double d = 0; +305 while(iter.hasNext()) { +306 iter.advance(); +307 d += iter.value() * larger.get(iter.key()); +308 } +309 return d; +310 } +311 +312 /** {@inheritDoc} */ +313 @Override +314 public double dotProduct(RealVector v) throws IllegalArgumentException { +315 if(v instanceof OpenMapRealVector) { +316 return dotProduct((OpenMapRealVector)v); +317 } else { +318 return super.dotProduct(v); +319 } +320 } +321 +322 /** {@inheritDoc} */ +323 public OpenMapRealVector ebeDivide(RealVector v) throws IllegalArgumentException { +324 checkVectorDimensions(v.getDimension()); +325 OpenMapRealVector res = new OpenMapRealVector(this); +326 Iterator iter = res.entries.iterator(); +327 while (iter.hasNext()) { +328 iter.advance(); +329 res.setEntry(iter.key(), iter.value() / v.getEntry(iter.key())); +330 } +331 return res; +332 } +333 +334 /** {@inheritDoc} */ +335 @Override +336 public OpenMapRealVector ebeDivide(double[] v) throws IllegalArgumentException { +337 checkVectorDimensions(v.length); +338 OpenMapRealVector res = new OpenMapRealVector(this); +339 Iterator iter = res.entries.iterator(); +340 while (iter.hasNext()) { +341 iter.advance(); +342 res.setEntry(iter.key(), iter.value() / v[iter.key()]); +343 } +344 return res; +345 } +346 +347 /** {@inheritDoc} */ +348 public OpenMapRealVector ebeMultiply(RealVector v) throws IllegalArgumentException { +349 checkVectorDimensions(v.getDimension()); +350 OpenMapRealVector res = new OpenMapRealVector(this); +351 Iterator iter = res.entries.iterator(); +352 while (iter.hasNext()) { +353 iter.advance(); +354 res.setEntry(iter.key(), iter.value() * v.getEntry(iter.key())); +355 } +356 return res; +357 } +358 +359 /** {@inheritDoc} */ +360 @Override +361 public OpenMapRealVector ebeMultiply(double[] v) throws IllegalArgumentException { +362 checkVectorDimensions(v.length); +363 OpenMapRealVector res = new OpenMapRealVector(this); +364 Iterator iter = res.entries.iterator(); +365 while (iter.hasNext()) { +366 iter.advance(); +367 res.setEntry(iter.key(), iter.value() * v[iter.key()]); +368 } +369 return res; +370 } +371 +372 /** {@inheritDoc} */ +373 public OpenMapRealVector getSubVector(int index, int n) throws MatrixIndexException { +374 checkIndex(index); +375 checkIndex(index + n - 1); +376 OpenMapRealVector res = new OpenMapRealVector(n); +377 int end = index + n; +378 Iterator iter = entries.iterator(); +379 while (iter.hasNext()) { +380 iter.advance(); +381 int key = iter.key(); +382 if (key >= index && key < end) { +383 res.setEntry(key - index, iter.value()); +384 } +385 } +386 return res; +387 } +388 +389 /** {@inheritDoc} */ +390 @Override +391 public double[] getData() { +392 double[] res = new double[virtualSize]; +393 Iterator iter = entries.iterator(); +394 while (iter.hasNext()) { +395 iter.advance(); +396 res[iter.key()] = iter.value(); +397 } +398 return res; +399 } +400 +401 /** {@inheritDoc} */ +402 public int getDimension() { +403 return virtualSize; +404 } +405 +406 /** +407 * Optimized method to compute distance. +408 * @param v The vector to compute distance to +409 * @return The distance from <code>this</code> and <code>v</code> +410 * @throws IllegalArgumentException If the dimensions don't match +411 */ +412 public double getDistance(OpenMapRealVector v) throws IllegalArgumentException { +413 Iterator iter = entries.iterator(); +414 double res = 0; +415 while (iter.hasNext()) { +416 iter.advance(); +417 int key = iter.key(); +418 double delta; +419 delta = iter.value() - v.getEntry(key); +420 res += delta * delta; +421 } +422 iter = v.getEntries().iterator(); +423 while (iter.hasNext()) { +424 iter.advance(); +425 int key = iter.key(); +426 if (!entries.containsKey(key)) { +427 final double value = iter.value(); +428 res += value * value; +429 } +430 } +431 return Math.sqrt(res); +432 } +433 +434 /** {@inheritDoc} */ +435 @Override +436 public double getDistance(RealVector v) throws IllegalArgumentException { +437 checkVectorDimensions(v.getDimension()); +438 if (v instanceof OpenMapRealVector) { +439 return getDistance((OpenMapRealVector) v); +440 } +441 return getDistance(v.getData()); +442 } +443 +444 /** {@inheritDoc} */ +445 @Override +446 public double getDistance(double[] v) throws IllegalArgumentException { +447 checkVectorDimensions(v.length); +448 double res = 0; +449 for (int i = 0; i < v.length; i++) { +450 double delta = entries.get(i) - v[i]; +451 res += delta * delta; +452 } +453 return Math.sqrt(res); +454 } +455 +456 /** {@inheritDoc} */ +457 public double getEntry(int index) throws MatrixIndexException { +458 checkIndex(index); +459 return entries.get(index); +460 } +461 +462 /** +463 * Distance between two vectors. +464 * <p>This method computes the distance consistent with +465 * L<sub>1</sub> norm, i.e. the sum of the absolute values of +466 * elements differences.</p> +467 * @param v vector to which distance is requested +468 * @return distance between two vectors. +469 */ +470 public double getL1Distance(OpenMapRealVector v) { +471 double max = 0; +472 Iterator iter = entries.iterator(); +473 while (iter.hasNext()) { +474 iter.advance(); +475 double delta = Math.abs(iter.value() - v.getEntry(iter.key())); +476 max += delta; +477 } +478 iter = v.getEntries().iterator(); +479 while (iter.hasNext()) { +480 iter.advance(); +481 int key = iter.key(); +482 if (!entries.containsKey(key)) { +483 double delta = Math.abs(iter.value()); +484 max += Math.abs(delta); +485 } +486 } +487 return max; +488 } +489 +490 /** {@inheritDoc} */ +491 @Override +492 public double getL1Distance(RealVector v) throws IllegalArgumentException { +493 checkVectorDimensions(v.getDimension()); +494 if (v instanceof OpenMapRealVector) { +495 return getL1Distance((OpenMapRealVector) v); +496 } +497 return getL1Distance(v.getData()); +498 } +499 +500 /** {@inheritDoc} */ +501 @Override +502 public double getL1Distance(double[] v) throws IllegalArgumentException { +503 checkVectorDimensions(v.length); +504 double max = 0; +505 for (int i = 0; i < v.length; i++) { +506 double delta = Math.abs(getEntry(i) - v[i]); +507 max += delta; +508 } +509 return max; +510 } +511 +512 /** +513 * Optimized method to compute LInfDistance. +514 * @param v The vector to compute from +515 * @return the LInfDistance +516 */ +517 private double getLInfDistance(OpenMapRealVector v) { +518 double max = 0; +519 Iterator iter = entries.iterator(); +520 while (iter.hasNext()) { +521 iter.advance(); +522 double delta = Math.abs(iter.value() - v.getEntry(iter.key())); +523 if (delta > max) { +524 max = delta; +525 } +526 } +527 iter = v.getEntries().iterator(); +528 while (iter.hasNext()) { +529 iter.advance(); +530 int key = iter.key(); +531 if (!entries.containsKey(key)) { +532 if (iter.value() > max) { +533 max = iter.value(); +534 } +535 } +536 } +537 return max; +538 } +539 +540 /** {@inheritDoc} */ +541 @Override +542 public double getLInfDistance(RealVector v) throws IllegalArgumentException { +543 checkVectorDimensions(v.getDimension()); +544 if (v instanceof OpenMapRealVector) { +545 return getLInfDistance((OpenMapRealVector) v); +546 } +547 return getLInfDistance(v.getData()); +548 } +549 +550 /** {@inheritDoc} */ +551 @Override +552 public double getLInfDistance(double[] v) throws IllegalArgumentException { +553 checkVectorDimensions(v.length); +554 double max = 0; +555 for (int i = 0; i < v.length; i++) { +556 double delta = Math.abs(getEntry(i) - v[i]); +557 if (delta > max) { +558 max = delta; +559 } +560 } +561 return max; +562 } +563 +564 /** {@inheritDoc} */ +565 public boolean isInfinite() { +566 boolean infiniteFound = false; +567 Iterator iter = entries.iterator(); +568 while (iter.hasNext()) { +569 iter.advance(); +570 final double value = iter.value(); +571 if (Double.isNaN(value)) { +572 return false; +573 } +574 if (Double.isInfinite(value)) { +575 infiniteFound = true; +576 } +577 } +578 return infiniteFound; +579 } +580 +581 /** {@inheritDoc} */ +582 public boolean isNaN() { +583 Iterator iter = entries.iterator(); +584 while (iter.hasNext()) { +585 iter.advance(); +586 if (Double.isNaN(iter.value())) { +587 return true; +588 } +589 } +590 return false; +591 } +592 +593 /** {@inheritDoc} */ +594 @Override +595 public OpenMapRealVector mapAdd(double d) { +596 return copy().mapAddToSelf(d); +597 } +598 +599 /** {@inheritDoc} */ +600 @Override +601 public OpenMapRealVector mapAddToSelf(double d) { +602 for (int i = 0; i < virtualSize; i++) { +603 setEntry(i, getEntry(i) + d); +604 } +605 return this; +606 } +607 +608 /** {@inheritDoc} */ +609 @Override +610 public RealMatrix outerProduct(double[] v) throws IllegalArgumentException { +611 checkVectorDimensions(v.length); +612 RealMatrix res = new OpenMapRealMatrix(virtualSize, virtualSize); +613 Iterator iter = entries.iterator(); +614 while (iter.hasNext()) { +615 iter.advance(); +616 int row = iter.key(); +617 double value = iter.value(); +618 for (int col = 0; col < virtualSize; col++) { +619 res.setEntry(row, col, value * v[col]); +620 } +621 } +622 return res; +623 } +624 +625 /** {@inheritDoc} */ +626 public RealVector projection(RealVector v) throws IllegalArgumentException { +627 checkVectorDimensions(v.getDimension()); +628 return v.mapMultiply(dotProduct(v) / v.dotProduct(v)); +629 } +630 +631 /** {@inheritDoc} */ +632 @Override +633 public OpenMapRealVector projection(double[] v) throws IllegalArgumentException { +634 checkVectorDimensions(v.length); +635 return (OpenMapRealVector) projection(new OpenMapRealVector(v)); +636 } +637 +638 /** {@inheritDoc} */ +639 public void setEntry(int index, double value) throws MatrixIndexException { +640 checkIndex(index); +641 if (!isDefaultValue(value)) { +642 entries.put(index, value); +643 } else if (entries.containsKey(index)) { +644 entries.remove(index); +645 } +646 } +647 +648 /** {@inheritDoc} */ +649 @Override +650 public void setSubVector(int index, RealVector v) throws MatrixIndexException { +651 checkIndex(index); +652 checkIndex(index + v.getDimension() - 1); +653 setSubVector(index, v.getData()); +654 } +655 +656 /** {@inheritDoc} */ +657 @Override +658 public void setSubVector(int index, double[] v) throws MatrixIndexException { +659 checkIndex(index); +660 checkIndex(index + v.length - 1); +661 for (int i = 0; i < v.length; i++) { +662 setEntry(i + index, v[i]); +663 } +664 } +665 +666 /** {@inheritDoc} */ +667 @Override +668 public void set(double value) { +669 for (int i = 0; i < virtualSize; i++) { +670 setEntry(i, value); +671 } +672 } +673 +674 /** +675 * Optimized method to subtract OpenMapRealVectors. +676 * @param v The vector to subtract from <code>this</code> +677 * @return The difference of <code>this</code> and <code>v</code> +678 * @throws IllegalArgumentException If the dimensions don't match +679 */ +680 public OpenMapRealVector subtract(OpenMapRealVector v) throws IllegalArgumentException{ +681 checkVectorDimensions(v.getDimension()); +682 OpenMapRealVector res = copy(); +683 Iterator iter = v.getEntries().iterator(); +684 while (iter.hasNext()) { +685 iter.advance(); +686 int key = iter.key(); +687 if (entries.containsKey(key)) { +688 res.setEntry(key, entries.get(key) - iter.value()); +689 } else { +690 res.setEntry(key, -iter.value()); +691 } +692 } +693 return res; +694 } +695 +696 /** {@inheritDoc} */ +697 @Override +698 public OpenMapRealVector subtract(RealVector v) throws IllegalArgumentException { +699 checkVectorDimensions(v.getDimension()); +700 if (v instanceof OpenMapRealVector) { +701 return subtract((OpenMapRealVector) v); +702 } +703 return subtract(v.getData()); +704 } +705 +706 /** {@inheritDoc} */ +707 @Override +708 public OpenMapRealVector subtract(double[] v) throws IllegalArgumentException { +709 checkVectorDimensions(v.length); +710 OpenMapRealVector res = new OpenMapRealVector(this); +711 for (int i = 0; i < v.length; i++) { +712 if (entries.containsKey(i)) { +713 res.setEntry(i, entries.get(i) - v[i]); +714 } else { +715 res.setEntry(i, -v[i]); +716 } +717 } +718 return res; +719 } +720 +721 +722 /** {@inheritDoc} */ +723 @Override +724 public OpenMapRealVector unitVector() { +725 OpenMapRealVector res = copy(); +726 res.unitize(); +727 return res; +728 } +729 +730 /** {@inheritDoc} */ +731 @Override +732 public void unitize() { +733 double norm = getNorm(); +734 if (isDefaultValue(norm)) { +735 throw MathRuntimeException.createArithmeticException("cannot normalize a zero norm vector"); +736 } +737 Iterator iter = entries.iterator(); +738 while (iter.hasNext()) { +739 iter.advance(); +740 entries.put(iter.key(), iter.value() / norm); +741 } +742 +743 } +744 +745 +746 /** {@inheritDoc} */ +747 @Override +748 public double[] toArray() { +749 return getData(); +750 } +751 +752 /** {@inheritDoc} +753 * <p> Implementation Note: This works on exact values, and as a result +754 * it is possible for {@code a.subtract(b)} to be the zero vector, while +755 * {@code a.hashCode() != b.hashCode()}.</p> +756 */ +757 @Override +758 public int hashCode() { +759 final int prime = 31; +760 int result = 1; +761 long temp; +762 temp = Double.doubleToLongBits(epsilon); +763 result = prime * result + (int) (temp ^ (temp >>> 32)); +764 result = prime * result + virtualSize; +765 Iterator iter = entries.iterator(); +766 while (iter.hasNext()) { +767 iter.advance(); +768 temp = Double.doubleToLongBits(iter.value()); +769 result = prime * result + (int) (temp ^ (temp >>32)); +770 } +771 return result; +772 } +773 +774 /** +775 * <p> Implementation Note: This performs an exact comparison, and as a result +776 * it is possible for {@code a.subtract(b}} to be the zero vector, while +777 * {@code a.equals(b) == false}.</p> +778 * {@inheritDoc} +779 */ +780 @Override +781 public boolean equals(Object obj) { +782 if (this == obj) { +783 return true; +784 } +785 if (!(obj instanceof OpenMapRealVector)) { +786 return false; +787 } +788 OpenMapRealVector other = (OpenMapRealVector) obj; +789 if (virtualSize != other.virtualSize) { +790 return false; +791 } +792 if (Double.doubleToLongBits(epsilon) != +793 Double.doubleToLongBits(other.epsilon)) { +794 return false; +795 } +796 Iterator iter = entries.iterator(); +797 while (iter.hasNext()) { +798 iter.advance(); +799 double test = other.getEntry(iter.key()); +800 if (Double.doubleToLongBits(test) != Double.doubleToLongBits(iter.value())) { +801 return false; +802 } +803 } +804 iter = other.getEntries().iterator(); +805 while (iter.hasNext()) { +806 iter.advance(); +807 double test = iter.value(); +808 if (Double.doubleToLongBits(test) != Double.doubleToLongBits(getEntry(iter.key()))) { +809 return false; +810 } +811 } +812 return true; +813 } +814 +815 /** +816 * +817 * @return the percentage of none zero elements as a decimal percent. +818 */ +819 public double getSparcity() { +820 return (double)entries.size()/(double)getDimension(); +821 } +822 +823 /** {@inheritDoc} */ +824 @Override +825 public java.util.Iterator<Entry> sparseIterator() { +826 return new OpenMapSparseIterator(); +827 } +828 +829 /** +830 * Implementation of <code>Entry</code> optimized for OpenMap. +831 * <p>This implementation does not allow arbitrary calls to <code>setIndex</code> +832 * since the order that entries are returned is undefined. +833 */ +834 protected class OpenMapEntry extends Entry { +835 +836 /** Iterator pointing to the entry. */ +837 private final Iterator iter; +838 +839 /** Build an entry from an iterator point to an element. +840 * @param iter iterator pointing to the entry +841 */ +842 protected OpenMapEntry(Iterator iter) { +843 this.iter = iter; +844 } +845 +846 /** {@inheritDoc} */ +847 @Override +848 public double getValue() { +849 return iter.value(); +850 } +851 +852 /** {@inheritDoc} */ +853 @Override +854 public void setValue(double value) { +855 entries.put(iter.key(), value); +856 } +857 +858 /** {@inheritDoc} */ +859 @Override +860 public int getIndex() { +861 return iter.key(); +862 } +863 +864 } +865 +866 /** +867 * Iterator class to do iteration over just the non-zero elements. +868 * <p>This implementation is fail-fast, so cannot be used to modify any zero element. +869 * +870 */ +871 protected class OpenMapSparseIterator implements java.util.Iterator<Entry> { +872 +873 /** Underlying iterator. */ +874 private final Iterator iter; +875 +876 /** Current entry. */ +877 private final Entry current; +878 +879 /** Simple constructor. */ +880 protected OpenMapSparseIterator() { +881 iter = entries.iterator(); +882 current = new OpenMapEntry(iter); +883 } +884 +885 /** {@inheritDoc} */ +886 public boolean hasNext() { +887 return iter.hasNext(); +888 } +889 +890 /** {@inheritDoc} */ +891 public Entry next() { +892 iter.advance(); +893 return current; +894 } +895 +896 /** {@inheritDoc} */ +897 public void remove() { +898 throw new UnsupportedOperationException("Not supported"); +899 } +900 +901 } +902 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/QRDecomposition.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/QRDecomposition.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,143 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 +021 /** +022 * An interface to classes that implement an algorithm to calculate the +023 * QR-decomposition of a real matrix. +024 * <p>This interface is based on the class with similar name from the +025 * <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> library, with the +026 * following changes:</p> +027 * <ul> +028 * <li>a {@link #getQT() getQT} method has been added,</li> +029 * <li>the <code>solve</code> and <code>isFullRank</code> methods have been replaced +030 * by a {@link #getSolver() getSolver} method and the equivalent methods provided by +031 * the returned {@link DecompositionSolver}.</li> +032 * </ul> +033 * +034 * @see <a href="http://mathworld.wolfram.com/QRDecomposition.html">MathWorld</a> +035 * @see <a href="http://en.wikipedia.org/wiki/QR_decomposition">Wikipedia</a> +036 * @version $Revision: 826627 $ $Date: 2009-10-19 06:27:47 -0400 (Mon, 19 Oct 2009) $ +037 * @since 1.2 +038 */ +039 public interface QRDecomposition { +040 +041 /** +042 * Returns the matrix R of the decomposition. +043 * <p>R is an upper-triangular matrix</p> +044 * @return the R matrix +045 */ +046 RealMatrix getR(); +047 +048 /** +049 * Returns the matrix Q of the decomposition. +050 * <p>Q is an orthogonal matrix</p> +051 * @return the Q matrix +052 */ +053 RealMatrix getQ(); +054 +055 /** +056 * Returns the transpose of the matrix Q of the decomposition. +057 * <p>Q is an orthogonal matrix</p> +058 * @return the Q matrix +059 */ +060 RealMatrix getQT(); +061 +062 /** +063 * Returns the Householder reflector vectors. +064 * <p>H is a lower trapezoidal matrix whose columns represent +065 * each successive Householder reflector vector. This matrix is used +066 * to compute Q.</p> +067 * @return a matrix containing the Householder reflector vectors +068 */ +069 RealMatrix getH(); +070 +071 /** +072 * Get a solver for finding the A × X = B solution in least square sense. +073 * @return a solver +074 */ +075 DecompositionSolver getSolver(); +076 +077 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/QRDecompositionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/QRDecompositionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,517 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.util.Arrays; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 +024 +025 /** +026 * Calculates the QR-decomposition of a matrix. +027 * <p>The QR-decomposition of a matrix A consists of two matrices Q and R +028 * that satisfy: A = QR, Q is orthogonal (Q<sup>T</sup>Q = I), and R is +029 * upper triangular. If A is m×n, Q is m×m and R m×n.</p> +030 * <p>This class compute the decomposition using Householder reflectors.</p> +031 * <p>For efficiency purposes, the decomposition in packed form is transposed. +032 * This allows inner loop to iterate inside rows, which is much more cache-efficient +033 * in Java.</p> +034 * +035 * @see <a href="http://mathworld.wolfram.com/QRDecomposition.html">MathWorld</a> +036 * @see <a href="http://en.wikipedia.org/wiki/QR_decomposition">Wikipedia</a> +037 * +038 * @version $Revision: 825919 $ $Date: 2009-10-16 10:51:55 -0400 (Fri, 16 Oct 2009) $ +039 * @since 1.2 +040 */ +041 public class QRDecompositionImpl implements QRDecomposition { +042 +043 /** +044 * A packed TRANSPOSED representation of the QR decomposition. +045 * <p>The elements BELOW the diagonal are the elements of the UPPER triangular +046 * matrix R, and the rows ABOVE the diagonal are the Householder reflector vectors +047 * from which an explicit form of Q can be recomputed if desired.</p> +048 */ +049 private double[][] qrt; +050 +051 /** The diagonal elements of R. */ +052 private double[] rDiag; +053 +054 /** Cached value of Q. */ +055 private RealMatrix cachedQ; +056 +057 /** Cached value of QT. */ +058 private RealMatrix cachedQT; +059 +060 /** Cached value of R. */ +061 private RealMatrix cachedR; +062 +063 /** Cached value of H. */ +064 private RealMatrix cachedH; +065 +066 /** +067 * Calculates the QR-decomposition of the given matrix. +068 * @param matrix The matrix to decompose. +069 */ +070 public QRDecompositionImpl(RealMatrix matrix) { +071 +072 final int m = matrix.getRowDimension(); +073 final int n = matrix.getColumnDimension(); +074 qrt = matrix.transpose().getData(); +075 rDiag = new double[Math.min(m, n)]; +076 cachedQ = null; +077 cachedQT = null; +078 cachedR = null; +079 cachedH = null; +080 +081 /* +082 * The QR decomposition of a matrix A is calculated using Householder +083 * reflectors by repeating the following operations to each minor +084 * A(minor,minor) of A: +085 */ +086 for (int minor = 0; minor < Math.min(m, n); minor++) { +087 +088 final double[] qrtMinor = qrt[minor]; +089 +090 /* +091 * Let x be the first column of the minor, and a^2 = |x|^2. +092 * x will be in the positions qr[minor][minor] through qr[m][minor]. +093 * The first column of the transformed minor will be (a,0,0,..)' +094 * The sign of a is chosen to be opposite to the sign of the first +095 * component of x. Let's find a: +096 */ +097 double xNormSqr = 0; +098 for (int row = minor; row < m; row++) { +099 final double c = qrtMinor[row]; +100 xNormSqr += c * c; +101 } +102 final double a = (qrtMinor[minor] > 0) ? -Math.sqrt(xNormSqr) : Math.sqrt(xNormSqr); +103 rDiag[minor] = a; +104 +105 if (a != 0.0) { +106 +107 /* +108 * Calculate the normalized reflection vector v and transform +109 * the first column. We know the norm of v beforehand: v = x-ae +110 * so |v|^2 = <x-ae,x-ae> = <x,x>-2a<x,e>+a^2<e,e> = +111 * a^2+a^2-2a<x,e> = 2a*(a - <x,e>). +112 * Here <x, e> is now qr[minor][minor]. +113 * v = x-ae is stored in the column at qr: +114 */ +115 qrtMinor[minor] -= a; // now |v|^2 = -2a*(qr[minor][minor]) +116 +117 /* +118 * Transform the rest of the columns of the minor: +119 * They will be transformed by the matrix H = I-2vv'/|v|^2. +120 * If x is a column vector of the minor, then +121 * Hx = (I-2vv'/|v|^2)x = x-2vv'x/|v|^2 = x - 2<x,v>/|v|^2 v. +122 * Therefore the transformation is easily calculated by +123 * subtracting the column vector (2<x,v>/|v|^2)v from x. +124 * +125 * Let 2<x,v>/|v|^2 = alpha. From above we have +126 * |v|^2 = -2a*(qr[minor][minor]), so +127 * alpha = -<x,v>/(a*qr[minor][minor]) +128 */ +129 for (int col = minor+1; col < n; col++) { +130 final double[] qrtCol = qrt[col]; +131 double alpha = 0; +132 for (int row = minor; row < m; row++) { +133 alpha -= qrtCol[row] * qrtMinor[row]; +134 } +135 alpha /= a * qrtMinor[minor]; +136 +137 // Subtract the column vector alpha*v from x. +138 for (int row = minor; row < m; row++) { +139 qrtCol[row] -= alpha * qrtMinor[row]; +140 } +141 } +142 } +143 } +144 } +145 +146 /** {@inheritDoc} */ +147 public RealMatrix getR() { +148 +149 if (cachedR == null) { +150 +151 // R is supposed to be m x n +152 final int n = qrt.length; +153 final int m = qrt[0].length; +154 cachedR = MatrixUtils.createRealMatrix(m, n); +155 +156 // copy the diagonal from rDiag and the upper triangle of qr +157 for (int row = Math.min(m, n) - 1; row >= 0; row--) { +158 cachedR.setEntry(row, row, rDiag[row]); +159 for (int col = row + 1; col < n; col++) { +160 cachedR.setEntry(row, col, qrt[col][row]); +161 } +162 } +163 +164 } +165 +166 // return the cached matrix +167 return cachedR; +168 +169 } +170 +171 /** {@inheritDoc} */ +172 public RealMatrix getQ() { +173 if (cachedQ == null) { +174 cachedQ = getQT().transpose(); +175 } +176 return cachedQ; +177 } +178 +179 /** {@inheritDoc} */ +180 public RealMatrix getQT() { +181 +182 if (cachedQT == null) { +183 +184 // QT is supposed to be m x m +185 final int n = qrt.length; +186 final int m = qrt[0].length; +187 cachedQT = MatrixUtils.createRealMatrix(m, m); +188 +189 /* +190 * Q = Q1 Q2 ... Q_m, so Q is formed by first constructing Q_m and then +191 * applying the Householder transformations Q_(m-1),Q_(m-2),...,Q1 in +192 * succession to the result +193 */ +194 for (int minor = m - 1; minor >= Math.min(m, n); minor--) { +195 cachedQT.setEntry(minor, minor, 1.0); +196 } +197 +198 for (int minor = Math.min(m, n)-1; minor >= 0; minor--){ +199 final double[] qrtMinor = qrt[minor]; +200 cachedQT.setEntry(minor, minor, 1.0); +201 if (qrtMinor[minor] != 0.0) { +202 for (int col = minor; col < m; col++) { +203 double alpha = 0; +204 for (int row = minor; row < m; row++) { +205 alpha -= cachedQT.getEntry(col, row) * qrtMinor[row]; +206 } +207 alpha /= rDiag[minor] * qrtMinor[minor]; +208 +209 for (int row = minor; row < m; row++) { +210 cachedQT.addToEntry(col, row, -alpha * qrtMinor[row]); +211 } +212 } +213 } +214 } +215 +216 } +217 +218 // return the cached matrix +219 return cachedQT; +220 +221 } +222 +223 /** {@inheritDoc} */ +224 public RealMatrix getH() { +225 +226 if (cachedH == null) { +227 +228 final int n = qrt.length; +229 final int m = qrt[0].length; +230 cachedH = MatrixUtils.createRealMatrix(m, n); +231 for (int i = 0; i < m; ++i) { +232 for (int j = 0; j < Math.min(i + 1, n); ++j) { +233 cachedH.setEntry(i, j, qrt[j][i] / -rDiag[j]); +234 } +235 } +236 +237 } +238 +239 // return the cached matrix +240 return cachedH; +241 +242 } +243 +244 /** {@inheritDoc} */ +245 public DecompositionSolver getSolver() { +246 return new Solver(qrt, rDiag); +247 } +248 +249 /** Specialized solver. */ +250 private static class Solver implements DecompositionSolver { +251 +252 /** +253 * A packed TRANSPOSED representation of the QR decomposition. +254 * <p>The elements BELOW the diagonal are the elements of the UPPER triangular +255 * matrix R, and the rows ABOVE the diagonal are the Householder reflector vectors +256 * from which an explicit form of Q can be recomputed if desired.</p> +257 */ +258 private final double[][] qrt; +259 +260 /** The diagonal elements of R. */ +261 private final double[] rDiag; +262 +263 /** +264 * Build a solver from decomposed matrix. +265 * @param qrt packed TRANSPOSED representation of the QR decomposition +266 * @param rDiag diagonal elements of R +267 */ +268 private Solver(final double[][] qrt, final double[] rDiag) { +269 this.qrt = qrt; +270 this.rDiag = rDiag; +271 } +272 +273 /** {@inheritDoc} */ +274 public boolean isNonSingular() { +275 +276 for (double diag : rDiag) { +277 if (diag == 0) { +278 return false; +279 } +280 } +281 return true; +282 +283 } +284 +285 /** {@inheritDoc} */ +286 public double[] solve(double[] b) +287 throws IllegalArgumentException, InvalidMatrixException { +288 +289 final int n = qrt.length; +290 final int m = qrt[0].length; +291 if (b.length != m) { +292 throw MathRuntimeException.createIllegalArgumentException( +293 "vector length mismatch: got {0} but expected {1}", +294 b.length, m); +295 } +296 if (!isNonSingular()) { +297 throw new SingularMatrixException(); +298 } +299 +300 final double[] x = new double[n]; +301 final double[] y = b.clone(); +302 +303 // apply Householder transforms to solve Q.y = b +304 for (int minor = 0; minor < Math.min(m, n); minor++) { +305 +306 final double[] qrtMinor = qrt[minor]; +307 double dotProduct = 0; +308 for (int row = minor; row < m; row++) { +309 dotProduct += y[row] * qrtMinor[row]; +310 } +311 dotProduct /= rDiag[minor] * qrtMinor[minor]; +312 +313 for (int row = minor; row < m; row++) { +314 y[row] += dotProduct * qrtMinor[row]; +315 } +316 +317 } +318 +319 // solve triangular system R.x = y +320 for (int row = rDiag.length - 1; row >= 0; --row) { +321 y[row] /= rDiag[row]; +322 final double yRow = y[row]; +323 final double[] qrtRow = qrt[row]; +324 x[row] = yRow; +325 for (int i = 0; i < row; i++) { +326 y[i] -= yRow * qrtRow[i]; +327 } +328 } +329 +330 return x; +331 +332 } +333 +334 /** {@inheritDoc} */ +335 public RealVector solve(RealVector b) +336 throws IllegalArgumentException, InvalidMatrixException { +337 try { +338 return solve((ArrayRealVector) b); +339 } catch (ClassCastException cce) { +340 return new ArrayRealVector(solve(b.getData()), false); +341 } +342 } +343 +344 /** Solve the linear equation A × X = B. +345 * <p>The A matrix is implicit here. It is </p> +346 * @param b right-hand side of the equation A × X = B +347 * @return a vector X that minimizes the two norm of A × X - B +348 * @throws IllegalArgumentException if matrices dimensions don't match +349 * @throws InvalidMatrixException if decomposed matrix is singular +350 */ +351 public ArrayRealVector solve(ArrayRealVector b) +352 throws IllegalArgumentException, InvalidMatrixException { +353 return new ArrayRealVector(solve(b.getDataRef()), false); +354 } +355 +356 /** {@inheritDoc} */ +357 public RealMatrix solve(RealMatrix b) +358 throws IllegalArgumentException, InvalidMatrixException { +359 +360 final int n = qrt.length; +361 final int m = qrt[0].length; +362 if (b.getRowDimension() != m) { +363 throw MathRuntimeException.createIllegalArgumentException( +364 "dimensions mismatch: got {0}x{1} but expected {2}x{3}", +365 b.getRowDimension(), b.getColumnDimension(), m, "n"); +366 } +367 if (!isNonSingular()) { +368 throw new SingularMatrixException(); +369 } +370 +371 final int columns = b.getColumnDimension(); +372 final int blockSize = BlockRealMatrix.BLOCK_SIZE; +373 final int cBlocks = (columns + blockSize - 1) / blockSize; +374 final double[][] xBlocks = BlockRealMatrix.createBlocksLayout(n, columns); +375 final double[][] y = new double[b.getRowDimension()][blockSize]; +376 final double[] alpha = new double[blockSize]; +377 +378 for (int kBlock = 0; kBlock < cBlocks; ++kBlock) { +379 final int kStart = kBlock * blockSize; +380 final int kEnd = Math.min(kStart + blockSize, columns); +381 final int kWidth = kEnd - kStart; +382 +383 // get the right hand side vector +384 b.copySubMatrix(0, m - 1, kStart, kEnd - 1, y); +385 +386 // apply Householder transforms to solve Q.y = b +387 for (int minor = 0; minor < Math.min(m, n); minor++) { +388 final double[] qrtMinor = qrt[minor]; +389 final double factor = 1.0 / (rDiag[minor] * qrtMinor[minor]); +390 +391 Arrays.fill(alpha, 0, kWidth, 0.0); +392 for (int row = minor; row < m; ++row) { +393 final double d = qrtMinor[row]; +394 final double[] yRow = y[row]; +395 for (int k = 0; k < kWidth; ++k) { +396 alpha[k] += d * yRow[k]; +397 } +398 } +399 for (int k = 0; k < kWidth; ++k) { +400 alpha[k] *= factor; +401 } +402 +403 for (int row = minor; row < m; ++row) { +404 final double d = qrtMinor[row]; +405 final double[] yRow = y[row]; +406 for (int k = 0; k < kWidth; ++k) { +407 yRow[k] += alpha[k] * d; +408 } +409 } +410 +411 } +412 +413 // solve triangular system R.x = y +414 for (int j = rDiag.length - 1; j >= 0; --j) { +415 final int jBlock = j / blockSize; +416 final int jStart = jBlock * blockSize; +417 final double factor = 1.0 / rDiag[j]; +418 final double[] yJ = y[j]; +419 final double[] xBlock = xBlocks[jBlock * cBlocks + kBlock]; +420 int index = (j - jStart) * kWidth; +421 for (int k = 0; k < kWidth; ++k) { +422 yJ[k] *= factor; +423 xBlock[index++] = yJ[k]; +424 } +425 +426 final double[] qrtJ = qrt[j]; +427 for (int i = 0; i < j; ++i) { +428 final double rIJ = qrtJ[i]; +429 final double[] yI = y[i]; +430 for (int k = 0; k < kWidth; ++k) { +431 yI[k] -= yJ[k] * rIJ; +432 } +433 } +434 +435 } +436 +437 } +438 +439 return new BlockRealMatrix(n, columns, xBlocks, false); +440 +441 } +442 +443 /** {@inheritDoc} */ +444 public RealMatrix getInverse() +445 throws InvalidMatrixException { +446 return solve(MatrixUtils.createRealIdentityMatrix(rDiag.length)); +447 } +448 +449 } +450 +451 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/RealMatrix.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/RealMatrix.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,935 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 +021 /** +022 * Interface defining a real-valued matrix with basic algebraic operations. +023 * <p> +024 * Matrix element indexing is 0-based -- e.g., <code>getEntry(0, 0)</code> +025 * returns the element in the first row, first column of the matrix.</p> +026 * +027 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +028 */ +029 public interface RealMatrix extends AnyMatrix { +030 +031 /** +032 * Create a new RealMatrix of the same type as the instance with the supplied +033 * row and column dimensions. +034 * +035 * @param rowDimension the number of rows in the new matrix +036 * @param columnDimension the number of columns in the new matrix +037 * @return a new matrix of the same type as the instance +038 * @throws IllegalArgumentException if row or column dimension is not positive +039 * @since 2.0 +040 */ +041 RealMatrix createMatrix(final int rowDimension, final int columnDimension); +042 +043 /** +044 * Returns a (deep) copy of this. +045 * +046 * @return matrix copy +047 */ +048 RealMatrix copy(); +049 +050 /** +051 * Compute the sum of this and m. +052 * +053 * @param m matrix to be added +054 * @return this + m +055 * @throws IllegalArgumentException if m is not the same size as this +056 */ +057 RealMatrix add(RealMatrix m) throws IllegalArgumentException; +058 +059 /** +060 * Compute this minus m. +061 * +062 * @param m matrix to be subtracted +063 * @return this - m +064 * @throws IllegalArgumentException if m is not the same size as this +065 */ +066 RealMatrix subtract(RealMatrix m) throws IllegalArgumentException; +067 +068 /** +069 * Returns the result of adding d to each entry of this. +070 * +071 * @param d value to be added to each entry +072 * @return d + this +073 */ +074 RealMatrix scalarAdd(double d); +075 +076 /** +077 * Returns the result multiplying each entry of this by d. +078 * +079 * @param d value to multiply all entries by +080 * @return d * this +081 */ +082 RealMatrix scalarMultiply(double d); +083 +084 /** +085 * Returns the result of postmultiplying this by m. +086 * +087 * @param m matrix to postmultiply by +088 * @return this * m +089 * @throws IllegalArgumentException +090 * if columnDimension(this) != rowDimension(m) +091 */ +092 RealMatrix multiply(RealMatrix m) throws IllegalArgumentException; +093 +094 /** +095 * Returns the result premultiplying this by <code>m</code>. +096 * @param m matrix to premultiply by +097 * @return m * this +098 * @throws IllegalArgumentException +099 * if rowDimension(this) != columnDimension(m) +100 */ +101 RealMatrix preMultiply(RealMatrix m) throws IllegalArgumentException; +102 +103 /** +104 * Returns matrix entries as a two-dimensional array. +105 * +106 * @return 2-dimensional array of entries +107 */ +108 double[][] getData(); +109 +110 /** +111 * Returns the <a href="http://mathworld.wolfram.com/MaximumAbsoluteRowSumNorm.html"> +112 * maximum absolute row sum norm</a> of the matrix. +113 * +114 * @return norm +115 */ +116 double getNorm(); +117 +118 /** +119 * Returns the <a href="http://mathworld.wolfram.com/FrobeniusNorm.html"> +120 * Frobenius norm</a> of the matrix. +121 * +122 * @return norm +123 */ +124 double getFrobeniusNorm(); +125 +126 /** +127 * Gets a submatrix. Rows and columns are indicated +128 * counting from 0 to n-1. +129 * +130 * @param startRow Initial row index +131 * @param endRow Final row index (inclusive) +132 * @param startColumn Initial column index +133 * @param endColumn Final column index (inclusive) +134 * @return The subMatrix containing the data of the +135 * specified rows and columns +136 * @exception MatrixIndexException if the indices are not valid +137 */ +138 RealMatrix getSubMatrix(int startRow, int endRow, int startColumn, int endColumn) +139 throws MatrixIndexException; +140 +141 /** +142 * Gets a submatrix. Rows and columns are indicated +143 * counting from 0 to n-1. +144 * +145 * @param selectedRows Array of row indices. +146 * @param selectedColumns Array of column indices. +147 * @return The subMatrix containing the data in the +148 * specified rows and columns +149 * @exception MatrixIndexException if row or column selections are not valid +150 */ +151 RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns) +152 throws MatrixIndexException; +153 +154 /** +155 * Copy a submatrix. Rows and columns are indicated +156 * counting from 0 to n-1. +157 * +158 * @param startRow Initial row index +159 * @param endRow Final row index (inclusive) +160 * @param startColumn Initial column index +161 * @param endColumn Final column index (inclusive) +162 * @param destination The arrays where the submatrix data should be copied +163 * (if larger than rows/columns counts, only the upper-left part will be used) +164 * @exception MatrixIndexException if the indices are not valid +165 * @exception IllegalArgumentException if the destination array is too small +166 */ +167 void copySubMatrix(int startRow, int endRow, int startColumn, int endColumn, +168 double[][] destination) +169 throws MatrixIndexException, IllegalArgumentException; +170 +171 /** +172 * Copy a submatrix. Rows and columns are indicated +173 * counting from 0 to n-1. +174 * +175 * @param selectedRows Array of row indices. +176 * @param selectedColumns Array of column indices. +177 * @param destination The arrays where the submatrix data should be copied +178 * (if larger than rows/columns counts, only the upper-left part will be used) +179 * @exception MatrixIndexException if the indices are not valid +180 * @exception IllegalArgumentException if the destination array is too small +181 */ +182 void copySubMatrix(int[] selectedRows, int[] selectedColumns, double[][] destination) +183 throws MatrixIndexException, IllegalArgumentException; +184 +185 /** +186 * Replace the submatrix starting at <code>row, column</code> using data in +187 * the input <code>subMatrix</code> array. Indexes are 0-based. +188 * <p> +189 * Example:<br> +190 * Starting with <pre> +191 * 1 2 3 4 +192 * 5 6 7 8 +193 * 9 0 1 2 +194 * </pre> +195 * and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking +196 * <code>setSubMatrix(subMatrix,1,1))</code> will result in <pre> +197 * 1 2 3 4 +198 * 5 3 4 8 +199 * 9 5 6 2 +200 * </pre></p> +201 * +202 * @param subMatrix array containing the submatrix replacement data +203 * @param row row coordinate of the top, left element to be replaced +204 * @param column column coordinate of the top, left element to be replaced +205 * @throws MatrixIndexException if subMatrix does not fit into this +206 * matrix from element in (row, column) +207 * @throws IllegalArgumentException if <code>subMatrix</code> is not rectangular +208 * (not all rows have the same length) or empty +209 * @throws NullPointerException if <code>subMatrix</code> is null +210 * @since 2.0 +211 */ +212 void setSubMatrix(double[][] subMatrix, int row, int column) +213 throws MatrixIndexException; +214 +215 /** +216 * Returns the entries in row number <code>row</code> +217 * as a row matrix. Row indices start at 0. +218 * +219 * @param row the row to be fetched +220 * @return row matrix +221 * @throws MatrixIndexException if the specified row index is invalid +222 */ +223 RealMatrix getRowMatrix(int row) throws MatrixIndexException; +224 +225 /** +226 * Sets the entries in row number <code>row</code> +227 * as a row matrix. Row indices start at 0. +228 * +229 * @param row the row to be set +230 * @param matrix row matrix (must have one row and the same number of columns +231 * as the instance) +232 * @throws MatrixIndexException if the specified row index is invalid +233 * @throws InvalidMatrixException if the matrix dimensions do not match one +234 * instance row +235 */ +236 void setRowMatrix(int row, RealMatrix matrix) +237 throws MatrixIndexException, InvalidMatrixException; +238 +239 /** +240 * Returns the entries in column number <code>column</code> +241 * as a column matrix. Column indices start at 0. +242 * +243 * @param column the column to be fetched +244 * @return column matrix +245 * @throws MatrixIndexException if the specified column index is invalid +246 */ +247 RealMatrix getColumnMatrix(int column) throws MatrixIndexException; +248 +249 /** +250 * Sets the entries in column number <code>column</code> +251 * as a column matrix. Column indices start at 0. +252 * +253 * @param column the column to be set +254 * @param matrix column matrix (must have one column and the same number of rows +255 * as the instance) +256 * @throws MatrixIndexException if the specified column index is invalid +257 * @throws InvalidMatrixException if the matrix dimensions do not match one +258 * instance column +259 */ +260 void setColumnMatrix(int column, RealMatrix matrix) +261 throws MatrixIndexException, InvalidMatrixException; +262 +263 /** +264 * Returns the entries in row number <code>row</code> +265 * as a vector. Row indices start at 0. +266 * +267 * @param row the row to be fetched +268 * @return row vector +269 * @throws MatrixIndexException if the specified row index is invalid +270 */ +271 RealVector getRowVector(int row) throws MatrixIndexException; +272 +273 /** +274 * Sets the entries in row number <code>row</code> +275 * as a vector. Row indices start at 0. +276 * +277 * @param row the row to be set +278 * @param vector row vector (must have the same number of columns +279 * as the instance) +280 * @throws MatrixIndexException if the specified row index is invalid +281 * @throws InvalidMatrixException if the vector dimension does not match one +282 * instance row +283 */ +284 void setRowVector(int row, RealVector vector) +285 throws MatrixIndexException, InvalidMatrixException; +286 +287 /** +288 * Returns the entries in column number <code>column</code> +289 * as a vector. Column indices start at 0. +290 * +291 * @param column the column to be fetched +292 * @return column vector +293 * @throws MatrixIndexException if the specified column index is invalid +294 */ +295 RealVector getColumnVector(int column) throws MatrixIndexException; +296 +297 /** +298 * Sets the entries in column number <code>column</code> +299 * as a vector. Column indices start at 0. +300 * +301 * @param column the column to be set +302 * @param vector column vector (must have the same number of rows as the instance) +303 * @throws MatrixIndexException if the specified column index is invalid +304 * @throws InvalidMatrixException if the vector dimension does not match one +305 * instance column +306 */ +307 void setColumnVector(int column, RealVector vector) +308 throws MatrixIndexException, InvalidMatrixException; +309 +310 /** +311 * Returns the entries in row number <code>row</code> as an array. +312 * <p> +313 * Row indices start at 0. A <code>MatrixIndexException</code> is thrown +314 * unless <code>0 <= row < rowDimension.</code></p> +315 * +316 * @param row the row to be fetched +317 * @return array of entries in the row +318 * @throws MatrixIndexException if the specified row index is not valid +319 */ +320 double[] getRow(int row) throws MatrixIndexException; +321 +322 /** +323 * Sets the entries in row number <code>row</code> +324 * as a row matrix. Row indices start at 0. +325 * +326 * @param row the row to be set +327 * @param array row matrix (must have the same number of columns as the instance) +328 * @throws MatrixIndexException if the specified row index is invalid +329 * @throws InvalidMatrixException if the array size does not match one +330 * instance row +331 */ +332 void setRow(int row, double[] array) +333 throws MatrixIndexException, InvalidMatrixException; +334 +335 /** +336 * Returns the entries in column number <code>col</code> as an array. +337 * <p> +338 * Column indices start at 0. A <code>MatrixIndexException</code> is thrown +339 * unless <code>0 <= column < columnDimension.</code></p> +340 * +341 * @param column the column to be fetched +342 * @return array of entries in the column +343 * @throws MatrixIndexException if the specified column index is not valid +344 */ +345 double[] getColumn(int column) throws MatrixIndexException; +346 +347 /** +348 * Sets the entries in column number <code>column</code> +349 * as a column matrix. Column indices start at 0. +350 * +351 * @param column the column to be set +352 * @param array column array (must have the same number of rows as the instance) +353 * @throws MatrixIndexException if the specified column index is invalid +354 * @throws InvalidMatrixException if the array size does not match one +355 * instance column +356 */ +357 void setColumn(int column, double[] array) +358 throws MatrixIndexException, InvalidMatrixException; +359 +360 /** +361 * Returns the entry in the specified row and column. +362 * <p> +363 * Row and column indices start at 0 and must satisfy +364 * <ul> +365 * <li><code>0 <= row < rowDimension</code></li> +366 * <li><code> 0 <= column < columnDimension</code></li> +367 * </ul> +368 * otherwise a <code>MatrixIndexException</code> is thrown.</p> +369 * +370 * @param row row location of entry to be fetched +371 * @param column column location of entry to be fetched +372 * @return matrix entry in row,column +373 * @throws MatrixIndexException if the row or column index is not valid +374 */ +375 double getEntry(int row, int column) throws MatrixIndexException; +376 +377 /** +378 * Set the entry in the specified row and column. +379 * <p> +380 * Row and column indices start at 0 and must satisfy +381 * <ul> +382 * <li><code>0 <= row < rowDimension</code></li> +383 * <li><code> 0 <= column < columnDimension</code></li> +384 * </ul> +385 * otherwise a <code>MatrixIndexException</code> is thrown.</p> +386 * +387 * @param row row location of entry to be set +388 * @param column column location of entry to be set +389 * @param value matrix entry to be set in row,column +390 * @throws MatrixIndexException if the row or column index is not valid +391 * @since 2.0 +392 */ +393 void setEntry(int row, int column, double value) throws MatrixIndexException; +394 +395 /** +396 * Change an entry in the specified row and column. +397 * <p> +398 * Row and column indices start at 0 and must satisfy +399 * <ul> +400 * <li><code>0 <= row < rowDimension</code></li> +401 * <li><code> 0 <= column < columnDimension</code></li> +402 * </ul> +403 * otherwise a <code>MatrixIndexException</code> is thrown.</p> +404 * +405 * @param row row location of entry to be set +406 * @param column column location of entry to be set +407 * @param increment value to add to the current matrix entry in row,column +408 * @throws MatrixIndexException if the row or column index is not valid +409 * @since 2.0 +410 */ +411 void addToEntry(int row, int column, double increment) throws MatrixIndexException; +412 +413 /** +414 * Change an entry in the specified row and column. +415 * <p> +416 * Row and column indices start at 0 and must satisfy +417 * <ul> +418 * <li><code>0 <= row < rowDimension</code></li> +419 * <li><code> 0 <= column < columnDimension</code></li> +420 * </ul> +421 * otherwise a <code>MatrixIndexException</code> is thrown.</p> +422 * +423 * @param row row location of entry to be set +424 * @param column column location of entry to be set +425 * @param factor multiplication factor for the current matrix entry in row,column +426 * @throws MatrixIndexException if the row or column index is not valid +427 * @since 2.0 +428 */ +429 void multiplyEntry(int row, int column, double factor) throws MatrixIndexException; +430 +431 /** +432 * Returns the transpose of this matrix. +433 * +434 * @return transpose matrix +435 */ +436 RealMatrix transpose(); +437 +438 /** +439 * Returns the inverse of this matrix. +440 * +441 * @return inverse matrix +442 * @throws InvalidMatrixException if this is not invertible +443 * @deprecated as of release 2.0, replaced by <code> +444 * {@link LUDecompositionImpl#LUDecompositionImpl(RealMatrix) +445 * new LUDecompositionImpl(m)}.{@link LUDecomposition#getSolver() +446 * getSolver()}.{@link DecompositionSolver#getInverse() +447 * getInverse()}</code> +448 */ +449 @Deprecated +450 RealMatrix inverse() throws InvalidMatrixException; +451 +452 /** +453 * Returns the determinant of this matrix. +454 * +455 * @return determinant +456 * @deprecated as of release 2.0, replaced by <code> +457 * {@link LUDecompositionImpl#LUDecompositionImpl(RealMatrix) +458 * new LUDecompositionImpl(m)}.{@link LUDecomposition#getDeterminant() +459 * getDeterminant()}</code> +460 */ +461 @Deprecated +462 double getDeterminant(); +463 +464 /** +465 * Is this a singular matrix? +466 * @return true if the matrix is singular +467 * @deprecated as of release 2.0, replaced by the boolean negation of +468 * <code>{@link LUDecompositionImpl#LUDecompositionImpl(RealMatrix) +469 * new LUDecompositionImpl(m)}.{@link LUDecomposition#getSolver() +470 * getSolver()}.{@link DecompositionSolver#isNonSingular() +471 * isNonSingular()}</code> +472 */ +473 @Deprecated +474 boolean isSingular(); +475 +476 /** +477 * Returns the <a href="http://mathworld.wolfram.com/MatrixTrace.html"> +478 * trace</a> of the matrix (the sum of the elements on the main diagonal). +479 * +480 * @return trace +481 * @throws NonSquareMatrixException if the matrix is not square +482 */ +483 double getTrace() throws NonSquareMatrixException; +484 +485 /** +486 * Returns the result of multiplying this by the vector <code>v</code>. +487 * +488 * @param v the vector to operate on +489 * @return this*v +490 * @throws IllegalArgumentException if columnDimension != v.size() +491 */ +492 double[] operate(double[] v) throws IllegalArgumentException; +493 +494 /** +495 * Returns the result of multiplying this by the vector <code>v</code>. +496 * +497 * @param v the vector to operate on +498 * @return this*v +499 * @throws IllegalArgumentException if columnDimension != v.size() +500 */ +501 RealVector operate(RealVector v) throws IllegalArgumentException; +502 +503 /** +504 * Returns the (row) vector result of premultiplying this by the vector <code>v</code>. +505 * +506 * @param v the row vector to premultiply by +507 * @return v*this +508 * @throws IllegalArgumentException if rowDimension != v.size() +509 */ +510 double[] preMultiply(double[] v) throws IllegalArgumentException; +511 +512 /** +513 * Returns the (row) vector result of premultiplying this by the vector <code>v</code>. +514 * +515 * @param v the row vector to premultiply by +516 * @return v*this +517 * @throws IllegalArgumentException if rowDimension != v.size() +518 */ +519 RealVector preMultiply(RealVector v) throws IllegalArgumentException; +520 +521 /** +522 * Visit (and possibly change) all matrix entries in row order. +523 * <p>Row order starts at upper left and iterating through all elements +524 * of a row from left to right before going to the leftmost element +525 * of the next row.</p> +526 * @param visitor visitor used to process all matrix entries +527 * @exception MatrixVisitorException if the visitor cannot process an entry +528 * @see #walkInRowOrder(RealMatrixPreservingVisitor) +529 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) +530 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) +531 * @see #walkInColumnOrder(RealMatrixChangingVisitor) +532 * @see #walkInColumnOrder(RealMatrixPreservingVisitor) +533 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) +534 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) +535 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) +536 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) +537 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) +538 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) +539 * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end +540 * of the walk +541 */ +542 double walkInRowOrder(RealMatrixChangingVisitor visitor) +543 throws MatrixVisitorException; +544 +545 /** +546 * Visit (but don't change) all matrix entries in row order. +547 * <p>Row order starts at upper left and iterating through all elements +548 * of a row from left to right before going to the leftmost element +549 * of the next row.</p> +550 * @param visitor visitor used to process all matrix entries +551 * @exception MatrixVisitorException if the visitor cannot process an entry +552 * @see #walkInRowOrder(RealMatrixChangingVisitor) +553 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) +554 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) +555 * @see #walkInColumnOrder(RealMatrixChangingVisitor) +556 * @see #walkInColumnOrder(RealMatrixPreservingVisitor) +557 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) +558 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) +559 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) +560 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) +561 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) +562 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) +563 * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end +564 * of the walk +565 */ +566 double walkInRowOrder(RealMatrixPreservingVisitor visitor) +567 throws MatrixVisitorException; +568 +569 /** +570 * Visit (and possibly change) some matrix entries in row order. +571 * <p>Row order starts at upper left and iterating through all elements +572 * of a row from left to right before going to the leftmost element +573 * of the next row.</p> +574 * @param visitor visitor used to process all matrix entries +575 * @param startRow Initial row index +576 * @param endRow Final row index (inclusive) +577 * @param startColumn Initial column index +578 * @param endColumn Final column index +579 * @exception MatrixVisitorException if the visitor cannot process an entry +580 * @exception MatrixIndexException if the indices are not valid +581 * @see #walkInRowOrder(RealMatrixChangingVisitor) +582 * @see #walkInRowOrder(RealMatrixPreservingVisitor) +583 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) +584 * @see #walkInColumnOrder(RealMatrixChangingVisitor) +585 * @see #walkInColumnOrder(RealMatrixPreservingVisitor) +586 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) +587 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) +588 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) +589 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) +590 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) +591 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) +592 * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end +593 * of the walk +594 */ +595 double walkInRowOrder(RealMatrixChangingVisitor visitor, +596 int startRow, int endRow, int startColumn, int endColumn) +597 throws MatrixIndexException, MatrixVisitorException; +598 +599 /** +600 * Visit (but don't change) some matrix entries in row order. +601 * <p>Row order starts at upper left and iterating through all elements +602 * of a row from left to right before going to the leftmost element +603 * of the next row.</p> +604 * @param visitor visitor used to process all matrix entries +605 * @param startRow Initial row index +606 * @param endRow Final row index (inclusive) +607 * @param startColumn Initial column index +608 * @param endColumn Final column index +609 * @exception MatrixVisitorException if the visitor cannot process an entry +610 * @exception MatrixIndexException if the indices are not valid +611 * @see #walkInRowOrder(RealMatrixChangingVisitor) +612 * @see #walkInRowOrder(RealMatrixPreservingVisitor) +613 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) +614 * @see #walkInColumnOrder(RealMatrixChangingVisitor) +615 * @see #walkInColumnOrder(RealMatrixPreservingVisitor) +616 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) +617 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) +618 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) +619 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) +620 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) +621 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) +622 * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end +623 * of the walk +624 */ +625 double walkInRowOrder(RealMatrixPreservingVisitor visitor, +626 int startRow, int endRow, int startColumn, int endColumn) +627 throws MatrixIndexException, MatrixVisitorException; +628 +629 /** +630 * Visit (and possibly change) all matrix entries in column order. +631 * <p>Column order starts at upper left and iterating through all elements +632 * of a column from top to bottom before going to the topmost element +633 * of the next column.</p> +634 * @param visitor visitor used to process all matrix entries +635 * @exception MatrixVisitorException if the visitor cannot process an entry +636 * @see #walkInRowOrder(RealMatrixChangingVisitor) +637 * @see #walkInRowOrder(RealMatrixPreservingVisitor) +638 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) +639 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) +640 * @see #walkInColumnOrder(RealMatrixPreservingVisitor) +641 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) +642 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) +643 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) +644 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) +645 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) +646 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) +647 * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end +648 * of the walk +649 */ +650 double walkInColumnOrder(RealMatrixChangingVisitor visitor) +651 throws MatrixVisitorException; +652 +653 /** +654 * Visit (but don't change) all matrix entries in column order. +655 * <p>Column order starts at upper left and iterating through all elements +656 * of a column from top to bottom before going to the topmost element +657 * of the next column.</p> +658 * @param visitor visitor used to process all matrix entries +659 * @exception MatrixVisitorException if the visitor cannot process an entry +660 * @see #walkInRowOrder(RealMatrixChangingVisitor) +661 * @see #walkInRowOrder(RealMatrixPreservingVisitor) +662 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) +663 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) +664 * @see #walkInColumnOrder(RealMatrixChangingVisitor) +665 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) +666 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) +667 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) +668 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) +669 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) +670 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) +671 * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end +672 * of the walk +673 */ +674 double walkInColumnOrder(RealMatrixPreservingVisitor visitor) +675 throws MatrixVisitorException; +676 +677 /** +678 * Visit (and possibly change) some matrix entries in column order. +679 * <p>Column order starts at upper left and iterating through all elements +680 * of a column from top to bottom before going to the topmost element +681 * of the next column.</p> +682 * @param visitor visitor used to process all matrix entries +683 * @param startRow Initial row index +684 * @param endRow Final row index (inclusive) +685 * @param startColumn Initial column index +686 * @param endColumn Final column index +687 * @exception MatrixVisitorException if the visitor cannot process an entry +688 * @exception MatrixIndexException if the indices are not valid +689 * @see #walkInRowOrder(RealMatrixChangingVisitor) +690 * @see #walkInRowOrder(RealMatrixPreservingVisitor) +691 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) +692 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) +693 * @see #walkInColumnOrder(RealMatrixChangingVisitor) +694 * @see #walkInColumnOrder(RealMatrixPreservingVisitor) +695 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) +696 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) +697 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) +698 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) +699 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) +700 * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end +701 * of the walk +702 */ +703 double walkInColumnOrder(RealMatrixChangingVisitor visitor, +704 int startRow, int endRow, int startColumn, int endColumn) +705 throws MatrixIndexException, MatrixVisitorException; +706 +707 /** +708 * Visit (but don't change) some matrix entries in column order. +709 * <p>Column order starts at upper left and iterating through all elements +710 * of a column from top to bottom before going to the topmost element +711 * of the next column.</p> +712 * @param visitor visitor used to process all matrix entries +713 * @param startRow Initial row index +714 * @param endRow Final row index (inclusive) +715 * @param startColumn Initial column index +716 * @param endColumn Final column index +717 * @exception MatrixVisitorException if the visitor cannot process an entry +718 * @exception MatrixIndexException if the indices are not valid +719 * @see #walkInRowOrder(RealMatrixChangingVisitor) +720 * @see #walkInRowOrder(RealMatrixPreservingVisitor) +721 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) +722 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) +723 * @see #walkInColumnOrder(RealMatrixChangingVisitor) +724 * @see #walkInColumnOrder(RealMatrixPreservingVisitor) +725 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) +726 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) +727 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) +728 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) +729 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) +730 * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end +731 * of the walk +732 */ +733 double walkInColumnOrder(RealMatrixPreservingVisitor visitor, +734 int startRow, int endRow, int startColumn, int endColumn) +735 throws MatrixIndexException, MatrixVisitorException; +736 +737 /** +738 * Visit (and possibly change) all matrix entries using the fastest possible order. +739 * <p>The fastest walking order depends on the exact matrix class. It may be +740 * different from traditional row or column orders.</p> +741 * @param visitor visitor used to process all matrix entries +742 * @exception MatrixVisitorException if the visitor cannot process an entry +743 * @see #walkInRowOrder(RealMatrixChangingVisitor) +744 * @see #walkInRowOrder(RealMatrixPreservingVisitor) +745 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) +746 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) +747 * @see #walkInColumnOrder(RealMatrixChangingVisitor) +748 * @see #walkInColumnOrder(RealMatrixPreservingVisitor) +749 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) +750 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) +751 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) +752 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) +753 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) +754 * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end +755 * of the walk +756 */ +757 double walkInOptimizedOrder(RealMatrixChangingVisitor visitor) +758 throws MatrixVisitorException; +759 +760 /** +761 * Visit (but don't change) all matrix entries using the fastest possible order. +762 * <p>The fastest walking order depends on the exact matrix class. It may be +763 * different from traditional row or column orders.</p> +764 * @param visitor visitor used to process all matrix entries +765 * @exception MatrixVisitorException if the visitor cannot process an entry +766 * @see #walkInRowOrder(RealMatrixChangingVisitor) +767 * @see #walkInRowOrder(RealMatrixPreservingVisitor) +768 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) +769 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) +770 * @see #walkInColumnOrder(RealMatrixChangingVisitor) +771 * @see #walkInColumnOrder(RealMatrixPreservingVisitor) +772 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) +773 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) +774 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) +775 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) +776 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) +777 * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end +778 * of the walk +779 */ +780 double walkInOptimizedOrder(RealMatrixPreservingVisitor visitor) +781 throws MatrixVisitorException; +782 +783 /** +784 * Visit (and possibly change) some matrix entries using the fastest possible order. +785 * <p>The fastest walking order depends on the exact matrix class. It may be +786 * different from traditional row or column orders.</p> +787 * @param visitor visitor used to process all matrix entries +788 * @param startRow Initial row index +789 * @param endRow Final row index (inclusive) +790 * @param startColumn Initial column index +791 * @param endColumn Final column index (inclusive) +792 * @exception MatrixVisitorException if the visitor cannot process an entry +793 * @exception MatrixIndexException if the indices are not valid +794 * @see #walkInRowOrder(RealMatrixChangingVisitor) +795 * @see #walkInRowOrder(RealMatrixPreservingVisitor) +796 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) +797 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) +798 * @see #walkInColumnOrder(RealMatrixChangingVisitor) +799 * @see #walkInColumnOrder(RealMatrixPreservingVisitor) +800 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) +801 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) +802 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) +803 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) +804 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int) +805 * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end +806 * of the walk +807 */ +808 double walkInOptimizedOrder(RealMatrixChangingVisitor visitor, +809 int startRow, int endRow, int startColumn, int endColumn) +810 throws MatrixIndexException, MatrixVisitorException; +811 +812 /** +813 * Visit (but don't change) some matrix entries using the fastest possible order. +814 * <p>The fastest walking order depends on the exact matrix class. It may be +815 * different from traditional row or column orders.</p> +816 * @param visitor visitor used to process all matrix entries +817 * @param startRow Initial row index +818 * @param endRow Final row index (inclusive) +819 * @param startColumn Initial column index +820 * @param endColumn Final column index (inclusive) +821 * @exception MatrixVisitorException if the visitor cannot process an entry +822 * @exception MatrixIndexException if the indices are not valid +823 * @see #walkInRowOrder(RealMatrixChangingVisitor) +824 * @see #walkInRowOrder(RealMatrixPreservingVisitor) +825 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int) +826 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int) +827 * @see #walkInColumnOrder(RealMatrixChangingVisitor) +828 * @see #walkInColumnOrder(RealMatrixPreservingVisitor) +829 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int) +830 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int) +831 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor) +832 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor) +833 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int) +834 * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end +835 * of the walk +836 */ +837 double walkInOptimizedOrder(RealMatrixPreservingVisitor visitor, +838 int startRow, int endRow, int startColumn, int endColumn) +839 throws MatrixIndexException, MatrixVisitorException; +840 +841 /** +842 * Returns the solution vector for a linear system with coefficient +843 * matrix = this and constant vector = <code>b</code>. +844 * +845 * @param b constant vector +846 * @return vector of solution values to AX = b, where A is *this +847 * @throws IllegalArgumentException if this.rowDimension != b.length +848 * @throws InvalidMatrixException if this matrix is not square or is singular +849 * @deprecated as of release 2.0, replaced by {@link DecompositionSolver#solve(double[])} +850 */ +851 @Deprecated +852 double[] solve(double[] b) throws IllegalArgumentException, InvalidMatrixException; +853 +854 /** +855 * Returns a matrix of (column) solution vectors for linear systems with +856 * coefficient matrix = this and constant vectors = columns of +857 * <code>b</code>. +858 * +859 * @param b matrix of constant vectors forming RHS of linear systems to +860 * to solve +861 * @return matrix of solution vectors +862 * @throws IllegalArgumentException if this.rowDimension != row dimension +863 * @throws InvalidMatrixException if this matrix is not square or is singular +864 * @deprecated as of release 2.0, replaced by {@link DecompositionSolver#solve(RealMatrix)} +865 */ +866 @Deprecated +867 RealMatrix solve(RealMatrix b) throws IllegalArgumentException, InvalidMatrixException; +868 +869 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/RealMatrixChangingVisitor.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/RealMatrixChangingVisitor.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,126 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 /** +021 * Interface defining a visitor for matrix entries. +022 * +023 * @see DefaultRealMatrixChangingVisitor +024 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +025 * @since 2.0 +026 */ +027 public interface RealMatrixChangingVisitor { +028 +029 /** +030 * Start visiting a matrix. +031 * <p>This method is called once before any entry of the matrix is visited.</p> +032 * @param rows number of rows of the matrix +033 * @param columns number of columns of the matrix +034 * @param startRow Initial row index +035 * @param endRow Final row index (inclusive) +036 * @param startColumn Initial column index +037 * @param endColumn Final column index (inclusive) +038 */ +039 void start(int rows, int columns, +040 int startRow, int endRow, int startColumn, int endColumn); +041 +042 /** +043 * Visit one matrix entry. +044 * @param row row index of the entry +045 * @param column column index of the entry +046 * @param value current value of the entry +047 * @return the new value to be set for the entry +048 * @throws MatrixVisitorException if something wrong occurs +049 */ +050 double visit(int row, int column, double value) +051 throws MatrixVisitorException; +052 +053 /** +054 * End visiting a matrix. +055 * <p>This method is called once after all entries of the matrix have been visited.</p> +056 * @return the value that the <code>walkInXxxOrder</code> must return +057 */ +058 double end(); +059 +060 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/RealMatrixImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/RealMatrixImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,693 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 +024 /** +025 * Implementation of RealMatrix using a double[][] array to store entries and +026 * <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf"> +027 * LU decomposition</a> to support linear system +028 * solution and inverse. +029 * <p> +030 * The LU decomposition is performed as needed, to support the following operations: <ul> +031 * <li>solve</li> +032 * <li>isSingular</li> +033 * <li>getDeterminant</li> +034 * <li>inverse</li> </ul></p> +035 * <p> +036 * <strong>Usage notes</strong>:<br> +037 * <ul><li> +038 * The LU decomposition is cached and reused on subsequent calls. +039 * If data are modified via references to the underlying array obtained using +040 * <code>getDataRef()</code>, then the stored LU decomposition will not be +041 * discarded. In this case, you need to explicitly invoke +042 * <code>LUDecompose()</code> to recompute the decomposition +043 * before using any of the methods above.</li> +044 * <li> +045 * As specified in the {@link RealMatrix} interface, matrix element indexing +046 * is 0-based -- e.g., <code>getEntry(0, 0)</code> +047 * returns the element in the first row, first column of the matrix.</li></ul> +048 * </p> +049 * +050 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +051 * @deprecated as of 2.0 replaced by {@link Array2DRowRealMatrix} +052 */ +053 @Deprecated +054 public class RealMatrixImpl extends AbstractRealMatrix implements Serializable { +055 +056 /** Serializable version identifier */ +057 private static final long serialVersionUID = -1067294169172445528L; +058 +059 /** Entries of the matrix */ +060 protected double data[][]; +061 +062 /** +063 * Creates a matrix with no data +064 */ +065 public RealMatrixImpl() { +066 } +067 +068 /** +069 * Create a new RealMatrix with the supplied row and column dimensions. +070 * +071 * @param rowDimension the number of rows in the new matrix +072 * @param columnDimension the number of columns in the new matrix +073 * @throws IllegalArgumentException if row or column dimension is not +074 * positive +075 */ +076 public RealMatrixImpl(final int rowDimension, final int columnDimension) +077 throws IllegalArgumentException { +078 super(rowDimension, columnDimension); +079 data = new double[rowDimension][columnDimension]; +080 } +081 +082 /** +083 * Create a new RealMatrix using the input array as the underlying +084 * data array. +085 * <p>The input array is copied, not referenced. This constructor has +086 * the same effect as calling {@link #RealMatrixImpl(double[][], boolean)} +087 * with the second argument set to <code>true</code>.</p> +088 * +089 * @param d data for new matrix +090 * @throws IllegalArgumentException if <code>d</code> is not rectangular +091 * (not all rows have the same length) or empty +092 * @throws NullPointerException if <code>d</code> is null +093 * @see #RealMatrixImpl(double[][], boolean) +094 */ +095 public RealMatrixImpl(final double[][] d) +096 throws IllegalArgumentException, NullPointerException { +097 copyIn(d); +098 } +099 +100 /** +101 * Create a new RealMatrix using the input array as the underlying +102 * data array. +103 * <p>If an array is built specially in order to be embedded in a +104 * RealMatrix and not used directly, the <code>copyArray</code> may be +105 * set to <code>false</code. This will prevent the copying and improve +106 * performance as no new array will be built and no data will be copied.</p> +107 * @param d data for new matrix +108 * @param copyArray if true, the input array will be copied, otherwise +109 * it will be referenced +110 * @throws IllegalArgumentException if <code>d</code> is not rectangular +111 * (not all rows have the same length) or empty +112 * @throws NullPointerException if <code>d</code> is null +113 * @see #RealMatrixImpl(double[][]) +114 */ +115 public RealMatrixImpl(final double[][] d, final boolean copyArray) +116 throws IllegalArgumentException, NullPointerException { +117 if (copyArray) { +118 copyIn(d); +119 } else { +120 if (d == null) { +121 throw new NullPointerException(); +122 } +123 final int nRows = d.length; +124 if (nRows == 0) { +125 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row"); +126 } +127 final int nCols = d[0].length; +128 if (nCols == 0) { +129 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column"); +130 } +131 for (int r = 1; r < nRows; r++) { +132 if (d[r].length != nCols) { +133 throw MathRuntimeException.createIllegalArgumentException( +134 "some rows have length {0} while others have length {1}", +135 nCols, d[r].length); +136 } +137 } +138 data = d; +139 } +140 } +141 +142 /** +143 * Create a new (column) RealMatrix using <code>v</code> as the +144 * data for the unique column of the <code>v.length x 1</code> matrix +145 * created. +146 * <p>The input array is copied, not referenced.</p> +147 * +148 * @param v column vector holding data for new matrix +149 */ +150 public RealMatrixImpl(final double[] v) { +151 final int nRows = v.length; +152 data = new double[nRows][1]; +153 for (int row = 0; row < nRows; row++) { +154 data[row][0] = v[row]; +155 } +156 } +157 +158 /** {@inheritDoc} */ +159 @Override +160 public RealMatrix createMatrix(final int rowDimension, final int columnDimension) +161 throws IllegalArgumentException { +162 return new RealMatrixImpl(rowDimension, columnDimension); +163 } +164 +165 /** {@inheritDoc} */ +166 @Override +167 public RealMatrix copy() { +168 return new RealMatrixImpl(copyOut(), false); +169 } +170 +171 /** {@inheritDoc} */ +172 @Override +173 public RealMatrix add(final RealMatrix m) +174 throws IllegalArgumentException { +175 try { +176 return add((RealMatrixImpl) m); +177 } catch (ClassCastException cce) { +178 return super.add(m); +179 } +180 } +181 +182 /** +183 * Compute the sum of this and <code>m</code>. +184 * +185 * @param m matrix to be added +186 * @return this + m +187 * @throws IllegalArgumentException if m is not the same size as this +188 */ +189 public RealMatrixImpl add(final RealMatrixImpl m) +190 throws IllegalArgumentException { +191 +192 // safety check +193 MatrixUtils.checkAdditionCompatible(this, m); +194 +195 final int rowCount = getRowDimension(); +196 final int columnCount = getColumnDimension(); +197 final double[][] outData = new double[rowCount][columnCount]; +198 for (int row = 0; row < rowCount; row++) { +199 final double[] dataRow = data[row]; +200 final double[] mRow = m.data[row]; +201 final double[] outDataRow = outData[row]; +202 for (int col = 0; col < columnCount; col++) { +203 outDataRow[col] = dataRow[col] + mRow[col]; +204 } +205 } +206 +207 return new RealMatrixImpl(outData, false); +208 +209 } +210 +211 /** {@inheritDoc} */ +212 @Override +213 public RealMatrix subtract(final RealMatrix m) +214 throws IllegalArgumentException { +215 try { +216 return subtract((RealMatrixImpl) m); +217 } catch (ClassCastException cce) { +218 return super.subtract(m); +219 } +220 } +221 +222 /** +223 * Compute this minus <code>m</code>. +224 * +225 * @param m matrix to be subtracted +226 * @return this + m +227 * @throws IllegalArgumentException if m is not the same size as this +228 */ +229 public RealMatrixImpl subtract(final RealMatrixImpl m) +230 throws IllegalArgumentException { +231 +232 // safety check +233 MatrixUtils.checkSubtractionCompatible(this, m); +234 +235 final int rowCount = getRowDimension(); +236 final int columnCount = getColumnDimension(); +237 final double[][] outData = new double[rowCount][columnCount]; +238 for (int row = 0; row < rowCount; row++) { +239 final double[] dataRow = data[row]; +240 final double[] mRow = m.data[row]; +241 final double[] outDataRow = outData[row]; +242 for (int col = 0; col < columnCount; col++) { +243 outDataRow[col] = dataRow[col] - mRow[col]; +244 } +245 } +246 +247 return new RealMatrixImpl(outData, false); +248 +249 } +250 +251 /** {@inheritDoc} */ +252 @Override +253 public RealMatrix multiply(final RealMatrix m) +254 throws IllegalArgumentException { +255 try { +256 return multiply((RealMatrixImpl) m); +257 } catch (ClassCastException cce) { +258 return super.multiply(m); +259 } +260 } +261 +262 /** +263 * Returns the result of postmultiplying this by <code>m</code>. +264 * @param m matrix to postmultiply by +265 * @return this*m +266 * @throws IllegalArgumentException +267 * if columnDimension(this) != rowDimension(m) +268 */ +269 public RealMatrixImpl multiply(final RealMatrixImpl m) +270 throws IllegalArgumentException { +271 +272 // safety check +273 MatrixUtils.checkMultiplicationCompatible(this, m); +274 +275 final int nRows = this.getRowDimension(); +276 final int nCols = m.getColumnDimension(); +277 final int nSum = this.getColumnDimension(); +278 final double[][] outData = new double[nRows][nCols]; +279 for (int row = 0; row < nRows; row++) { +280 final double[] dataRow = data[row]; +281 final double[] outDataRow = outData[row]; +282 for (int col = 0; col < nCols; col++) { +283 double sum = 0; +284 for (int i = 0; i < nSum; i++) { +285 sum += dataRow[i] * m.data[i][col]; +286 } +287 outDataRow[col] = sum; +288 } +289 } +290 +291 return new RealMatrixImpl(outData, false); +292 +293 } +294 +295 /** {@inheritDoc} */ +296 @Override +297 public double[][] getData() { +298 return copyOut(); +299 } +300 +301 /** +302 * Returns a reference to the underlying data array. +303 * <p> +304 * Does <strong>not</strong> make a fresh copy of the underlying data.</p> +305 * +306 * @return 2-dimensional array of entries +307 */ +308 public double[][] getDataRef() { +309 return data; +310 } +311 +312 /** {@inheritDoc} */ +313 @Override +314 public void setSubMatrix(final double[][] subMatrix, final int row, final int column) +315 throws MatrixIndexException { +316 if (data == null) { +317 if (row > 0) { +318 throw MathRuntimeException.createIllegalStateException( +319 "first {0} rows are not initialized yet", +320 row); +321 } +322 if (column > 0) { +323 throw MathRuntimeException.createIllegalStateException( +324 "first {0} columns are not initialized yet", +325 column); +326 } +327 final int nRows = subMatrix.length; +328 if (nRows == 0) { +329 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row"); +330 } +331 +332 final int nCols = subMatrix[0].length; +333 if (nCols == 0) { +334 throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column"); +335 } +336 data = new double[subMatrix.length][nCols]; +337 for (int i = 0; i < data.length; ++i) { +338 if (subMatrix[i].length != nCols) { +339 throw MathRuntimeException.createIllegalArgumentException( +340 "some rows have length {0} while others have length {1}", +341 nCols, subMatrix[i].length); +342 } +343 System.arraycopy(subMatrix[i], 0, data[i + row], column, nCols); +344 } +345 } else { +346 super.setSubMatrix(subMatrix, row, column); +347 } +348 +349 } +350 +351 /** {@inheritDoc} */ +352 @Override +353 public double getEntry(final int row, final int column) +354 throws MatrixIndexException { +355 try { +356 return data[row][column]; +357 } catch (ArrayIndexOutOfBoundsException e) { +358 throw new MatrixIndexException( +359 "no entry at indices ({0}, {1}) in a {2}x{3} matrix", +360 row, column, getRowDimension(), getColumnDimension()); +361 } +362 } +363 +364 /** {@inheritDoc} */ +365 @Override +366 public void setEntry(final int row, final int column, final double value) +367 throws MatrixIndexException { +368 try { +369 data[row][column] = value; +370 } catch (ArrayIndexOutOfBoundsException e) { +371 throw new MatrixIndexException( +372 "no entry at indices ({0}, {1}) in a {2}x{3} matrix", +373 row, column, getRowDimension(), getColumnDimension()); +374 } +375 } +376 +377 /** {@inheritDoc} */ +378 @Override +379 public void addToEntry(final int row, final int column, final double increment) +380 throws MatrixIndexException { +381 try { +382 data[row][column] += increment; +383 } catch (ArrayIndexOutOfBoundsException e) { +384 throw new MatrixIndexException( +385 "no entry at indices ({0}, {1}) in a {2}x{3} matrix", +386 row, column, getRowDimension(), getColumnDimension()); +387 } +388 } +389 +390 /** {@inheritDoc} */ +391 @Override +392 public void multiplyEntry(final int row, final int column, final double factor) +393 throws MatrixIndexException { +394 try { +395 data[row][column] *= factor; +396 } catch (ArrayIndexOutOfBoundsException e) { +397 throw new MatrixIndexException( +398 "no entry at indices ({0}, {1}) in a {2}x{3} matrix", +399 row, column, getRowDimension(), getColumnDimension()); +400 } +401 } +402 +403 /** {@inheritDoc} */ +404 @Override +405 public int getRowDimension() { +406 return (data == null) ? 0 : data.length; +407 } +408 +409 /** {@inheritDoc} */ +410 @Override +411 public int getColumnDimension() { +412 return ((data == null) || (data[0] == null)) ? 0 : data[0].length; +413 } +414 +415 /** {@inheritDoc} */ +416 @Override +417 public double[] operate(final double[] v) +418 throws IllegalArgumentException { +419 final int nRows = this.getRowDimension(); +420 final int nCols = this.getColumnDimension(); +421 if (v.length != nCols) { +422 throw MathRuntimeException.createIllegalArgumentException( +423 "vector length mismatch: got {0} but expected {1}", +424 v.length, nCols); +425 } +426 final double[] out = new double[nRows]; +427 for (int row = 0; row < nRows; row++) { +428 final double[] dataRow = data[row]; +429 double sum = 0; +430 for (int i = 0; i < nCols; i++) { +431 sum += dataRow[i] * v[i]; +432 } +433 out[row] = sum; +434 } +435 return out; +436 } +437 +438 /** {@inheritDoc} */ +439 @Override +440 public double[] preMultiply(final double[] v) +441 throws IllegalArgumentException { +442 +443 final int nRows = getRowDimension(); +444 final int nCols = getColumnDimension(); +445 if (v.length != nRows) { +446 throw MathRuntimeException.createIllegalArgumentException( +447 "vector length mismatch: got {0} but expected {1}", +448 v.length, nRows); +449 } +450 +451 final double[] out = new double[nCols]; +452 for (int col = 0; col < nCols; ++col) { +453 double sum = 0; +454 for (int i = 0; i < nRows; ++i) { +455 sum += data[i][col] * v[i]; +456 } +457 out[col] = sum; +458 } +459 +460 return out; +461 +462 } +463 +464 /** {@inheritDoc} */ +465 @Override +466 public double walkInRowOrder(final RealMatrixChangingVisitor visitor) +467 throws MatrixVisitorException { +468 final int rows = getRowDimension(); +469 final int columns = getColumnDimension(); +470 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +471 for (int i = 0; i < rows; ++i) { +472 final double[] rowI = data[i]; +473 for (int j = 0; j < columns; ++j) { +474 rowI[j] = visitor.visit(i, j, rowI[j]); +475 } +476 } +477 return visitor.end(); +478 } +479 +480 /** {@inheritDoc} */ +481 @Override +482 public double walkInRowOrder(final RealMatrixPreservingVisitor visitor) +483 throws MatrixVisitorException { +484 final int rows = getRowDimension(); +485 final int columns = getColumnDimension(); +486 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +487 for (int i = 0; i < rows; ++i) { +488 final double[] rowI = data[i]; +489 for (int j = 0; j < columns; ++j) { +490 visitor.visit(i, j, rowI[j]); +491 } +492 } +493 return visitor.end(); +494 } +495 +496 /** {@inheritDoc} */ +497 @Override +498 public double walkInRowOrder(final RealMatrixChangingVisitor visitor, +499 final int startRow, final int endRow, +500 final int startColumn, final int endColumn) +501 throws MatrixIndexException, MatrixVisitorException { +502 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +503 visitor.start(getRowDimension(), getColumnDimension(), +504 startRow, endRow, startColumn, endColumn); +505 for (int i = startRow; i <= endRow; ++i) { +506 final double[] rowI = data[i]; +507 for (int j = startColumn; j <= endColumn; ++j) { +508 rowI[j] = visitor.visit(i, j, rowI[j]); +509 } +510 } +511 return visitor.end(); +512 } +513 +514 /** {@inheritDoc} */ +515 @Override +516 public double walkInRowOrder(final RealMatrixPreservingVisitor visitor, +517 final int startRow, final int endRow, +518 final int startColumn, final int endColumn) +519 throws MatrixIndexException, MatrixVisitorException { +520 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +521 visitor.start(getRowDimension(), getColumnDimension(), +522 startRow, endRow, startColumn, endColumn); +523 for (int i = startRow; i <= endRow; ++i) { +524 final double[] rowI = data[i]; +525 for (int j = startColumn; j <= endColumn; ++j) { +526 visitor.visit(i, j, rowI[j]); +527 } +528 } +529 return visitor.end(); +530 } +531 +532 /** {@inheritDoc} */ +533 @Override +534 public double walkInColumnOrder(final RealMatrixChangingVisitor visitor) +535 throws MatrixVisitorException { +536 final int rows = getRowDimension(); +537 final int columns = getColumnDimension(); +538 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +539 for (int j = 0; j < columns; ++j) { +540 for (int i = 0; i < rows; ++i) { +541 final double[] rowI = data[i]; +542 rowI[j] = visitor.visit(i, j, rowI[j]); +543 } +544 } +545 return visitor.end(); +546 } +547 +548 /** {@inheritDoc} */ +549 @Override +550 public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor) +551 throws MatrixVisitorException { +552 final int rows = getRowDimension(); +553 final int columns = getColumnDimension(); +554 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1); +555 for (int j = 0; j < columns; ++j) { +556 for (int i = 0; i < rows; ++i) { +557 visitor.visit(i, j, data[i][j]); +558 } +559 } +560 return visitor.end(); +561 } +562 +563 /** {@inheritDoc} */ +564 @Override +565 public double walkInColumnOrder(final RealMatrixChangingVisitor visitor, +566 final int startRow, final int endRow, +567 final int startColumn, final int endColumn) +568 throws MatrixIndexException, MatrixVisitorException { +569 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +570 visitor.start(getRowDimension(), getColumnDimension(), +571 startRow, endRow, startColumn, endColumn); +572 for (int j = startColumn; j <= endColumn; ++j) { +573 for (int i = startRow; i <= endRow; ++i) { +574 final double[] rowI = data[i]; +575 rowI[j] = visitor.visit(i, j, rowI[j]); +576 } +577 } +578 return visitor.end(); +579 } +580 +581 /** {@inheritDoc} */ +582 @Override +583 public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor, +584 final int startRow, final int endRow, +585 final int startColumn, final int endColumn) +586 throws MatrixIndexException, MatrixVisitorException { +587 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); +588 visitor.start(getRowDimension(), getColumnDimension(), +589 startRow, endRow, startColumn, endColumn); +590 for (int j = startColumn; j <= endColumn; ++j) { +591 for (int i = startRow; i <= endRow; ++i) { +592 visitor.visit(i, j, data[i][j]); +593 } +594 } +595 return visitor.end(); +596 } +597 +598 /** +599 * Returns a fresh copy of the underlying data array. +600 * +601 * @return a copy of the underlying data array. +602 */ +603 private double[][] copyOut() { +604 final int nRows = this.getRowDimension(); +605 final double[][] out = new double[nRows][this.getColumnDimension()]; +606 // can't copy 2-d array in one shot, otherwise get row references +607 for (int i = 0; i < nRows; i++) { +608 System.arraycopy(data[i], 0, out[i], 0, data[i].length); +609 } +610 return out; +611 } +612 +613 /** +614 * Replaces data with a fresh copy of the input array. +615 * <p> +616 * Verifies that the input array is rectangular and non-empty.</p> +617 * +618 * @param in data to copy in +619 * @throws IllegalArgumentException if input array is empty or not +620 * rectangular +621 * @throws NullPointerException if input array is null +622 */ +623 private void copyIn(final double[][] in) { +624 setSubMatrix(in, 0, 0); +625 } +626 +627 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/RealMatrixPreservingVisitor.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/RealMatrixPreservingVisitor.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,125 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 /** +021 * Interface defining a visitor for matrix entries. +022 * +023 * @see DefaultRealMatrixPreservingVisitor +024 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +025 * @since 2.0 +026 */ +027 public interface RealMatrixPreservingVisitor { +028 +029 /** +030 * Start visiting a matrix. +031 * <p>This method is called once before any entry of the matrix is visited.</p> +032 * @param rows number of rows of the matrix +033 * @param columns number of columns of the matrix +034 * @param startRow Initial row index +035 * @param endRow Final row index (inclusive) +036 * @param startColumn Initial column index +037 * @param endColumn Final column index (inclusive) +038 */ +039 void start(int rows, int columns, +040 int startRow, int endRow, int startColumn, int endColumn); +041 +042 /** +043 * Visit one matrix entry. +044 * @param row row index of the entry +045 * @param column column index of the entry +046 * @param value current value of the entry +047 * @throws MatrixVisitorException if something wrong occurs +048 */ +049 void visit(int row, int column, double value) +050 throws MatrixVisitorException; +051 +052 /** +053 * End visiting a matrix. +054 * <p>This method is called once after all entries of the matrix have been visited.</p> +055 * @return the value that the <code>walkInXxxOrder</code> must return +056 */ +057 double end(); +058 +059 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/RealVector.Entry.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/RealVector.Entry.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,939 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.linear; +018 +019 import java.util.Iterator; +020 +021 import org.apache.commons.math.FunctionEvaluationException; +022 import org.apache.commons.math.analysis.UnivariateRealFunction; +023 +024 +025 /** +026 * Interface defining a real-valued vector with basic algebraic operations. +027 * <p> +028 * vector element indexing is 0-based -- e.g., <code>getEntry(0)</code> +029 * returns the first element of the vector. +030 * </p> +031 * <p> +032 * The various <code>mapXxx</code> and <code>mapXxxToSelf</code> methods operate +033 * on vectors element-wise, i.e. they perform the same operation (adding a scalar, +034 * applying a function ...) on each element in turn. The <code>mapXxx</code> +035 * versions create a new vector to hold the result and do not change the instance. +036 * The <code>mapXxxToSelf</code> versions use the instance itself to store the +037 * results, so the instance is changed by these methods. In both cases, the result +038 * vector is returned by the methods, this allows to use the <i>fluent API</i> +039 * style, like this: +040 * </p> +041 * <pre> +042 * RealVector result = v.mapAddToSelf(3.0).mapTanToSelf().mapSquareToSelf(); +043 * </pre> +044 * +045 * @version $Revision: 902214 $ $Date: 2010-01-22 13:40:28 -0500 (Fri, 22 Jan 2010) $ +046 * @since 2.0 +047 */ +048 public interface RealVector { +049 +050 /** +051 * Acts as if it is implemented as: +052 * Entry e = null; +053 * for(Iterator<Entry> it = iterator(); it.hasNext(); e = it.next()) { +054 * e.setValue(function.value(e.getValue())); +055 * } +056 * @param function to apply to each successive entry +057 * @return this vector +058 * @throws FunctionEvaluationException if function throws it on application to any entry +059 */ +060 RealVector mapToSelf(UnivariateRealFunction function) throws FunctionEvaluationException; +061 +062 /** +063 * Acts as if implemented as: +064 * return copy().map(function); +065 * @param function to apply to each successive entry +066 * @return a new vector +067 * @throws FunctionEvaluationException if function throws it on application to any entry +068 */ +069 RealVector map(UnivariateRealFunction function) throws FunctionEvaluationException; +070 +071 /** Class representing a modifiable entry in the vector. */ +072 public abstract class Entry { +073 +074 /** Index of the entry. */ +075 private int index; +076 +077 /** Get the value of the entry. +078 * @return value of the entry +079 */ +080 public abstract double getValue(); +081 +082 /** Set the value of the entry. +083 * @param value new value for the entry +084 */ +085 public abstract void setValue(double value); +086 +087 /** Get the index of the entry. +088 * @return index of the entry +089 */ +090 public int getIndex() { +091 return index; +092 } +093 +094 /** Set the index of the entry. +095 * @param index new index for the entry +096 */ +097 public void setIndex(int index) { +098 this.index = index; +099 } +100 +101 } +102 +103 /** +104 * Generic dense iterator - starts with index == zero, and hasNext() == true until index == getDimension(); +105 * @return a dense iterator +106 */ +107 Iterator<Entry> iterator(); +108 +109 /** +110 * Specialized implementations may choose to not iterate over all dimensions, either because those values are +111 * unset, or are equal to defaultValue(), or are small enough to be ignored for the purposes of iteration. +112 * No guarantees are made about order of iteration. +113 * In dense implementations, this method will often delegate to {@link #iterator()} +114 * @return a sparse iterator +115 */ +116 Iterator<Entry> sparseIterator(); +117 +118 /** +119 * Returns a (deep) copy of this. +120 * @return vector copy +121 */ +122 RealVector copy(); +123 +124 /** +125 * Compute the sum of this and v. +126 * @param v vector to be added +127 * @return this + v +128 * @throws IllegalArgumentException if v is not the same size as this +129 */ +130 RealVector add(RealVector v) +131 throws IllegalArgumentException; +132 +133 /** +134 * Compute the sum of this and v. +135 * @param v vector to be added +136 * @return this + v +137 * @throws IllegalArgumentException if v is not the same size as this +138 */ +139 RealVector add(double[] v) +140 throws IllegalArgumentException; +141 +142 /** +143 * Compute this minus v. +144 * @param v vector to be subtracted +145 * @return this + v +146 * @throws IllegalArgumentException if v is not the same size as this +147 */ +148 RealVector subtract(RealVector v) +149 throws IllegalArgumentException; +150 +151 /** +152 * Compute this minus v. +153 * @param v vector to be subtracted +154 * @return this + v +155 * @throws IllegalArgumentException if v is not the same size as this +156 */ +157 RealVector subtract(double[] v) +158 throws IllegalArgumentException; +159 +160 /** +161 * Map an addition operation to each entry. +162 * @param d value to be added to each entry +163 * @return this + d +164 */ +165 RealVector mapAdd(double d); +166 +167 /** +168 * Map an addition operation to each entry. +169 * <p>The instance <strong>is</strong> changed by this method.</p> +170 * @param d value to be added to each entry +171 * @return for convenience, return this +172 */ +173 RealVector mapAddToSelf(double d); +174 +175 /** +176 * Map a subtraction operation to each entry. +177 * @param d value to be subtracted to each entry +178 * @return this - d +179 */ +180 RealVector mapSubtract(double d); +181 +182 /** +183 * Map a subtraction operation to each entry. +184 * <p>The instance <strong>is</strong> changed by this method.</p> +185 * @param d value to be subtracted to each entry +186 * @return for convenience, return this +187 */ +188 RealVector mapSubtractToSelf(double d); +189 +190 /** +191 * Map a multiplication operation to each entry. +192 * @param d value to multiply all entries by +193 * @return this * d +194 */ +195 RealVector mapMultiply(double d); +196 +197 /** +198 * Map a multiplication operation to each entry. +199 * <p>The instance <strong>is</strong> changed by this method.</p> +200 * @param d value to multiply all entries by +201 * @return for convenience, return this +202 */ +203 RealVector mapMultiplyToSelf(double d); +204 +205 /** +206 * Map a division operation to each entry. +207 * @param d value to divide all entries by +208 * @return this / d +209 */ +210 RealVector mapDivide(double d); +211 +212 /** +213 * Map a division operation to each entry. +214 * <p>The instance <strong>is</strong> changed by this method.</p> +215 * @param d value to divide all entries by +216 * @return for convenience, return this +217 */ +218 RealVector mapDivideToSelf(double d); +219 +220 /** +221 * Map a power operation to each entry. +222 * @param d value to raise all entries to +223 * @return this ^ d +224 */ +225 RealVector mapPow(double d); +226 +227 /** +228 * Map a power operation to each entry. +229 * <p>The instance <strong>is</strong> changed by this method.</p> +230 * @param d value to raise all entries to +231 * @return for convenience, return this +232 */ +233 RealVector mapPowToSelf(double d); +234 +235 /** +236 * Map the {@link Math#exp(double)} function to each entry. +237 * @return a vector containing the result of applying the function to each entry +238 */ +239 RealVector mapExp(); +240 +241 /** +242 * Map the {@link Math#exp(double)} function to each entry. +243 * <p>The instance <strong>is</strong> changed by this method.</p> +244 * @return for convenience, return this +245 */ +246 RealVector mapExpToSelf(); +247 +248 /** +249 * Map the {@link Math#expm1(double)} function to each entry. +250 * @return a vector containing the result of applying the function to each entry +251 */ +252 RealVector mapExpm1(); +253 +254 /** +255 * Map the {@link Math#expm1(double)} function to each entry. +256 * <p>The instance <strong>is</strong> changed by this method.</p> +257 * @return for convenience, return this +258 */ +259 RealVector mapExpm1ToSelf(); +260 +261 /** +262 * Map the {@link Math#log(double)} function to each entry. +263 * @return a vector containing the result of applying the function to each entry +264 */ +265 RealVector mapLog(); +266 +267 /** +268 * Map the {@link Math#log(double)} function to each entry. +269 * <p>The instance <strong>is</strong> changed by this method.</p> +270 * @return for convenience, return this +271 */ +272 RealVector mapLogToSelf(); +273 +274 /** +275 * Map the {@link Math#log10(double)} function to each entry. +276 * @return a vector containing the result of applying the function to each entry +277 */ +278 RealVector mapLog10(); +279 +280 /** +281 * Map the {@link Math#log10(double)} function to each entry. +282 * <p>The instance <strong>is</strong> changed by this method.</p> +283 * @return for convenience, return this +284 */ +285 RealVector mapLog10ToSelf(); +286 +287 /** +288 * Map the {@link Math#log1p(double)} function to each entry. +289 * @return a vector containing the result of applying the function to each entry +290 */ +291 RealVector mapLog1p(); +292 +293 /** +294 * Map the {@link Math#log1p(double)} function to each entry. +295 * <p>The instance <strong>is</strong> changed by this method.</p> +296 * @return for convenience, return this +297 */ +298 RealVector mapLog1pToSelf(); +299 +300 /** +301 * Map the {@link Math#cosh(double)} function to each entry. +302 * @return a vector containing the result of applying the function to each entry +303 */ +304 RealVector mapCosh(); +305 +306 /** +307 * Map the {@link Math#cosh(double)} function to each entry. +308 * <p>The instance <strong>is</strong> changed by this method.</p> +309 * @return for convenience, return this +310 */ +311 RealVector mapCoshToSelf(); +312 +313 /** +314 * Map the {@link Math#sinh(double)} function to each entry. +315 * @return a vector containing the result of applying the function to each entry +316 */ +317 RealVector mapSinh(); +318 +319 /** +320 * Map the {@link Math#sinh(double)} function to each entry. +321 * <p>The instance <strong>is</strong> changed by this method.</p> +322 * @return for convenience, return this +323 */ +324 RealVector mapSinhToSelf(); +325 +326 /** +327 * Map the {@link Math#tanh(double)} function to each entry. +328 * @return a vector containing the result of applying the function to each entry +329 */ +330 RealVector mapTanh(); +331 +332 /** +333 * Map the {@link Math#tanh(double)} function to each entry. +334 * <p>The instance <strong>is</strong> changed by this method.</p> +335 * @return for convenience, return this +336 */ +337 RealVector mapTanhToSelf(); +338 +339 /** +340 * Map the {@link Math#cos(double)} function to each entry. +341 * @return a vector containing the result of applying the function to each entry +342 */ +343 RealVector mapCos(); +344 +345 /** +346 * Map the {@link Math#cos(double)} function to each entry. +347 * <p>The instance <strong>is</strong> changed by this method.</p> +348 * @return for convenience, return this +349 */ +350 RealVector mapCosToSelf(); +351 +352 /** +353 * Map the {@link Math#sin(double)} function to each entry. +354 * @return a vector containing the result of applying the function to each entry +355 */ +356 RealVector mapSin(); +357 +358 /** +359 * Map the {@link Math#sin(double)} function to each entry. +360 * <p>The instance <strong>is</strong> changed by this method.</p> +361 * @return for convenience, return this +362 */ +363 RealVector mapSinToSelf(); +364 +365 /** +366 * Map the {@link Math#tan(double)} function to each entry. +367 * @return a vector containing the result of applying the function to each entry +368 */ +369 RealVector mapTan(); +370 +371 /** +372 * Map the {@link Math#tan(double)} function to each entry. +373 * <p>The instance <strong>is</strong> changed by this method.</p> +374 * @return for convenience, return this +375 */ +376 RealVector mapTanToSelf(); +377 +378 /** +379 * Map the {@link Math#acos(double)} function to each entry. +380 * @return a vector containing the result of applying the function to each entry +381 */ +382 RealVector mapAcos(); +383 +384 /** +385 * Map the {@link Math#acos(double)} function to each entry. +386 * <p>The instance <strong>is</strong> changed by this method.</p> +387 * @return for convenience, return this +388 */ +389 RealVector mapAcosToSelf(); +390 +391 /** +392 * Map the {@link Math#asin(double)} function to each entry. +393 * @return a vector containing the result of applying the function to each entry +394 */ +395 RealVector mapAsin(); +396 +397 /** +398 * Map the {@link Math#asin(double)} function to each entry. +399 * <p>The instance <strong>is</strong> changed by this method.</p> +400 * @return for convenience, return this +401 */ +402 RealVector mapAsinToSelf(); +403 +404 /** +405 * Map the {@link Math#atan(double)} function to each entry. +406 * @return a vector containing the result of applying the function to each entry +407 */ +408 RealVector mapAtan(); +409 +410 /** +411 * Map the {@link Math#atan(double)} function to each entry. +412 * <p>The instance <strong>is</strong> changed by this method.</p> +413 * @return for convenience, return this +414 */ +415 RealVector mapAtanToSelf(); +416 +417 /** +418 * Map the 1/x function to each entry. +419 * @return a vector containing the result of applying the function to each entry +420 */ +421 RealVector mapInv(); +422 +423 /** +424 * Map the 1/x function to each entry. +425 * <p>The instance <strong>is</strong> changed by this method.</p> +426 * @return for convenience, return this +427 */ +428 RealVector mapInvToSelf(); +429 +430 /** +431 * Map the {@link Math#abs(double)} function to each entry. +432 * @return a vector containing the result of applying the function to each entry +433 */ +434 RealVector mapAbs(); +435 +436 /** +437 * Map the {@link Math#abs(double)} function to each entry. +438 * <p>The instance <strong>is</strong> changed by this method.</p> +439 * @return for convenience, return this +440 */ +441 RealVector mapAbsToSelf(); +442 +443 /** +444 * Map the {@link Math#sqrt(double)} function to each entry. +445 * @return a vector containing the result of applying the function to each entry +446 */ +447 RealVector mapSqrt(); +448 +449 /** +450 * Map the {@link Math#sqrt(double)} function to each entry. +451 * <p>The instance <strong>is</strong> changed by this method.</p> +452 * @return for convenience, return this +453 */ +454 RealVector mapSqrtToSelf(); +455 +456 /** +457 * Map the {@link Math#cbrt(double)} function to each entry. +458 * @return a vector containing the result of applying the function to each entry +459 */ +460 RealVector mapCbrt(); +461 +462 /** +463 * Map the {@link Math#cbrt(double)} function to each entry. +464 * <p>The instance <strong>is</strong> changed by this method.</p> +465 * @return for convenience, return this +466 */ +467 RealVector mapCbrtToSelf(); +468 +469 /** +470 * Map the {@link Math#ceil(double)} function to each entry. +471 * @return a vector containing the result of applying the function to each entry +472 */ +473 RealVector mapCeil(); +474 +475 /** +476 * Map the {@link Math#ceil(double)} function to each entry. +477 * <p>The instance <strong>is</strong> changed by this method.</p> +478 * @return for convenience, return this +479 */ +480 RealVector mapCeilToSelf(); +481 +482 /** +483 * Map the {@link Math#floor(double)} function to each entry. +484 * @return a vector containing the result of applying the function to each entry +485 */ +486 RealVector mapFloor(); +487 +488 /** +489 * Map the {@link Math#floor(double)} function to each entry. +490 * <p>The instance <strong>is</strong> changed by this method.</p> +491 * @return for convenience, return this +492 */ +493 RealVector mapFloorToSelf(); +494 +495 /** +496 * Map the {@link Math#rint(double)} function to each entry. +497 * @return a vector containing the result of applying the function to each entry +498 */ +499 RealVector mapRint(); +500 +501 /** +502 * Map the {@link Math#rint(double)} function to each entry. +503 * <p>The instance <strong>is</strong> changed by this method.</p> +504 * @return for convenience, return this +505 */ +506 RealVector mapRintToSelf(); +507 +508 /** +509 * Map the {@link Math#signum(double)} function to each entry. +510 * @return a vector containing the result of applying the function to each entry +511 */ +512 RealVector mapSignum(); +513 +514 /** +515 * Map the {@link Math#signum(double)} function to each entry. +516 * <p>The instance <strong>is</strong> changed by this method.</p> +517 * @return for convenience, return this +518 */ +519 RealVector mapSignumToSelf(); +520 +521 /** +522 * Map the {@link Math#ulp(double)} function to each entry. +523 * @return a vector containing the result of applying the function to each entry +524 */ +525 RealVector mapUlp(); +526 +527 /** +528 * Map the {@link Math#ulp(double)} function to each entry. +529 * <p>The instance <strong>is</strong> changed by this method.</p> +530 * @return for convenience, return this +531 */ +532 RealVector mapUlpToSelf(); +533 +534 /** +535 * Element-by-element multiplication. +536 * @param v vector by which instance elements must be multiplied +537 * @return a vector containing this[i] * v[i] for all i +538 * @throws IllegalArgumentException if v is not the same size as this +539 */ +540 RealVector ebeMultiply(RealVector v) throws IllegalArgumentException; +541 +542 /** +543 * Element-by-element multiplication. +544 * @param v vector by which instance elements must be multiplied +545 * @return a vector containing this[i] * v[i] for all i +546 * @throws IllegalArgumentException if v is not the same size as this +547 */ +548 RealVector ebeMultiply(double[] v) throws IllegalArgumentException; +549 +550 /** +551 * Element-by-element division. +552 * @param v vector by which instance elements must be divided +553 * @return a vector containing this[i] / v[i] for all i +554 * @throws IllegalArgumentException if v is not the same size as this +555 */ +556 RealVector ebeDivide(RealVector v) throws IllegalArgumentException; +557 +558 /** +559 * Element-by-element division. +560 * @param v vector by which instance elements must be divided +561 * @return a vector containing this[i] / v[i] for all i +562 * @throws IllegalArgumentException if v is not the same size as this +563 */ +564 RealVector ebeDivide(double[] v) throws IllegalArgumentException; +565 +566 /** +567 * Returns vector entries as a double array. +568 * @return double array of entries +569 */ +570 double[] getData(); +571 +572 /** +573 * Compute the dot product. +574 * @param v vector with which dot product should be computed +575 * @return the scalar dot product between instance and v +576 * @exception IllegalArgumentException if v is not the same size as this +577 */ +578 double dotProduct(RealVector v) +579 throws IllegalArgumentException; +580 +581 /** +582 * Compute the dot product. +583 * @param v vector with which dot product should be computed +584 * @return the scalar dot product between instance and v +585 * @exception IllegalArgumentException if v is not the same size as this +586 */ +587 double dotProduct(double[] v) +588 throws IllegalArgumentException; +589 +590 /** +591 * Returns the L<sub>2</sub> norm of the vector. +592 * <p>The L<sub>2</sub> norm is the root of the sum of +593 * the squared elements.</p> +594 * @return norm +595 * @see #getL1Norm() +596 * @see #getLInfNorm() +597 * @see #getDistance(RealVector) +598 */ +599 double getNorm(); +600 +601 /** +602 * Returns the L<sub>1</sub> norm of the vector. +603 * <p>The L<sub>1</sub> norm is the sum of the absolute +604 * values of elements.</p> +605 * @return norm +606 * @see #getNorm() +607 * @see #getLInfNorm() +608 * @see #getL1Distance(RealVector) +609 */ +610 double getL1Norm(); +611 +612 /** +613 * Returns the L<sub>∞</sub> norm of the vector. +614 * <p>The L<sub>∞</sub> norm is the max of the absolute +615 * values of elements.</p> +616 * @return norm +617 * @see #getNorm() +618 * @see #getL1Norm() +619 * @see #getLInfDistance(RealVector) +620 */ +621 double getLInfNorm(); +622 +623 /** +624 * Distance between two vectors. +625 * <p>This method computes the distance consistent with the +626 * L<sub>2</sub> norm, i.e. the square root of the sum of +627 * elements differences, or euclidian distance.</p> +628 * @param v vector to which distance is requested +629 * @return distance between two vectors. +630 * @exception IllegalArgumentException if v is not the same size as this +631 * @see #getL1Distance(RealVector) +632 * @see #getLInfDistance(RealVector) +633 * @see #getNorm() +634 */ +635 double getDistance(RealVector v) +636 throws IllegalArgumentException; +637 +638 /** +639 * Distance between two vectors. +640 * <p>This method computes the distance consistent with the +641 * L<sub>2</sub> norm, i.e. the square root of the sum of +642 * elements differences, or euclidian distance.</p> +643 * @param v vector to which distance is requested +644 * @return distance between two vectors. +645 * @exception IllegalArgumentException if v is not the same size as this +646 * @see #getL1Distance(double[]) +647 * @see #getLInfDistance(double[]) +648 * @see #getNorm() +649 */ +650 double getDistance(double[] v) +651 throws IllegalArgumentException; +652 +653 /** +654 * Distance between two vectors. +655 * <p>This method computes the distance consistent with +656 * L<sub>1</sub> norm, i.e. the sum of the absolute values of +657 * elements differences.</p> +658 * @param v vector to which distance is requested +659 * @return distance between two vectors. +660 * @exception IllegalArgumentException if v is not the same size as this +661 * @see #getDistance(RealVector) +662 * @see #getLInfDistance(RealVector) +663 * @see #getL1Norm() +664 */ +665 double getL1Distance(RealVector v) +666 throws IllegalArgumentException; +667 +668 /** +669 * Distance between two vectors. +670 * <p>This method computes the distance consistent with +671 * L<sub>1</sub> norm, i.e. the sum of the absolute values of +672 * elements differences.</p> +673 * @param v vector to which distance is requested +674 * @return distance between two vectors. +675 * @exception IllegalArgumentException if v is not the same size as this +676 * @see #getDistance(double[]) +677 * @see #getLInfDistance(double[]) +678 * @see #getL1Norm() +679 */ +680 double getL1Distance(double[] v) +681 throws IllegalArgumentException; +682 +683 /** +684 * Distance between two vectors. +685 * <p>This method computes the distance consistent with +686 * L<sub>∞</sub> norm, i.e. the max of the absolute values of +687 * elements differences.</p> +688 * @param v vector to which distance is requested +689 * @return distance between two vectors. +690 * @exception IllegalArgumentException if v is not the same size as this +691 * @see #getDistance(RealVector) +692 * @see #getL1Distance(RealVector) +693 * @see #getLInfNorm() +694 */ +695 double getLInfDistance(RealVector v) +696 throws IllegalArgumentException; +697 +698 /** +699 * Distance between two vectors. +700 * <p>This method computes the distance consistent with +701 * L<sub>∞</sub> norm, i.e. the max of the absolute values of +702 * elements differences.</p> +703 * @param v vector to which distance is requested +704 * @return distance between two vectors. +705 * @exception IllegalArgumentException if v is not the same size as this +706 * @see #getDistance(double[]) +707 * @see #getL1Distance(double[]) +708 * @see #getLInfNorm() +709 */ +710 double getLInfDistance(double[] v) +711 throws IllegalArgumentException; +712 +713 /** Creates a unit vector pointing in the direction of this vector. +714 * <p>The instance is not changed by this method.</p> +715 * @return a unit vector pointing in direction of this vector +716 * @exception ArithmeticException if the norm is null +717 */ +718 RealVector unitVector(); +719 +720 /** Converts this vector into a unit vector. +721 * <p>The instance itself is changed by this method.</p> +722 * @exception ArithmeticException if the norm is null +723 */ +724 void unitize(); +725 +726 /** Find the orthogonal projection of this vector onto another vector. +727 * @param v vector onto which instance must be projected +728 * @return projection of the instance onto v +729 * @throws IllegalArgumentException if v is not the same size as this +730 */ +731 RealVector projection(RealVector v) +732 throws IllegalArgumentException; +733 +734 /** Find the orthogonal projection of this vector onto another vector. +735 * @param v vector onto which instance must be projected +736 * @return projection of the instance onto v +737 * @throws IllegalArgumentException if v is not the same size as this +738 */ +739 RealVector projection(double[] v) +740 throws IllegalArgumentException; +741 +742 /** +743 * Compute the outer product. +744 * @param v vector with which outer product should be computed +745 * @return the square matrix outer product between instance and v +746 * @exception IllegalArgumentException if v is not the same size as this +747 */ +748 RealMatrix outerProduct(RealVector v) +749 throws IllegalArgumentException; +750 +751 /** +752 * Compute the outer product. +753 * @param v vector with which outer product should be computed +754 * @return the square matrix outer product between instance and v +755 * @exception IllegalArgumentException if v is not the same size as this +756 */ +757 RealMatrix outerProduct(double[] v) +758 throws IllegalArgumentException; +759 +760 /** +761 * Returns the entry in the specified index. +762 * <p> +763 * The index start at 0 and must be lesser than the size, +764 * otherwise a {@link MatrixIndexException} is thrown. +765 * </p> +766 * @param index index location of entry to be fetched +767 * @return vector entry at index +768 * @throws MatrixIndexException if the index is not valid +769 * @see #setEntry(int, double) +770 */ +771 double getEntry(int index) +772 throws MatrixIndexException; +773 +774 /** +775 * Set a single element. +776 * @param index element index. +777 * @param value new value for the element. +778 * @exception MatrixIndexException if the index is +779 * inconsistent with vector size +780 * @see #getEntry(int) +781 */ +782 void setEntry(int index, double value) +783 throws MatrixIndexException; +784 +785 /** +786 * Returns the size of the vector. +787 * @return size +788 */ +789 int getDimension(); +790 +791 /** +792 * Construct a vector by appending a vector to this vector. +793 * @param v vector to append to this one. +794 * @return a new vector +795 */ +796 RealVector append(RealVector v); +797 +798 /** +799 * Construct a vector by appending a double to this vector. +800 * @param d double to append. +801 * @return a new vector +802 */ +803 RealVector append(double d); +804 +805 /** +806 * Construct a vector by appending a double array to this vector. +807 * @param a double array to append. +808 * @return a new vector +809 */ +810 RealVector append(double[] a); +811 +812 /** +813 * Get a subvector from consecutive elements. +814 * @param index index of first element. +815 * @param n number of elements to be retrieved. +816 * @return a vector containing n elements. +817 * @exception MatrixIndexException if the index is +818 * inconsistent with vector size +819 */ +820 RealVector getSubVector(int index, int n) +821 throws MatrixIndexException; +822 +823 /** +824 * Set a set of consecutive elements. +825 * @param index index of first element to be set. +826 * @param v vector containing the values to set. +827 * @exception MatrixIndexException if the index is +828 * inconsistent with vector size +829 * @see #setSubVector(int, double[]) +830 */ +831 void setSubVector(int index, RealVector v) +832 throws MatrixIndexException; +833 +834 /** +835 * Set a set of consecutive elements. +836 * @param index index of first element to be set. +837 * @param v vector containing the values to set. +838 * @exception MatrixIndexException if the index is +839 * inconsistent with vector size +840 * @see #setSubVector(int, RealVector) +841 */ +842 void setSubVector(int index, double[] v) +843 throws MatrixIndexException; +844 +845 /** +846 * Set all elements to a single value. +847 * @param value single value to set for all elements +848 */ +849 void set(double value); +850 +851 /** +852 * Convert the vector to a double array. +853 * <p>The array is independent from vector data, it's elements +854 * are copied.</p> +855 * @return array containing a copy of vector elements +856 */ +857 double[] toArray(); +858 +859 /** +860 * Returns true if any coordinate of this vector is NaN; false otherwise +861 * @return true if any coordinate of this vector is NaN; false otherwise +862 */ +863 boolean isNaN(); +864 +865 /** +866 * Returns true if any coordinate of this vector is infinite and none are NaN; +867 * false otherwise +868 * @return true if any coordinate of this vector is infinite and none are NaN; +869 * false otherwise +870 */ +871 boolean isInfinite(); +872 +873 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/RealVector.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/RealVector.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,939 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.linear; +018 +019 import java.util.Iterator; +020 +021 import org.apache.commons.math.FunctionEvaluationException; +022 import org.apache.commons.math.analysis.UnivariateRealFunction; +023 +024 +025 /** +026 * Interface defining a real-valued vector with basic algebraic operations. +027 * <p> +028 * vector element indexing is 0-based -- e.g., <code>getEntry(0)</code> +029 * returns the first element of the vector. +030 * </p> +031 * <p> +032 * The various <code>mapXxx</code> and <code>mapXxxToSelf</code> methods operate +033 * on vectors element-wise, i.e. they perform the same operation (adding a scalar, +034 * applying a function ...) on each element in turn. The <code>mapXxx</code> +035 * versions create a new vector to hold the result and do not change the instance. +036 * The <code>mapXxxToSelf</code> versions use the instance itself to store the +037 * results, so the instance is changed by these methods. In both cases, the result +038 * vector is returned by the methods, this allows to use the <i>fluent API</i> +039 * style, like this: +040 * </p> +041 * <pre> +042 * RealVector result = v.mapAddToSelf(3.0).mapTanToSelf().mapSquareToSelf(); +043 * </pre> +044 * +045 * @version $Revision: 902214 $ $Date: 2010-01-22 13:40:28 -0500 (Fri, 22 Jan 2010) $ +046 * @since 2.0 +047 */ +048 public interface RealVector { +049 +050 /** +051 * Acts as if it is implemented as: +052 * Entry e = null; +053 * for(Iterator<Entry> it = iterator(); it.hasNext(); e = it.next()) { +054 * e.setValue(function.value(e.getValue())); +055 * } +056 * @param function to apply to each successive entry +057 * @return this vector +058 * @throws FunctionEvaluationException if function throws it on application to any entry +059 */ +060 RealVector mapToSelf(UnivariateRealFunction function) throws FunctionEvaluationException; +061 +062 /** +063 * Acts as if implemented as: +064 * return copy().map(function); +065 * @param function to apply to each successive entry +066 * @return a new vector +067 * @throws FunctionEvaluationException if function throws it on application to any entry +068 */ +069 RealVector map(UnivariateRealFunction function) throws FunctionEvaluationException; +070 +071 /** Class representing a modifiable entry in the vector. */ +072 public abstract class Entry { +073 +074 /** Index of the entry. */ +075 private int index; +076 +077 /** Get the value of the entry. +078 * @return value of the entry +079 */ +080 public abstract double getValue(); +081 +082 /** Set the value of the entry. +083 * @param value new value for the entry +084 */ +085 public abstract void setValue(double value); +086 +087 /** Get the index of the entry. +088 * @return index of the entry +089 */ +090 public int getIndex() { +091 return index; +092 } +093 +094 /** Set the index of the entry. +095 * @param index new index for the entry +096 */ +097 public void setIndex(int index) { +098 this.index = index; +099 } +100 +101 } +102 +103 /** +104 * Generic dense iterator - starts with index == zero, and hasNext() == true until index == getDimension(); +105 * @return a dense iterator +106 */ +107 Iterator<Entry> iterator(); +108 +109 /** +110 * Specialized implementations may choose to not iterate over all dimensions, either because those values are +111 * unset, or are equal to defaultValue(), or are small enough to be ignored for the purposes of iteration. +112 * No guarantees are made about order of iteration. +113 * In dense implementations, this method will often delegate to {@link #iterator()} +114 * @return a sparse iterator +115 */ +116 Iterator<Entry> sparseIterator(); +117 +118 /** +119 * Returns a (deep) copy of this. +120 * @return vector copy +121 */ +122 RealVector copy(); +123 +124 /** +125 * Compute the sum of this and v. +126 * @param v vector to be added +127 * @return this + v +128 * @throws IllegalArgumentException if v is not the same size as this +129 */ +130 RealVector add(RealVector v) +131 throws IllegalArgumentException; +132 +133 /** +134 * Compute the sum of this and v. +135 * @param v vector to be added +136 * @return this + v +137 * @throws IllegalArgumentException if v is not the same size as this +138 */ +139 RealVector add(double[] v) +140 throws IllegalArgumentException; +141 +142 /** +143 * Compute this minus v. +144 * @param v vector to be subtracted +145 * @return this + v +146 * @throws IllegalArgumentException if v is not the same size as this +147 */ +148 RealVector subtract(RealVector v) +149 throws IllegalArgumentException; +150 +151 /** +152 * Compute this minus v. +153 * @param v vector to be subtracted +154 * @return this + v +155 * @throws IllegalArgumentException if v is not the same size as this +156 */ +157 RealVector subtract(double[] v) +158 throws IllegalArgumentException; +159 +160 /** +161 * Map an addition operation to each entry. +162 * @param d value to be added to each entry +163 * @return this + d +164 */ +165 RealVector mapAdd(double d); +166 +167 /** +168 * Map an addition operation to each entry. +169 * <p>The instance <strong>is</strong> changed by this method.</p> +170 * @param d value to be added to each entry +171 * @return for convenience, return this +172 */ +173 RealVector mapAddToSelf(double d); +174 +175 /** +176 * Map a subtraction operation to each entry. +177 * @param d value to be subtracted to each entry +178 * @return this - d +179 */ +180 RealVector mapSubtract(double d); +181 +182 /** +183 * Map a subtraction operation to each entry. +184 * <p>The instance <strong>is</strong> changed by this method.</p> +185 * @param d value to be subtracted to each entry +186 * @return for convenience, return this +187 */ +188 RealVector mapSubtractToSelf(double d); +189 +190 /** +191 * Map a multiplication operation to each entry. +192 * @param d value to multiply all entries by +193 * @return this * d +194 */ +195 RealVector mapMultiply(double d); +196 +197 /** +198 * Map a multiplication operation to each entry. +199 * <p>The instance <strong>is</strong> changed by this method.</p> +200 * @param d value to multiply all entries by +201 * @return for convenience, return this +202 */ +203 RealVector mapMultiplyToSelf(double d); +204 +205 /** +206 * Map a division operation to each entry. +207 * @param d value to divide all entries by +208 * @return this / d +209 */ +210 RealVector mapDivide(double d); +211 +212 /** +213 * Map a division operation to each entry. +214 * <p>The instance <strong>is</strong> changed by this method.</p> +215 * @param d value to divide all entries by +216 * @return for convenience, return this +217 */ +218 RealVector mapDivideToSelf(double d); +219 +220 /** +221 * Map a power operation to each entry. +222 * @param d value to raise all entries to +223 * @return this ^ d +224 */ +225 RealVector mapPow(double d); +226 +227 /** +228 * Map a power operation to each entry. +229 * <p>The instance <strong>is</strong> changed by this method.</p> +230 * @param d value to raise all entries to +231 * @return for convenience, return this +232 */ +233 RealVector mapPowToSelf(double d); +234 +235 /** +236 * Map the {@link Math#exp(double)} function to each entry. +237 * @return a vector containing the result of applying the function to each entry +238 */ +239 RealVector mapExp(); +240 +241 /** +242 * Map the {@link Math#exp(double)} function to each entry. +243 * <p>The instance <strong>is</strong> changed by this method.</p> +244 * @return for convenience, return this +245 */ +246 RealVector mapExpToSelf(); +247 +248 /** +249 * Map the {@link Math#expm1(double)} function to each entry. +250 * @return a vector containing the result of applying the function to each entry +251 */ +252 RealVector mapExpm1(); +253 +254 /** +255 * Map the {@link Math#expm1(double)} function to each entry. +256 * <p>The instance <strong>is</strong> changed by this method.</p> +257 * @return for convenience, return this +258 */ +259 RealVector mapExpm1ToSelf(); +260 +261 /** +262 * Map the {@link Math#log(double)} function to each entry. +263 * @return a vector containing the result of applying the function to each entry +264 */ +265 RealVector mapLog(); +266 +267 /** +268 * Map the {@link Math#log(double)} function to each entry. +269 * <p>The instance <strong>is</strong> changed by this method.</p> +270 * @return for convenience, return this +271 */ +272 RealVector mapLogToSelf(); +273 +274 /** +275 * Map the {@link Math#log10(double)} function to each entry. +276 * @return a vector containing the result of applying the function to each entry +277 */ +278 RealVector mapLog10(); +279 +280 /** +281 * Map the {@link Math#log10(double)} function to each entry. +282 * <p>The instance <strong>is</strong> changed by this method.</p> +283 * @return for convenience, return this +284 */ +285 RealVector mapLog10ToSelf(); +286 +287 /** +288 * Map the {@link Math#log1p(double)} function to each entry. +289 * @return a vector containing the result of applying the function to each entry +290 */ +291 RealVector mapLog1p(); +292 +293 /** +294 * Map the {@link Math#log1p(double)} function to each entry. +295 * <p>The instance <strong>is</strong> changed by this method.</p> +296 * @return for convenience, return this +297 */ +298 RealVector mapLog1pToSelf(); +299 +300 /** +301 * Map the {@link Math#cosh(double)} function to each entry. +302 * @return a vector containing the result of applying the function to each entry +303 */ +304 RealVector mapCosh(); +305 +306 /** +307 * Map the {@link Math#cosh(double)} function to each entry. +308 * <p>The instance <strong>is</strong> changed by this method.</p> +309 * @return for convenience, return this +310 */ +311 RealVector mapCoshToSelf(); +312 +313 /** +314 * Map the {@link Math#sinh(double)} function to each entry. +315 * @return a vector containing the result of applying the function to each entry +316 */ +317 RealVector mapSinh(); +318 +319 /** +320 * Map the {@link Math#sinh(double)} function to each entry. +321 * <p>The instance <strong>is</strong> changed by this method.</p> +322 * @return for convenience, return this +323 */ +324 RealVector mapSinhToSelf(); +325 +326 /** +327 * Map the {@link Math#tanh(double)} function to each entry. +328 * @return a vector containing the result of applying the function to each entry +329 */ +330 RealVector mapTanh(); +331 +332 /** +333 * Map the {@link Math#tanh(double)} function to each entry. +334 * <p>The instance <strong>is</strong> changed by this method.</p> +335 * @return for convenience, return this +336 */ +337 RealVector mapTanhToSelf(); +338 +339 /** +340 * Map the {@link Math#cos(double)} function to each entry. +341 * @return a vector containing the result of applying the function to each entry +342 */ +343 RealVector mapCos(); +344 +345 /** +346 * Map the {@link Math#cos(double)} function to each entry. +347 * <p>The instance <strong>is</strong> changed by this method.</p> +348 * @return for convenience, return this +349 */ +350 RealVector mapCosToSelf(); +351 +352 /** +353 * Map the {@link Math#sin(double)} function to each entry. +354 * @return a vector containing the result of applying the function to each entry +355 */ +356 RealVector mapSin(); +357 +358 /** +359 * Map the {@link Math#sin(double)} function to each entry. +360 * <p>The instance <strong>is</strong> changed by this method.</p> +361 * @return for convenience, return this +362 */ +363 RealVector mapSinToSelf(); +364 +365 /** +366 * Map the {@link Math#tan(double)} function to each entry. +367 * @return a vector containing the result of applying the function to each entry +368 */ +369 RealVector mapTan(); +370 +371 /** +372 * Map the {@link Math#tan(double)} function to each entry. +373 * <p>The instance <strong>is</strong> changed by this method.</p> +374 * @return for convenience, return this +375 */ +376 RealVector mapTanToSelf(); +377 +378 /** +379 * Map the {@link Math#acos(double)} function to each entry. +380 * @return a vector containing the result of applying the function to each entry +381 */ +382 RealVector mapAcos(); +383 +384 /** +385 * Map the {@link Math#acos(double)} function to each entry. +386 * <p>The instance <strong>is</strong> changed by this method.</p> +387 * @return for convenience, return this +388 */ +389 RealVector mapAcosToSelf(); +390 +391 /** +392 * Map the {@link Math#asin(double)} function to each entry. +393 * @return a vector containing the result of applying the function to each entry +394 */ +395 RealVector mapAsin(); +396 +397 /** +398 * Map the {@link Math#asin(double)} function to each entry. +399 * <p>The instance <strong>is</strong> changed by this method.</p> +400 * @return for convenience, return this +401 */ +402 RealVector mapAsinToSelf(); +403 +404 /** +405 * Map the {@link Math#atan(double)} function to each entry. +406 * @return a vector containing the result of applying the function to each entry +407 */ +408 RealVector mapAtan(); +409 +410 /** +411 * Map the {@link Math#atan(double)} function to each entry. +412 * <p>The instance <strong>is</strong> changed by this method.</p> +413 * @return for convenience, return this +414 */ +415 RealVector mapAtanToSelf(); +416 +417 /** +418 * Map the 1/x function to each entry. +419 * @return a vector containing the result of applying the function to each entry +420 */ +421 RealVector mapInv(); +422 +423 /** +424 * Map the 1/x function to each entry. +425 * <p>The instance <strong>is</strong> changed by this method.</p> +426 * @return for convenience, return this +427 */ +428 RealVector mapInvToSelf(); +429 +430 /** +431 * Map the {@link Math#abs(double)} function to each entry. +432 * @return a vector containing the result of applying the function to each entry +433 */ +434 RealVector mapAbs(); +435 +436 /** +437 * Map the {@link Math#abs(double)} function to each entry. +438 * <p>The instance <strong>is</strong> changed by this method.</p> +439 * @return for convenience, return this +440 */ +441 RealVector mapAbsToSelf(); +442 +443 /** +444 * Map the {@link Math#sqrt(double)} function to each entry. +445 * @return a vector containing the result of applying the function to each entry +446 */ +447 RealVector mapSqrt(); +448 +449 /** +450 * Map the {@link Math#sqrt(double)} function to each entry. +451 * <p>The instance <strong>is</strong> changed by this method.</p> +452 * @return for convenience, return this +453 */ +454 RealVector mapSqrtToSelf(); +455 +456 /** +457 * Map the {@link Math#cbrt(double)} function to each entry. +458 * @return a vector containing the result of applying the function to each entry +459 */ +460 RealVector mapCbrt(); +461 +462 /** +463 * Map the {@link Math#cbrt(double)} function to each entry. +464 * <p>The instance <strong>is</strong> changed by this method.</p> +465 * @return for convenience, return this +466 */ +467 RealVector mapCbrtToSelf(); +468 +469 /** +470 * Map the {@link Math#ceil(double)} function to each entry. +471 * @return a vector containing the result of applying the function to each entry +472 */ +473 RealVector mapCeil(); +474 +475 /** +476 * Map the {@link Math#ceil(double)} function to each entry. +477 * <p>The instance <strong>is</strong> changed by this method.</p> +478 * @return for convenience, return this +479 */ +480 RealVector mapCeilToSelf(); +481 +482 /** +483 * Map the {@link Math#floor(double)} function to each entry. +484 * @return a vector containing the result of applying the function to each entry +485 */ +486 RealVector mapFloor(); +487 +488 /** +489 * Map the {@link Math#floor(double)} function to each entry. +490 * <p>The instance <strong>is</strong> changed by this method.</p> +491 * @return for convenience, return this +492 */ +493 RealVector mapFloorToSelf(); +494 +495 /** +496 * Map the {@link Math#rint(double)} function to each entry. +497 * @return a vector containing the result of applying the function to each entry +498 */ +499 RealVector mapRint(); +500 +501 /** +502 * Map the {@link Math#rint(double)} function to each entry. +503 * <p>The instance <strong>is</strong> changed by this method.</p> +504 * @return for convenience, return this +505 */ +506 RealVector mapRintToSelf(); +507 +508 /** +509 * Map the {@link Math#signum(double)} function to each entry. +510 * @return a vector containing the result of applying the function to each entry +511 */ +512 RealVector mapSignum(); +513 +514 /** +515 * Map the {@link Math#signum(double)} function to each entry. +516 * <p>The instance <strong>is</strong> changed by this method.</p> +517 * @return for convenience, return this +518 */ +519 RealVector mapSignumToSelf(); +520 +521 /** +522 * Map the {@link Math#ulp(double)} function to each entry. +523 * @return a vector containing the result of applying the function to each entry +524 */ +525 RealVector mapUlp(); +526 +527 /** +528 * Map the {@link Math#ulp(double)} function to each entry. +529 * <p>The instance <strong>is</strong> changed by this method.</p> +530 * @return for convenience, return this +531 */ +532 RealVector mapUlpToSelf(); +533 +534 /** +535 * Element-by-element multiplication. +536 * @param v vector by which instance elements must be multiplied +537 * @return a vector containing this[i] * v[i] for all i +538 * @throws IllegalArgumentException if v is not the same size as this +539 */ +540 RealVector ebeMultiply(RealVector v) throws IllegalArgumentException; +541 +542 /** +543 * Element-by-element multiplication. +544 * @param v vector by which instance elements must be multiplied +545 * @return a vector containing this[i] * v[i] for all i +546 * @throws IllegalArgumentException if v is not the same size as this +547 */ +548 RealVector ebeMultiply(double[] v) throws IllegalArgumentException; +549 +550 /** +551 * Element-by-element division. +552 * @param v vector by which instance elements must be divided +553 * @return a vector containing this[i] / v[i] for all i +554 * @throws IllegalArgumentException if v is not the same size as this +555 */ +556 RealVector ebeDivide(RealVector v) throws IllegalArgumentException; +557 +558 /** +559 * Element-by-element division. +560 * @param v vector by which instance elements must be divided +561 * @return a vector containing this[i] / v[i] for all i +562 * @throws IllegalArgumentException if v is not the same size as this +563 */ +564 RealVector ebeDivide(double[] v) throws IllegalArgumentException; +565 +566 /** +567 * Returns vector entries as a double array. +568 * @return double array of entries +569 */ +570 double[] getData(); +571 +572 /** +573 * Compute the dot product. +574 * @param v vector with which dot product should be computed +575 * @return the scalar dot product between instance and v +576 * @exception IllegalArgumentException if v is not the same size as this +577 */ +578 double dotProduct(RealVector v) +579 throws IllegalArgumentException; +580 +581 /** +582 * Compute the dot product. +583 * @param v vector with which dot product should be computed +584 * @return the scalar dot product between instance and v +585 * @exception IllegalArgumentException if v is not the same size as this +586 */ +587 double dotProduct(double[] v) +588 throws IllegalArgumentException; +589 +590 /** +591 * Returns the L<sub>2</sub> norm of the vector. +592 * <p>The L<sub>2</sub> norm is the root of the sum of +593 * the squared elements.</p> +594 * @return norm +595 * @see #getL1Norm() +596 * @see #getLInfNorm() +597 * @see #getDistance(RealVector) +598 */ +599 double getNorm(); +600 +601 /** +602 * Returns the L<sub>1</sub> norm of the vector. +603 * <p>The L<sub>1</sub> norm is the sum of the absolute +604 * values of elements.</p> +605 * @return norm +606 * @see #getNorm() +607 * @see #getLInfNorm() +608 * @see #getL1Distance(RealVector) +609 */ +610 double getL1Norm(); +611 +612 /** +613 * Returns the L<sub>∞</sub> norm of the vector. +614 * <p>The L<sub>∞</sub> norm is the max of the absolute +615 * values of elements.</p> +616 * @return norm +617 * @see #getNorm() +618 * @see #getL1Norm() +619 * @see #getLInfDistance(RealVector) +620 */ +621 double getLInfNorm(); +622 +623 /** +624 * Distance between two vectors. +625 * <p>This method computes the distance consistent with the +626 * L<sub>2</sub> norm, i.e. the square root of the sum of +627 * elements differences, or euclidian distance.</p> +628 * @param v vector to which distance is requested +629 * @return distance between two vectors. +630 * @exception IllegalArgumentException if v is not the same size as this +631 * @see #getL1Distance(RealVector) +632 * @see #getLInfDistance(RealVector) +633 * @see #getNorm() +634 */ +635 double getDistance(RealVector v) +636 throws IllegalArgumentException; +637 +638 /** +639 * Distance between two vectors. +640 * <p>This method computes the distance consistent with the +641 * L<sub>2</sub> norm, i.e. the square root of the sum of +642 * elements differences, or euclidian distance.</p> +643 * @param v vector to which distance is requested +644 * @return distance between two vectors. +645 * @exception IllegalArgumentException if v is not the same size as this +646 * @see #getL1Distance(double[]) +647 * @see #getLInfDistance(double[]) +648 * @see #getNorm() +649 */ +650 double getDistance(double[] v) +651 throws IllegalArgumentException; +652 +653 /** +654 * Distance between two vectors. +655 * <p>This method computes the distance consistent with +656 * L<sub>1</sub> norm, i.e. the sum of the absolute values of +657 * elements differences.</p> +658 * @param v vector to which distance is requested +659 * @return distance between two vectors. +660 * @exception IllegalArgumentException if v is not the same size as this +661 * @see #getDistance(RealVector) +662 * @see #getLInfDistance(RealVector) +663 * @see #getL1Norm() +664 */ +665 double getL1Distance(RealVector v) +666 throws IllegalArgumentException; +667 +668 /** +669 * Distance between two vectors. +670 * <p>This method computes the distance consistent with +671 * L<sub>1</sub> norm, i.e. the sum of the absolute values of +672 * elements differences.</p> +673 * @param v vector to which distance is requested +674 * @return distance between two vectors. +675 * @exception IllegalArgumentException if v is not the same size as this +676 * @see #getDistance(double[]) +677 * @see #getLInfDistance(double[]) +678 * @see #getL1Norm() +679 */ +680 double getL1Distance(double[] v) +681 throws IllegalArgumentException; +682 +683 /** +684 * Distance between two vectors. +685 * <p>This method computes the distance consistent with +686 * L<sub>∞</sub> norm, i.e. the max of the absolute values of +687 * elements differences.</p> +688 * @param v vector to which distance is requested +689 * @return distance between two vectors. +690 * @exception IllegalArgumentException if v is not the same size as this +691 * @see #getDistance(RealVector) +692 * @see #getL1Distance(RealVector) +693 * @see #getLInfNorm() +694 */ +695 double getLInfDistance(RealVector v) +696 throws IllegalArgumentException; +697 +698 /** +699 * Distance between two vectors. +700 * <p>This method computes the distance consistent with +701 * L<sub>∞</sub> norm, i.e. the max of the absolute values of +702 * elements differences.</p> +703 * @param v vector to which distance is requested +704 * @return distance between two vectors. +705 * @exception IllegalArgumentException if v is not the same size as this +706 * @see #getDistance(double[]) +707 * @see #getL1Distance(double[]) +708 * @see #getLInfNorm() +709 */ +710 double getLInfDistance(double[] v) +711 throws IllegalArgumentException; +712 +713 /** Creates a unit vector pointing in the direction of this vector. +714 * <p>The instance is not changed by this method.</p> +715 * @return a unit vector pointing in direction of this vector +716 * @exception ArithmeticException if the norm is null +717 */ +718 RealVector unitVector(); +719 +720 /** Converts this vector into a unit vector. +721 * <p>The instance itself is changed by this method.</p> +722 * @exception ArithmeticException if the norm is null +723 */ +724 void unitize(); +725 +726 /** Find the orthogonal projection of this vector onto another vector. +727 * @param v vector onto which instance must be projected +728 * @return projection of the instance onto v +729 * @throws IllegalArgumentException if v is not the same size as this +730 */ +731 RealVector projection(RealVector v) +732 throws IllegalArgumentException; +733 +734 /** Find the orthogonal projection of this vector onto another vector. +735 * @param v vector onto which instance must be projected +736 * @return projection of the instance onto v +737 * @throws IllegalArgumentException if v is not the same size as this +738 */ +739 RealVector projection(double[] v) +740 throws IllegalArgumentException; +741 +742 /** +743 * Compute the outer product. +744 * @param v vector with which outer product should be computed +745 * @return the square matrix outer product between instance and v +746 * @exception IllegalArgumentException if v is not the same size as this +747 */ +748 RealMatrix outerProduct(RealVector v) +749 throws IllegalArgumentException; +750 +751 /** +752 * Compute the outer product. +753 * @param v vector with which outer product should be computed +754 * @return the square matrix outer product between instance and v +755 * @exception IllegalArgumentException if v is not the same size as this +756 */ +757 RealMatrix outerProduct(double[] v) +758 throws IllegalArgumentException; +759 +760 /** +761 * Returns the entry in the specified index. +762 * <p> +763 * The index start at 0 and must be lesser than the size, +764 * otherwise a {@link MatrixIndexException} is thrown. +765 * </p> +766 * @param index index location of entry to be fetched +767 * @return vector entry at index +768 * @throws MatrixIndexException if the index is not valid +769 * @see #setEntry(int, double) +770 */ +771 double getEntry(int index) +772 throws MatrixIndexException; +773 +774 /** +775 * Set a single element. +776 * @param index element index. +777 * @param value new value for the element. +778 * @exception MatrixIndexException if the index is +779 * inconsistent with vector size +780 * @see #getEntry(int) +781 */ +782 void setEntry(int index, double value) +783 throws MatrixIndexException; +784 +785 /** +786 * Returns the size of the vector. +787 * @return size +788 */ +789 int getDimension(); +790 +791 /** +792 * Construct a vector by appending a vector to this vector. +793 * @param v vector to append to this one. +794 * @return a new vector +795 */ +796 RealVector append(RealVector v); +797 +798 /** +799 * Construct a vector by appending a double to this vector. +800 * @param d double to append. +801 * @return a new vector +802 */ +803 RealVector append(double d); +804 +805 /** +806 * Construct a vector by appending a double array to this vector. +807 * @param a double array to append. +808 * @return a new vector +809 */ +810 RealVector append(double[] a); +811 +812 /** +813 * Get a subvector from consecutive elements. +814 * @param index index of first element. +815 * @param n number of elements to be retrieved. +816 * @return a vector containing n elements. +817 * @exception MatrixIndexException if the index is +818 * inconsistent with vector size +819 */ +820 RealVector getSubVector(int index, int n) +821 throws MatrixIndexException; +822 +823 /** +824 * Set a set of consecutive elements. +825 * @param index index of first element to be set. +826 * @param v vector containing the values to set. +827 * @exception MatrixIndexException if the index is +828 * inconsistent with vector size +829 * @see #setSubVector(int, double[]) +830 */ +831 void setSubVector(int index, RealVector v) +832 throws MatrixIndexException; +833 +834 /** +835 * Set a set of consecutive elements. +836 * @param index index of first element to be set. +837 * @param v vector containing the values to set. +838 * @exception MatrixIndexException if the index is +839 * inconsistent with vector size +840 * @see #setSubVector(int, RealVector) +841 */ +842 void setSubVector(int index, double[] v) +843 throws MatrixIndexException; +844 +845 /** +846 * Set all elements to a single value. +847 * @param value single value to set for all elements +848 */ +849 void set(double value); +850 +851 /** +852 * Convert the vector to a double array. +853 * <p>The array is independent from vector data, it's elements +854 * are copied.</p> +855 * @return array containing a copy of vector elements +856 */ +857 double[] toArray(); +858 +859 /** +860 * Returns true if any coordinate of this vector is NaN; false otherwise +861 * @return true if any coordinate of this vector is NaN; false otherwise +862 */ +863 boolean isNaN(); +864 +865 /** +866 * Returns true if any coordinate of this vector is infinite and none are NaN; +867 * false otherwise +868 * @return true if any coordinate of this vector is infinite and none are NaN; +869 * false otherwise +870 */ +871 boolean isInfinite(); +872 +873 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/RealVectorFormat.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/RealVectorFormat.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,406 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import java.text.FieldPosition; +021 import java.text.NumberFormat; +022 import java.text.ParseException; +023 import java.text.ParsePosition; +024 import java.util.ArrayList; +025 import java.util.List; +026 import java.util.Locale; +027 +028 import org.apache.commons.math.MathRuntimeException; +029 import org.apache.commons.math.util.CompositeFormat; +030 +031 /** +032 * Formats a vector in components list format "{v0; v1; ...; vk-1}". +033 * <p>The prefix and suffix "{" and "}" and the separator "; " can be replaced by +034 * any user-defined strings. The number format for components can be configured.</p> +035 * <p>White space is ignored at parse time, even if it is in the prefix, suffix +036 * or separator specifications. So even if the default separator does include a space +037 * character that is used at format time, both input string "{1;1;1}" and +038 * " { 1 ; 1 ; 1 } " will be parsed without error and the same vector will be +039 * returned. In the second case, however, the parse position after parsing will be +040 * just after the closing curly brace, i.e. just before the trailing space.</p> +041 * +042 * @version $Revision: 783702 $ $Date: 2009-06-11 04:54:02 -0400 (Thu, 11 Jun 2009) $ +043 * @since 2.0 +044 */ +045 public class RealVectorFormat extends CompositeFormat { +046 +047 /** Serializable version identifier */ +048 private static final long serialVersionUID = -708767813036157690L; +049 +050 /** The default prefix: "{". */ +051 private static final String DEFAULT_PREFIX = "{"; +052 +053 /** The default suffix: "}". */ +054 private static final String DEFAULT_SUFFIX = "}"; +055 +056 /** The default separator: ", ". */ +057 private static final String DEFAULT_SEPARATOR = "; "; +058 +059 /** Prefix. */ +060 private final String prefix; +061 +062 /** Suffix. */ +063 private final String suffix; +064 +065 /** Separator. */ +066 private final String separator; +067 +068 /** Trimmed prefix. */ +069 private final String trimmedPrefix; +070 +071 /** Trimmed suffix. */ +072 private final String trimmedSuffix; +073 +074 /** Trimmed separator. */ +075 private final String trimmedSeparator; +076 +077 /** The format used for components. */ +078 private NumberFormat format; +079 +080 /** +081 * Create an instance with default settings. +082 * <p>The instance uses the default prefix, suffix and separator: +083 * "{", "}", and "; " and the default number format for components.</p> +084 */ +085 public RealVectorFormat() { +086 this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, getDefaultNumberFormat()); +087 } +088 +089 /** +090 * Create an instance with a custom number format for components. +091 * @param format the custom format for components. +092 */ +093 public RealVectorFormat(final NumberFormat format) { +094 this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, format); +095 } +096 +097 /** +098 * Create an instance with custom prefix, suffix and separator. +099 * @param prefix prefix to use instead of the default "{" +100 * @param suffix suffix to use instead of the default "}" +101 * @param separator separator to use instead of the default "; " +102 */ +103 public RealVectorFormat(final String prefix, final String suffix, +104 final String separator) { +105 this(prefix, suffix, separator, getDefaultNumberFormat()); +106 } +107 +108 /** +109 * Create an instance with custom prefix, suffix, separator and format +110 * for components. +111 * @param prefix prefix to use instead of the default "{" +112 * @param suffix suffix to use instead of the default "}" +113 * @param separator separator to use instead of the default "; " +114 * @param format the custom format for components. +115 */ +116 public RealVectorFormat(final String prefix, final String suffix, +117 final String separator, final NumberFormat format) { +118 this.prefix = prefix; +119 this.suffix = suffix; +120 this.separator = separator; +121 trimmedPrefix = prefix.trim(); +122 trimmedSuffix = suffix.trim(); +123 trimmedSeparator = separator.trim(); +124 this.format = format; +125 } +126 +127 /** +128 * Get the set of locales for which real vectors formats are available. +129 * <p>This is the same set as the {@link NumberFormat} set.</p> +130 * @return available real vector format locales. +131 */ +132 public static Locale[] getAvailableLocales() { +133 return NumberFormat.getAvailableLocales(); +134 } +135 +136 /** +137 * Get the format prefix. +138 * @return format prefix. +139 */ +140 public String getPrefix() { +141 return prefix; +142 } +143 +144 /** +145 * Get the format suffix. +146 * @return format suffix. +147 */ +148 public String getSuffix() { +149 return suffix; +150 } +151 +152 /** +153 * Get the format separator between components. +154 * @return format separator. +155 */ +156 public String getSeparator() { +157 return separator; +158 } +159 +160 /** +161 * Get the components format. +162 * @return components format. +163 */ +164 public NumberFormat getFormat() { +165 return format; +166 } +167 +168 /** +169 * Returns the default real vector format for the current locale. +170 * @return the default real vector format. +171 */ +172 public static RealVectorFormat getInstance() { +173 return getInstance(Locale.getDefault()); +174 } +175 +176 /** +177 * Returns the default real vector format for the given locale. +178 * @param locale the specific locale used by the format. +179 * @return the real vector format specific to the given locale. +180 */ +181 public static RealVectorFormat getInstance(final Locale locale) { +182 return new RealVectorFormat(getDefaultNumberFormat(locale)); +183 } +184 +185 /** +186 * This static method calls {@link #format(Object)} on a default instance of +187 * RealVectorFormat. +188 * +189 * @param v RealVector object to format +190 * @return A formatted vector +191 */ +192 public static String formatRealVector(RealVector v) { +193 return getInstance().format(v); +194 } +195 +196 /** +197 * Formats a {@link RealVector} object to produce a string. +198 * @param vector the object to format. +199 * @param toAppendTo where the text is to be appended +200 * @param pos On input: an alignment field, if desired. On output: the +201 * offsets of the alignment field +202 * @return the value passed in as toAppendTo. +203 */ +204 public StringBuffer format(RealVector vector, StringBuffer toAppendTo, +205 FieldPosition pos) { +206 +207 pos.setBeginIndex(0); +208 pos.setEndIndex(0); +209 +210 // format prefix +211 toAppendTo.append(prefix); +212 +213 // format components +214 for (int i = 0; i < vector.getDimension(); ++i) { +215 if (i > 0) { +216 toAppendTo.append(separator); +217 } +218 formatDouble(vector.getEntry(i), format, toAppendTo, pos); +219 } +220 +221 // format suffix +222 toAppendTo.append(suffix); +223 +224 return toAppendTo; +225 +226 } +227 +228 /** +229 * Formats a object to produce a string. +230 * <p><code>obj</code> must be a {@link RealVector} object. Any other type of +231 * object will result in an {@link IllegalArgumentException} being thrown.</p> +232 * @param obj the object to format. +233 * @param toAppendTo where the text is to be appended +234 * @param pos On input: an alignment field, if desired. On output: the +235 * offsets of the alignment field +236 * @return the value passed in as toAppendTo. +237 * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) +238 * @throws IllegalArgumentException is <code>obj</code> is not a valid type. +239 */ +240 @Override +241 public StringBuffer format(Object obj, StringBuffer toAppendTo, +242 FieldPosition pos) { +243 +244 if (obj instanceof RealVector) { +245 return format( (RealVector)obj, toAppendTo, pos); +246 } +247 +248 throw MathRuntimeException.createIllegalArgumentException( +249 "cannot format a {0} instance as a real vector", +250 obj.getClass().getName()); +251 +252 } +253 +254 /** +255 * Parses a string to produce a {@link RealVector} object. +256 * @param source the string to parse +257 * @return the parsed {@link RealVector} object. +258 * @exception ParseException if the beginning of the specified string +259 * cannot be parsed. +260 */ +261 public ArrayRealVector parse(String source) throws ParseException { +262 ParsePosition parsePosition = new ParsePosition(0); +263 ArrayRealVector result = parse(source, parsePosition); +264 if (parsePosition.getIndex() == 0) { +265 throw MathRuntimeException.createParseException( +266 parsePosition.getErrorIndex(), +267 "unparseable real vector: \"{0}\"", source); +268 } +269 return result; +270 } +271 +272 /** +273 * Parses a string to produce a {@link RealVector} object. +274 * @param source the string to parse +275 * @param pos input/ouput parsing parameter. +276 * @return the parsed {@link RealVector} object. +277 */ +278 public ArrayRealVector parse(String source, ParsePosition pos) { +279 int initialIndex = pos.getIndex(); +280 +281 // parse prefix +282 parseAndIgnoreWhitespace(source, pos); +283 if (!parseFixedstring(source, trimmedPrefix, pos)) { +284 return null; +285 } +286 +287 // parse components +288 List<Number> components = new ArrayList<Number>(); +289 for (boolean loop = true; loop;){ +290 +291 if (!components.isEmpty()) { +292 parseAndIgnoreWhitespace(source, pos); +293 if (!parseFixedstring(source, trimmedSeparator, pos)) { +294 loop = false; +295 } +296 } +297 +298 if (loop) { +299 parseAndIgnoreWhitespace(source, pos); +300 Number component = parseNumber(source, format, pos); +301 if (component != null) { +302 components.add(component); +303 } else { +304 // invalid component +305 // set index back to initial, error index should already be set +306 pos.setIndex(initialIndex); +307 return null; +308 } +309 } +310 +311 } +312 +313 // parse suffix +314 parseAndIgnoreWhitespace(source, pos); +315 if (!parseFixedstring(source, trimmedSuffix, pos)) { +316 return null; +317 } +318 +319 // build vector +320 double[] data = new double[components.size()]; +321 for (int i = 0; i < data.length; ++i) { +322 data[i] = components.get(i).doubleValue(); +323 } +324 return new ArrayRealVector(data, false); +325 +326 } +327 +328 /** +329 * Parses a string to produce a object. +330 * @param source the string to parse +331 * @param pos input/ouput parsing parameter. +332 * @return the parsed object. +333 * @see java.text.Format#parseObject(java.lang.String, java.text.ParsePosition) +334 */ +335 @Override +336 public Object parseObject(String source, ParsePosition pos) { +337 return parse(source, pos); +338 } +339 +340 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/SingularMatrixException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/SingularMatrixException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,104 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 +021 /** +022 * Thrown when a matrix is singular. +023 * @version $Revision: 799857 $ $Date: 2009-08-01 09:07:12 -0400 (Sat, 01 Aug 2009) $ +024 * @since 2.0 +025 */ +026 public class SingularMatrixException extends InvalidMatrixException { +027 +028 /** Serializable version identifier. */ +029 private static final long serialVersionUID = -7379143356784298432L; +030 +031 /** +032 * Construct an exception with a default message. +033 */ +034 public SingularMatrixException() { +035 super("matrix is singular"); +036 } +037 +038 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/SingularValueDecomposition.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/SingularValueDecomposition.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,213 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 +021 +022 /** +023 * An interface to classes that implement an algorithm to calculate the +024 * Singular Value Decomposition of a real matrix. +025 * <p> +026 * The Singular Value Decomposition of matrix A is a set of three matrices: U, +027 * Σ and V such that A = U × Σ × V<sup>T</sup>. Let A be +028 * a m × n matrix, then U is a m × p orthogonal matrix, Σ is a +029 * p × p diagonal matrix with positive or null elements, V is a p × +030 * n orthogonal matrix (hence V<sup>T</sup> is also orthogonal) where +031 * p=min(m,n). +032 * </p> +033 * <p>This interface is similar to the class with similar name from the +034 * <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> library, with the +035 * following changes:</p> +036 * <ul> +037 * <li>the <code>norm2</code> method which has been renamed as {@link #getNorm() +038 * getNorm},</li> +039 * <li>the <code>cond</code> method which has been renamed as {@link +040 * #getConditionNumber() getConditionNumber},</li> +041 * <li>the <code>rank</code> method which has been renamed as {@link #getRank() +042 * getRank},</li> +043 * <li>a {@link #getUT() getUT} method has been added,</li> +044 * <li>a {@link #getVT() getVT} method has been added,</li> +045 * <li>a {@link #getSolver() getSolver} method has been added,</li> +046 * <li>a {@link #getCovariance(double) getCovariance} method has been added.</li> +047 * </ul> +048 * @see <a href="http://mathworld.wolfram.com/SingularValueDecomposition.html">MathWorld</a> +049 * @see <a href="http://en.wikipedia.org/wiki/Singular_value_decomposition">Wikipedia</a> +050 * @version $Revision: 928081 $ $Date: 2010-03-26 18:36:38 -0400 (Fri, 26 Mar 2010) $ +051 * @since 2.0 +052 */ +053 public interface SingularValueDecomposition { +054 +055 /** +056 * Returns the matrix U of the decomposition. +057 * <p>U is an orthogonal matrix, i.e. its transpose is also its inverse.</p> +058 * @return the U matrix +059 * @see #getUT() +060 */ +061 RealMatrix getU(); +062 +063 /** +064 * Returns the transpose of the matrix U of the decomposition. +065 * <p>U is an orthogonal matrix, i.e. its transpose is also its inverse.</p> +066 * @return the U matrix (or null if decomposed matrix is singular) +067 * @see #getU() +068 */ +069 RealMatrix getUT(); +070 +071 /** +072 * Returns the diagonal matrix Σ of the decomposition. +073 * <p>Σ is a diagonal matrix. The singular values are provided in +074 * non-increasing order, for compatibility with Jama.</p> +075 * @return the Σ matrix +076 */ +077 RealMatrix getS(); +078 +079 /** +080 * Returns the diagonal elements of the matrix Σ of the decomposition. +081 * <p>The singular values are provided in non-increasing order, for +082 * compatibility with Jama.</p> +083 * @return the diagonal elements of the Σ matrix +084 */ +085 double[] getSingularValues(); +086 +087 /** +088 * Returns the matrix V of the decomposition. +089 * <p>V is an orthogonal matrix, i.e. its transpose is also its inverse.</p> +090 * @return the V matrix (or null if decomposed matrix is singular) +091 * @see #getVT() +092 */ +093 RealMatrix getV(); +094 +095 /** +096 * Returns the transpose of the matrix V of the decomposition. +097 * <p>V is an orthogonal matrix, i.e. its transpose is also its inverse.</p> +098 * @return the V matrix (or null if decomposed matrix is singular) +099 * @see #getV() +100 */ +101 RealMatrix getVT(); +102 +103 /** +104 * Returns the n × n covariance matrix. +105 * <p>The covariance matrix is V × J × V<sup>T</sup> +106 * where J is the diagonal matrix of the inverse of the squares of +107 * the singular values.</p> +108 * @param minSingularValue value below which singular values are ignored +109 * (a 0 or negative value implies all singular value will be used) +110 * @return covariance matrix +111 * @exception IllegalArgumentException if minSingularValue is larger than +112 * the largest singular value, meaning all singular values are ignored +113 */ +114 RealMatrix getCovariance(double minSingularValue) throws IllegalArgumentException; +115 +116 /** +117 * Returns the L<sub>2</sub> norm of the matrix. +118 * <p>The L<sub>2</sub> norm is max(|A × u|<sub>2</sub> / +119 * |u|<sub>2</sub>), where |.|<sub>2</sub> denotes the vectorial 2-norm +120 * (i.e. the traditional euclidian norm).</p> +121 * @return norm +122 */ +123 double getNorm(); +124 +125 /** +126 * Return the condition number of the matrix. +127 * @return condition number of the matrix +128 */ +129 double getConditionNumber(); +130 +131 /** +132 * Return the effective numerical matrix rank. +133 * <p>The effective numerical rank is the number of non-negligible +134 * singular values. The threshold used to identify non-negligible +135 * terms is max(m,n) × ulp(s<sub>1</sub>) where ulp(s<sub>1</sub>) +136 * is the least significant bit of the largest singular value.</p> +137 * @return effective numerical matrix rank +138 */ +139 int getRank(); +140 +141 /** +142 * Get a solver for finding the A × X = B solution in least square sense. +143 * @return a solver +144 */ +145 DecompositionSolver getSolver(); +146 +147 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/SingularValueDecompositionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/SingularValueDecompositionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,444 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 import org.apache.commons.math.MathRuntimeException; +021 +022 /** +023 * Calculates the compact Singular Value Decomposition of a matrix. +024 * <p> +025 * The Singular Value Decomposition of matrix A is a set of three matrices: U, +026 * Σ and V such that A = U × Σ × V<sup>T</sup>. Let A be +027 * a m × n matrix, then U is a m × p orthogonal matrix, Σ is a +028 * p × p diagonal matrix with positive or null elements, V is a p × +029 * n orthogonal matrix (hence V<sup>T</sup> is also orthogonal) where +030 * p=min(m,n). +031 * </p> +032 * @version $Revision: 912413 $ $Date: 2010-02-21 16:46:12 -0500 (Sun, 21 Feb 2010) $ +033 * @since 2.0 +034 */ +035 public class SingularValueDecompositionImpl implements +036 SingularValueDecomposition { +037 +038 /** Number of rows of the initial matrix. */ +039 private int m; +040 +041 /** Number of columns of the initial matrix. */ +042 private int n; +043 +044 /** Eigen decomposition of the tridiagonal matrix. */ +045 private EigenDecomposition eigenDecomposition; +046 +047 /** Singular values. */ +048 private double[] singularValues; +049 +050 /** Cached value of U. */ +051 private RealMatrix cachedU; +052 +053 /** Cached value of U<sup>T</sup>. */ +054 private RealMatrix cachedUt; +055 +056 /** Cached value of S. */ +057 private RealMatrix cachedS; +058 +059 /** Cached value of V. */ +060 private RealMatrix cachedV; +061 +062 /** Cached value of V<sup>T</sup>. */ +063 private RealMatrix cachedVt; +064 +065 /** +066 * Calculates the compact Singular Value Decomposition of the given matrix. +067 * @param matrix +068 * The matrix to decompose. +069 * @exception InvalidMatrixException +070 * (wrapping a +071 * {@link org.apache.commons.math.ConvergenceException} if +072 * algorithm fails to converge +073 */ +074 public SingularValueDecompositionImpl(final RealMatrix matrix) +075 throws InvalidMatrixException { +076 +077 m = matrix.getRowDimension(); +078 n = matrix.getColumnDimension(); +079 +080 cachedU = null; +081 cachedS = null; +082 cachedV = null; +083 cachedVt = null; +084 +085 double[][] localcopy = matrix.getData(); +086 double[][] matATA = new double[n][n]; +087 // +088 // create A^T*A +089 // +090 for (int i = 0; i < n; i++) { +091 for (int j = i; j < n; j++) { +092 matATA[i][j] = 0.0; +093 for (int k = 0; k < m; k++) { +094 matATA[i][j] += localcopy[k][i] * localcopy[k][j]; +095 } +096 matATA[j][i]=matATA[i][j]; +097 } +098 } +099 +100 double[][] matAAT = new double[m][m]; +101 // +102 // create A*A^T +103 // +104 for (int i = 0; i < m; i++) { +105 for (int j = i; j < m; j++) { +106 matAAT[i][j] = 0.0; +107 for (int k = 0; k < n; k++) { +108 matAAT[i][j] += localcopy[i][k] * localcopy[j][k]; +109 } +110 matAAT[j][i]=matAAT[i][j]; +111 } +112 } +113 int p; +114 if (m>=n) { +115 p=n; +116 // compute eigen decomposition of A^T*A +117 eigenDecomposition = new EigenDecompositionImpl( +118 new Array2DRowRealMatrix(matATA),1.0); +119 singularValues = eigenDecomposition.getRealEigenvalues(); +120 cachedV = eigenDecomposition.getV(); +121 +122 // compute eigen decomposition of A*A^T +123 eigenDecomposition = new EigenDecompositionImpl( +124 new Array2DRowRealMatrix(matAAT),1.0); +125 cachedU = eigenDecomposition.getV().getSubMatrix(0, m - 1, 0, p - 1); +126 } else { +127 p=m; +128 // compute eigen decomposition of A*A^T +129 eigenDecomposition = new EigenDecompositionImpl( +130 new Array2DRowRealMatrix(matAAT),1.0); +131 singularValues = eigenDecomposition.getRealEigenvalues(); +132 cachedU = eigenDecomposition.getV(); +133 +134 // compute eigen decomposition of A^T*A +135 eigenDecomposition = new EigenDecompositionImpl( +136 new Array2DRowRealMatrix(matATA),1.0); +137 cachedV = eigenDecomposition.getV().getSubMatrix(0,n-1,0,p-1); +138 } +139 for (int i = 0; i < p; i++) { +140 singularValues[i] = Math.sqrt(Math.abs(singularValues[i])); +141 } +142 // Up to this point, U and V are computed independently of each other. +143 // There still an sign indetermination of each column of, say, U. +144 // The sign is set such that A.V_i=sigma_i.U_i (i<=p) +145 // The right sign corresponds to a positive dot product of A.V_i and U_i +146 for (int i = 0; i < p; i++) { +147 RealVector tmp = cachedU.getColumnVector(i); +148 double product=matrix.operate(cachedV.getColumnVector(i)).dotProduct(tmp); +149 if (product<0) { +150 cachedU.setColumnVector(i, tmp.mapMultiply(-1.0)); +151 } +152 } +153 } +154 +155 /** {@inheritDoc} */ +156 public RealMatrix getU() throws InvalidMatrixException { +157 // return the cached matrix +158 return cachedU; +159 +160 } +161 +162 /** {@inheritDoc} */ +163 public RealMatrix getUT() throws InvalidMatrixException { +164 +165 if (cachedUt == null) { +166 cachedUt = getU().transpose(); +167 } +168 +169 // return the cached matrix +170 return cachedUt; +171 +172 } +173 +174 /** {@inheritDoc} */ +175 public RealMatrix getS() throws InvalidMatrixException { +176 +177 if (cachedS == null) { +178 +179 // cache the matrix for subsequent calls +180 cachedS = MatrixUtils.createRealDiagonalMatrix(singularValues); +181 +182 } +183 return cachedS; +184 } +185 +186 /** {@inheritDoc} */ +187 public double[] getSingularValues() throws InvalidMatrixException { +188 return singularValues.clone(); +189 } +190 +191 /** {@inheritDoc} */ +192 public RealMatrix getV() throws InvalidMatrixException { +193 // return the cached matrix +194 return cachedV; +195 +196 } +197 +198 /** {@inheritDoc} */ +199 public RealMatrix getVT() throws InvalidMatrixException { +200 +201 if (cachedVt == null) { +202 cachedVt = getV().transpose(); +203 } +204 +205 // return the cached matrix +206 return cachedVt; +207 +208 } +209 +210 /** {@inheritDoc} */ +211 public RealMatrix getCovariance(final double minSingularValue) { +212 +213 // get the number of singular values to consider +214 final int p = singularValues.length; +215 int dimension = 0; +216 while ((dimension < p) && (singularValues[dimension] >= minSingularValue)) { +217 ++dimension; +218 } +219 +220 if (dimension == 0) { +221 throw MathRuntimeException.createIllegalArgumentException( +222 "cutoff singular value is {0}, should be at most {1}", +223 minSingularValue, singularValues[0]); +224 } +225 +226 final double[][] data = new double[dimension][p]; +227 getVT().walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() { +228 /** {@inheritDoc} */ +229 @Override +230 public void visit(final int row, final int column, +231 final double value) { +232 data[row][column] = value / singularValues[row]; +233 } +234 }, 0, dimension - 1, 0, p - 1); +235 +236 RealMatrix jv = new Array2DRowRealMatrix(data, false); +237 return jv.transpose().multiply(jv); +238 +239 } +240 +241 /** {@inheritDoc} */ +242 public double getNorm() throws InvalidMatrixException { +243 return singularValues[0]; +244 } +245 +246 /** {@inheritDoc} */ +247 public double getConditionNumber() throws InvalidMatrixException { +248 return singularValues[0] / singularValues[singularValues.length - 1]; +249 } +250 +251 /** {@inheritDoc} */ +252 public int getRank() throws IllegalStateException { +253 +254 final double threshold = Math.max(m, n) * Math.ulp(singularValues[0]); +255 +256 for (int i = singularValues.length - 1; i >= 0; --i) { +257 if (singularValues[i] > threshold) { +258 return i + 1; +259 } +260 } +261 return 0; +262 +263 } +264 +265 /** {@inheritDoc} */ +266 public DecompositionSolver getSolver() { +267 return new Solver(singularValues, getUT(), getV(), getRank() == Math +268 .max(m, n)); +269 } +270 +271 /** Specialized solver. */ +272 private static class Solver implements DecompositionSolver { +273 +274 /** Pseudo-inverse of the initial matrix. */ +275 private final RealMatrix pseudoInverse; +276 +277 /** Singularity indicator. */ +278 private boolean nonSingular; +279 +280 /** +281 * Build a solver from decomposed matrix. +282 * @param singularValues +283 * singularValues +284 * @param uT +285 * U<sup>T</sup> matrix of the decomposition +286 * @param v +287 * V matrix of the decomposition +288 * @param nonSingular +289 * singularity indicator +290 */ +291 private Solver(final double[] singularValues, final RealMatrix uT, +292 final RealMatrix v, final boolean nonSingular) { +293 double[][] suT = uT.getData(); +294 for (int i = 0; i < singularValues.length; ++i) { +295 final double a; +296 if (singularValues[i]>0) { +297 a=1.0 / singularValues[i]; +298 } else { +299 a=0.0; +300 } +301 final double[] suTi = suT[i]; +302 for (int j = 0; j < suTi.length; ++j) { +303 suTi[j] *= a; +304 } +305 } +306 pseudoInverse = v.multiply(new Array2DRowRealMatrix(suT, false)); +307 this.nonSingular = nonSingular; +308 } +309 +310 /** +311 * Solve the linear equation A × X = B in least square sense. +312 * <p> +313 * The m×n matrix A may not be square, the solution X is such that +314 * ||A × X - B|| is minimal. +315 * </p> +316 * @param b +317 * right-hand side of the equation A × X = B +318 * @return a vector X that minimizes the two norm of A × X - B +319 * @exception IllegalArgumentException +320 * if matrices dimensions don't match +321 */ +322 public double[] solve(final double[] b) throws IllegalArgumentException { +323 return pseudoInverse.operate(b); +324 } +325 +326 /** +327 * Solve the linear equation A × X = B in least square sense. +328 * <p> +329 * The m×n matrix A may not be square, the solution X is such that +330 * ||A × X - B|| is minimal. +331 * </p> +332 * @param b +333 * right-hand side of the equation A × X = B +334 * @return a vector X that minimizes the two norm of A × X - B +335 * @exception IllegalArgumentException +336 * if matrices dimensions don't match +337 */ +338 public RealVector solve(final RealVector b) +339 throws IllegalArgumentException { +340 return pseudoInverse.operate(b); +341 } +342 +343 /** +344 * Solve the linear equation A × X = B in least square sense. +345 * <p> +346 * The m×n matrix A may not be square, the solution X is such that +347 * ||A × X - B|| is minimal. +348 * </p> +349 * @param b +350 * right-hand side of the equation A × X = B +351 * @return a matrix X that minimizes the two norm of A × X - B +352 * @exception IllegalArgumentException +353 * if matrices dimensions don't match +354 */ +355 public RealMatrix solve(final RealMatrix b) +356 throws IllegalArgumentException { +357 return pseudoInverse.multiply(b); +358 } +359 +360 /** +361 * Check if the decomposed matrix is non-singular. +362 * @return true if the decomposed matrix is non-singular +363 */ +364 public boolean isNonSingular() { +365 return nonSingular; +366 } +367 +368 /** +369 * Get the pseudo-inverse of the decomposed matrix. +370 * @return inverse matrix +371 */ +372 public RealMatrix getInverse() { +373 return pseudoInverse; +374 } +375 +376 } +377 +378 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/SparseFieldMatrix.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/SparseFieldMatrix.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,256 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.linear; +018 +019 import org.apache.commons.math.Field; +020 import org.apache.commons.math.FieldElement; +021 import org.apache.commons.math.util.OpenIntToFieldHashMap; +022 +023 /** +024 * Sparse matrix implementation based on an open addressed map. +025 * +026 * @param <T> the type of the field elements +027 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +028 * @since 2.0 +029 */ +030 public class SparseFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMatrix<T> { +031 /** +032 * Serial id +033 */ +034 private static final long serialVersionUID = 9078068119297757342L; +035 /** Storage for (sparse) matrix elements. */ +036 private final OpenIntToFieldHashMap<T> entries; +037 /** +038 * row dimension +039 */ +040 private final int rows; +041 /** +042 * column dimension +043 */ +044 private final int columns; +045 +046 +047 /** +048 * Creates a matrix with no data. +049 * @param field field to which the elements belong +050 */ +051 public SparseFieldMatrix(final Field<T> field) { +052 super(field); +053 rows = 0; +054 columns= 0; +055 entries = new OpenIntToFieldHashMap<T>(field); +056 } +057 +058 /** +059 * Create a new SparseFieldMatrix<T> with the supplied row and column dimensions. +060 * +061 * @param field field to which the elements belong +062 * @param rowDimension the number of rows in the new matrix +063 * @param columnDimension the number of columns in the new matrix +064 * @throws IllegalArgumentException if row or column dimension is not positive +065 */ +066 public SparseFieldMatrix(final Field<T> field, +067 final int rowDimension, final int columnDimension) +068 throws IllegalArgumentException { +069 super(field, rowDimension, columnDimension); +070 this.rows = rowDimension; +071 this.columns = columnDimension; +072 entries = new OpenIntToFieldHashMap<T>(field); +073 } +074 +075 /** +076 * Copy constructor. +077 * @param other The instance to copy +078 */ +079 public SparseFieldMatrix(SparseFieldMatrix<T> other) { +080 super(other.getField(), other.getRowDimension(), other.getColumnDimension()); +081 rows = other.getRowDimension(); +082 columns = other.getColumnDimension(); +083 entries = new OpenIntToFieldHashMap<T>(other.entries); +084 } +085 +086 /** +087 * Generic copy constructor. +088 * @param other The instance to copy +089 */ +090 public SparseFieldMatrix(FieldMatrix<T> other){ +091 super(other.getField(), other.getRowDimension(), other.getColumnDimension()); +092 rows = other.getRowDimension(); +093 columns = other.getColumnDimension(); +094 entries = new OpenIntToFieldHashMap<T>(getField()); +095 for (int i = 0; i < rows; i++) { +096 for (int j = 0; j < columns; j++) { +097 setEntry(i, j, other.getEntry(i, j)); +098 } +099 } +100 } +101 +102 /** {@inheritDoc} */ +103 @Override +104 public void addToEntry(int row, int column, T increment) +105 throws MatrixIndexException { +106 checkRowIndex(row); +107 checkColumnIndex(column); +108 final int key = computeKey(row, column); +109 final T value = entries.get(key).add(increment); +110 if (getField().getZero().equals(value)) { +111 entries.remove(key); +112 } else { +113 entries.put(key, value); +114 } +115 +116 } +117 +118 /** {@inheritDoc} */ +119 @Override +120 public FieldMatrix<T> copy() { +121 return new SparseFieldMatrix<T>(this); +122 } +123 +124 /** {@inheritDoc} */ +125 @Override +126 public FieldMatrix<T> createMatrix(int rowDimension, int columnDimension) +127 throws IllegalArgumentException { +128 return new SparseFieldMatrix<T>(getField(), rowDimension, columnDimension); +129 } +130 +131 /** {@inheritDoc} */ +132 @Override +133 public int getColumnDimension() { +134 return columns; +135 } +136 +137 /** {@inheritDoc} */ +138 @Override +139 public T getEntry(int row, int column) throws MatrixIndexException { +140 checkRowIndex(row); +141 checkColumnIndex(column); +142 return entries.get(computeKey(row, column)); +143 } +144 +145 /** {@inheritDoc} */ +146 @Override +147 public int getRowDimension() { +148 return rows; +149 } +150 +151 /** {@inheritDoc} */ +152 @Override +153 public void multiplyEntry(int row, int column, T factor) +154 throws MatrixIndexException { +155 checkRowIndex(row); +156 checkColumnIndex(column); +157 final int key = computeKey(row, column); +158 final T value = entries.get(key).multiply(factor); +159 if (getField().getZero().equals(value)) { +160 entries.remove(key); +161 } else { +162 entries.put(key, value); +163 } +164 +165 } +166 +167 /** {@inheritDoc} */ +168 @Override +169 public void setEntry(int row, int column, T value) +170 throws MatrixIndexException { +171 checkRowIndex(row); +172 checkColumnIndex(column); +173 if (getField().getZero().equals(value)) { +174 entries.remove(computeKey(row, column)); +175 } else { +176 entries.put(computeKey(row, column), value); +177 } +178 +179 } +180 /** +181 * Compute the key to access a matrix element +182 * @param row row index of the matrix element +183 * @param column column index of the matrix element +184 * @return key within the map to access the matrix element +185 */ +186 private int computeKey(int row, int column) { +187 return row * columns + column; +188 } +189 +190 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/SparseFieldVector.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/SparseFieldVector.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,723 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.linear; +018 +019 import java.io.Serializable; +020 import java.lang.reflect.Array; +021 +022 import org.apache.commons.math.Field; +023 import org.apache.commons.math.FieldElement; +024 import org.apache.commons.math.MathRuntimeException; +025 import org.apache.commons.math.util.OpenIntToFieldHashMap; +026 +027 /** +028 * This class implements the {@link FieldVector} interface with a {@link OpenIntToFieldHashMap} backing store. +029 * @param <T> the type of the field elements +030 * @version $Revision: 922714 $ $Date: 2010-03-13 20:35:14 -0500 (Sat, 13 Mar 2010) $ +031 * @since 2.0 +032 */ +033 public class SparseFieldVector<T extends FieldElement<T>> implements FieldVector<T>, Serializable { +034 +035 /** +036 * Serial version id +037 */ +038 private static final long serialVersionUID = 7841233292190413362L; +039 /** Field to which the elements belong. */ +040 private final Field<T> field; +041 /** Entries of the vector. */ +042 private final OpenIntToFieldHashMap<T> entries; +043 /** Dimension of the vector. */ +044 private final int virtualSize; +045 +046 /** +047 * Build a 0-length vector. +048 * <p>Zero-length vectors may be used to initialize construction of vectors +049 * by data gathering. We start with zero-length and use either the {@link +050 * #SparseFieldVector(SparseFieldVector, int)} constructor +051 * or one of the <code>append</code> method ({@link #append(FieldElement)}, +052 * {@link #append(FieldElement[])}, {@link #append(FieldVector)}, +053 * {@link #append(SparseFieldVector)}) to gather data into this vector.</p> +054 * @param field field to which the elements belong +055 */ +056 public SparseFieldVector(Field<T> field) { +057 this(field, 0); +058 } +059 +060 +061 /** +062 * Construct a (dimension)-length vector of zeros. +063 * @param field field to which the elements belong +064 * @param dimension Size of the vector +065 */ +066 public SparseFieldVector(Field<T> field, int dimension) { +067 this.field = field; +068 virtualSize = dimension; +069 entries = new OpenIntToFieldHashMap<T>(field); +070 } +071 +072 /** +073 * Build a resized vector, for use with append. +074 * @param v The original vector +075 * @param resize The amount to resize it +076 */ +077 protected SparseFieldVector(SparseFieldVector<T> v, int resize) { +078 field = v.field; +079 virtualSize = v.getDimension() + resize; +080 entries = new OpenIntToFieldHashMap<T>(v.entries); +081 } +082 +083 +084 /** +085 * Build a vector with known the sparseness (for advanced use only). +086 * @param field field to which the elements belong +087 * @param dimension The size of the vector +088 * @param expectedSize The expected number of non-zero entries +089 */ +090 public SparseFieldVector(Field<T> field, int dimension, int expectedSize) { +091 this.field = field; +092 virtualSize = dimension; +093 entries = new OpenIntToFieldHashMap<T>(field,expectedSize); +094 } +095 +096 /** +097 * Create from a Field array. +098 * Only non-zero entries will be stored +099 * @param field field to which the elements belong +100 * @param values The set of values to create from +101 */ +102 public SparseFieldVector(Field<T> field, T[] values) { +103 this.field = field; +104 virtualSize = values.length; +105 entries = new OpenIntToFieldHashMap<T>(field); +106 for (int key = 0; key < values.length; key++) { +107 T value = values[key]; +108 entries.put(key, value); +109 } +110 } +111 +112 +113 +114 /** +115 * Copy constructor. +116 * @param v The instance to copy from +117 */ +118 public SparseFieldVector(SparseFieldVector<T> v) { +119 field = v.field; +120 virtualSize = v.getDimension(); +121 entries = new OpenIntToFieldHashMap<T>(v.getEntries()); +122 } +123 +124 /** +125 * Get the entries of this instance. +126 * @return entries of this instance +127 */ +128 private OpenIntToFieldHashMap<T> getEntries() { +129 return entries; +130 } +131 +132 /** +133 * Optimized method to add sparse vectors. +134 * @param v vector to add +135 * @return The sum of <code>this</code> and <code>v</code> +136 * @throws IllegalArgumentException If the dimensions don't match +137 */ +138 public FieldVector<T> add(SparseFieldVector<T> v) throws IllegalArgumentException { +139 checkVectorDimensions(v.getDimension()); +140 SparseFieldVector<T> res = (SparseFieldVector<T>)copy(); +141 OpenIntToFieldHashMap<T>.Iterator iter = v.getEntries().iterator(); +142 while (iter.hasNext()) { +143 iter.advance(); +144 int key = iter.key(); +145 T value = iter.value(); +146 if (entries.containsKey(key)) { +147 res.setEntry(key, entries.get(key).add(value)); +148 } else { +149 res.setEntry(key, value); +150 } +151 } +152 return res; +153 +154 } +155 +156 +157 /** {@inheritDoc} */ +158 public FieldVector<T> add(T[] v) throws IllegalArgumentException { +159 checkVectorDimensions(v.length); +160 SparseFieldVector<T> res = new SparseFieldVector<T>(field,getDimension()); +161 for (int i = 0; i < v.length; i++) { +162 res.setEntry(i, v[i].add(getEntry(i))); +163 } +164 return res; +165 } +166 +167 /** +168 * Construct a vector by appending a vector to this vector. +169 * @param v vector to append to this one. +170 * @return a new vector +171 */ +172 public FieldVector<T> append(SparseFieldVector<T> v) { +173 SparseFieldVector<T> res = new SparseFieldVector<T>(this, v.getDimension()); +174 OpenIntToFieldHashMap<T>.Iterator iter = v.entries.iterator(); +175 while (iter.hasNext()) { +176 iter.advance(); +177 res.setEntry(iter.key() + virtualSize, iter.value()); +178 } +179 return res; +180 } +181 +182 /** {@inheritDoc} */ +183 public FieldVector<T> append(FieldVector<T> v) { +184 if (v instanceof SparseFieldVector<?>) { +185 return append((SparseFieldVector<T>) v); +186 } else { +187 return append(v.toArray()); +188 } +189 } +190 +191 /** {@inheritDoc} */ +192 public FieldVector<T> append(T d) { +193 FieldVector<T> res = new SparseFieldVector<T>(this, 1); +194 res.setEntry(virtualSize, d); +195 return res; +196 } +197 +198 /** {@inheritDoc} */ +199 public FieldVector<T> append(T[] a) { +200 FieldVector<T> res = new SparseFieldVector<T>(this, a.length); +201 for (int i = 0; i < a.length; i++) { +202 res.setEntry(i + virtualSize, a[i]); +203 } +204 return res; +205 } +206 +207 /** {@inheritDoc} */ +208 public FieldVector<T> copy() { +209 return new SparseFieldVector<T>(this); +210 } +211 +212 /** {@inheritDoc} */ +213 public T dotProduct(FieldVector<T> v) throws IllegalArgumentException { +214 checkVectorDimensions(v.getDimension()); +215 T res = field.getZero(); +216 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator(); +217 while (iter.hasNext()) { +218 iter.advance(); +219 res = res.add(v.getEntry(iter.key()).multiply(iter.value())); +220 } +221 return res; +222 } +223 +224 /** {@inheritDoc} */ +225 public T dotProduct(T[] v) throws IllegalArgumentException { +226 checkVectorDimensions(v.length); +227 T res = field.getZero(); +228 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator(); +229 while (iter.hasNext()) { +230 int idx = iter.key(); +231 T value = field.getZero(); +232 if (idx < v.length) { +233 value = v[idx]; +234 } +235 res = res.add(value.multiply(iter.value())); +236 } +237 return res; +238 } +239 +240 /** {@inheritDoc} */ +241 public FieldVector<T> ebeDivide(FieldVector<T> v) +242 throws IllegalArgumentException { +243 checkVectorDimensions(v.getDimension()); +244 SparseFieldVector<T> res = new SparseFieldVector<T>(this); +245 OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator(); +246 while (iter.hasNext()) { +247 iter.advance(); +248 res.setEntry(iter.key(), iter.value().divide(v.getEntry(iter.key()))); +249 } +250 return res; +251 } +252 +253 /** {@inheritDoc} */ +254 public FieldVector<T> ebeDivide(T[] v) throws IllegalArgumentException { +255 checkVectorDimensions(v.length); +256 SparseFieldVector<T> res = new SparseFieldVector<T>(this); +257 OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator(); +258 while (iter.hasNext()) { +259 iter.advance(); +260 res.setEntry(iter.key(), iter.value().divide(v[iter.key()])); +261 } +262 return res; +263 } +264 +265 /** {@inheritDoc} */ +266 public FieldVector<T> ebeMultiply(FieldVector<T> v)throws IllegalArgumentException { +267 checkVectorDimensions(v.getDimension()); +268 SparseFieldVector<T> res = new SparseFieldVector<T>(this); +269 OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator(); +270 while (iter.hasNext()) { +271 iter.advance(); +272 res.setEntry(iter.key(), iter.value().multiply(v.getEntry(iter.key()))); +273 } +274 return res; +275 } +276 +277 /** {@inheritDoc} */ +278 public FieldVector<T> ebeMultiply(T[] v) throws IllegalArgumentException { +279 checkVectorDimensions(v.length); +280 SparseFieldVector<T> res = new SparseFieldVector<T>(this); +281 OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator(); +282 while (iter.hasNext()) { +283 iter.advance(); +284 res.setEntry(iter.key(), iter.value().multiply(v[iter.key()])); +285 } +286 return res; +287 } +288 +289 /** {@inheritDoc} */ +290 public T[] getData() { +291 T[] res = buildArray(virtualSize); +292 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator(); +293 while (iter.hasNext()) { +294 iter.advance(); +295 res[iter.key()] = iter.value(); +296 } +297 return res; +298 } +299 +300 /** {@inheritDoc} */ +301 public int getDimension() { +302 return virtualSize; +303 } +304 +305 /** {@inheritDoc} */ +306 public T getEntry(int index) throws MatrixIndexException { +307 checkIndex(index); +308 return entries.get(index); +309 } +310 +311 /** {@inheritDoc} */ +312 public Field<T> getField() { +313 return field; +314 } +315 +316 /** {@inheritDoc} */ +317 public FieldVector<T> getSubVector(int index, int n) +318 throws MatrixIndexException { +319 checkIndex(index); +320 checkIndex(index + n - 1); +321 SparseFieldVector<T> res = new SparseFieldVector<T>(field,n); +322 int end = index + n; +323 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator(); +324 while (iter.hasNext()) { +325 iter.advance(); +326 int key = iter.key(); +327 if (key >= index && key < end) { +328 res.setEntry(key - index, iter.value()); +329 } +330 } +331 return res; +332 } +333 +334 /** {@inheritDoc} */ +335 public FieldVector<T> mapAdd(T d) { +336 return copy().mapAddToSelf(d); +337 } +338 +339 /** {@inheritDoc} */ +340 public FieldVector<T> mapAddToSelf(T d) { +341 for (int i = 0; i < virtualSize; i++) { +342 setEntry(i, getEntry(i).add(d)); +343 } +344 return this; +345 } +346 +347 /** {@inheritDoc} */ +348 public FieldVector<T> mapDivide(T d) { +349 return copy().mapDivideToSelf(d); +350 } +351 +352 /** {@inheritDoc} */ +353 public FieldVector<T> mapDivideToSelf(T d) { +354 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator(); +355 while (iter.hasNext()) { +356 iter.advance(); +357 entries.put(iter.key(), iter.value().divide(d)); +358 } +359 return this; +360 } +361 +362 /** {@inheritDoc} */ +363 public FieldVector<T> mapInv() { +364 return copy().mapInvToSelf(); +365 } +366 +367 /** {@inheritDoc} */ +368 public FieldVector<T> mapInvToSelf() { +369 for (int i = 0; i < virtualSize; i++) { +370 setEntry(i, field.getOne().divide(getEntry(i))); +371 } +372 return this; +373 } +374 +375 /** {@inheritDoc} */ +376 public FieldVector<T> mapMultiply(T d) { +377 return copy().mapMultiplyToSelf(d); +378 } +379 +380 /** {@inheritDoc} */ +381 public FieldVector<T> mapMultiplyToSelf(T d) { +382 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator(); +383 while (iter.hasNext()) { +384 iter.advance(); +385 entries.put(iter.key(), iter.value().multiply(d)); +386 } +387 return this; +388 } +389 +390 /** {@inheritDoc} */ +391 public FieldVector<T> mapSubtract(T d) { +392 return copy().mapSubtractToSelf(d); +393 } +394 +395 /** {@inheritDoc} */ +396 public FieldVector<T> mapSubtractToSelf(T d) { +397 return mapAddToSelf(field.getZero().subtract(d)); +398 } +399 +400 /** +401 * Optimized method to compute outer product when both vectors are sparse. +402 * @param v vector with which outer product should be computed +403 * @return the square matrix outer product between instance and v +404 * @throws IllegalArgumentException if v is not the same size as {@code this} +405 */ +406 public FieldMatrix<T> outerProduct(SparseFieldVector<T> v) +407 throws IllegalArgumentException { +408 checkVectorDimensions(v.getDimension()); +409 SparseFieldMatrix<T> res = new SparseFieldMatrix<T>(field, virtualSize, virtualSize); +410 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator(); +411 while (iter.hasNext()) { +412 iter.advance(); +413 OpenIntToFieldHashMap<T>.Iterator iter2 = v.entries.iterator(); +414 while (iter2.hasNext()) { +415 iter2.advance(); +416 res.setEntry(iter.key(), iter2.key(), iter.value().multiply(iter2.value())); +417 } +418 } +419 return res; +420 } +421 +422 /** {@inheritDoc} */ +423 public FieldMatrix<T> outerProduct(T[] v) throws IllegalArgumentException { +424 checkVectorDimensions(v.length); +425 FieldMatrix<T> res = new SparseFieldMatrix<T>(field, virtualSize, virtualSize); +426 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator(); +427 while (iter.hasNext()) { +428 iter.advance(); +429 int row = iter.key(); +430 FieldElement<T>value = iter.value(); +431 for (int col = 0; col < virtualSize; col++) { +432 res.setEntry(row, col, value.multiply(v[col])); +433 } +434 } +435 return res; +436 } +437 +438 /** {@inheritDoc} */ +439 public FieldMatrix<T> outerProduct(FieldVector<T> v) +440 throws IllegalArgumentException { +441 if(v instanceof SparseFieldVector<?>) +442 return outerProduct((SparseFieldVector<T>)v); +443 else +444 return outerProduct(v.toArray()); +445 } +446 +447 /** {@inheritDoc} */ +448 public FieldVector<T> projection(FieldVector<T> v) +449 throws IllegalArgumentException { +450 checkVectorDimensions(v.getDimension()); +451 return v.mapMultiply(dotProduct(v).divide(v.dotProduct(v))); +452 } +453 +454 /** {@inheritDoc} */ +455 public FieldVector<T> projection(T[] v) throws IllegalArgumentException { +456 checkVectorDimensions(v.length); +457 return projection(new SparseFieldVector<T>(field,v)); +458 } +459 +460 /** {@inheritDoc} */ +461 public void set(T value) { +462 for (int i = 0; i < virtualSize; i++) { +463 setEntry(i, value); +464 } +465 } +466 +467 /** {@inheritDoc} */ +468 public void setEntry(int index, T value) throws MatrixIndexException { +469 checkIndex(index); +470 entries.put(index, value); +471 } +472 +473 /** {@inheritDoc} */ +474 public void setSubVector(int index, FieldVector<T> v) +475 throws MatrixIndexException { +476 checkIndex(index); +477 checkIndex(index + v.getDimension() - 1); +478 setSubVector(index, v.getData()); +479 } +480 +481 /** {@inheritDoc} */ +482 public void setSubVector(int index, T[] v) throws MatrixIndexException { +483 checkIndex(index); +484 checkIndex(index + v.length - 1); +485 for (int i = 0; i < v.length; i++) { +486 setEntry(i + index, v[i]); +487 } +488 +489 } +490 +491 /** +492 * Optimized method to subtract SparseRealVectors. +493 * @param v The vector to subtract from <code>this</code> +494 * @return The difference of <code>this</code> and <code>v</code> +495 * @throws IllegalArgumentException If the dimensions don't match +496 */ +497 public SparseFieldVector<T> subtract(SparseFieldVector<T> v) throws IllegalArgumentException{ +498 checkVectorDimensions(v.getDimension()); +499 SparseFieldVector<T> res = (SparseFieldVector<T>)copy(); +500 OpenIntToFieldHashMap<T>.Iterator iter = v.getEntries().iterator(); +501 while (iter.hasNext()) { +502 iter.advance(); +503 int key = iter.key(); +504 if (entries.containsKey(key)) { +505 res.setEntry(key, entries.get(key).subtract(iter.value())); +506 } else { +507 res.setEntry(key, field.getZero().subtract(iter.value())); +508 } +509 } +510 return res; +511 } +512 +513 /** {@inheritDoc} */ +514 public FieldVector<T> subtract(FieldVector<T> v) +515 throws IllegalArgumentException { +516 if(v instanceof SparseFieldVector<?>) +517 return subtract((SparseFieldVector<T>)v); +518 else +519 return subtract(v.toArray()); +520 } +521 +522 /** {@inheritDoc} */ +523 public FieldVector<T> subtract(T[] v) throws IllegalArgumentException { +524 checkVectorDimensions(v.length); +525 SparseFieldVector<T> res = new SparseFieldVector<T>(this); +526 for (int i = 0; i < v.length; i++) { +527 if (entries.containsKey(i)) { +528 res.setEntry(i, entries.get(i).subtract(v[i])); +529 } else { +530 res.setEntry(i, field.getZero().subtract(v[i])); +531 } +532 } +533 return res; +534 } +535 +536 /** {@inheritDoc} */ +537 public T[] toArray() { +538 return getData(); +539 } +540 +541 /** +542 * Check if an index is valid. +543 * +544 * @param index +545 * index to check +546 * @exception MatrixIndexException +547 * if index is not valid +548 */ +549 private void checkIndex(final int index) throws MatrixIndexException { +550 if (index < 0 || index >= getDimension()) { +551 throw new MatrixIndexException( +552 "index {0} out of allowed range [{1}, {2}]", +553 index, 0, getDimension() - 1); +554 } +555 } +556 +557 /** +558 * Check if instance dimension is equal to some expected value. +559 * +560 * @param n +561 * expected dimension. +562 * @exception IllegalArgumentException +563 * if the dimension is inconsistent with vector size +564 */ +565 protected void checkVectorDimensions(int n) throws IllegalArgumentException { +566 if (getDimension() != n) { +567 throw MathRuntimeException.createIllegalArgumentException( +568 "vector length mismatch: got {0} but expected {1}", +569 getDimension(), n); +570 } +571 } +572 +573 +574 /** {@inheritDoc} */ +575 public FieldVector<T> add(FieldVector<T> v) throws IllegalArgumentException { +576 if (v instanceof SparseFieldVector<?>) { +577 return add((SparseFieldVector<T>)v); +578 } else { +579 return add(v.toArray()); +580 } +581 } +582 +583 /** Build an array of elements. +584 * @param length size of the array to build +585 * @return a new array +586 */ +587 @SuppressWarnings("unchecked") // field is type T +588 private T[] buildArray(final int length) { +589 return (T[]) Array.newInstance(field.getZero().getClass(), length); +590 } +591 +592 +593 /** {@inheritDoc} */ +594 @Override +595 public int hashCode() { +596 final int prime = 31; +597 int result = 1; +598 result = prime * result + ((field == null) ? 0 : field.hashCode()); +599 result = prime * result + virtualSize; +600 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator(); +601 while (iter.hasNext()) { +602 iter.advance(); +603 int temp = iter.value().hashCode(); +604 result = prime * result + temp; +605 } +606 return result; +607 } +608 +609 +610 /** {@inheritDoc} */ +611 @Override +612 public boolean equals(Object obj) { +613 +614 if (this == obj) { +615 return true; +616 } +617 +618 if (!(obj instanceof SparseFieldVector<?>)) { +619 return false; +620 } +621 +622 @SuppressWarnings("unchecked") // OK, because "else if" check below ensures that +623 // other must be the same type as this +624 SparseFieldVector<T> other = (SparseFieldVector<T>) obj; +625 if (field == null) { +626 if (other.field != null) { +627 return false; +628 } +629 } else if (!field.equals(other.field)) { +630 return false; +631 } +632 if (virtualSize != other.virtualSize) { +633 return false; +634 } +635 +636 OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator(); +637 while (iter.hasNext()) { +638 iter.advance(); +639 T test = other.getEntry(iter.key()); +640 if (!test.equals(iter.value())) { +641 return false; +642 } +643 } +644 iter = other.getEntries().iterator(); +645 while (iter.hasNext()) { +646 iter.advance(); +647 T test = iter.value(); +648 if (!test.equals(getEntry(iter.key()))) { +649 return false; +650 } +651 } +652 return true; +653 } +654 +655 +656 +657 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/SparseRealMatrix.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/SparseRealMatrix.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,95 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.linear; +019 +020 /** +021 * Marker interface for {@link RealMatrix} implementations that require sparse backing storage +022 * +023 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +024 * @since 2.0 +025 * +026 */ +027 public interface SparseRealMatrix extends RealMatrix { +028 +029 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/SparseRealVector.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/linear/SparseRealVector.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,93 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.linear; +018 +019 /** +020 * Marker interface for RealVectors that require sparse backing storage +021 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +022 * @since 2.0 +023 * +024 */ +025 public interface SparseRealVector extends RealVector { +026 +027 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/AbstractIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/AbstractIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,342 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode; +019 +020 import java.util.ArrayList; +021 import java.util.Collection; +022 import java.util.Collections; +023 +024 import org.apache.commons.math.MaxEvaluationsExceededException; +025 import org.apache.commons.math.ode.events.CombinedEventsManager; +026 import org.apache.commons.math.ode.events.EventHandler; +027 import org.apache.commons.math.ode.events.EventState; +028 import org.apache.commons.math.ode.sampling.StepHandler; +029 +030 /** +031 * Base class managing common boilerplate for all integrators. +032 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +033 * @since 2.0 +034 */ +035 public abstract class AbstractIntegrator implements FirstOrderIntegrator { +036 +037 /** Step handler. */ +038 protected Collection<StepHandler> stepHandlers; +039 +040 /** Current step start time. */ +041 protected double stepStart; +042 +043 /** Current stepsize. */ +044 protected double stepSize; +045 +046 /** Events handlers manager. */ +047 protected CombinedEventsManager eventsHandlersManager; +048 +049 /** Name of the method. */ +050 private final String name; +051 +052 /** Maximal number of evaluations allowed. */ +053 private int maxEvaluations; +054 +055 /** Number of evaluations already performed. */ +056 private int evaluations; +057 +058 /** Differential equations to integrate. */ +059 private transient FirstOrderDifferentialEquations equations; +060 +061 /** Build an instance. +062 * @param name name of the method +063 */ +064 public AbstractIntegrator(final String name) { +065 this.name = name; +066 stepHandlers = new ArrayList<StepHandler>(); +067 stepStart = Double.NaN; +068 stepSize = Double.NaN; +069 eventsHandlersManager = new CombinedEventsManager(); +070 setMaxEvaluations(-1); +071 resetEvaluations(); +072 } +073 +074 /** Build an instance with a null name. +075 */ +076 protected AbstractIntegrator() { +077 this(null); +078 } +079 +080 /** {@inheritDoc} */ +081 public String getName() { +082 return name; +083 } +084 +085 /** {@inheritDoc} */ +086 public void addStepHandler(final StepHandler handler) { +087 stepHandlers.add(handler); +088 } +089 +090 /** {@inheritDoc} */ +091 public Collection<StepHandler> getStepHandlers() { +092 return Collections.unmodifiableCollection(stepHandlers); +093 } +094 +095 /** {@inheritDoc} */ +096 public void clearStepHandlers() { +097 stepHandlers.clear(); +098 } +099 +100 /** {@inheritDoc} */ +101 public void addEventHandler(final EventHandler function, +102 final double maxCheckInterval, +103 final double convergence, +104 final int maxIterationCount) { +105 eventsHandlersManager.addEventHandler(function, maxCheckInterval, +106 convergence, maxIterationCount); +107 } +108 +109 /** {@inheritDoc} */ +110 public Collection<EventHandler> getEventHandlers() { +111 return eventsHandlersManager.getEventsHandlers(); +112 } +113 +114 /** {@inheritDoc} */ +115 public void clearEventHandlers() { +116 eventsHandlersManager.clearEventsHandlers(); +117 } +118 +119 /** Check if one of the step handlers requires dense output. +120 * @return true if one of the step handlers requires dense output +121 */ +122 protected boolean requiresDenseOutput() { +123 for (StepHandler handler : stepHandlers) { +124 if (handler.requiresDenseOutput()) { +125 return true; +126 } +127 } +128 return false; +129 } +130 +131 /** {@inheritDoc} */ +132 public double getCurrentStepStart() { +133 return stepStart; +134 } +135 +136 /** {@inheritDoc} */ +137 public double getCurrentSignedStepsize() { +138 return stepSize; +139 } +140 +141 /** {@inheritDoc} */ +142 public void setMaxEvaluations(int maxEvaluations) { +143 this.maxEvaluations = (maxEvaluations < 0) ? Integer.MAX_VALUE : maxEvaluations; +144 } +145 +146 /** {@inheritDoc} */ +147 public int getMaxEvaluations() { +148 return maxEvaluations; +149 } +150 +151 /** {@inheritDoc} */ +152 public int getEvaluations() { +153 return evaluations; +154 } +155 +156 /** Reset the number of evaluations to zero. +157 */ +158 protected void resetEvaluations() { +159 evaluations = 0; +160 } +161 +162 /** Set the differential equations. +163 * @param equations differential equations to integrate +164 * @see #computeDerivatives(double, double[], double[]) +165 */ +166 protected void setEquations(final FirstOrderDifferentialEquations equations) { +167 this.equations = equations; +168 } +169 +170 /** Compute the derivatives and check the number of evaluations. +171 * @param t current value of the independent <I>time</I> variable +172 * @param y array containing the current value of the state vector +173 * @param yDot placeholder array where to put the time derivative of the state vector +174 * @throws DerivativeException this exception is propagated to the caller if the +175 * underlying user function triggers one +176 */ +177 public void computeDerivatives(final double t, final double[] y, final double[] yDot) +178 throws DerivativeException { +179 if (++evaluations > maxEvaluations) { +180 throw new DerivativeException(new MaxEvaluationsExceededException(maxEvaluations)); +181 } +182 equations.computeDerivatives(t, y, yDot); +183 } +184 +185 /** Perform some sanity checks on the integration parameters. +186 * @param ode differential equations set +187 * @param t0 start time +188 * @param y0 state vector at t0 +189 * @param t target time for the integration +190 * @param y placeholder where to put the state vector +191 * @exception IntegratorException if some inconsistency is detected +192 */ +193 protected void sanityChecks(final FirstOrderDifferentialEquations ode, +194 final double t0, final double[] y0, +195 final double t, final double[] y) +196 throws IntegratorException { +197 +198 if (ode.getDimension() != y0.length) { +199 throw new IntegratorException( +200 "dimensions mismatch: ODE problem has dimension {0}," + +201 " initial state vector has dimension {1}", +202 ode.getDimension(), y0.length); +203 } +204 +205 if (ode.getDimension() != y.length) { +206 throw new IntegratorException( +207 "dimensions mismatch: ODE problem has dimension {0}," + +208 " final state vector has dimension {1}", +209 ode.getDimension(), y.length); +210 } +211 +212 if (Math.abs(t - t0) <= 1.0e-12 * Math.max(Math.abs(t0), Math.abs(t))) { +213 throw new IntegratorException( +214 "too small integration interval: length = {0}", +215 Math.abs(t - t0)); +216 } +217 +218 } +219 +220 /** Add an event handler for end time checking. +221 * <p>This method can be used to simplify handling of integration end time. +222 * It leverages the nominal stop condition with the exceptional stop +223 * conditions.</p> +224 * @param startTime integration start time +225 * @param endTime desired end time +226 * @param manager manager containing the user-defined handlers +227 * @return a new manager containing all the user-defined handlers plus a +228 * dedicated manager triggering a stop event at entTime +229 */ +230 protected CombinedEventsManager addEndTimeChecker(final double startTime, +231 final double endTime, +232 final CombinedEventsManager manager) { +233 CombinedEventsManager newManager = new CombinedEventsManager(); +234 for (final EventState state : manager.getEventsStates()) { +235 newManager.addEventHandler(state.getEventHandler(), +236 state.getMaxCheckInterval(), +237 state.getConvergence(), +238 state.getMaxIterationCount()); +239 } +240 newManager.addEventHandler(new EndTimeChecker(endTime), +241 Double.POSITIVE_INFINITY, +242 Math.ulp(Math.max(Math.abs(startTime), Math.abs(endTime))), +243 100); +244 return newManager; +245 } +246 +247 /** Specialized event handler to stop integration. */ +248 private static class EndTimeChecker implements EventHandler { +249 +250 /** Desired end time. */ +251 private final double endTime; +252 +253 /** Build an instance. +254 * @param endTime desired time +255 */ +256 public EndTimeChecker(final double endTime) { +257 this.endTime = endTime; +258 } +259 +260 /** {@inheritDoc} */ +261 public int eventOccurred(double t, double[] y, boolean increasing) { +262 return STOP; +263 } +264 +265 /** {@inheritDoc} */ +266 public double g(double t, double[] y) { +267 return t - endTime; +268 } +269 +270 /** {@inheritDoc} */ +271 public void resetState(double t, double[] y) { +272 } +273 +274 } +275 +276 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/ContinuousOutputModel.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/ContinuousOutputModel.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,442 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode; +019 +020 import java.util.ArrayList; +021 import java.util.List; +022 import java.io.Serializable; +023 +024 import org.apache.commons.math.MathRuntimeException; +025 import org.apache.commons.math.ode.sampling.StepHandler; +026 import org.apache.commons.math.ode.sampling.StepInterpolator; +027 +028 /** +029 * This class stores all information provided by an ODE integrator +030 * during the integration process and build a continuous model of the +031 * solution from this. +032 * +033 * <p>This class act as a step handler from the integrator point of +034 * view. It is called iteratively during the integration process and +035 * stores a copy of all steps information in a sorted collection for +036 * later use. Once the integration process is over, the user can use +037 * the {@link #setInterpolatedTime setInterpolatedTime} and {@link +038 * #getInterpolatedState getInterpolatedState} to retrieve this +039 * information at any time. It is important to wait for the +040 * integration to be over before attempting to call {@link +041 * #setInterpolatedTime setInterpolatedTime} because some internal +042 * variables are set only once the last step has been handled.</p> +043 * +044 * <p>This is useful for example if the main loop of the user +045 * application should remain independent from the integration process +046 * or if one needs to mimic the behaviour of an analytical model +047 * despite a numerical model is used (i.e. one needs the ability to +048 * get the model value at any time or to navigate through the +049 * data).</p> +050 * +051 * <p>If problem modeling is done with several separate +052 * integration phases for contiguous intervals, the same +053 * ContinuousOutputModel can be used as step handler for all +054 * integration phases as long as they are performed in order and in +055 * the same direction. As an example, one can extrapolate the +056 * trajectory of a satellite with one model (i.e. one set of +057 * differential equations) up to the beginning of a maneuver, use +058 * another more complex model including thrusters modeling and +059 * accurate attitude control during the maneuver, and revert to the +060 * first model after the end of the maneuver. If the same continuous +061 * output model handles the steps of all integration phases, the user +062 * do not need to bother when the maneuver begins or ends, he has all +063 * the data available in a transparent manner.</p> +064 * +065 * <p>An important feature of this class is that it implements the +066 * <code>Serializable</code> interface. This means that the result of +067 * an integration can be serialized and reused later (if stored into a +068 * persistent medium like a filesystem or a database) or elsewhere (if +069 * sent to another application). Only the result of the integration is +070 * stored, there is no reference to the integrated problem by +071 * itself.</p> +072 * +073 * <p>One should be aware that the amount of data stored in a +074 * ContinuousOutputModel instance can be important if the state vector +075 * is large, if the integration interval is long or if the steps are +076 * small (which can result from small tolerance settings in {@link +077 * org.apache.commons.math.ode.nonstiff.AdaptiveStepsizeIntegrator adaptive +078 * step size integrators}).</p> +079 * +080 * @see StepHandler +081 * @see StepInterpolator +082 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +083 * @since 1.2 +084 */ +085 +086 public class ContinuousOutputModel +087 implements StepHandler, Serializable { +088 +089 /** Serializable version identifier */ +090 private static final long serialVersionUID = -1417964919405031606L; +091 +092 /** Initial integration time. */ +093 private double initialTime; +094 +095 /** Final integration time. */ +096 private double finalTime; +097 +098 /** Integration direction indicator. */ +099 private boolean forward; +100 +101 /** Current interpolator index. */ +102 private int index; +103 +104 /** Steps table. */ +105 private List<StepInterpolator> steps; +106 +107 /** Simple constructor. +108 * Build an empty continuous output model. +109 */ +110 public ContinuousOutputModel() { +111 steps = new ArrayList<StepInterpolator>(); +112 reset(); +113 } +114 +115 /** Append another model at the end of the instance. +116 * @param model model to add at the end of the instance +117 * @exception DerivativeException if some step interpolators from +118 * the appended model cannot be copied +119 * @exception IllegalArgumentException if the model to append is not +120 * compatible with the instance (dimension of the state vector, +121 * propagation direction, hole between the dates) +122 */ +123 public void append(final ContinuousOutputModel model) +124 throws DerivativeException { +125 +126 if (model.steps.size() == 0) { +127 return; +128 } +129 +130 if (steps.size() == 0) { +131 initialTime = model.initialTime; +132 forward = model.forward; +133 } else { +134 +135 if (getInterpolatedState().length != model.getInterpolatedState().length) { +136 throw MathRuntimeException.createIllegalArgumentException( +137 "dimension mismatch {0} != {1}", +138 getInterpolatedState().length, model.getInterpolatedState().length); +139 } +140 +141 if (forward ^ model.forward) { +142 throw MathRuntimeException.createIllegalArgumentException( +143 "propagation direction mismatch"); +144 } +145 +146 final StepInterpolator lastInterpolator = steps.get(index); +147 final double current = lastInterpolator.getCurrentTime(); +148 final double previous = lastInterpolator.getPreviousTime(); +149 final double step = current - previous; +150 final double gap = model.getInitialTime() - current; +151 if (Math.abs(gap) > 1.0e-3 * Math.abs(step)) { +152 throw MathRuntimeException.createIllegalArgumentException( +153 "{0} wide hole between models time ranges", Math.abs(gap)); +154 } +155 +156 } +157 +158 for (StepInterpolator interpolator : model.steps) { +159 steps.add(interpolator.copy()); +160 } +161 +162 index = steps.size() - 1; +163 finalTime = (steps.get(index)).getCurrentTime(); +164 +165 } +166 +167 /** Determines whether this handler needs dense output. +168 * <p>The essence of this class is to provide dense output over all +169 * steps, hence it requires the internal steps to provide themselves +170 * dense output. The method therefore returns always true.</p> +171 * @return always true +172 */ +173 public boolean requiresDenseOutput() { +174 return true; +175 } +176 +177 /** Reset the step handler. +178 * Initialize the internal data as required before the first step is +179 * handled. +180 */ +181 public void reset() { +182 initialTime = Double.NaN; +183 finalTime = Double.NaN; +184 forward = true; +185 index = 0; +186 steps.clear(); +187 } +188 +189 /** Handle the last accepted step. +190 * A copy of the information provided by the last step is stored in +191 * the instance for later use. +192 * @param interpolator interpolator for the last accepted step. +193 * @param isLast true if the step is the last one +194 * @throws DerivativeException this exception is propagated to the +195 * caller if the underlying user function triggers one +196 */ +197 public void handleStep(final StepInterpolator interpolator, final boolean isLast) +198 throws DerivativeException { +199 +200 if (steps.size() == 0) { +201 initialTime = interpolator.getPreviousTime(); +202 forward = interpolator.isForward(); +203 } +204 +205 steps.add(interpolator.copy()); +206 +207 if (isLast) { +208 finalTime = interpolator.getCurrentTime(); +209 index = steps.size() - 1; +210 } +211 +212 } +213 +214 /** +215 * Get the initial integration time. +216 * @return initial integration time +217 */ +218 public double getInitialTime() { +219 return initialTime; +220 } +221 +222 /** +223 * Get the final integration time. +224 * @return final integration time +225 */ +226 public double getFinalTime() { +227 return finalTime; +228 } +229 +230 /** +231 * Get the time of the interpolated point. +232 * If {@link #setInterpolatedTime} has not been called, it returns +233 * the final integration time. +234 * @return interpolation point time +235 */ +236 public double getInterpolatedTime() { +237 return steps.get(index).getInterpolatedTime(); +238 } +239 +240 /** Set the time of the interpolated point. +241 * <p>This method should <strong>not</strong> be called before the +242 * integration is over because some internal variables are set only +243 * once the last step has been handled.</p> +244 * <p>Setting the time outside of the integration interval is now +245 * allowed (it was not allowed up to version 5.9 of Mantissa), but +246 * should be used with care since the accuracy of the interpolator +247 * will probably be very poor far from this interval. This allowance +248 * has been added to simplify implementation of search algorithms +249 * near the interval endpoints.</p> +250 * @param time time of the interpolated point +251 */ +252 public void setInterpolatedTime(final double time) { +253 +254 // initialize the search with the complete steps table +255 int iMin = 0; +256 final StepInterpolator sMin = steps.get(iMin); +257 double tMin = 0.5 * (sMin.getPreviousTime() + sMin.getCurrentTime()); +258 +259 int iMax = steps.size() - 1; +260 final StepInterpolator sMax = steps.get(iMax); +261 double tMax = 0.5 * (sMax.getPreviousTime() + sMax.getCurrentTime()); +262 +263 // handle points outside of the integration interval +264 // or in the first and last step +265 if (locatePoint(time, sMin) <= 0) { +266 index = iMin; +267 sMin.setInterpolatedTime(time); +268 return; +269 } +270 if (locatePoint(time, sMax) >= 0) { +271 index = iMax; +272 sMax.setInterpolatedTime(time); +273 return; +274 } +275 +276 // reduction of the table slice size +277 while (iMax - iMin > 5) { +278 +279 // use the last estimated index as the splitting index +280 final StepInterpolator si = steps.get(index); +281 final int location = locatePoint(time, si); +282 if (location < 0) { +283 iMax = index; +284 tMax = 0.5 * (si.getPreviousTime() + si.getCurrentTime()); +285 } else if (location > 0) { +286 iMin = index; +287 tMin = 0.5 * (si.getPreviousTime() + si.getCurrentTime()); +288 } else { +289 // we have found the target step, no need to continue searching +290 si.setInterpolatedTime(time); +291 return; +292 } +293 +294 // compute a new estimate of the index in the reduced table slice +295 final int iMed = (iMin + iMax) / 2; +296 final StepInterpolator sMed = steps.get(iMed); +297 final double tMed = 0.5 * (sMed.getPreviousTime() + sMed.getCurrentTime()); +298 +299 if ((Math.abs(tMed - tMin) < 1e-6) || (Math.abs(tMax - tMed) < 1e-6)) { +300 // too close to the bounds, we estimate using a simple dichotomy +301 index = iMed; +302 } else { +303 // estimate the index using a reverse quadratic polynom +304 // (reverse means we have i = P(t), thus allowing to simply +305 // compute index = P(time) rather than solving a quadratic equation) +306 final double d12 = tMax - tMed; +307 final double d23 = tMed - tMin; +308 final double d13 = tMax - tMin; +309 final double dt1 = time - tMax; +310 final double dt2 = time - tMed; +311 final double dt3 = time - tMin; +312 final double iLagrange = ((dt2 * dt3 * d23) * iMax - +313 (dt1 * dt3 * d13) * iMed + +314 (dt1 * dt2 * d12) * iMin) / +315 (d12 * d23 * d13); +316 index = (int) Math.rint(iLagrange); +317 } +318 +319 // force the next size reduction to be at least one tenth +320 final int low = Math.max(iMin + 1, (9 * iMin + iMax) / 10); +321 final int high = Math.min(iMax - 1, (iMin + 9 * iMax) / 10); +322 if (index < low) { +323 index = low; +324 } else if (index > high) { +325 index = high; +326 } +327 +328 } +329 +330 // now the table slice is very small, we perform an iterative search +331 index = iMin; +332 while ((index <= iMax) && (locatePoint(time, steps.get(index)) > 0)) { +333 ++index; +334 } +335 +336 steps.get(index).setInterpolatedTime(time); +337 +338 } +339 +340 /** +341 * Get the state vector of the interpolated point. +342 * @return state vector at time {@link #getInterpolatedTime} +343 * @throws DerivativeException if this call induces an automatic +344 * step finalization that throws one +345 */ +346 public double[] getInterpolatedState() throws DerivativeException { +347 return steps.get(index).getInterpolatedState(); +348 } +349 +350 /** Compare a step interval and a double. +351 * @param time point to locate +352 * @param interval step interval +353 * @return -1 if the double is before the interval, 0 if it is in +354 * the interval, and +1 if it is after the interval, according to +355 * the interval direction +356 */ +357 private int locatePoint(final double time, final StepInterpolator interval) { +358 if (forward) { +359 if (time < interval.getPreviousTime()) { +360 return -1; +361 } else if (time > interval.getCurrentTime()) { +362 return +1; +363 } else { +364 return 0; +365 } +366 } +367 if (time > interval.getPreviousTime()) { +368 return -1; +369 } else if (time < interval.getCurrentTime()) { +370 return +1; +371 } else { +372 return 0; +373 } +374 } +375 +376 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/DerivativeException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/DerivativeException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,117 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode; +019 +020 import org.apache.commons.math.MathException; +021 +022 /** +023 * This exception is made available to users to report +024 * the error conditions that are triggered while computing +025 * the differential equations. +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 * @since 1.2 +028 */ +029 public class DerivativeException +030 extends MathException { +031 +032 /** Serializable version identifier */ +033 private static final long serialVersionUID = 5666710788967425123L; +034 +035 /** Simple constructor. +036 * Build an exception by translating and formating a message +037 * @param specifier format specifier (to be translated) +038 * @param parts to insert in the format (no translation) +039 */ +040 public DerivativeException(final String specifier, final Object ... parts) { +041 super(specifier, parts); +042 } +043 +044 /** Build an instance from an underlying cause. +045 * @param cause cause for the exception +046 */ +047 public DerivativeException(final Throwable cause) { +048 super(cause); +049 } +050 +051 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/FirstOrderConverter.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/FirstOrderConverter.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,183 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode; +019 +020 /** This class converts second order differential equations to first +021 * order ones. +022 * +023 * <p>This class is a wrapper around a {@link +024 * SecondOrderDifferentialEquations} which allow to use a {@link +025 * FirstOrderIntegrator} to integrate it.</p> +026 * +027 * <p>The transformation is done by changing the n dimension state +028 * vector to a 2n dimension vector, where the first n components are +029 * the initial state variables and the n last components are their +030 * first time derivative. The first time derivative of this state +031 * vector then really contains both the first and second time +032 * derivative of the initial state vector, which can be handled by the +033 * underlying second order equations set.</p> +034 * +035 * <p>One should be aware that the data is duplicated during the +036 * transformation process and that for each call to {@link +037 * #computeDerivatives computeDerivatives}, this wrapper does copy 4n +038 * scalars : 2n before the call to {@link +039 * SecondOrderDifferentialEquations#computeSecondDerivatives +040 * computeSecondDerivatives} in order to dispatch the y state vector +041 * into z and zDot, and 2n after the call to gather zDot and zDDot +042 * into yDot. Since the underlying problem by itself perhaps also +043 * needs to copy data and dispatch the arrays into domain objects, +044 * this has an impact on both memory and CPU usage. The only way to +045 * avoid this duplication is to perform the transformation at the +046 * problem level, i.e. to implement the problem as a first order one +047 * and then avoid using this class.</p> +048 * +049 * @see FirstOrderIntegrator +050 * @see FirstOrderDifferentialEquations +051 * @see SecondOrderDifferentialEquations +052 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +053 * @since 1.2 +054 */ +055 +056 public class FirstOrderConverter implements FirstOrderDifferentialEquations { +057 +058 /** Underlying second order equations set. */ +059 private final SecondOrderDifferentialEquations equations; +060 +061 /** second order problem dimension. */ +062 private final int dimension; +063 +064 /** state vector. */ +065 private final double[] z; +066 +067 /** first time derivative of the state vector. */ +068 private final double[] zDot; +069 +070 /** second time derivative of the state vector. */ +071 private final double[] zDDot; +072 +073 /** Simple constructor. +074 * Build a converter around a second order equations set. +075 * @param equations second order equations set to convert +076 */ +077 public FirstOrderConverter (final SecondOrderDifferentialEquations equations) { +078 this.equations = equations; +079 dimension = equations.getDimension(); +080 z = new double[dimension]; +081 zDot = new double[dimension]; +082 zDDot = new double[dimension]; +083 } +084 +085 /** Get the dimension of the problem. +086 * <p>The dimension of the first order problem is twice the +087 * dimension of the underlying second order problem.</p> +088 * @return dimension of the problem +089 */ +090 public int getDimension() { +091 return 2 * dimension; +092 } +093 +094 /** Get the current time derivative of the state vector. +095 * @param t current value of the independent <I>time</I> variable +096 * @param y array containing the current value of the state vector +097 * @param yDot placeholder array where to put the time derivative of the state vector +098 * @throws DerivativeException this exception is propagated to the caller if the +099 * underlying user function triggers one +100 */ +101 public void computeDerivatives(final double t, final double[] y, final double[] yDot) +102 throws DerivativeException { +103 +104 // split the state vector in two +105 System.arraycopy(y, 0, z, 0, dimension); +106 System.arraycopy(y, dimension, zDot, 0, dimension); +107 +108 // apply the underlying equations set +109 equations.computeSecondDerivatives(t, z, zDot, zDDot); +110 +111 // build the result state derivative +112 System.arraycopy(zDot, 0, yDot, 0, dimension); +113 System.arraycopy(zDDot, 0, yDot, dimension, dimension); +114 +115 } +116 +117 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/FirstOrderDifferentialEquations.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/FirstOrderDifferentialEquations.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,130 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode; +019 +020 +021 /** This interface represents a first order differential equations set. +022 * +023 * <p>This interface should be implemented by all real first order +024 * differential equation problems before they can be handled by the +025 * integrators {@link FirstOrderIntegrator#integrate} method.</p> +026 * +027 * <p>A first order differential equations problem, as seen by an +028 * integrator is the time derivative <code>dY/dt</code> of a state +029 * vector <code>Y</code>, both being one dimensional arrays. From the +030 * integrator point of view, this derivative depends only on the +031 * current time <code>t</code> and on the state vector +032 * <code>Y</code>.</p> +033 * +034 * <p>For real problems, the derivative depends also on parameters +035 * that do not belong to the state vector (dynamical model constants +036 * for example). These constants are completely outside of the scope +037 * of this interface, the classes that implement it are allowed to +038 * handle them as they want.</p> +039 * +040 * @see FirstOrderIntegrator +041 * @see FirstOrderConverter +042 * @see SecondOrderDifferentialEquations +043 * +044 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +045 * @since 1.2 +046 */ +047 +048 public interface FirstOrderDifferentialEquations { +049 +050 /** Get the dimension of the problem. +051 * @return dimension of the problem +052 */ +053 int getDimension(); +054 +055 /** Get the current time derivative of the state vector. +056 * @param t current value of the independent <I>time</I> variable +057 * @param y array containing the current value of the state vector +058 * @param yDot placeholder array where to put the time derivative of the state vector +059 * @throws DerivativeException this exception is propagated to the caller if the +060 * underlying user function triggers one +061 */ +062 void computeDerivatives(double t, double[] y, double[] yDot) throws DerivativeException; +063 +064 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/FirstOrderIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/FirstOrderIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,126 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode; +019 +020 /** This interface represents a first order integrator for +021 * differential equations. +022 +023 * <p>The classes which are devoted to solve first order differential +024 * equations should implement this interface. The problems which can +025 * be handled should implement the {@link +026 * FirstOrderDifferentialEquations} interface.</p> +027 * +028 * @see FirstOrderDifferentialEquations +029 * @see org.apache.commons.math.ode.sampling.StepHandler +030 * @see org.apache.commons.math.ode.events.EventHandler +031 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +032 * @since 1.2 +033 */ +034 +035 public interface FirstOrderIntegrator extends ODEIntegrator { +036 +037 /** Integrate the differential equations up to the given time. +038 * <p>This method solves an Initial Value Problem (IVP).</p> +039 * <p>Since this method stores some internal state variables made +040 * available in its public interface during integration ({@link +041 * #getCurrentSignedStepsize()}), it is <em>not</em> thread-safe.</p> +042 * @param equations differential equations to integrate +043 * @param t0 initial time +044 * @param y0 initial value of the state vector at t0 +045 * @param t target time for the integration +046 * (can be set to a value smaller than <code>t0</code> for backward integration) +047 * @param y placeholder where to put the state vector at each successful +048 * step (and hence at the end of integration), can be the same object as y0 +049 * @return stop time, will be the same as target time if integration reached its +050 * target, but may be different if some {@link +051 * org.apache.commons.math.ode.events.EventHandler} stops it at some point. +052 * @throws IntegratorException if the integrator cannot perform integration +053 * @throws DerivativeException this exception is propagated to the caller if +054 * the underlying user function triggers one +055 */ +056 double integrate (FirstOrderDifferentialEquations equations, +057 double t0, double[] y0, +058 double t, double[] y) throws DerivativeException, IntegratorException; +059 +060 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/IntegratorException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/IntegratorException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,117 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode; +019 +020 import org.apache.commons.math.MathException; +021 +022 /** +023 * This exception is made available to users to report +024 * the error conditions that are triggered during integration +025 * @version $Revision: 746578 $ $Date: 2009-02-21 15:01:14 -0500 (Sat, 21 Feb 2009) $ +026 * @since 1.2 +027 */ +028 public class IntegratorException +029 extends MathException { +030 +031 /** Serializable version identifier */ +032 private static final long serialVersionUID = -1607588949778036796L; +033 +034 /** Simple constructor. +035 * Build an exception by translating and formating a message +036 * @param specifier format specifier (to be translated) +037 * @param parts to insert in the format (no translation) +038 */ +039 public IntegratorException(final String specifier, final Object ... parts) { +040 super(specifier, parts); +041 } +042 +043 /** +044 * Create an exception with a given root cause. +045 * @param cause the exception or error that caused this exception to be thrown +046 */ +047 public IntegratorException(final Throwable cause) { +048 super(cause); +049 } +050 +051 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/MultistepIntegrator.NordsieckTransformer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/MultistepIntegrator.NordsieckTransformer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,470 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode; +019 +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.linear.Array2DRowRealMatrix; +022 import org.apache.commons.math.linear.RealMatrix; +023 import org.apache.commons.math.ode.nonstiff.AdaptiveStepsizeIntegrator; +024 import org.apache.commons.math.ode.nonstiff.DormandPrince853Integrator; +025 import org.apache.commons.math.ode.sampling.StepHandler; +026 import org.apache.commons.math.ode.sampling.StepInterpolator; +027 +028 /** +029 * This class is the base class for multistep integrators for Ordinary +030 * Differential Equations. +031 * <p>We define scaled derivatives s<sub>i</sub>(n) at step n as: +032 * <pre> +033 * s<sub>1</sub>(n) = h y'<sub>n</sub> for first derivative +034 * s<sub>2</sub>(n) = h<sup>2</sup>/2 y''<sub>n</sub> for second derivative +035 * s<sub>3</sub>(n) = h<sup>3</sup>/6 y'''<sub>n</sub> for third derivative +036 * ... +037 * s<sub>k</sub>(n) = h<sup>k</sup>/k! y(k)<sub>n</sub> for k<sup>th</sup> derivative +038 * </pre></p> +039 * <p>Rather than storing several previous steps separately, this implementation uses +040 * the Nordsieck vector with higher degrees scaled derivatives all taken at the same +041 * step (y<sub>n</sub>, s<sub>1</sub>(n) and r<sub>n</sub>) where r<sub>n</sub> is defined as: +042 * <pre> +043 * r<sub>n</sub> = [ s<sub>2</sub>(n), s<sub>3</sub>(n) ... s<sub>k</sub>(n) ]<sup>T</sup> +044 * </pre> +045 * (we omit the k index in the notation for clarity)</p> +046 * <p> +047 * Multistep integrators with Nordsieck representation are highly sensitive to +048 * large step changes because when the step is multiplied by a factor a, the +049 * k<sup>th</sup> component of the Nordsieck vector is multiplied by a<sup>k</sup> +050 * and the last components are the least accurate ones. The default max growth +051 * factor is therefore set to a quite low value: 2<sup>1/order</sup>. +052 * </p> +053 * +054 * @see org.apache.commons.math.ode.nonstiff.AdamsBashforthIntegrator +055 * @see org.apache.commons.math.ode.nonstiff.AdamsMoultonIntegrator +056 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +057 * @since 2.0 +058 */ +059 public abstract class MultistepIntegrator extends AdaptiveStepsizeIntegrator { +060 +061 /** First scaled derivative (h y'). */ +062 protected double[] scaled; +063 +064 /** Nordsieck matrix of the higher scaled derivatives. +065 * <p>(h<sup>2</sup>/2 y'', h<sup>3</sup>/6 y''' ..., h<sup>k</sup>/k! y(k))</p> +066 */ +067 protected Array2DRowRealMatrix nordsieck; +068 +069 /** Starter integrator. */ +070 private FirstOrderIntegrator starter; +071 +072 /** Number of steps of the multistep method (excluding the one being computed). */ +073 private final int nSteps; +074 +075 /** Stepsize control exponent. */ +076 private double exp; +077 +078 /** Safety factor for stepsize control. */ +079 private double safety; +080 +081 /** Minimal reduction factor for stepsize control. */ +082 private double minReduction; +083 +084 /** Maximal growth factor for stepsize control. */ +085 private double maxGrowth; +086 +087 /** +088 * Build a multistep integrator with the given stepsize bounds. +089 * <p>The default starter integrator is set to the {@link +090 * DormandPrince853Integrator Dormand-Prince 8(5,3)} integrator with +091 * some defaults settings.</p> +092 * <p> +093 * The default max growth factor is set to a quite low value: 2<sup>1/order</sup>. +094 * </p> +095 * @param name name of the method +096 * @param nSteps number of steps of the multistep method +097 * (excluding the one being computed) +098 * @param order order of the method +099 * @param minStep minimal step (must be positive even for backward +100 * integration), the last step can be smaller than this +101 * @param maxStep maximal step (must be positive even for backward +102 * integration) +103 * @param scalAbsoluteTolerance allowed absolute error +104 * @param scalRelativeTolerance allowed relative error +105 */ +106 protected MultistepIntegrator(final String name, final int nSteps, +107 final int order, +108 final double minStep, final double maxStep, +109 final double scalAbsoluteTolerance, +110 final double scalRelativeTolerance) { +111 +112 super(name, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); +113 +114 if (nSteps <= 0) { +115 throw MathRuntimeException.createIllegalArgumentException( +116 "{0} method needs at least one previous point", +117 name); +118 } +119 +120 starter = new DormandPrince853Integrator(minStep, maxStep, +121 scalAbsoluteTolerance, +122 scalRelativeTolerance); +123 this.nSteps = nSteps; +124 +125 exp = -1.0 / order; +126 +127 // set the default values of the algorithm control parameters +128 setSafety(0.9); +129 setMinReduction(0.2); +130 setMaxGrowth(Math.pow(2.0, -exp)); +131 +132 } +133 +134 /** +135 * Build a multistep integrator with the given stepsize bounds. +136 * <p>The default starter integrator is set to the {@link +137 * DormandPrince853Integrator Dormand-Prince 8(5,3)} integrator with +138 * some defaults settings.</p> +139 * <p> +140 * The default max growth factor is set to a quite low value: 2<sup>1/order</sup>. +141 * </p> +142 * @param name name of the method +143 * @param nSteps number of steps of the multistep method +144 * (excluding the one being computed) +145 * @param order order of the method +146 * @param minStep minimal step (must be positive even for backward +147 * integration), the last step can be smaller than this +148 * @param maxStep maximal step (must be positive even for backward +149 * integration) +150 * @param vecAbsoluteTolerance allowed absolute error +151 * @param vecRelativeTolerance allowed relative error +152 */ +153 protected MultistepIntegrator(final String name, final int nSteps, +154 final int order, +155 final double minStep, final double maxStep, +156 final double[] vecAbsoluteTolerance, +157 final double[] vecRelativeTolerance) { +158 super(name, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); +159 starter = new DormandPrince853Integrator(minStep, maxStep, +160 vecAbsoluteTolerance, +161 vecRelativeTolerance); +162 this.nSteps = nSteps; +163 +164 exp = -1.0 / order; +165 +166 // set the default values of the algorithm control parameters +167 setSafety(0.9); +168 setMinReduction(0.2); +169 setMaxGrowth(Math.pow(2.0, -exp)); +170 +171 } +172 +173 /** +174 * Get the starter integrator. +175 * @return starter integrator +176 */ +177 public ODEIntegrator getStarterIntegrator() { +178 return starter; +179 } +180 +181 /** +182 * Set the starter integrator. +183 * <p>The various step and event handlers for this starter integrator +184 * will be managed automatically by the multi-step integrator. Any +185 * user configuration for these elements will be cleared before use.</p> +186 * @param starterIntegrator starter integrator +187 */ +188 public void setStarterIntegrator(FirstOrderIntegrator starterIntegrator) { +189 this.starter = starterIntegrator; +190 } +191 +192 /** Start the integration. +193 * <p>This method computes one step using the underlying starter integrator, +194 * and initializes the Nordsieck vector at step start. The starter integrator +195 * purpose is only to establish initial conditions, it does not really change +196 * time by itself. The top level multistep integrator remains in charge of +197 * handling time propagation and events handling as it will starts its own +198 * computation right from the beginning. In a sense, the starter integrator +199 * can be seen as a dummy one and so it will never trigger any user event nor +200 * call any user step handler.</p> +201 * @param t0 initial time +202 * @param y0 initial value of the state vector at t0 +203 * @param t target time for the integration +204 * (can be set to a value smaller than <code>t0</code> for backward integration) +205 * @throws IntegratorException if the integrator cannot perform integration +206 * @throws DerivativeException this exception is propagated to the caller if +207 * the underlying user function triggers one +208 */ +209 protected void start(final double t0, final double[] y0, final double t) +210 throws DerivativeException, IntegratorException { +211 +212 // make sure NO user event nor user step handler is triggered, +213 // this is the task of the top level integrator, not the task +214 // of the starter integrator +215 starter.clearEventHandlers(); +216 starter.clearStepHandlers(); +217 +218 // set up one specific step handler to extract initial Nordsieck vector +219 starter.addStepHandler(new NordsieckInitializer(y0.length)); +220 +221 // start integration, expecting a InitializationCompletedMarkerException +222 try { +223 starter.integrate(new CountingDifferentialEquations(y0.length), +224 t0, y0, t, new double[y0.length]); +225 } catch (DerivativeException de) { +226 if (!(de instanceof InitializationCompletedMarkerException)) { +227 // this is not the expected nominal interruption of the start integrator +228 throw de; +229 } +230 } +231 +232 // remove the specific step handler +233 starter.clearStepHandlers(); +234 +235 } +236 +237 /** Initialize the high order scaled derivatives at step start. +238 * @param first first scaled derivative at step start +239 * @param multistep scaled derivatives after step start (hy'1, ..., hy'k-1) +240 * will be modified +241 * @return high order scaled derivatives at step start +242 */ +243 protected abstract Array2DRowRealMatrix initializeHighOrderDerivatives(final double[] first, +244 final double[][] multistep); +245 +246 /** Get the minimal reduction factor for stepsize control. +247 * @return minimal reduction factor +248 */ +249 public double getMinReduction() { +250 return minReduction; +251 } +252 +253 /** Set the minimal reduction factor for stepsize control. +254 * @param minReduction minimal reduction factor +255 */ +256 public void setMinReduction(final double minReduction) { +257 this.minReduction = minReduction; +258 } +259 +260 /** Get the maximal growth factor for stepsize control. +261 * @return maximal growth factor +262 */ +263 public double getMaxGrowth() { +264 return maxGrowth; +265 } +266 +267 /** Set the maximal growth factor for stepsize control. +268 * @param maxGrowth maximal growth factor +269 */ +270 public void setMaxGrowth(final double maxGrowth) { +271 this.maxGrowth = maxGrowth; +272 } +273 +274 /** Get the safety factor for stepsize control. +275 * @return safety factor +276 */ +277 public double getSafety() { +278 return safety; +279 } +280 +281 /** Set the safety factor for stepsize control. +282 * @param safety safety factor +283 */ +284 public void setSafety(final double safety) { +285 this.safety = safety; +286 } +287 +288 /** Compute step grow/shrink factor according to normalized error. +289 * @param error normalized error of the current step +290 * @return grow/shrink factor for next step +291 */ +292 protected double computeStepGrowShrinkFactor(final double error) { +293 return Math.min(maxGrowth, Math.max(minReduction, safety * Math.pow(error, exp))); +294 } +295 +296 /** Transformer used to convert the first step to Nordsieck representation. */ +297 public static interface NordsieckTransformer { +298 /** Initialize the high order scaled derivatives at step start. +299 * @param first first scaled derivative at step start +300 * @param multistep scaled derivatives after step start (hy'1, ..., hy'k-1) +301 * will be modified +302 * @return high order derivatives at step start +303 */ +304 RealMatrix initializeHighOrderDerivatives(double[] first, double[][] multistep); +305 } +306 +307 /** Specialized step handler storing the first step. */ +308 private class NordsieckInitializer implements StepHandler { +309 +310 /** Problem dimension. */ +311 private final int n; +312 +313 /** Simple constructor. +314 * @param n problem dimension +315 */ +316 public NordsieckInitializer(final int n) { +317 this.n = n; +318 } +319 +320 /** {@inheritDoc} */ +321 public void handleStep(StepInterpolator interpolator, boolean isLast) +322 throws DerivativeException { +323 +324 final double prev = interpolator.getPreviousTime(); +325 final double curr = interpolator.getCurrentTime(); +326 stepStart = prev; +327 stepSize = (curr - prev) / (nSteps + 1); +328 +329 // compute the first scaled derivative +330 interpolator.setInterpolatedTime(prev); +331 scaled = interpolator.getInterpolatedDerivatives().clone(); +332 for (int j = 0; j < n; ++j) { +333 scaled[j] *= stepSize; +334 } +335 +336 // compute the high order scaled derivatives +337 final double[][] multistep = new double[nSteps][]; +338 for (int i = 1; i <= nSteps; ++i) { +339 interpolator.setInterpolatedTime(prev + stepSize * i); +340 final double[] msI = interpolator.getInterpolatedDerivatives().clone(); +341 for (int j = 0; j < n; ++j) { +342 msI[j] *= stepSize; +343 } +344 multistep[i - 1] = msI; +345 } +346 nordsieck = initializeHighOrderDerivatives(scaled, multistep); +347 +348 // stop the integrator after the first step has been handled +349 throw new InitializationCompletedMarkerException(); +350 +351 } +352 +353 /** {@inheritDoc} */ +354 public boolean requiresDenseOutput() { +355 return true; +356 } +357 +358 /** {@inheritDoc} */ +359 public void reset() { +360 // nothing to do +361 } +362 +363 } +364 +365 /** Marker exception used ONLY to stop the starter integrator after first step. */ +366 private static class InitializationCompletedMarkerException +367 extends DerivativeException { +368 +369 /** Serializable version identifier. */ +370 private static final long serialVersionUID = -4105805787353488365L; +371 +372 /** Simple constructor. */ +373 public InitializationCompletedMarkerException() { +374 super((Throwable) null); +375 } +376 +377 } +378 +379 /** Wrapper for differential equations, ensuring start evaluations are counted. */ +380 private class CountingDifferentialEquations implements FirstOrderDifferentialEquations { +381 +382 /** Dimension of the problem. */ +383 private final int dimension; +384 +385 /** Simple constructor. +386 * @param dimension dimension of the problem +387 */ +388 public CountingDifferentialEquations(final int dimension) { +389 this.dimension = dimension; +390 } +391 +392 /** {@inheritDoc} */ +393 public void computeDerivatives(double t, double[] y, double[] dot) +394 throws DerivativeException { +395 MultistepIntegrator.this.computeDerivatives(t, y, dot); +396 } +397 +398 /** {@inheritDoc} */ +399 public int getDimension() { +400 return dimension; +401 } +402 } +403 +404 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/MultistepIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/MultistepIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,470 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode; +019 +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.linear.Array2DRowRealMatrix; +022 import org.apache.commons.math.linear.RealMatrix; +023 import org.apache.commons.math.ode.nonstiff.AdaptiveStepsizeIntegrator; +024 import org.apache.commons.math.ode.nonstiff.DormandPrince853Integrator; +025 import org.apache.commons.math.ode.sampling.StepHandler; +026 import org.apache.commons.math.ode.sampling.StepInterpolator; +027 +028 /** +029 * This class is the base class for multistep integrators for Ordinary +030 * Differential Equations. +031 * <p>We define scaled derivatives s<sub>i</sub>(n) at step n as: +032 * <pre> +033 * s<sub>1</sub>(n) = h y'<sub>n</sub> for first derivative +034 * s<sub>2</sub>(n) = h<sup>2</sup>/2 y''<sub>n</sub> for second derivative +035 * s<sub>3</sub>(n) = h<sup>3</sup>/6 y'''<sub>n</sub> for third derivative +036 * ... +037 * s<sub>k</sub>(n) = h<sup>k</sup>/k! y(k)<sub>n</sub> for k<sup>th</sup> derivative +038 * </pre></p> +039 * <p>Rather than storing several previous steps separately, this implementation uses +040 * the Nordsieck vector with higher degrees scaled derivatives all taken at the same +041 * step (y<sub>n</sub>, s<sub>1</sub>(n) and r<sub>n</sub>) where r<sub>n</sub> is defined as: +042 * <pre> +043 * r<sub>n</sub> = [ s<sub>2</sub>(n), s<sub>3</sub>(n) ... s<sub>k</sub>(n) ]<sup>T</sup> +044 * </pre> +045 * (we omit the k index in the notation for clarity)</p> +046 * <p> +047 * Multistep integrators with Nordsieck representation are highly sensitive to +048 * large step changes because when the step is multiplied by a factor a, the +049 * k<sup>th</sup> component of the Nordsieck vector is multiplied by a<sup>k</sup> +050 * and the last components are the least accurate ones. The default max growth +051 * factor is therefore set to a quite low value: 2<sup>1/order</sup>. +052 * </p> +053 * +054 * @see org.apache.commons.math.ode.nonstiff.AdamsBashforthIntegrator +055 * @see org.apache.commons.math.ode.nonstiff.AdamsMoultonIntegrator +056 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +057 * @since 2.0 +058 */ +059 public abstract class MultistepIntegrator extends AdaptiveStepsizeIntegrator { +060 +061 /** First scaled derivative (h y'). */ +062 protected double[] scaled; +063 +064 /** Nordsieck matrix of the higher scaled derivatives. +065 * <p>(h<sup>2</sup>/2 y'', h<sup>3</sup>/6 y''' ..., h<sup>k</sup>/k! y(k))</p> +066 */ +067 protected Array2DRowRealMatrix nordsieck; +068 +069 /** Starter integrator. */ +070 private FirstOrderIntegrator starter; +071 +072 /** Number of steps of the multistep method (excluding the one being computed). */ +073 private final int nSteps; +074 +075 /** Stepsize control exponent. */ +076 private double exp; +077 +078 /** Safety factor for stepsize control. */ +079 private double safety; +080 +081 /** Minimal reduction factor for stepsize control. */ +082 private double minReduction; +083 +084 /** Maximal growth factor for stepsize control. */ +085 private double maxGrowth; +086 +087 /** +088 * Build a multistep integrator with the given stepsize bounds. +089 * <p>The default starter integrator is set to the {@link +090 * DormandPrince853Integrator Dormand-Prince 8(5,3)} integrator with +091 * some defaults settings.</p> +092 * <p> +093 * The default max growth factor is set to a quite low value: 2<sup>1/order</sup>. +094 * </p> +095 * @param name name of the method +096 * @param nSteps number of steps of the multistep method +097 * (excluding the one being computed) +098 * @param order order of the method +099 * @param minStep minimal step (must be positive even for backward +100 * integration), the last step can be smaller than this +101 * @param maxStep maximal step (must be positive even for backward +102 * integration) +103 * @param scalAbsoluteTolerance allowed absolute error +104 * @param scalRelativeTolerance allowed relative error +105 */ +106 protected MultistepIntegrator(final String name, final int nSteps, +107 final int order, +108 final double minStep, final double maxStep, +109 final double scalAbsoluteTolerance, +110 final double scalRelativeTolerance) { +111 +112 super(name, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); +113 +114 if (nSteps <= 0) { +115 throw MathRuntimeException.createIllegalArgumentException( +116 "{0} method needs at least one previous point", +117 name); +118 } +119 +120 starter = new DormandPrince853Integrator(minStep, maxStep, +121 scalAbsoluteTolerance, +122 scalRelativeTolerance); +123 this.nSteps = nSteps; +124 +125 exp = -1.0 / order; +126 +127 // set the default values of the algorithm control parameters +128 setSafety(0.9); +129 setMinReduction(0.2); +130 setMaxGrowth(Math.pow(2.0, -exp)); +131 +132 } +133 +134 /** +135 * Build a multistep integrator with the given stepsize bounds. +136 * <p>The default starter integrator is set to the {@link +137 * DormandPrince853Integrator Dormand-Prince 8(5,3)} integrator with +138 * some defaults settings.</p> +139 * <p> +140 * The default max growth factor is set to a quite low value: 2<sup>1/order</sup>. +141 * </p> +142 * @param name name of the method +143 * @param nSteps number of steps of the multistep method +144 * (excluding the one being computed) +145 * @param order order of the method +146 * @param minStep minimal step (must be positive even for backward +147 * integration), the last step can be smaller than this +148 * @param maxStep maximal step (must be positive even for backward +149 * integration) +150 * @param vecAbsoluteTolerance allowed absolute error +151 * @param vecRelativeTolerance allowed relative error +152 */ +153 protected MultistepIntegrator(final String name, final int nSteps, +154 final int order, +155 final double minStep, final double maxStep, +156 final double[] vecAbsoluteTolerance, +157 final double[] vecRelativeTolerance) { +158 super(name, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); +159 starter = new DormandPrince853Integrator(minStep, maxStep, +160 vecAbsoluteTolerance, +161 vecRelativeTolerance); +162 this.nSteps = nSteps; +163 +164 exp = -1.0 / order; +165 +166 // set the default values of the algorithm control parameters +167 setSafety(0.9); +168 setMinReduction(0.2); +169 setMaxGrowth(Math.pow(2.0, -exp)); +170 +171 } +172 +173 /** +174 * Get the starter integrator. +175 * @return starter integrator +176 */ +177 public ODEIntegrator getStarterIntegrator() { +178 return starter; +179 } +180 +181 /** +182 * Set the starter integrator. +183 * <p>The various step and event handlers for this starter integrator +184 * will be managed automatically by the multi-step integrator. Any +185 * user configuration for these elements will be cleared before use.</p> +186 * @param starterIntegrator starter integrator +187 */ +188 public void setStarterIntegrator(FirstOrderIntegrator starterIntegrator) { +189 this.starter = starterIntegrator; +190 } +191 +192 /** Start the integration. +193 * <p>This method computes one step using the underlying starter integrator, +194 * and initializes the Nordsieck vector at step start. The starter integrator +195 * purpose is only to establish initial conditions, it does not really change +196 * time by itself. The top level multistep integrator remains in charge of +197 * handling time propagation and events handling as it will starts its own +198 * computation right from the beginning. In a sense, the starter integrator +199 * can be seen as a dummy one and so it will never trigger any user event nor +200 * call any user step handler.</p> +201 * @param t0 initial time +202 * @param y0 initial value of the state vector at t0 +203 * @param t target time for the integration +204 * (can be set to a value smaller than <code>t0</code> for backward integration) +205 * @throws IntegratorException if the integrator cannot perform integration +206 * @throws DerivativeException this exception is propagated to the caller if +207 * the underlying user function triggers one +208 */ +209 protected void start(final double t0, final double[] y0, final double t) +210 throws DerivativeException, IntegratorException { +211 +212 // make sure NO user event nor user step handler is triggered, +213 // this is the task of the top level integrator, not the task +214 // of the starter integrator +215 starter.clearEventHandlers(); +216 starter.clearStepHandlers(); +217 +218 // set up one specific step handler to extract initial Nordsieck vector +219 starter.addStepHandler(new NordsieckInitializer(y0.length)); +220 +221 // start integration, expecting a InitializationCompletedMarkerException +222 try { +223 starter.integrate(new CountingDifferentialEquations(y0.length), +224 t0, y0, t, new double[y0.length]); +225 } catch (DerivativeException de) { +226 if (!(de instanceof InitializationCompletedMarkerException)) { +227 // this is not the expected nominal interruption of the start integrator +228 throw de; +229 } +230 } +231 +232 // remove the specific step handler +233 starter.clearStepHandlers(); +234 +235 } +236 +237 /** Initialize the high order scaled derivatives at step start. +238 * @param first first scaled derivative at step start +239 * @param multistep scaled derivatives after step start (hy'1, ..., hy'k-1) +240 * will be modified +241 * @return high order scaled derivatives at step start +242 */ +243 protected abstract Array2DRowRealMatrix initializeHighOrderDerivatives(final double[] first, +244 final double[][] multistep); +245 +246 /** Get the minimal reduction factor for stepsize control. +247 * @return minimal reduction factor +248 */ +249 public double getMinReduction() { +250 return minReduction; +251 } +252 +253 /** Set the minimal reduction factor for stepsize control. +254 * @param minReduction minimal reduction factor +255 */ +256 public void setMinReduction(final double minReduction) { +257 this.minReduction = minReduction; +258 } +259 +260 /** Get the maximal growth factor for stepsize control. +261 * @return maximal growth factor +262 */ +263 public double getMaxGrowth() { +264 return maxGrowth; +265 } +266 +267 /** Set the maximal growth factor for stepsize control. +268 * @param maxGrowth maximal growth factor +269 */ +270 public void setMaxGrowth(final double maxGrowth) { +271 this.maxGrowth = maxGrowth; +272 } +273 +274 /** Get the safety factor for stepsize control. +275 * @return safety factor +276 */ +277 public double getSafety() { +278 return safety; +279 } +280 +281 /** Set the safety factor for stepsize control. +282 * @param safety safety factor +283 */ +284 public void setSafety(final double safety) { +285 this.safety = safety; +286 } +287 +288 /** Compute step grow/shrink factor according to normalized error. +289 * @param error normalized error of the current step +290 * @return grow/shrink factor for next step +291 */ +292 protected double computeStepGrowShrinkFactor(final double error) { +293 return Math.min(maxGrowth, Math.max(minReduction, safety * Math.pow(error, exp))); +294 } +295 +296 /** Transformer used to convert the first step to Nordsieck representation. */ +297 public static interface NordsieckTransformer { +298 /** Initialize the high order scaled derivatives at step start. +299 * @param first first scaled derivative at step start +300 * @param multistep scaled derivatives after step start (hy'1, ..., hy'k-1) +301 * will be modified +302 * @return high order derivatives at step start +303 */ +304 RealMatrix initializeHighOrderDerivatives(double[] first, double[][] multistep); +305 } +306 +307 /** Specialized step handler storing the first step. */ +308 private class NordsieckInitializer implements StepHandler { +309 +310 /** Problem dimension. */ +311 private final int n; +312 +313 /** Simple constructor. +314 * @param n problem dimension +315 */ +316 public NordsieckInitializer(final int n) { +317 this.n = n; +318 } +319 +320 /** {@inheritDoc} */ +321 public void handleStep(StepInterpolator interpolator, boolean isLast) +322 throws DerivativeException { +323 +324 final double prev = interpolator.getPreviousTime(); +325 final double curr = interpolator.getCurrentTime(); +326 stepStart = prev; +327 stepSize = (curr - prev) / (nSteps + 1); +328 +329 // compute the first scaled derivative +330 interpolator.setInterpolatedTime(prev); +331 scaled = interpolator.getInterpolatedDerivatives().clone(); +332 for (int j = 0; j < n; ++j) { +333 scaled[j] *= stepSize; +334 } +335 +336 // compute the high order scaled derivatives +337 final double[][] multistep = new double[nSteps][]; +338 for (int i = 1; i <= nSteps; ++i) { +339 interpolator.setInterpolatedTime(prev + stepSize * i); +340 final double[] msI = interpolator.getInterpolatedDerivatives().clone(); +341 for (int j = 0; j < n; ++j) { +342 msI[j] *= stepSize; +343 } +344 multistep[i - 1] = msI; +345 } +346 nordsieck = initializeHighOrderDerivatives(scaled, multistep); +347 +348 // stop the integrator after the first step has been handled +349 throw new InitializationCompletedMarkerException(); +350 +351 } +352 +353 /** {@inheritDoc} */ +354 public boolean requiresDenseOutput() { +355 return true; +356 } +357 +358 /** {@inheritDoc} */ +359 public void reset() { +360 // nothing to do +361 } +362 +363 } +364 +365 /** Marker exception used ONLY to stop the starter integrator after first step. */ +366 private static class InitializationCompletedMarkerException +367 extends DerivativeException { +368 +369 /** Serializable version identifier. */ +370 private static final long serialVersionUID = -4105805787353488365L; +371 +372 /** Simple constructor. */ +373 public InitializationCompletedMarkerException() { +374 super((Throwable) null); +375 } +376 +377 } +378 +379 /** Wrapper for differential equations, ensuring start evaluations are counted. */ +380 private class CountingDifferentialEquations implements FirstOrderDifferentialEquations { +381 +382 /** Dimension of the problem. */ +383 private final int dimension; +384 +385 /** Simple constructor. +386 * @param dimension dimension of the problem +387 */ +388 public CountingDifferentialEquations(final int dimension) { +389 this.dimension = dimension; +390 } +391 +392 /** {@inheritDoc} */ +393 public void computeDerivatives(double t, double[] y, double[] dot) +394 throws DerivativeException { +395 MultistepIntegrator.this.computeDerivatives(t, y, dot); +396 } +397 +398 /** {@inheritDoc} */ +399 public int getDimension() { +400 return dimension; +401 } +402 } +403 +404 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/ODEIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/ODEIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,206 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode; +019 +020 import java.util.Collection; +021 +022 import org.apache.commons.math.ode.events.EventHandler; +023 import org.apache.commons.math.ode.sampling.StepHandler; +024 +025 /** +026 * This interface defines the common parts shared by integrators +027 * for first and second order differential equations. +028 * @see FirstOrderIntegrator +029 * @see SecondOrderIntegrator +030 * @version $Revision: 785473 $ $Date: 2009-06-17 00:02:35 -0400 (Wed, 17 Jun 2009) $ +031 * @since 2.0 +032 */ +033 public interface ODEIntegrator { +034 +035 /** Get the name of the method. +036 * @return name of the method +037 */ +038 String getName(); +039 +040 /** Add a step handler to this integrator. +041 * <p>The handler will be called by the integrator for each accepted +042 * step.</p> +043 * @param handler handler for the accepted steps +044 * @see #getStepHandlers() +045 * @see #clearStepHandlers() +046 * @since 2.0 +047 */ +048 void addStepHandler(StepHandler handler); +049 +050 /** Get all the step handlers that have been added to the integrator. +051 * @return an unmodifiable collection of the added events handlers +052 * @see #addStepHandler(StepHandler) +053 * @see #clearStepHandlers() +054 * @since 2.0 +055 */ +056 Collection<StepHandler> getStepHandlers(); +057 +058 /** Remove all the step handlers that have been added to the integrator. +059 * @see #addStepHandler(StepHandler) +060 * @see #getStepHandlers() +061 * @since 2.0 +062 */ +063 void clearStepHandlers(); +064 +065 /** Add an event handler to the integrator. +066 * @param handler event handler +067 * @param maxCheckInterval maximal time interval between switching +068 * function checks (this interval prevents missing sign changes in +069 * case the integration steps becomes very large) +070 * @param convergence convergence threshold in the event time search +071 * @param maxIterationCount upper limit of the iteration count in +072 * the event time search +073 * @see #getEventHandlers() +074 * @see #clearEventHandlers() +075 */ +076 void addEventHandler(EventHandler handler, +077 double maxCheckInterval, +078 double convergence, +079 int maxIterationCount); +080 +081 /** Get all the event handlers that have been added to the integrator. +082 * @return an unmodifiable collection of the added events handlers +083 * @see #addEventHandler(EventHandler, double, double, int) +084 * @see #clearEventHandlers() +085 */ +086 Collection<EventHandler> getEventHandlers(); +087 +088 /** Remove all the event handlers that have been added to the integrator. +089 * @see #addEventHandler(EventHandler, double, double, int) +090 * @see #getEventHandlers() +091 */ +092 void clearEventHandlers(); +093 +094 /** Get the current value of the step start time t<sub>i</sub>. +095 * <p>This method can be called during integration (typically by +096 * the object implementing the {@link FirstOrderDifferentialEquations +097 * differential equations} problem) if the value of the current step that +098 * is attempted is needed.</p> +099 * <p>The result is undefined if the method is called outside of +100 * calls to <code>integrate</code>.</p> +101 * @return current value of the step start time t<sub>i</sub> +102 */ +103 double getCurrentStepStart(); +104 +105 /** Get the current signed value of the integration stepsize. +106 * <p>This method can be called during integration (typically by +107 * the object implementing the {@link FirstOrderDifferentialEquations +108 * differential equations} problem) if the signed value of the current stepsize +109 * that is tried is needed.</p> +110 * <p>The result is undefined if the method is called outside of +111 * calls to <code>integrate</code>.</p> +112 * @return current signed value of the stepsize +113 */ +114 double getCurrentSignedStepsize(); +115 +116 /** Set the maximal number of differential equations function evaluations. +117 * <p>The purpose of this method is to avoid infinite loops which can occur +118 * for example when stringent error constraints are set or when lots of +119 * discrete events are triggered, thus leading to many rejected steps.</p> +120 * @param maxEvaluations maximal number of function evaluations (negative +121 * values are silently converted to maximal integer value, thus representing +122 * almost unlimited evaluations) +123 */ +124 void setMaxEvaluations(int maxEvaluations); +125 +126 /** Get the maximal number of functions evaluations. +127 * @return maximal number of functions evaluations +128 */ +129 int getMaxEvaluations(); +130 +131 /** Get the number of evaluations of the differential equations function. +132 * <p> +133 * The number of evaluations corresponds to the last call to the +134 * <code>integrate</code> method. It is 0 if the method has not been called yet. +135 * </p> +136 * @return number of evaluations of the differential equations function +137 */ +138 int getEvaluations(); +139 +140 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/SecondOrderDifferentialEquations.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/SecondOrderDifferentialEquations.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,133 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode; +019 +020 /** This interface represents a second order differential equations set. +021 +022 * <p>This interface should be implemented by all real second order +023 * differential equation problems before they can be handled by the +024 * integrators {@link SecondOrderIntegrator#integrate} method.</p> +025 * +026 * <p>A second order differential equations problem, as seen by an +027 * integrator is the second time derivative <code>d2Y/dt^2</code> of a +028 * state vector <code>Y</code>, both being one dimensional +029 * arrays. From the integrator point of view, this derivative depends +030 * only on the current time <code>t</code>, on the state vector +031 * <code>Y</code> and on the first time derivative of the state +032 * vector.</p> +033 * +034 * <p>For real problems, the derivative depends also on parameters +035 * that do not belong to the state vector (dynamical model constants +036 * for example). These constants are completely outside of the scope +037 * of this interface, the classes that implement it are allowed to +038 * handle them as they want.</p> +039 * +040 * @see SecondOrderIntegrator +041 * @see FirstOrderConverter +042 * @see FirstOrderDifferentialEquations +043 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +044 * @since 1.2 +045 */ +046 +047 public interface SecondOrderDifferentialEquations { +048 +049 /** Get the dimension of the problem. +050 * @return dimension of the problem +051 */ +052 int getDimension(); +053 +054 /** Get the current time derivative of the state vector. +055 * @param t current value of the independent <I>time</I> variable +056 * @param y array containing the current value of the state vector +057 * @param yDot array containing the current value of the first derivative +058 * of the state vector +059 * @param yDDot placeholder array where to put the second time derivative +060 * of the state vector +061 * @throws DerivativeException this exception is propagated to the caller if the +062 * underlying user function triggers one +063 */ +064 void computeSecondDerivatives(double t, double[] y, double[] yDot, +065 double[] yDDot) throws DerivativeException; +066 +067 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/SecondOrderIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/SecondOrderIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,124 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode; +019 +020 +021 /** This interface represents a second order integrator for +022 * differential equations. +023 * +024 * <p>The classes which are devoted to solve second order differential +025 * equations should implement this interface. The problems which can +026 * be handled should implement the {@link +027 * SecondOrderDifferentialEquations} interface.</p> +028 * +029 * @see SecondOrderDifferentialEquations +030 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +031 * @since 1.2 +032 */ +033 +034 public interface SecondOrderIntegrator extends ODEIntegrator { +035 +036 /** Integrate the differential equations up to the given time +037 * @param equations differential equations to integrate +038 * @param t0 initial time +039 * @param y0 initial value of the state vector at t0 +040 * @param yDot0 initial value of the first derivative of the state +041 * vector at t0 +042 * @param t target time for the integration +043 * (can be set to a value smaller thant <code>t0</code> for backward integration) +044 * @param y placeholder where to put the state vector at each +045 * successful step (and hence at the end of integration), can be the +046 * same object as y0 +047 * @param yDot placeholder where to put the first derivative of +048 * the state vector at time t, can be the same object as yDot0 +049 * @throws IntegratorException if the integrator cannot perform integration +050 * @throws DerivativeException this exception is propagated to the caller if the +051 * underlying user function triggers one +052 */ +053 void integrate(SecondOrderDifferentialEquations equations, +054 double t0, double[] y0, double[] yDot0, +055 double t, double[] y, double[] yDot) +056 throws DerivativeException, IntegratorException; +057 +058 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/events/CombinedEventsManager.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/events/CombinedEventsManager.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,313 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.events; +019 +020 import java.util.ArrayList; +021 import java.util.Collection; +022 import java.util.Collections; +023 import java.util.List; +024 +025 import org.apache.commons.math.ConvergenceException; +026 import org.apache.commons.math.ode.DerivativeException; +027 import org.apache.commons.math.ode.IntegratorException; +028 import org.apache.commons.math.ode.sampling.StepInterpolator; +029 +030 /** This class manages several {@link EventHandler event handlers} during integration. +031 * +032 * @see EventHandler +033 * @see EventState +034 * @version $Revision: 786881 $ $Date: 2009-06-20 14:53:08 -0400 (Sat, 20 Jun 2009) $ +035 * @since 1.2 +036 */ +037 +038 public class CombinedEventsManager { +039 +040 /** Events states. */ +041 private final List<EventState> states; +042 +043 /** First active event. */ +044 private EventState first; +045 +046 /** Initialization indicator. */ +047 private boolean initialized; +048 +049 /** Simple constructor. +050 * Create an empty manager +051 */ +052 public CombinedEventsManager() { +053 states = new ArrayList<EventState>(); +054 first = null; +055 initialized = false; +056 } +057 +058 /** Add an events handler. +059 * @param handler event handler +060 * @param maxCheckInterval maximal time interval between events +061 * checks (this interval prevents missing sign changes in +062 * case the integration steps becomes very large) +063 * @param convergence convergence threshold in the event time search +064 * @param maxIterationCount upper limit of the iteration count in +065 * the event time search +066 * @see #getEventsHandlers() +067 * @see #clearEventsHandlers() +068 */ +069 public void addEventHandler(final EventHandler handler, final double maxCheckInterval, +070 final double convergence, final int maxIterationCount) { +071 states.add(new EventState(handler, maxCheckInterval, +072 convergence, maxIterationCount)); +073 } +074 +075 /** Get all the events handlers that have been added to the manager. +076 * @return an unmodifiable collection of the added event handlers +077 * @see #addEventHandler(EventHandler, double, double, int) +078 * @see #clearEventsHandlers() +079 * @see #getEventsStates() +080 */ +081 public Collection<EventHandler> getEventsHandlers() { +082 final List<EventHandler> list = new ArrayList<EventHandler>(); +083 for (EventState state : states) { +084 list.add(state.getEventHandler()); +085 } +086 return Collections.unmodifiableCollection(list); +087 } +088 +089 /** Remove all the events handlers that have been added to the manager. +090 * @see #addEventHandler(EventHandler, double, double, int) +091 * @see #getEventsHandlers() +092 */ +093 public void clearEventsHandlers() { +094 states.clear(); +095 } +096 +097 /** Get all the events state wrapping the handlers that have been added to the manager. +098 * @return a collection of the events states +099 * @see #getEventsHandlers() +100 */ +101 public Collection<EventState> getEventsStates() { +102 return states; +103 } +104 +105 /** Check if the manager does not manage any event handlers. +106 * @return true if manager is empty +107 */ +108 public boolean isEmpty() { +109 return states.isEmpty(); +110 } +111 +112 /** Evaluate the impact of the proposed step on all managed +113 * event handlers. +114 * @param interpolator step interpolator for the proposed step +115 * @return true if at least one event handler triggers an event +116 * before the end of the proposed step (this implies the step should +117 * be rejected) +118 * @exception DerivativeException if the interpolator fails to +119 * compute the function somewhere within the step +120 * @exception IntegratorException if an event cannot be located +121 */ +122 public boolean evaluateStep(final StepInterpolator interpolator) +123 throws DerivativeException, IntegratorException { +124 +125 try { +126 +127 first = null; +128 if (states.isEmpty()) { +129 // there is nothing to do, return now to avoid setting the +130 // interpolator time (and hence avoid unneeded calls to the +131 // user function due to interpolator finalization) +132 return false; +133 } +134 +135 if (! initialized) { +136 +137 // initialize the events states +138 final double t0 = interpolator.getPreviousTime(); +139 interpolator.setInterpolatedTime(t0); +140 final double [] y = interpolator.getInterpolatedState(); +141 for (EventState state : states) { +142 state.reinitializeBegin(t0, y); +143 } +144 +145 initialized = true; +146 +147 } +148 +149 // check events occurrence +150 for (EventState state : states) { +151 +152 if (state.evaluateStep(interpolator)) { +153 if (first == null) { +154 first = state; +155 } else { +156 if (interpolator.isForward()) { +157 if (state.getEventTime() < first.getEventTime()) { +158 first = state; +159 } +160 } else { +161 if (state.getEventTime() > first.getEventTime()) { +162 first = state; +163 } +164 } +165 } +166 } +167 +168 } +169 +170 return first != null; +171 +172 } catch (EventException se) { +173 throw new IntegratorException(se); +174 } catch (ConvergenceException ce) { +175 throw new IntegratorException(ce); +176 } +177 +178 } +179 +180 /** Get the occurrence time of the first event triggered in the +181 * last evaluated step. +182 * @return occurrence time of the first event triggered in the last +183 * evaluated step, or </code>Double.NaN</code> if no event is +184 * triggered +185 */ +186 public double getEventTime() { +187 return (first == null) ? Double.NaN : first.getEventTime(); +188 } +189 +190 /** Inform the event handlers that the step has been accepted +191 * by the integrator. +192 * @param t value of the independent <i>time</i> variable at the +193 * end of the step +194 * @param y array containing the current value of the state vector +195 * at the end of the step +196 * @exception IntegratorException if the value of one of the +197 * events states cannot be evaluated +198 */ +199 public void stepAccepted(final double t, final double[] y) +200 throws IntegratorException { +201 try { +202 for (EventState state : states) { +203 state.stepAccepted(t, y); +204 } +205 } catch (EventException se) { +206 throw new IntegratorException(se); +207 } +208 } +209 +210 /** Check if the integration should be stopped at the end of the +211 * current step. +212 * @return true if the integration should be stopped +213 */ +214 public boolean stop() { +215 for (EventState state : states) { +216 if (state.stop()) { +217 return true; +218 } +219 } +220 return false; +221 } +222 +223 /** Let the event handlers reset the state if they want. +224 * @param t value of the independent <i>time</i> variable at the +225 * beginning of the next step +226 * @param y array were to put the desired state vector at the beginning +227 * of the next step +228 * @return true if the integrator should reset the derivatives too +229 * @exception IntegratorException if one of the events states +230 * that should reset the state fails to do it +231 */ +232 public boolean reset(final double t, final double[] y) +233 throws IntegratorException { +234 try { +235 boolean resetDerivatives = false; +236 for (EventState state : states) { +237 if (state.reset(t, y)) { +238 resetDerivatives = true; +239 } +240 } +241 return resetDerivatives; +242 } catch (EventException se) { +243 throw new IntegratorException(se); +244 } +245 } +246 +247 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/events/EventException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/events/EventException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,116 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.events; +019 +020 import org.apache.commons.math.MathException; +021 +022 /** +023 * This exception is made available to users to report +024 * the error conditions that are triggered by {@link EventHandler} +025 * @version $Revision: 746578 $ $Date: 2009-02-21 15:01:14 -0500 (Sat, 21 Feb 2009) $ +026 * @since 2.0 +027 */ +028 public class EventException extends MathException { +029 +030 /** Serialization UID. */ +031 private static final long serialVersionUID = -898215297400035290L; +032 +033 /** Simple constructor. +034 * Build an exception by translating and formating a message +035 * @param specifier format specifier (to be translated) +036 * @param parts to insert in the format (no translation) +037 */ +038 public EventException(final String specifier, final Object ... parts) { +039 super(specifier, parts); +040 } +041 +042 /** +043 * Create an exception with a given root cause. +044 * @param cause the exception or error that caused this exception to be thrown +045 */ +046 public EventException(final Throwable cause) { +047 super(cause); +048 } +049 +050 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/events/EventHandler.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/events/EventHandler.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,249 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.events; +019 +020 /** This interface represents a handler for discrete events triggered +021 * during ODE integration. +022 * +023 * <p>Some events can be triggered at discrete times as an ODE problem +024 * is solved. This occurs for example when the integration process +025 * should be stopped as some state is reached (G-stop facility) when the +026 * precise date is unknown a priori, or when the derivatives have +027 * discontinuities, or simply when the user wants to monitor some +028 * states boundaries crossings. +029 * </p> +030 * +031 * <p>These events are defined as occurring when a <code>g</code> +032 * switching function sign changes.</p> +033 * +034 * <p>Since events are only problem-dependent and are triggered by the +035 * independent <i>time</i> variable and the state vector, they can +036 * occur at virtually any time, unknown in advance. The integrators will +037 * take care to avoid sign changes inside the steps, they will reduce +038 * the step size when such an event is detected in order to put this +039 * event exactly at the end of the current step. This guarantees that +040 * step interpolation (which always has a one step scope) is relevant +041 * even in presence of discontinuities. This is independent from the +042 * stepsize control provided by integrators that monitor the local +043 * error (this event handling feature is available for all integrators, +044 * including fixed step ones).</p> +045 * +046 * @version $Revision: 902214 $ $Date: 2010-01-22 13:40:28 -0500 (Fri, 22 Jan 2010) $ +047 * @since 1.2 +048 */ +049 +050 public interface EventHandler { +051 +052 /** Stop indicator. +053 * <p>This value should be used as the return value of the {@link +054 * #eventOccurred eventOccurred} method when the integration should be +055 * stopped after the event ending the current step.</p> +056 */ +057 int STOP = 0; +058 +059 /** Reset state indicator. +060 * <p>This value should be used as the return value of the {@link +061 * #eventOccurred eventOccurred} method when the integration should +062 * go on after the event ending the current step, with a new state +063 * vector (which will be retrieved thanks to the {@link #resetState +064 * resetState} method).</p> +065 */ +066 int RESET_STATE = 1; +067 +068 /** Reset derivatives indicator. +069 * <p>This value should be used as the return value of the {@link +070 * #eventOccurred eventOccurred} method when the integration should +071 * go on after the event ending the current step, with a new derivatives +072 * vector (which will be retrieved thanks to the {@link +073 * org.apache.commons.math.ode.FirstOrderDifferentialEquations#computeDerivatives} +074 * method).</p> +075 */ +076 int RESET_DERIVATIVES = 2; +077 +078 /** Continue indicator. +079 * <p>This value should be used as the return value of the {@link +080 * #eventOccurred eventOccurred} method when the integration should go +081 * on after the event ending the current step.</p> +082 */ +083 int CONTINUE = 3; +084 +085 /** Compute the value of the switching function. +086 +087 * <p>The discrete events are generated when the sign of this +088 * switching function changes. The integrator will take care to change +089 * the stepsize in such a way these events occur exactly at step boundaries. +090 * The switching function must be continuous in its roots neighborhood +091 * (but not necessarily smooth), as the integrator will need to find its +092 * roots to locate precisely the events.</p> +093 +094 * @param t current value of the independent <i>time</i> variable +095 * @param y array containing the current value of the state vector +096 * @return value of the g switching function +097 * @exception EventException if the switching function cannot be evaluated +098 */ +099 double g(double t, double[] y) throws EventException; +100 +101 /** Handle an event and choose what to do next. +102 +103 * <p>This method is called when the integrator has accepted a step +104 * ending exactly on a sign change of the function, just <em>before</em> +105 * the step handler itself is called (see below for scheduling). It +106 * allows the user to update his internal data to acknowledge the fact +107 * the event has been handled (for example setting a flag in the {@link +108 * org.apache.commons.math.ode.FirstOrderDifferentialEquations +109 * differential equations} to switch the derivatives computation in +110 * case of discontinuity), or to direct the integrator to either stop +111 * or continue integration, possibly with a reset state or derivatives.</p> +112 +113 * <ul> +114 * <li>if {@link #STOP} is returned, the step handler will be called +115 * with the <code>isLast</code> flag of the {@link +116 * org.apache.commons.math.ode.sampling.StepHandler#handleStep handleStep} +117 * method set to true and the integration will be stopped,</li> +118 * <li>if {@link #RESET_STATE} is returned, the {@link #resetState +119 * resetState} method will be called once the step handler has +120 * finished its task, and the integrator will also recompute the +121 * derivatives,</li> +122 * <li>if {@link #RESET_DERIVATIVES} is returned, the integrator +123 * will recompute the derivatives, +124 * <li>if {@link #CONTINUE} is returned, no specific action will +125 * be taken (apart from having called this method) and integration +126 * will continue.</li> +127 * </ul> +128 +129 * <p>The scheduling between this method and the {@link +130 * org.apache.commons.math.ode.sampling.StepHandler StepHandler} method {@link +131 * org.apache.commons.math.ode.sampling.StepHandler#handleStep( +132 * org.apache.commons.math.ode.sampling.StepInterpolator, boolean) +133 * handleStep(interpolator, isLast)} is to call this method first and +134 * <code>handleStep</code> afterwards. This scheduling allows the integrator to +135 * pass <code>true</code> as the <code>isLast</code> parameter to the step +136 * handler to make it aware the step will be the last one if this method +137 * returns {@link #STOP}. As the interpolator may be used to navigate back +138 * throughout the last step (as {@link +139 * org.apache.commons.math.ode.sampling.StepNormalizer StepNormalizer} +140 * does for example), user code called by this method and user +141 * code called by step handlers may experience apparently out of order values +142 * of the independent time variable. As an example, if the same user object +143 * implements both this {@link EventHandler EventHandler} interface and the +144 * {@link org.apache.commons.math.ode.sampling.FixedStepHandler FixedStepHandler} +145 * interface, a <em>forward</em> integration may call its +146 * <code>eventOccurred</code> method with t = 10 first and call its +147 * <code>handleStep</code> method with t = 9 afterwards. Such out of order +148 * calls are limited to the size of the integration step for {@link +149 * org.apache.commons.math.ode.sampling.StepHandler variable step handlers} and +150 * to the size of the fixed step for {@link +151 * org.apache.commons.math.ode.sampling.FixedStepHandler fixed step handlers}.</p> +152 +153 * @param t current value of the independent <i>time</i> variable +154 * @param y array containing the current value of the state vector +155 * @param increasing if true, the value of the switching function increases +156 * when times increases around event (note that increase is measured with respect +157 * to physical time, not with respect to integration which may go backward in time) +158 * @return indication of what the integrator should do next, this +159 * value must be one of {@link #STOP}, {@link #RESET_STATE}, +160 * {@link #RESET_DERIVATIVES} or {@link #CONTINUE} +161 * @exception EventException if the event occurrence triggers an error +162 */ +163 int eventOccurred(double t, double[] y, boolean increasing) throws EventException; +164 +165 /** Reset the state prior to continue the integration. +166 +167 * <p>This method is called after the step handler has returned and +168 * before the next step is started, but only when {@link +169 * #eventOccurred} has itself returned the {@link #RESET_STATE} +170 * indicator. It allows the user to reset the state vector for the +171 * next step, without perturbing the step handler of the finishing +172 * step. If the {@link #eventOccurred} never returns the {@link +173 * #RESET_STATE} indicator, this function will never be called, and it is +174 * safe to leave its body empty.</p> +175 +176 * @param t current value of the independent <i>time</i> variable +177 * @param y array containing the current value of the state vector +178 * the new state should be put in the same array +179 * @exception EventException if the state cannot be reseted +180 */ +181 void resetState(double t, double[] y) throws EventException; +182 +183 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/events/EventState.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/events/EventState.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,411 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.events; +019 +020 import org.apache.commons.math.ConvergenceException; +021 import org.apache.commons.math.FunctionEvaluationException; +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.analysis.UnivariateRealFunction; +024 import org.apache.commons.math.analysis.solvers.BrentSolver; +025 import org.apache.commons.math.ode.DerivativeException; +026 import org.apache.commons.math.ode.sampling.StepInterpolator; +027 +028 /** This class handles the state for one {@link EventHandler +029 * event handler} during integration steps. +030 * +031 * <p>Each time the integrator proposes a step, the event handler +032 * switching function should be checked. This class handles the state +033 * of one handler during one integration step, with references to the +034 * state at the end of the preceding step. This information is used to +035 * decide if the handler should trigger an event or not during the +036 * proposed step (and hence the step should be reduced to ensure the +037 * event occurs at a bound rather than inside the step).</p> +038 * +039 * @version $Revision: 889006 $ $Date: 2009-12-09 17:46:36 -0500 (Wed, 09 Dec 2009) $ +040 * @since 1.2 +041 */ +042 public class EventState { +043 +044 /** Event handler. */ +045 private final EventHandler handler; +046 +047 /** Maximal time interval between events handler checks. */ +048 private final double maxCheckInterval; +049 +050 /** Convergence threshold for event localization. */ +051 private final double convergence; +052 +053 /** Upper limit in the iteration count for event localization. */ +054 private final int maxIterationCount; +055 +056 /** Time at the beginning of the step. */ +057 private double t0; +058 +059 /** Value of the events handler at the beginning of the step. */ +060 private double g0; +061 +062 /** Simulated sign of g0 (we cheat when crossing events). */ +063 private boolean g0Positive; +064 +065 /** Indicator of event expected during the step. */ +066 private boolean pendingEvent; +067 +068 /** Occurrence time of the pending event. */ +069 private double pendingEventTime; +070 +071 /** Occurrence time of the previous event. */ +072 private double previousEventTime; +073 +074 /** Integration direction. */ +075 private boolean forward; +076 +077 /** Variation direction around pending event. +078 * (this is considered with respect to the integration direction) +079 */ +080 private boolean increasing; +081 +082 /** Next action indicator. */ +083 private int nextAction; +084 +085 /** Simple constructor. +086 * @param handler event handler +087 * @param maxCheckInterval maximal time interval between switching +088 * function checks (this interval prevents missing sign changes in +089 * case the integration steps becomes very large) +090 * @param convergence convergence threshold in the event time search +091 * @param maxIterationCount upper limit of the iteration count in +092 * the event time search +093 */ +094 public EventState(final EventHandler handler, final double maxCheckInterval, +095 final double convergence, final int maxIterationCount) { +096 this.handler = handler; +097 this.maxCheckInterval = maxCheckInterval; +098 this.convergence = Math.abs(convergence); +099 this.maxIterationCount = maxIterationCount; +100 +101 // some dummy values ... +102 t0 = Double.NaN; +103 g0 = Double.NaN; +104 g0Positive = true; +105 pendingEvent = false; +106 pendingEventTime = Double.NaN; +107 previousEventTime = Double.NaN; +108 increasing = true; +109 nextAction = EventHandler.CONTINUE; +110 +111 } +112 +113 /** Get the underlying event handler. +114 * @return underlying event handler +115 */ +116 public EventHandler getEventHandler() { +117 return handler; +118 } +119 +120 /** Get the maximal time interval between events handler checks. +121 * @return maximal time interval between events handler checks +122 */ +123 public double getMaxCheckInterval() { +124 return maxCheckInterval; +125 } +126 +127 /** Get the convergence threshold for event localization. +128 * @return convergence threshold for event localization +129 */ +130 public double getConvergence() { +131 return convergence; +132 } +133 +134 /** Get the upper limit in the iteration count for event localization. +135 * @return upper limit in the iteration count for event localization +136 */ +137 public int getMaxIterationCount() { +138 return maxIterationCount; +139 } +140 +141 /** Reinitialize the beginning of the step. +142 * @param tStart value of the independent <i>time</i> variable at the +143 * beginning of the step +144 * @param yStart array containing the current value of the state vector +145 * at the beginning of the step +146 * @exception EventException if the event handler +147 * value cannot be evaluated at the beginning of the step +148 */ +149 public void reinitializeBegin(final double tStart, final double[] yStart) +150 throws EventException { +151 t0 = tStart; +152 g0 = handler.g(tStart, yStart); +153 g0Positive = g0 >= 0; +154 } +155 +156 /** Evaluate the impact of the proposed step on the event handler. +157 * @param interpolator step interpolator for the proposed step +158 * @return true if the event handler triggers an event before +159 * the end of the proposed step (this implies the step should be +160 * rejected) +161 * @exception DerivativeException if the interpolator fails to +162 * compute the switching function somewhere within the step +163 * @exception EventException if the switching function +164 * cannot be evaluated +165 * @exception ConvergenceException if an event cannot be located +166 */ +167 public boolean evaluateStep(final StepInterpolator interpolator) +168 throws DerivativeException, EventException, ConvergenceException { +169 +170 try { +171 +172 forward = interpolator.isForward(); +173 final double t1 = interpolator.getCurrentTime(); +174 final int n = Math.max(1, (int) Math.ceil(Math.abs(t1 - t0) / maxCheckInterval)); +175 final double h = (t1 - t0) / n; +176 +177 double ta = t0; +178 double ga = g0; +179 double tb = t0 + (interpolator.isForward() ? convergence : -convergence); +180 for (int i = 0; i < n; ++i) { +181 +182 // evaluate handler value at the end of the substep +183 tb += h; +184 interpolator.setInterpolatedTime(tb); +185 final double gb = handler.g(tb, interpolator.getInterpolatedState()); +186 +187 // check events occurrence +188 if (g0Positive ^ (gb >= 0)) { +189 // there is a sign change: an event is expected during this step +190 +191 if (ga * gb > 0) { +192 // this is a corner case: +193 // - there was an event near ta, +194 // - there is another event between ta and tb +195 // - when ta was computed, convergence was reached on the "wrong side" of the interval +196 // this implies that the real sign of ga is the same as gb, so we need to slightly +197 // shift ta to make sure ga and gb get opposite signs and the solver won't complain +198 // about bracketing +199 final double epsilon = (forward ? 0.25 : -0.25) * convergence; +200 for (int k = 0; (k < 4) && (ga * gb > 0); ++k) { +201 ta += epsilon; +202 interpolator.setInterpolatedTime(ta); +203 ga = handler.g(ta, interpolator.getInterpolatedState()); +204 } +205 if (ga * gb > 0) { +206 // this should never happen +207 throw MathRuntimeException.createInternalError(null); +208 } +209 } +210 +211 // variation direction, with respect to the integration direction +212 increasing = gb >= ga; +213 +214 final UnivariateRealFunction f = new UnivariateRealFunction() { +215 public double value(final double t) throws FunctionEvaluationException { +216 try { +217 interpolator.setInterpolatedTime(t); +218 return handler.g(t, interpolator.getInterpolatedState()); +219 } catch (DerivativeException e) { +220 throw new FunctionEvaluationException(e, t); +221 } catch (EventException e) { +222 throw new FunctionEvaluationException(e, t); +223 } +224 } +225 }; +226 final BrentSolver solver = new BrentSolver(); +227 solver.setAbsoluteAccuracy(convergence); +228 solver.setMaximalIterationCount(maxIterationCount); +229 final double root = (ta <= tb) ? solver.solve(f, ta, tb) : solver.solve(f, tb, ta); +230 if ((Math.abs(root - ta) <= convergence) && +231 (Math.abs(root - previousEventTime) <= convergence)) { +232 // we have either found nothing or found (again ?) a past event, we simply ignore it +233 ta = tb; +234 ga = gb; +235 } else if (Double.isNaN(previousEventTime) || +236 (Math.abs(previousEventTime - root) > convergence)) { +237 pendingEventTime = root; +238 if (pendingEvent && (Math.abs(t1 - pendingEventTime) <= convergence)) { +239 // we were already waiting for this event which was +240 // found during a previous call for a step that was +241 // rejected, this step must now be accepted since it +242 // properly ends exactly at the event occurrence +243 return false; +244 } +245 // either we were not waiting for the event or it has +246 // moved in such a way the step cannot be accepted +247 pendingEvent = true; +248 return true; +249 } +250 +251 } else { +252 // no sign change: there is no event for now +253 ta = tb; +254 ga = gb; +255 } +256 +257 } +258 +259 // no event during the whole step +260 pendingEvent = false; +261 pendingEventTime = Double.NaN; +262 return false; +263 +264 } catch (FunctionEvaluationException e) { +265 final Throwable cause = e.getCause(); +266 if ((cause != null) && (cause instanceof DerivativeException)) { +267 throw (DerivativeException) cause; +268 } else if ((cause != null) && (cause instanceof EventException)) { +269 throw (EventException) cause; +270 } +271 throw new EventException(e); +272 } +273 +274 } +275 +276 /** Get the occurrence time of the event triggered in the current +277 * step. +278 * @return occurrence time of the event triggered in the current +279 * step. +280 */ +281 public double getEventTime() { +282 return pendingEventTime; +283 } +284 +285 /** Acknowledge the fact the step has been accepted by the integrator. +286 * @param t value of the independent <i>time</i> variable at the +287 * end of the step +288 * @param y array containing the current value of the state vector +289 * at the end of the step +290 * @exception EventException if the value of the event +291 * handler cannot be evaluated +292 */ +293 public void stepAccepted(final double t, final double[] y) +294 throws EventException { +295 +296 t0 = t; +297 g0 = handler.g(t, y); +298 +299 if (pendingEvent) { +300 // force the sign to its value "just after the event" +301 previousEventTime = t; +302 g0Positive = increasing; +303 nextAction = handler.eventOccurred(t, y, !(increasing ^ forward)); +304 } else { +305 g0Positive = g0 >= 0; +306 nextAction = EventHandler.CONTINUE; +307 } +308 } +309 +310 /** Check if the integration should be stopped at the end of the +311 * current step. +312 * @return true if the integration should be stopped +313 */ +314 public boolean stop() { +315 return nextAction == EventHandler.STOP; +316 } +317 +318 /** Let the event handler reset the state if it wants. +319 * @param t value of the independent <i>time</i> variable at the +320 * beginning of the next step +321 * @param y array were to put the desired state vector at the beginning +322 * of the next step +323 * @return true if the integrator should reset the derivatives too +324 * @exception EventException if the state cannot be reseted by the event +325 * handler +326 */ +327 public boolean reset(final double t, final double[] y) +328 throws EventException { +329 +330 if (! pendingEvent) { +331 return false; +332 } +333 +334 if (nextAction == EventHandler.RESET_STATE) { +335 handler.resetState(t, y); +336 } +337 pendingEvent = false; +338 pendingEventTime = Double.NaN; +339 +340 return (nextAction == EventHandler.RESET_STATE) || +341 (nextAction == EventHandler.RESET_DERIVATIVES); +342 +343 } +344 +345 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/jacobians/EventHandlerWithJacobians.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/jacobians/EventHandlerWithJacobians.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,290 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.jacobians; +019 +020 import org.apache.commons.math.ode.events.EventException; +021 +022 /** This interface represents a handler for discrete events triggered +023 * during ODE integration. +024 * +025 * <p>Some events can be triggered at discrete times as an ODE problem +026 * is solved. This occurs for example when the integration process +027 * should be stopped as some state is reached (G-stop facility) when the +028 * precise date is unknown a priori, or when the derivatives have +029 * discontinuities, or simply when the user wants to monitor some +030 * states boundaries crossings. +031 * </p> +032 * +033 * <p>These events are defined as occurring when a <code>g</code> +034 * switching function sign changes.</p> +035 * +036 * <p>Since events are only problem-dependent and are triggered by the +037 * independent <i>time</i> variable and the state vector, they can +038 * occur at virtually any time, unknown in advance. The integrators will +039 * take care to avoid sign changes inside the steps, they will reduce +040 * the step size when such an event is detected in order to put this +041 * event exactly at the end of the current step. This guarantees that +042 * step interpolation (which always has a one step scope) is relevant +043 * even in presence of discontinuities. This is independent from the +044 * stepsize control provided by integrators that monitor the local +045 * error (this event handling feature is available for all integrators, +046 * including fixed step ones).</p> +047 * +048 * <p>Note that is is possible to register a {@link +049 * org.apache.commons.math.ode.events.EventHandler classical event handler} +050 * in the low level integrator used to build a {@link FirstOrderIntegratorWithJacobians} +051 * rather than implementing this class. The event handlers registered at low level +052 * will see the big compound state whether the event handlers defined by this interface +053 * see the original state, and its jacobians in separate arrays.</p> +054 * +055 * <p>The compound state is guaranteed to contain the original state in the first +056 * elements, followed by the jacobian with respect to initial state (in row order), +057 * followed by the jacobian with respect to parameters (in row order). If for example +058 * the original state dimension is 6 and there are 3 parameters, the compound state will +059 * be a 60 elements array. The first 6 elements will be the original state, the next 36 +060 * elements will be the jacobian with respect to initial state, and the remaining 18 elements +061 * will be the jacobian with respect to parameters.</p> +062 * +063 * <p>Dealing with low level event handlers is cumbersome if one really needs the jacobians +064 * in these methods, but it also prevents many data being copied back and forth between +065 * state and jacobians on one side and compound state on the other side. So for performance +066 * reasons, it is recommended to use this interface <em>only</em> if jacobians are really +067 * needed and to use lower level handlers if only state is needed.</p> +068 * +069 * @version $Revision: 920131 $ $Date: 2010-03-07 17:19:18 -0500 (Sun, 07 Mar 2010) $ +070 * @since 2.1 +071 */ +072 +073 public interface EventHandlerWithJacobians { +074 +075 /** Stop indicator. +076 * <p>This value should be used as the return value of the {@link +077 * #eventOccurred eventOccurred} method when the integration should be +078 * stopped after the event ending the current step.</p> +079 */ +080 int STOP = 0; +081 +082 /** Reset state indicator. +083 * <p>This value should be used as the return value of the {@link +084 * #eventOccurred eventOccurred} method when the integration should +085 * go on after the event ending the current step, with a new state +086 * vector (which will be retrieved thanks to the {@link #resetState +087 * resetState} method).</p> +088 */ +089 int RESET_STATE = 1; +090 +091 /** Reset derivatives indicator. +092 * <p>This value should be used as the return value of the {@link +093 * #eventOccurred eventOccurred} method when the integration should +094 * go on after the event ending the current step, with a new derivatives +095 * vector (which will be retrieved thanks to the {@link +096 * org.apache.commons.math.ode.FirstOrderDifferentialEquations#computeDerivatives} +097 * method).</p> +098 */ +099 int RESET_DERIVATIVES = 2; +100 +101 /** Continue indicator. +102 * <p>This value should be used as the return value of the {@link +103 * #eventOccurred eventOccurred} method when the integration should go +104 * on after the event ending the current step.</p> +105 */ +106 int CONTINUE = 3; +107 +108 /** Compute the value of the switching function. +109 +110 * <p>The discrete events are generated when the sign of this +111 * switching function changes. The integrator will take care to change +112 * the stepsize in such a way these events occur exactly at step boundaries. +113 * The switching function must be continuous in its roots neighborhood +114 * (but not necessarily smooth), as the integrator will need to find its +115 * roots to locate precisely the events.</p> +116 +117 * @param t current value of the independent <i>time</i> variable +118 * @param y array containing the current value of the state vector +119 * @param dydy0 array containing the current value of the jacobian of +120 * the state vector with respect to initial state +121 * @param dydp array containing the current value of the jacobian of +122 * the state vector with respect to parameters +123 * @return value of the g switching function +124 * @exception EventException if the switching function cannot be evaluated +125 */ +126 double g(double t, double[] y, double[][] dydy0, double[][] dydp) +127 throws EventException; +128 +129 /** Handle an event and choose what to do next. +130 +131 * <p>This method is called when the integrator has accepted a step +132 * ending exactly on a sign change of the function, just <em>before</em> +133 * the step handler itself is called (see below for scheduling). It +134 * allows the user to update his internal data to acknowledge the fact +135 * the event has been handled (for example setting a flag in the {@link +136 * org.apache.commons.math.ode.jacobians.ODEWithJacobians +137 * differential equations} to switch the derivatives computation in +138 * case of discontinuity), or to direct the integrator to either stop +139 * or continue integration, possibly with a reset state or derivatives.</p> +140 +141 * <ul> +142 * <li>if {@link #STOP} is returned, the step handler will be called +143 * with the <code>isLast</code> flag of the {@link +144 * org.apache.commons.math.ode.jacobians.StepHandlerWithJacobians#handleStep( +145 * StepInterpolatorWithJacobians, boolean) handleStep} method set to true and +146 * the integration will be stopped,</li> +147 * <li>if {@link #RESET_STATE} is returned, the {@link #resetState +148 * resetState} method will be called once the step handler has +149 * finished its task, and the integrator will also recompute the +150 * derivatives,</li> +151 * <li>if {@link #RESET_DERIVATIVES} is returned, the integrator +152 * will recompute the derivatives, +153 * <li>if {@link #CONTINUE} is returned, no specific action will +154 * be taken (apart from having called this method) and integration +155 * will continue.</li> +156 * </ul> +157 +158 * <p>The scheduling between this method and the {@link +159 * org.apache.commons.math.ode.jacobians.StepHandlerWithJacobians +160 * StepHandlerWithJacobians} method {@link +161 * org.apache.commons.math.ode.jacobians.StepHandlerWithJacobians#handleStep( +162 * StepInterpolatorWithJacobians, boolean) handleStep(interpolator, isLast)} +163 * is to call this method first and <code>handleStep</code> afterwards. This +164 * scheduling allows the integrator to pass <code>true</code> as the +165 * <code>isLast</code> parameter to the step handler to make it aware the step +166 * will be the last one if this method returns {@link #STOP}. As the +167 * interpolator may be used to navigate back throughout the last step (as {@link +168 * org.apache.commons.math.ode.sampling.StepNormalizer StepNormalizer} +169 * does for example), user code called by this method and user +170 * code called by step handlers may experience apparently out of order values +171 * of the independent time variable. As an example, if the same user object +172 * implements both this {@link EventHandlerWithJacobians EventHandler} interface and the +173 * {@link org.apache.commons.math.ode.sampling.FixedStepHandler FixedStepHandler} +174 * interface, a <em>forward</em> integration may call its +175 * <code>eventOccurred</code> method with t = 10 first and call its +176 * <code>handleStep</code> method with t = 9 afterwards. Such out of order +177 * calls are limited to the size of the integration step for {@link +178 * org.apache.commons.math.ode.sampling.StepHandler variable step handlers} and +179 * to the size of the fixed step for {@link +180 * org.apache.commons.math.ode.sampling.FixedStepHandler fixed step handlers}.</p> +181 +182 * @param t current value of the independent <i>time</i> variable +183 * @param y array containing the current value of the state vector +184 * @param dydy0 array containing the current value of the jacobian of +185 * the state vector with respect to initial state +186 * @param dydp array containing the current value of the jacobian of +187 * the state vector with respect to parameters +188 * @param increasing if true, the value of the switching function increases +189 * when times increases around event (note that increase is measured with respect +190 * to physical time, not with respect to integration which may go backward in time) +191 * @return indication of what the integrator should do next, this +192 * value must be one of {@link #STOP}, {@link #RESET_STATE}, +193 * {@link #RESET_DERIVATIVES} or {@link #CONTINUE} +194 * @exception EventException if the event occurrence triggers an error +195 */ +196 int eventOccurred(double t, double[] y, double[][] dydy0, double[][] dydp, +197 boolean increasing) throws EventException; +198 +199 /** Reset the state prior to continue the integration. +200 +201 * <p>This method is called after the step handler has returned and +202 * before the next step is started, but only when {@link +203 * #eventOccurred} has itself returned the {@link #RESET_STATE} +204 * indicator. It allows the user to reset the state vector for the +205 * next step, without perturbing the step handler of the finishing +206 * step. If the {@link #eventOccurred} never returns the {@link +207 * #RESET_STATE} indicator, this function will never be called, and it is +208 * safe to leave its body empty.</p> +209 +210 * @param t current value of the independent <i>time</i> variable +211 * @param y array containing the current value of the state vector +212 * the new state should be put in the same array +213 * @param dydy0 array containing the current value of the jacobian of +214 * the state vector with respect to initial state, the new jacobian +215 * should be put in the same array +216 * @param dydp array containing the current value of the jacobian of +217 * the state vector with respect to parameters, the new jacobian +218 * should be put in the same array +219 * @exception EventException if the state cannot be reseted +220 */ +221 void resetState(double t, double[] y, double[][] dydy0, double[][] dydp) +222 throws EventException; +223 +224 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobians.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/jacobians/FirstOrderIntegratorWithJacobians.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,957 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.jacobians; +019 +020 import java.io.IOException; +021 import java.io.ObjectInput; +022 import java.io.ObjectOutput; +023 import java.lang.reflect.Array; +024 import java.util.ArrayList; +025 import java.util.Collection; +026 +027 import org.apache.commons.math.MathRuntimeException; +028 import org.apache.commons.math.MaxEvaluationsExceededException; +029 import org.apache.commons.math.ode.DerivativeException; +030 import org.apache.commons.math.ode.FirstOrderDifferentialEquations; +031 import org.apache.commons.math.ode.FirstOrderIntegrator; +032 import org.apache.commons.math.ode.IntegratorException; +033 import org.apache.commons.math.ode.events.EventException; +034 import org.apache.commons.math.ode.events.EventHandler; +035 import org.apache.commons.math.ode.sampling.StepHandler; +036 import org.apache.commons.math.ode.sampling.StepInterpolator; +037 +038 /** This class enhances a first order integrator for differential equations to +039 * compute also partial derivatives of the solution with respect to initial state +040 * and parameters. +041 * <p>In order to compute both the state and its derivatives, the ODE problem +042 * is extended with jacobians of the raw ODE and the variational equations are +043 * added to form a new compound problem of higher dimension. If the original ODE +044 * problem has dimension n and there are p parameters, the compound problem will +045 * have dimension n × (1 + n + p).</p> +046 * @see ParameterizedODE +047 * @see ODEWithJacobians +048 * @version $Revision: 927342 $ $Date: 2010-03-25 06:55:55 -0400 (Thu, 25 Mar 2010) $ +049 * @since 2.1 +050 */ +051 public class FirstOrderIntegratorWithJacobians { +052 +053 /** Underlying integrator for compound problem. */ +054 private final FirstOrderIntegrator integrator; +055 +056 /** Raw equations to integrate. */ +057 private final ODEWithJacobians ode; +058 +059 /** Maximal number of evaluations allowed. */ +060 private int maxEvaluations; +061 +062 /** Number of evaluations already performed. */ +063 private int evaluations; +064 +065 /** Build an enhanced integrator using internal differentiation to compute jacobians. +066 * @param integrator underlying integrator to solve the compound problem +067 * @param ode original problem (f in the equation y' = f(t, y)) +068 * @param p parameters array (may be null if {@link +069 * ParameterizedODE#getParametersDimension() +070 * getParametersDimension()} from original problem is zero) +071 * @param hY step sizes to use for computing the jacobian df/dy, must have the +072 * same dimension as the original problem +073 * @param hP step sizes to use for computing the jacobian df/dp, must have the +074 * same dimension as the original problem parameters dimension +075 * @see #FirstOrderIntegratorWithJacobians(FirstOrderIntegrator, +076 * ODEWithJacobians) +077 */ +078 public FirstOrderIntegratorWithJacobians(final FirstOrderIntegrator integrator, +079 final ParameterizedODE ode, +080 final double[] p, final double[] hY, final double[] hP) { +081 checkDimension(ode.getDimension(), hY); +082 checkDimension(ode.getParametersDimension(), p); +083 checkDimension(ode.getParametersDimension(), hP); +084 this.integrator = integrator; +085 this.ode = new FiniteDifferencesWrapper(ode, p, hY, hP); +086 setMaxEvaluations(-1); +087 } +088 +089 /** Build an enhanced integrator using ODE builtin jacobian computation features. +090 * @param integrator underlying integrator to solve the compound problem +091 * @param ode original problem, which can compute the jacobians by itself +092 * @see #FirstOrderIntegratorWithJacobians(FirstOrderIntegrator, +093 * ParameterizedODE, double[], double[], double[]) +094 */ +095 public FirstOrderIntegratorWithJacobians(final FirstOrderIntegrator integrator, +096 final ODEWithJacobians ode) { +097 this.integrator = integrator; +098 this.ode = ode; +099 setMaxEvaluations(-1); +100 } +101 +102 /** Add a step handler to this integrator. +103 * <p>The handler will be called by the integrator for each accepted +104 * step.</p> +105 * @param handler handler for the accepted steps +106 * @see #getStepHandlers() +107 * @see #clearStepHandlers() +108 */ +109 public void addStepHandler(StepHandlerWithJacobians handler) { +110 final int n = ode.getDimension(); +111 final int k = ode.getParametersDimension(); +112 integrator.addStepHandler(new StepHandlerWrapper(handler, n, k)); +113 } +114 +115 /** Get all the step handlers that have been added to the integrator. +116 * @return an unmodifiable collection of the added events handlers +117 * @see #addStepHandler(StepHandlerWithJacobians) +118 * @see #clearStepHandlers() +119 */ +120 public Collection<StepHandlerWithJacobians> getStepHandlers() { +121 final Collection<StepHandlerWithJacobians> handlers = +122 new ArrayList<StepHandlerWithJacobians>(); +123 for (final StepHandler handler : integrator.getStepHandlers()) { +124 if (handler instanceof StepHandlerWrapper) { +125 handlers.add(((StepHandlerWrapper) handler).getHandler()); +126 } +127 } +128 return handlers; +129 } +130 +131 /** Remove all the step handlers that have been added to the integrator. +132 * @see #addStepHandler(StepHandlerWithJacobians) +133 * @see #getStepHandlers() +134 */ +135 public void clearStepHandlers() { +136 integrator.clearStepHandlers(); +137 } +138 +139 /** Add an event handler to the integrator. +140 * @param handler event handler +141 * @param maxCheckInterval maximal time interval between switching +142 * function checks (this interval prevents missing sign changes in +143 * case the integration steps becomes very large) +144 * @param convergence convergence threshold in the event time search +145 * @param maxIterationCount upper limit of the iteration count in +146 * the event time search +147 * @see #getEventHandlers() +148 * @see #clearEventHandlers() +149 */ +150 public void addEventHandler(EventHandlerWithJacobians handler, +151 double maxCheckInterval, +152 double convergence, +153 int maxIterationCount) { +154 final int n = ode.getDimension(); +155 final int k = ode.getParametersDimension(); +156 integrator.addEventHandler(new EventHandlerWrapper(handler, n, k), +157 maxCheckInterval, convergence, maxIterationCount); +158 } +159 +160 /** Get all the event handlers that have been added to the integrator. +161 * @return an unmodifiable collection of the added events handlers +162 * @see #addEventHandler(EventHandlerWithJacobians, double, double, int) +163 * @see #clearEventHandlers() +164 */ +165 public Collection<EventHandlerWithJacobians> getEventHandlers() { +166 final Collection<EventHandlerWithJacobians> handlers = +167 new ArrayList<EventHandlerWithJacobians>(); +168 for (final EventHandler handler : integrator.getEventHandlers()) { +169 if (handler instanceof EventHandlerWrapper) { +170 handlers.add(((EventHandlerWrapper) handler).getHandler()); +171 } +172 } +173 return handlers; +174 } +175 +176 /** Remove all the event handlers that have been added to the integrator. +177 * @see #addEventHandler(EventHandlerWithJacobians, double, double, int) +178 * @see #getEventHandlers() +179 */ +180 public void clearEventHandlers() { +181 integrator.clearEventHandlers(); +182 } +183 +184 /** Integrate the differential equations and the variational equations up to the given time. +185 * <p>This method solves an Initial Value Problem (IVP) and also computes the derivatives +186 * of the solution with respect to initial state and parameters. This can be used as +187 * a basis to solve Boundary Value Problems (BVP).</p> +188 * <p>Since this method stores some internal state variables made +189 * available in its public interface during integration ({@link +190 * #getCurrentSignedStepsize()}), it is <em>not</em> thread-safe.</p> +191 * @param t0 initial time +192 * @param y0 initial value of the state vector at t0 +193 * @param dY0dP initial value of the state vector derivative with respect to the +194 * parameters at t0 +195 * @param t target time for the integration +196 * (can be set to a value smaller than <code>t0</code> for backward integration) +197 * @param y placeholder where to put the state vector at each successful +198 * step (and hence at the end of integration), can be the same object as y0 +199 * @param dYdY0 placeholder where to put the state vector derivative with respect +200 * to the initial state (dy[i]/dy0[j] is in element array dYdY0[i][j]) at each successful +201 * step (and hence at the end of integration) +202 * @param dYdP placeholder where to put the state vector derivative with respect +203 * to the parameters (dy[i]/dp[j] is in element array dYdP[i][j]) at each successful +204 * step (and hence at the end of integration) +205 * @return stop time, will be the same as target time if integration reached its +206 * target, but may be different if some event handler stops it at some point. +207 * @throws IntegratorException if the integrator cannot perform integration +208 * @throws DerivativeException this exception is propagated to the caller if +209 * the underlying user function triggers one +210 */ +211 public double integrate(final double t0, final double[] y0, final double[][] dY0dP, +212 final double t, final double[] y, +213 final double[][] dYdY0, final double[][] dYdP) +214 throws DerivativeException, IntegratorException { +215 +216 final int n = ode.getDimension(); +217 final int k = ode.getParametersDimension(); +218 checkDimension(n, y0); +219 checkDimension(n, y); +220 checkDimension(n, dYdY0); +221 checkDimension(n, dYdY0[0]); +222 if (k != 0) { +223 checkDimension(n, dY0dP); +224 checkDimension(k, dY0dP[0]); +225 checkDimension(n, dYdP); +226 checkDimension(k, dYdP[0]); +227 } +228 +229 // set up initial state, including partial derivatives +230 // the compound state z contains the raw state y and its derivatives +231 // with respect to initial state y0 and to parameters p +232 // y[i] is stored in z[i] +233 // dy[i]/dy0[j] is stored in z[n + i * n + j] +234 // dy[i]/dp[j] is stored in z[n * (n + 1) + i * k + j] +235 final double[] z = new double[n * (1 + n + k)]; +236 System.arraycopy(y0, 0, z, 0, n); +237 for (int i = 0; i < n; ++i) { +238 +239 // set diagonal element of dy/dy0 to 1.0 at t = t0 +240 z[i * (1 + n) + n] = 1.0; +241 +242 // set initial derivatives with respect to parameters +243 System.arraycopy(dY0dP[i], 0, z, n * (n + 1) + i * k, k); +244 +245 } +246 +247 // integrate the compound state variational equations +248 evaluations = 0; +249 final double stopTime = integrator.integrate(new MappingWrapper(), t0, z, t, z); +250 +251 // dispatch the final compound state into the state and partial derivatives arrays +252 dispatchCompoundState(z, y, dYdY0, dYdP); +253 +254 return stopTime; +255 +256 } +257 +258 /** Dispatch a compound state array into state and jacobians arrays. +259 * @param z compound state +260 * @param y raw state array to fill +261 * @param dydy0 jacobian array to fill +262 * @param dydp jacobian array to fill +263 */ +264 private static void dispatchCompoundState(final double[] z, final double[] y, +265 final double[][] dydy0, final double[][] dydp) { +266 +267 final int n = y.length; +268 final int k = dydp[0].length; +269 +270 // state +271 System.arraycopy(z, 0, y, 0, n); +272 +273 // jacobian with respect to initial state +274 for (int i = 0; i < n; ++i) { +275 System.arraycopy(z, n * (i + 1), dydy0[i], 0, n); +276 } +277 +278 // jacobian with respect to parameters +279 for (int i = 0; i < n; ++i) { +280 System.arraycopy(z, n * (n + 1) + i * k, dydp[i], 0, k); +281 } +282 +283 } +284 +285 /** Get the current value of the step start time t<sub>i</sub>. +286 * <p>This method can be called during integration (typically by +287 * the object implementing the {@link FirstOrderDifferentialEquations +288 * differential equations} problem) if the value of the current step that +289 * is attempted is needed.</p> +290 * <p>The result is undefined if the method is called outside of +291 * calls to <code>integrate</code>.</p> +292 * @return current value of the step start time t<sub>i</sub> +293 */ +294 public double getCurrentStepStart() { +295 return integrator.getCurrentStepStart(); +296 } +297 +298 /** Get the current signed value of the integration stepsize. +299 * <p>This method can be called during integration (typically by +300 * the object implementing the {@link FirstOrderDifferentialEquations +301 * differential equations} problem) if the signed value of the current stepsize +302 * that is tried is needed.</p> +303 * <p>The result is undefined if the method is called outside of +304 * calls to <code>integrate</code>.</p> +305 * @return current signed value of the stepsize +306 */ +307 public double getCurrentSignedStepsize() { +308 return integrator.getCurrentSignedStepsize(); +309 } +310 +311 /** Set the maximal number of differential equations function evaluations. +312 * <p>The purpose of this method is to avoid infinite loops which can occur +313 * for example when stringent error constraints are set or when lots of +314 * discrete events are triggered, thus leading to many rejected steps.</p> +315 * @param maxEvaluations maximal number of function evaluations (negative +316 * values are silently converted to maximal integer value, thus representing +317 * almost unlimited evaluations) +318 */ +319 public void setMaxEvaluations(int maxEvaluations) { +320 this.maxEvaluations = (maxEvaluations < 0) ? Integer.MAX_VALUE : maxEvaluations; +321 } +322 +323 /** Get the maximal number of functions evaluations. +324 * @return maximal number of functions evaluations +325 */ +326 public int getMaxEvaluations() { +327 return maxEvaluations; +328 } +329 +330 /** Get the number of evaluations of the differential equations function. +331 * <p> +332 * The number of evaluations corresponds to the last call to the +333 * <code>integrate</code> method. It is 0 if the method has not been called yet. +334 * </p> +335 * @return number of evaluations of the differential equations function +336 */ +337 public int getEvaluations() { +338 return evaluations; +339 } +340 +341 /** Check array dimensions. +342 * @param expected expected dimension +343 * @param array (may be null if expected is 0) +344 * @throws IllegalArgumentException if the array dimension does not match the expected one +345 */ +346 private void checkDimension(final int expected, final Object array) +347 throws IllegalArgumentException { +348 int arrayDimension = (array == null) ? 0 : Array.getLength(array); +349 if (arrayDimension != expected) { +350 throw MathRuntimeException.createIllegalArgumentException( +351 "dimension mismatch {0} != {1}", arrayDimension, expected); +352 } +353 } +354 +355 /** Wrapper class used to map state and jacobians into compound state. */ +356 private class MappingWrapper implements FirstOrderDifferentialEquations { +357 +358 /** Current state. */ +359 private final double[] y; +360 +361 /** Time derivative of the current state. */ +362 private final double[] yDot; +363 +364 /** Derivatives of yDot with respect to state. */ +365 private final double[][] dFdY; +366 +367 /** Derivatives of yDot with respect to parameters. */ +368 private final double[][] dFdP; +369 +370 /** Simple constructor. +371 */ +372 public MappingWrapper() { +373 +374 final int n = ode.getDimension(); +375 final int k = ode.getParametersDimension(); +376 y = new double[n]; +377 yDot = new double[n]; +378 dFdY = new double[n][n]; +379 dFdP = new double[n][k]; +380 +381 } +382 +383 /** {@inheritDoc} */ +384 public int getDimension() { +385 final int n = y.length; +386 final int k = dFdP[0].length; +387 return n * (1 + n + k); +388 } +389 +390 /** {@inheritDoc} */ +391 public void computeDerivatives(final double t, final double[] z, final double[] zDot) +392 throws DerivativeException { +393 +394 final int n = y.length; +395 final int k = dFdP[0].length; +396 +397 // compute raw ODE and its jacobians: dy/dt, d[dy/dt]/dy0 and d[dy/dt]/dp +398 System.arraycopy(z, 0, y, 0, n); +399 if (++evaluations > maxEvaluations) { +400 throw new DerivativeException(new MaxEvaluationsExceededException(maxEvaluations)); +401 } +402 ode.computeDerivatives(t, y, yDot); +403 ode.computeJacobians(t, y, yDot, dFdY, dFdP); +404 +405 // state part of the compound equations +406 System.arraycopy(yDot, 0, zDot, 0, n); +407 +408 // variational equations: from d[dy/dt]/dy0 to d[dy/dy0]/dt +409 for (int i = 0; i < n; ++i) { +410 final double[] dFdYi = dFdY[i]; +411 for (int j = 0; j < n; ++j) { +412 double s = 0; +413 final int startIndex = n + j; +414 int zIndex = startIndex; +415 for (int l = 0; l < n; ++l) { +416 s += dFdYi[l] * z[zIndex]; +417 zIndex += n; +418 } +419 zDot[startIndex + i * n] = s; +420 } +421 } +422 +423 // variational equations: from d[dy/dt]/dy0 and d[dy/dt]/dp to d[dy/dp]/dt +424 for (int i = 0; i < n; ++i) { +425 final double[] dFdYi = dFdY[i]; +426 final double[] dFdPi = dFdP[i]; +427 for (int j = 0; j < k; ++j) { +428 double s = dFdPi[j]; +429 final int startIndex = n * (n + 1) + j; +430 int zIndex = startIndex; +431 for (int l = 0; l < n; ++l) { +432 s += dFdYi[l] * z[zIndex]; +433 zIndex += k; +434 } +435 zDot[startIndex + i * k] = s; +436 } +437 } +438 +439 } +440 +441 } +442 +443 /** Wrapper class to compute jacobians by finite differences for ODE which do not compute them themselves. */ +444 private class FiniteDifferencesWrapper +445 implements ODEWithJacobians { +446 +447 /** Raw ODE without jacobians computation. */ +448 private final ParameterizedODE ode; +449 +450 /** Parameters array (may be null if parameters dimension from original problem is zero) */ +451 private final double[] p; +452 +453 /** Step sizes to use for computing the jacobian df/dy. */ +454 private final double[] hY; +455 +456 /** Step sizes to use for computing the jacobian df/dp. */ +457 private final double[] hP; +458 +459 /** Temporary array for state derivatives used to compute jacobians. */ +460 private final double[] tmpDot; +461 +462 /** Simple constructor. +463 * @param ode original ODE problem, without jacobians computations +464 * @param p parameters array (may be null if parameters dimension from original problem is zero) +465 * @param hY step sizes to use for computing the jacobian df/dy +466 * @param hP step sizes to use for computing the jacobian df/dp +467 */ +468 public FiniteDifferencesWrapper(final ParameterizedODE ode, +469 final double[] p, final double[] hY, final double[] hP) { +470 this.ode = ode; +471 this.p = p.clone(); +472 this.hY = hY.clone(); +473 this.hP = hP.clone(); +474 tmpDot = new double[ode.getDimension()]; +475 } +476 +477 /** {@inheritDoc} */ +478 public int getDimension() { +479 return ode.getDimension(); +480 } +481 +482 /** {@inheritDoc} */ +483 public void computeDerivatives(double t, double[] y, double[] yDot) throws DerivativeException { +484 // this call to computeDerivatives has already been counted, +485 // we must not increment the counter again +486 ode.computeDerivatives(t, y, yDot); +487 } +488 +489 /** {@inheritDoc} */ +490 public int getParametersDimension() { +491 return ode.getParametersDimension(); +492 } +493 +494 /** {@inheritDoc} */ +495 public void computeJacobians(double t, double[] y, double[] yDot, +496 double[][] dFdY, double[][] dFdP) +497 throws DerivativeException { +498 +499 final int n = hY.length; +500 final int k = hP.length; +501 +502 evaluations += n + k; +503 if (evaluations > maxEvaluations) { +504 throw new DerivativeException(new MaxEvaluationsExceededException(maxEvaluations)); +505 } +506 +507 // compute df/dy where f is the ODE and y is the state array +508 for (int j = 0; j < n; ++j) { +509 final double savedYj = y[j]; +510 y[j] += hY[j]; +511 ode.computeDerivatives(t, y, tmpDot); +512 for (int i = 0; i < n; ++i) { +513 dFdY[i][j] = (tmpDot[i] - yDot[i]) / hY[j]; +514 } +515 y[j] = savedYj; +516 } +517 +518 // compute df/dp where f is the ODE and p is the parameters array +519 for (int j = 0; j < k; ++j) { +520 ode.setParameter(j, p[j] + hP[j]); +521 ode.computeDerivatives(t, y, tmpDot); +522 for (int i = 0; i < n; ++i) { +523 dFdP[i][j] = (tmpDot[i] - yDot[i]) / hP[j]; +524 } +525 ode.setParameter(j, p[j]); +526 } +527 +528 } +529 +530 } +531 +532 /** Wrapper for step handlers. */ +533 private static class StepHandlerWrapper implements StepHandler { +534 +535 /** Underlying step handler with jacobians. */ +536 private final StepHandlerWithJacobians handler; +537 +538 /** Dimension of the original ODE. */ +539 private final int n; +540 +541 /** Number of parameters. */ +542 private final int k; +543 +544 /** Simple constructor. +545 * @param handler underlying step handler with jacobians +546 * @param n dimension of the original ODE +547 * @param k number of parameters +548 */ +549 public StepHandlerWrapper(final StepHandlerWithJacobians handler, +550 final int n, final int k) { +551 this.handler = handler; +552 this.n = n; +553 this.k = k; +554 } +555 +556 /** Get the underlying step handler with jacobians. +557 * @return underlying step handler with jacobians +558 */ +559 public StepHandlerWithJacobians getHandler() { +560 return handler; +561 } +562 +563 /** {@inheritDoc} */ +564 public void handleStep(StepInterpolator interpolator, boolean isLast) +565 throws DerivativeException { +566 handler.handleStep(new StepInterpolatorWrapper(interpolator, n, k), isLast); +567 } +568 +569 /** {@inheritDoc} */ +570 public boolean requiresDenseOutput() { +571 return handler.requiresDenseOutput(); +572 } +573 +574 /** {@inheritDoc} */ +575 public void reset() { +576 handler.reset(); +577 } +578 +579 } +580 +581 /** Wrapper for step interpolators. */ +582 private static class StepInterpolatorWrapper +583 implements StepInterpolatorWithJacobians { +584 +585 /** Wrapped interpolator. */ +586 private StepInterpolator interpolator; +587 +588 /** State array. */ +589 private double[] y; +590 +591 /** Jacobian with respect to initial state dy/dy0. */ +592 private double[][] dydy0; +593 +594 /** Jacobian with respect to parameters dy/dp. */ +595 private double[][] dydp; +596 +597 /** Time derivative of the state array. */ +598 private double[] yDot; +599 +600 /** Time derivative of the sacobian with respect to initial state dy/dy0. */ +601 private double[][] dydy0Dot; +602 +603 /** Time derivative of the jacobian with respect to parameters dy/dp. */ +604 private double[][] dydpDot; +605 +606 /** Simple constructor. +607 * <p>This constructor is used only for externalization. It does nothing.</p> +608 */ +609 @SuppressWarnings("unused") +610 public StepInterpolatorWrapper() { +611 } +612 +613 /** Simple constructor. +614 * @param interpolator wrapped interpolator +615 * @param n dimension of the original ODE +616 * @param k number of parameters +617 */ +618 public StepInterpolatorWrapper(final StepInterpolator interpolator, +619 final int n, final int k) { +620 this.interpolator = interpolator; +621 y = new double[n]; +622 dydy0 = new double[n][n]; +623 dydp = new double[n][k]; +624 yDot = new double[n]; +625 dydy0Dot = new double[n][n]; +626 dydpDot = new double[n][k]; +627 } +628 +629 /** {@inheritDoc} */ +630 public void setInterpolatedTime(double time) { +631 interpolator.setInterpolatedTime(time); +632 } +633 +634 /** {@inheritDoc} */ +635 public boolean isForward() { +636 return interpolator.isForward(); +637 } +638 +639 /** {@inheritDoc} */ +640 public double getPreviousTime() { +641 return interpolator.getPreviousTime(); +642 } +643 +644 /** {@inheritDoc} */ +645 public double getInterpolatedTime() { +646 return interpolator.getInterpolatedTime(); +647 } +648 +649 /** {@inheritDoc} */ +650 public double[] getInterpolatedY() throws DerivativeException { +651 double[] extendedState = interpolator.getInterpolatedState(); +652 System.arraycopy(extendedState, 0, y, 0, y.length); +653 return y; +654 } +655 +656 /** {@inheritDoc} */ +657 public double[][] getInterpolatedDyDy0() throws DerivativeException { +658 double[] extendedState = interpolator.getInterpolatedState(); +659 final int n = y.length; +660 int start = n; +661 for (int i = 0; i < n; ++i) { +662 System.arraycopy(extendedState, start, dydy0[i], 0, n); +663 start += n; +664 } +665 return dydy0; +666 } +667 +668 /** {@inheritDoc} */ +669 public double[][] getInterpolatedDyDp() throws DerivativeException { +670 double[] extendedState = interpolator.getInterpolatedState(); +671 final int n = y.length; +672 final int k = dydp[0].length; +673 int start = n * (n + 1); +674 for (int i = 0; i < n; ++i) { +675 System.arraycopy(extendedState, start, dydp[i], 0, k); +676 start += k; +677 } +678 return dydp; +679 } +680 +681 /** {@inheritDoc} */ +682 public double[] getInterpolatedYDot() throws DerivativeException { +683 double[] extendedDerivatives = interpolator.getInterpolatedDerivatives(); +684 System.arraycopy(extendedDerivatives, 0, yDot, 0, yDot.length); +685 return yDot; +686 } +687 +688 /** {@inheritDoc} */ +689 public double[][] getInterpolatedDyDy0Dot() throws DerivativeException { +690 double[] extendedDerivatives = interpolator.getInterpolatedDerivatives(); +691 final int n = y.length; +692 int start = n; +693 for (int i = 0; i < n; ++i) { +694 System.arraycopy(extendedDerivatives, start, dydy0Dot[i], 0, n); +695 start += n; +696 } +697 return dydy0Dot; +698 } +699 +700 /** {@inheritDoc} */ +701 public double[][] getInterpolatedDyDpDot() throws DerivativeException { +702 double[] extendedDerivatives = interpolator.getInterpolatedDerivatives(); +703 final int n = y.length; +704 final int k = dydpDot[0].length; +705 int start = n * (n + 1); +706 for (int i = 0; i < n; ++i) { +707 System.arraycopy(extendedDerivatives, start, dydpDot[i], 0, k); +708 start += k; +709 } +710 return dydpDot; +711 } +712 +713 /** {@inheritDoc} */ +714 public double getCurrentTime() { +715 return interpolator.getCurrentTime(); +716 } +717 +718 /** {@inheritDoc} */ +719 public StepInterpolatorWithJacobians copy() throws DerivativeException { +720 final int n = y.length; +721 final int k = dydp[0].length; +722 StepInterpolatorWrapper copied = +723 new StepInterpolatorWrapper(interpolator.copy(), n, k); +724 copyArray(y, copied.y); +725 copyArray(dydy0, copied.dydy0); +726 copyArray(dydp, copied.dydp); +727 copyArray(yDot, copied.yDot); +728 copyArray(dydy0Dot, copied.dydy0Dot); +729 copyArray(dydpDot, copied.dydpDot); +730 return copied; +731 } +732 +733 /** {@inheritDoc} */ +734 public void writeExternal(ObjectOutput out) throws IOException { +735 out.writeObject(interpolator); +736 out.writeInt(y.length); +737 out.writeInt(dydp[0].length); +738 writeArray(out, y); +739 writeArray(out, dydy0); +740 writeArray(out, dydp); +741 writeArray(out, yDot); +742 writeArray(out, dydy0Dot); +743 writeArray(out, dydpDot); +744 } +745 +746 /** {@inheritDoc} */ +747 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { +748 interpolator = (StepInterpolator) in.readObject(); +749 final int n = in.readInt(); +750 final int k = in.readInt(); +751 y = new double[n]; +752 dydy0 = new double[n][n]; +753 dydp = new double[n][k]; +754 yDot = new double[n]; +755 dydy0Dot = new double[n][n]; +756 dydpDot = new double[n][k]; +757 readArray(in, y); +758 readArray(in, dydy0); +759 readArray(in, dydp); +760 readArray(in, yDot); +761 readArray(in, dydy0Dot); +762 readArray(in, dydpDot); +763 } +764 +765 /** Copy an array. +766 * @param src source array +767 * @param dest destination array +768 */ +769 private static void copyArray(final double[] src, final double[] dest) { +770 System.arraycopy(src, 0, dest, 0, src.length); +771 } +772 +773 /** Copy an array. +774 * @param src source array +775 * @param dest destination array +776 */ +777 private static void copyArray(final double[][] src, final double[][] dest) { +778 for (int i = 0; i < src.length; ++i) { +779 copyArray(src[i], dest[i]); +780 } +781 } +782 +783 /** Write an array. +784 * @param out output stream +785 * @param array array to write +786 * @exception IOException if array cannot be read +787 */ +788 private static void writeArray(final ObjectOutput out, final double[] array) +789 throws IOException { +790 for (int i = 0; i < array.length; ++i) { +791 out.writeDouble(array[i]); +792 } +793 } +794 +795 /** Write an array. +796 * @param out output stream +797 * @param array array to write +798 * @exception IOException if array cannot be read +799 */ +800 private static void writeArray(final ObjectOutput out, final double[][] array) +801 throws IOException { +802 for (int i = 0; i < array.length; ++i) { +803 writeArray(out, array[i]); +804 } +805 } +806 +807 /** Read an array. +808 * @param in input stream +809 * @param array array to read +810 * @exception IOException if array cannot be read +811 */ +812 private static void readArray(final ObjectInput in, final double[] array) +813 throws IOException { +814 for (int i = 0; i < array.length; ++i) { +815 array[i] = in.readDouble(); +816 } +817 } +818 +819 /** Read an array. +820 * @param in input stream +821 * @param array array to read +822 * @exception IOException if array cannot be read +823 */ +824 private static void readArray(final ObjectInput in, final double[][] array) +825 throws IOException { +826 for (int i = 0; i < array.length; ++i) { +827 readArray(in, array[i]); +828 } +829 } +830 +831 } +832 +833 /** Wrapper for event handlers. */ +834 private static class EventHandlerWrapper implements EventHandler { +835 +836 /** Underlying event handler with jacobians. */ +837 private final EventHandlerWithJacobians handler; +838 +839 /** State array. */ +840 private double[] y; +841 +842 /** Jacobian with respect to initial state dy/dy0. */ +843 private double[][] dydy0; +844 +845 /** Jacobian with respect to parameters dy/dp. */ +846 private double[][] dydp; +847 +848 /** Simple constructor. +849 * @param handler underlying event handler with jacobians +850 * @param n dimension of the original ODE +851 * @param k number of parameters +852 */ +853 public EventHandlerWrapper(final EventHandlerWithJacobians handler, +854 final int n, final int k) { +855 this.handler = handler; +856 y = new double[n]; +857 dydy0 = new double[n][n]; +858 dydp = new double[n][k]; +859 } +860 +861 /** Get the underlying event handler with jacobians. +862 * @return underlying event handler with jacobians +863 */ +864 public EventHandlerWithJacobians getHandler() { +865 return handler; +866 } +867 +868 /** {@inheritDoc} */ +869 public int eventOccurred(double t, double[] z, boolean increasing) +870 throws EventException { +871 dispatchCompoundState(z, y, dydy0, dydp); +872 return handler.eventOccurred(t, y, dydy0, dydp, increasing); +873 } +874 +875 /** {@inheritDoc} */ +876 public double g(double t, double[] z) +877 throws EventException { +878 dispatchCompoundState(z, y, dydy0, dydp); +879 return handler.g(t, y, dydy0, dydp); +880 } +881 +882 /** {@inheritDoc} */ +883 public void resetState(double t, double[] z) +884 throws EventException { +885 dispatchCompoundState(z, y, dydy0, dydp); +886 handler.resetState(t, y, dydy0, dydp); +887 } +888 +889 } +890 +891 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/jacobians/ODEWithJacobians.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/jacobians/ODEWithJacobians.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,118 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.jacobians; +019 +020 import org.apache.commons.math.ode.DerivativeException; +021 import org.apache.commons.math.ode.FirstOrderDifferentialEquations; +022 +023 +024 /** This interface represents {@link ParameterizedODE +025 * first order differential equations} with parameters and partial derivatives. +026 * +027 * @see FirstOrderIntegratorWithJacobians +028 * +029 * @version $Revision: 919963 $ $Date: 2010-03-07 05:59:33 -0500 (Sun, 07 Mar 2010) $ +030 * @since 2.1 +031 */ +032 +033 public interface ODEWithJacobians extends FirstOrderDifferentialEquations { +034 +035 /** Get the number of parameters. +036 * @return number of parameters +037 */ +038 int getParametersDimension(); +039 +040 /** Compute the partial derivatives of ODE with respect to state. +041 * @param t current value of the independent <I>time</I> variable +042 * @param y array containing the current value of the state vector +043 * @param yDot array containing the current value of the time derivative of the state vector +044 * @param dFdY placeholder array where to put the jacobian of the ODE with respect to the state vector +045 * @param dFdP placeholder array where to put the jacobian of the ODE with respect to the parameters +046 * @throws DerivativeException this exception is propagated to the caller if the +047 * underlying user function triggers one +048 */ +049 void computeJacobians(double t, double[] y, double[] yDot, double[][] dFdY, double[][] dFdP) +050 throws DerivativeException; +051 +052 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/jacobians/ParameterizedODE.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/jacobians/ParameterizedODE.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,113 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.jacobians; +019 +020 import org.apache.commons.math.ode.FirstOrderDifferentialEquations; +021 +022 +023 /** This interface represents {@link FirstOrderDifferentialEquations +024 * first order differential equations} with parameters. +025 * +026 * @see FirstOrderIntegratorWithJacobians +027 * +028 * @version $Revision: 918702 $ $Date: 2010-03-03 16:28:16 -0500 (Wed, 03 Mar 2010) $ +029 * @since 2.1 +030 */ +031 +032 public interface ParameterizedODE +033 extends FirstOrderDifferentialEquations { +034 +035 /** Get the number of parameters. +036 * @return number of parameters +037 */ +038 int getParametersDimension(); +039 +040 /** Set a parameter. +041 * @param i index of the parameters (must be between 0 +042 * and {@link #getParametersDimension() getParametersDimension() - 1}) +043 * @param value value for the parameter +044 */ +045 void setParameter(int i, double value); +046 +047 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/jacobians/StepHandlerWithJacobians.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/jacobians/StepHandlerWithJacobians.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,161 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.jacobians; +019 +020 import org.apache.commons.math.ode.DerivativeException; +021 +022 /** +023 * This interface represents a handler that should be called after +024 * each successful step. +025 * +026 * <p>The ODE integrators compute the evolution of the state vector at +027 * some grid points that depend on their own internal algorithm. Once +028 * they have found a new grid point (possibly after having computed +029 * several evaluation of the derivative at intermediate points), they +030 * provide it to objects implementing this interface. These objects +031 * typically either ignore the intermediate steps and wait for the +032 * last one, store the points in an ephemeris, or forward them to +033 * specialized processing or output methods.</p> +034 * +035 * <p>Note that is is possible to register a {@link +036 * org.apache.commons.math.ode.sampling.StepHandler classical step handler} +037 * in the low level integrator used to build a {@link FirstOrderIntegratorWithJacobians} +038 * rather than implementing this class. The step handlers registered at low level +039 * will see the big compound state whether the step handlers defined by this interface +040 * see the original state, and its jacobians in separate arrays.</p> +041 * +042 * <p>The compound state is guaranteed to contain the original state in the first +043 * elements, followed by the jacobian with respect to initial state (in row order), +044 * followed by the jacobian with respect to parameters (in row order). If for example +045 * the original state dimension is 6 and there are 3 parameters, the compound state will +046 * be a 60 elements array. The first 6 elements will be the original state, the next 36 +047 * elements will be the jacobian with respect to initial state, and the remaining 18 elements +048 * will be the jacobian with respect to parameters.</p> +049 * +050 * <p>Dealing with low level step handlers is cumbersome if one really needs the jacobians +051 * in these methods, but it also prevents many data being copied back and forth between +052 * state and jacobians on one side and compound state on the other side. So for performance +053 * reasons, it is recommended to use this interface <em>only</em> if jacobians are really +054 * needed and to use lower level handlers if only state is needed.</p> +055 * +056 * @see FirstOrderIntegratorWithJacobians +057 * @see StepInterpolatorWithJacobians +058 * @version $Revision: 920131 $ $Date: 2010-03-07 17:19:18 -0500 (Sun, 07 Mar 2010) $ +059 * @since 2.1 +060 */ +061 +062 public interface StepHandlerWithJacobians { +063 +064 /** Determines whether this handler needs dense output. +065 * <p>This method allows the integrator to avoid performing extra +066 * computation if the handler does not need dense output.</p> +067 * @return true if the handler needs dense output +068 */ +069 boolean requiresDenseOutput(); +070 +071 /** Reset the step handler. +072 * Initialize the internal data as required before the first step is +073 * handled. +074 */ +075 void reset(); +076 +077 /** +078 * Handle the last accepted step +079 * @param interpolator interpolator for the last accepted step. For +080 * efficiency purposes, the various integrators reuse the same +081 * object on each call, so if the instance wants to keep it across +082 * all calls (for example to provide at the end of the integration a +083 * continuous model valid throughout the integration range, as the +084 * {@link org.apache.commons.math.ode.ContinuousOutputModel +085 * ContinuousOutputModel} class does), it should build a local copy +086 * using the clone method of the interpolator and store this copy. +087 * Keeping only a reference to the interpolator and reusing it will +088 * result in unpredictable behavior (potentially crashing the application). +089 * @param isLast true if the step is the last one +090 * @throws DerivativeException this exception is propagated to the +091 * caller if the underlying user function triggers one +092 */ +093 void handleStep(StepInterpolatorWithJacobians interpolator, boolean isLast) throws DerivativeException; +094 +095 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/jacobians/StepInterpolatorWithJacobians.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/jacobians/StepInterpolatorWithJacobians.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,252 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.jacobians; +019 +020 import java.io.Externalizable; +021 +022 import org.apache.commons.math.ode.DerivativeException; +023 +024 /** This interface represents an interpolator over the last step +025 * during an ODE integration. +026 * +027 * <p>The various ODE integrators provide objects implementing this +028 * interface to the step handlers. These objects are often custom +029 * objects tightly bound to the integrator internal algorithms. The +030 * handlers can use these objects to retrieve the state vector at +031 * intermediate times between the previous and the current grid points +032 * (this feature is often called dense output).</p> +033 * <p>One important thing to note is that the step handlers may be so +034 * tightly bound to the integrators that they often share some internal +035 * state arrays. This imply that one should <em>never</em> use a direct +036 * reference to a step interpolator outside of the step handler, either +037 * for future use or for use in another thread. If such a need arise, the +038 * step interpolator <em>must</em> be copied using the dedicated +039 * {@link #copy()} method. +040 * </p> +041 * +042 * @see FirstOrderIntegratorWithJacobians +043 * @see StepHandlerWithJacobians +044 * @version $Revision: 918702 $ $Date: 2010-03-03 16:28:16 -0500 (Wed, 03 Mar 2010) $ +045 * @since 2.1 +046 */ +047 +048 public interface StepInterpolatorWithJacobians extends Externalizable { +049 +050 /** +051 * Get the previous grid point time. +052 * @return previous grid point time +053 */ +054 double getPreviousTime(); +055 +056 /** +057 * Get the current grid point time. +058 * @return current grid point time +059 */ +060 double getCurrentTime(); +061 +062 /** +063 * Get the time of the interpolated point. +064 * If {@link #setInterpolatedTime} has not been called, it returns +065 * the current grid point time. +066 * @return interpolation point time +067 */ +068 double getInterpolatedTime(); +069 +070 /** +071 * Set the time of the interpolated point. +072 * <p>Setting the time outside of the current step is now allowed, but +073 * should be used with care since the accuracy of the interpolator will +074 * probably be very poor far from this step. This allowance has been +075 * added to simplify implementation of search algorithms near the +076 * step endpoints.</p> +077 * <p>Setting the time changes the instance internal state. If a +078 * specific state must be preserved, a copy of the instance must be +079 * created using {@link #copy()}.</p> +080 * @param time time of the interpolated point +081 */ +082 void setInterpolatedTime(double time); +083 +084 /** +085 * Get the state vector of the interpolated point. +086 * <p>The returned vector is a reference to a reused array, so +087 * it should not be modified and it should be copied if it needs +088 * to be preserved across several calls.</p> +089 * @return state vector at time {@link #getInterpolatedTime} +090 * @see #getInterpolatedYDot() +091 * @throws DerivativeException if this call induces an automatic +092 * step finalization that throws one +093 */ +094 double[] getInterpolatedY() throws DerivativeException; +095 +096 /** +097 * Get the partial derivatives of the state vector with respect to +098 * the initial state of the interpolated point. +099 * <p>The returned vector is a reference to a reused array, so +100 * it should not be modified and it should be copied if it needs +101 * to be preserved across several calls.</p> +102 * @return partial derivatives of the state vector with respect to +103 * the initial state at time {@link #getInterpolatedTime} +104 * @see #getInterpolatedY() +105 * @throws DerivativeException if this call induces an automatic +106 * step finalization that throws one +107 */ +108 double[][] getInterpolatedDyDy0() throws DerivativeException; +109 +110 /** +111 * Get the partial derivatives of the state vector with respect to +112 * the ODE parameters of the interpolated point. +113 * <p>The returned vector is a reference to a reused array, so +114 * it should not be modified and it should be copied if it needs +115 * to be preserved across several calls.</p> +116 * @return partial derivatives of the state vector with respect to +117 * the ODE parameters at time {@link #getInterpolatedTime} +118 * @see #getInterpolatedY() +119 * @throws DerivativeException if this call induces an automatic +120 * step finalization that throws one +121 */ +122 double[][] getInterpolatedDyDp() throws DerivativeException; +123 +124 /** +125 * Get the time derivatives of the state vector of the interpolated point. +126 * <p>The returned vector is a reference to a reused array, so +127 * it should not be modified and it should be copied if it needs +128 * to be preserved across several calls.</p> +129 * @return derivatives of the state vector at time {@link #getInterpolatedTime} +130 * @see #getInterpolatedY() +131 * @throws DerivativeException if this call induces an automatic +132 * step finalization that throws one +133 */ +134 double[] getInterpolatedYDot() throws DerivativeException; +135 +136 /** +137 * Get the time derivatives of the jacobian of the state vector +138 * with respect to the initial state of the interpolated point. +139 * <p>The returned vector is a reference to a reused array, so +140 * it should not be modified and it should be copied if it needs +141 * to be preserved across several calls.</p> +142 * @return time derivatives of the jacobian of the state vector +143 * with respect to the initial state at time {@link #getInterpolatedTime} +144 * @see #getInterpolatedY() +145 * @throws DerivativeException if this call induces an automatic +146 * step finalization that throws one +147 */ +148 double[][] getInterpolatedDyDy0Dot() throws DerivativeException; +149 +150 /** +151 * Get the time derivatives of the jacobian of the state vector +152 * with respect to the ODE parameters of the interpolated point. +153 * <p>The returned vector is a reference to a reused array, so +154 * it should not be modified and it should be copied if it needs +155 * to be preserved across several calls.</p> +156 * @return time derivatives of the jacobian of the state vector +157 * with respect to the ODE parameters at time {@link #getInterpolatedTime} +158 * @see #getInterpolatedY() +159 * @throws DerivativeException if this call induces an automatic +160 * step finalization that throws one +161 */ +162 double[][] getInterpolatedDyDpDot() throws DerivativeException; +163 +164 /** Check if the natural integration direction is forward. +165 * <p>This method provides the integration direction as specified by +166 * the integrator itself, it avoid some nasty problems in +167 * degenerated cases like null steps due to cancellation at step +168 * initialization, step control or discrete events +169 * triggering.</p> +170 * @return true if the integration variable (time) increases during +171 * integration +172 */ +173 boolean isForward(); +174 +175 /** Copy the instance. +176 * <p>The copied instance is guaranteed to be independent from the +177 * original one. Both can be used with different settings for +178 * interpolated time without any side effect.</p> +179 * @return a deep copy of the instance, which can be used independently. +180 * @throws DerivativeException if this call induces an automatic +181 * step finalization that throws one +182 * @see #setInterpolatedTime(double) +183 */ +184 StepInterpolatorWithJacobians copy() throws DerivativeException; +185 +186 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/AdamsBashforthIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/AdamsBashforthIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,419 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 import org.apache.commons.math.linear.Array2DRowRealMatrix; +021 import org.apache.commons.math.ode.DerivativeException; +022 import org.apache.commons.math.ode.FirstOrderDifferentialEquations; +023 import org.apache.commons.math.ode.IntegratorException; +024 import org.apache.commons.math.ode.events.CombinedEventsManager; +025 import org.apache.commons.math.ode.sampling.NordsieckStepInterpolator; +026 import org.apache.commons.math.ode.sampling.StepHandler; +027 +028 +029 /** +030 * This class implements explicit Adams-Bashforth integrators for Ordinary +031 * Differential Equations. +032 * +033 * <p>Adams-Bashforth methods (in fact due to Adams alone) are explicit +034 * multistep ODE solvers. This implementation is a variation of the classical +035 * one: it uses adaptive stepsize to implement error control, whereas +036 * classical implementations are fixed step size. The value of state vector +037 * at step n+1 is a simple combination of the value at step n and of the +038 * derivatives at steps n, n-1, n-2 ... Depending on the number k of previous +039 * steps one wants to use for computing the next value, different formulas +040 * are available:</p> +041 * <ul> +042 * <li>k = 1: y<sub>n+1</sub> = y<sub>n</sub> + h y'<sub>n</sub></li> +043 * <li>k = 2: y<sub>n+1</sub> = y<sub>n</sub> + h (3y'<sub>n</sub>-y'<sub>n-1</sub>)/2</li> +044 * <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> +045 * <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> +046 * <li>...</li> +047 * </ul> +048 * +049 * <p>A k-steps Adams-Bashforth method is of order k.</p> +050 * +051 * <h3>Implementation details</h3> +052 * +053 * <p>We define scaled derivatives s<sub>i</sub>(n) at step n as: +054 * <pre> +055 * s<sub>1</sub>(n) = h y'<sub>n</sub> for first derivative +056 * s<sub>2</sub>(n) = h<sup>2</sup>/2 y''<sub>n</sub> for second derivative +057 * s<sub>3</sub>(n) = h<sup>3</sup>/6 y'''<sub>n</sub> for third derivative +058 * ... +059 * s<sub>k</sub>(n) = h<sup>k</sup>/k! y(k)<sub>n</sub> for k<sup>th</sup> derivative +060 * </pre></p> +061 * +062 * <p>The definitions above use the classical representation with several previous first +063 * derivatives. Lets define +064 * <pre> +065 * 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> +066 * </pre> +067 * (we omit the k index in the notation for clarity). With these definitions, +068 * Adams-Bashforth methods can be written: +069 * <ul> +070 * <li>k = 1: y<sub>n+1</sub> = y<sub>n</sub> + s<sub>1</sub>(n)</li> +071 * <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> +072 * <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> +073 * <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> +074 * <li>...</li> +075 * </ul></p> +076 * +077 * <p>Instead of using the classical representation with first derivatives only (y<sub>n</sub>, +078 * s<sub>1</sub>(n) and q<sub>n</sub>), our implementation uses the Nordsieck vector with +079 * higher degrees scaled derivatives all taken at the same step (y<sub>n</sub>, s<sub>1</sub>(n) +080 * and r<sub>n</sub>) where r<sub>n</sub> is defined as: +081 * <pre> +082 * r<sub>n</sub> = [ s<sub>2</sub>(n), s<sub>3</sub>(n) ... s<sub>k</sub>(n) ]<sup>T</sup> +083 * </pre> +084 * (here again we omit the k index in the notation for clarity) +085 * </p> +086 * +087 * <p>Taylor series formulas show that for any index offset i, s<sub>1</sub>(n-i) can be +088 * computed from s<sub>1</sub>(n), s<sub>2</sub>(n) ... s<sub>k</sub>(n), the formula being exact +089 * for degree k polynomials. +090 * <pre> +091 * s<sub>1</sub>(n-i) = s<sub>1</sub>(n) + ∑<sub>j</sub> j (-i)<sup>j-1</sup> s<sub>j</sub>(n) +092 * </pre> +093 * The previous formula can be used with several values for i to compute the transform between +094 * classical representation and Nordsieck vector. The transform between r<sub>n</sub> +095 * and q<sub>n</sub> resulting from the Taylor series formulas above is: +096 * <pre> +097 * q<sub>n</sub> = s<sub>1</sub>(n) u + P r<sub>n</sub> +098 * </pre> +099 * where u is the [ 1 1 ... 1 ]<sup>T</sup> vector and P is the (k-1)×(k-1) matrix built +100 * with the j (-i)<sup>j-1</sup> terms: +101 * <pre> +102 * [ -2 3 -4 5 ... ] +103 * [ -4 12 -32 80 ... ] +104 * P = [ -6 27 -108 405 ... ] +105 * [ -8 48 -256 1280 ... ] +106 * [ ... ] +107 * </pre></p> +108 * +109 * <p>Using the Nordsieck vector has several advantages: +110 * <ul> +111 * <li>it greatly simplifies step interpolation as the interpolator mainly applies +112 * Taylor series formulas,</li> +113 * <li>it simplifies step changes that occur when discrete events that truncate +114 * the step are triggered,</li> +115 * <li>it allows to extend the methods in order to support adaptive stepsize.</li> +116 * </ul></p> +117 * +118 * <p>The Nordsieck vector at step n+1 is computed from the Nordsieck vector at step n as follows: +119 * <ul> +120 * <li>y<sub>n+1</sub> = y<sub>n</sub> + s<sub>1</sub>(n) + u<sup>T</sup> r<sub>n</sub></li> +121 * <li>s<sub>1</sub>(n+1) = h f(t<sub>n+1</sub>, y<sub>n+1</sub>)</li> +122 * <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> +123 * </ul> +124 * where A is a rows shifting matrix (the lower left part is an identity matrix): +125 * <pre> +126 * [ 0 0 ... 0 0 | 0 ] +127 * [ ---------------+---] +128 * [ 1 0 ... 0 0 | 0 ] +129 * A = [ 0 1 ... 0 0 | 0 ] +130 * [ ... | 0 ] +131 * [ 0 0 ... 1 0 | 0 ] +132 * [ 0 0 ... 0 1 | 0 ] +133 * </pre></p> +134 * +135 * <p>The P<sup>-1</sup>u vector and the P<sup>-1</sup> A P matrix do not depend on the state, +136 * they only depend on k and therefore are precomputed once for all.</p> +137 * +138 * @version $Revision: 927202 $ $Date: 2010-03-24 18:11:51 -0400 (Wed, 24 Mar 2010) $ +139 * @since 2.0 +140 */ +141 public class AdamsBashforthIntegrator extends AdamsIntegrator { +142 +143 /** +144 * Build an Adams-Bashforth integrator with the given order and step control parameters. +145 * @param nSteps number of steps of the method excluding the one being computed +146 * @param minStep minimal step (must be positive even for backward +147 * integration), the last step can be smaller than this +148 * @param maxStep maximal step (must be positive even for backward +149 * integration) +150 * @param scalAbsoluteTolerance allowed absolute error +151 * @param scalRelativeTolerance allowed relative error +152 * @exception IllegalArgumentException if order is 1 or less +153 */ +154 public AdamsBashforthIntegrator(final int nSteps, +155 final double minStep, final double maxStep, +156 final double scalAbsoluteTolerance, +157 final double scalRelativeTolerance) +158 throws IllegalArgumentException { +159 super("Adams-Bashforth", nSteps, nSteps, minStep, maxStep, +160 scalAbsoluteTolerance, scalRelativeTolerance); +161 } +162 +163 /** +164 * Build an Adams-Bashforth integrator with the given order and step control parameters. +165 * @param nSteps number of steps of the method excluding the one being computed +166 * @param minStep minimal step (must be positive even for backward +167 * integration), the last step can be smaller than this +168 * @param maxStep maximal step (must be positive even for backward +169 * integration) +170 * @param vecAbsoluteTolerance allowed absolute error +171 * @param vecRelativeTolerance allowed relative error +172 * @exception IllegalArgumentException if order is 1 or less +173 */ +174 public AdamsBashforthIntegrator(final int nSteps, +175 final double minStep, final double maxStep, +176 final double[] vecAbsoluteTolerance, +177 final double[] vecRelativeTolerance) +178 throws IllegalArgumentException { +179 super("Adams-Bashforth", nSteps, nSteps, minStep, maxStep, +180 vecAbsoluteTolerance, vecRelativeTolerance); +181 } +182 +183 /** {@inheritDoc} */ +184 @Override +185 public double integrate(final FirstOrderDifferentialEquations equations, +186 final double t0, final double[] y0, +187 final double t, final double[] y) +188 throws DerivativeException, IntegratorException { +189 +190 final int n = y0.length; +191 sanityChecks(equations, t0, y0, t, y); +192 setEquations(equations); +193 resetEvaluations(); +194 final boolean forward = t > t0; +195 +196 // initialize working arrays +197 if (y != y0) { +198 System.arraycopy(y0, 0, y, 0, n); +199 } +200 final double[] yDot = new double[n]; +201 final double[] yTmp = new double[y0.length]; +202 +203 // set up an interpolator sharing the integrator arrays +204 final NordsieckStepInterpolator interpolator = new NordsieckStepInterpolator(); +205 interpolator.reinitialize(y, forward); +206 final NordsieckStepInterpolator interpolatorTmp = new NordsieckStepInterpolator(); +207 interpolatorTmp.reinitialize(yTmp, forward); +208 +209 // set up integration control objects +210 for (StepHandler handler : stepHandlers) { +211 handler.reset(); +212 } +213 CombinedEventsManager manager = addEndTimeChecker(t0, t, eventsHandlersManager); +214 +215 // compute the initial Nordsieck vector using the configured starter integrator +216 start(t0, y, t); +217 interpolator.reinitialize(stepStart, stepSize, scaled, nordsieck); +218 interpolator.storeTime(stepStart); +219 final int lastRow = nordsieck.getRowDimension() - 1; +220 +221 // reuse the step that was chosen by the starter integrator +222 double hNew = stepSize; +223 interpolator.rescale(hNew); +224 +225 boolean lastStep = false; +226 while (!lastStep) { +227 +228 // shift all data +229 interpolator.shift(); +230 +231 double error = 0; +232 for (boolean loop = true; loop;) { +233 +234 stepSize = hNew; +235 +236 // evaluate error using the last term of the Taylor expansion +237 error = 0; +238 for (int i = 0; i < y0.length; ++i) { +239 final double yScale = Math.abs(y[i]); +240 final double tol = (vecAbsoluteTolerance == null) ? +241 (scalAbsoluteTolerance + scalRelativeTolerance * yScale) : +242 (vecAbsoluteTolerance[i] + vecRelativeTolerance[i] * yScale); +243 final double ratio = nordsieck.getEntry(lastRow, i) / tol; +244 error += ratio * ratio; +245 } +246 error = Math.sqrt(error / y0.length); +247 +248 if (error <= 1.0) { +249 +250 // predict a first estimate of the state at step end +251 final double stepEnd = stepStart + stepSize; +252 interpolator.setInterpolatedTime(stepEnd); +253 System.arraycopy(interpolator.getInterpolatedState(), 0, yTmp, 0, y0.length); +254 +255 // evaluate the derivative +256 computeDerivatives(stepEnd, yTmp, yDot); +257 +258 // update Nordsieck vector +259 final double[] predictedScaled = new double[y0.length]; +260 for (int j = 0; j < y0.length; ++j) { +261 predictedScaled[j] = stepSize * yDot[j]; +262 } +263 final Array2DRowRealMatrix nordsieckTmp = updateHighOrderDerivativesPhase1(nordsieck); +264 updateHighOrderDerivativesPhase2(scaled, predictedScaled, nordsieckTmp); +265 +266 // discrete events handling +267 interpolatorTmp.reinitialize(stepEnd, stepSize, predictedScaled, nordsieckTmp); +268 interpolatorTmp.storeTime(stepStart); +269 interpolatorTmp.shift(); +270 interpolatorTmp.storeTime(stepEnd); +271 if (manager.evaluateStep(interpolatorTmp)) { +272 final double dt = manager.getEventTime() - stepStart; +273 if (Math.abs(dt) <= Math.ulp(stepStart)) { +274 // we cannot simply truncate the step, reject the current computation +275 // and let the loop compute another state with the truncated step. +276 // it is so small (much probably exactly 0 due to limited accuracy) +277 // that the code above would fail handling it. +278 // So we set up an artificial 0 size step by copying states +279 interpolator.storeTime(stepStart); +280 System.arraycopy(y, 0, yTmp, 0, y0.length); +281 hNew = 0; +282 stepSize = 0; +283 loop = false; +284 } else { +285 // reject the step to match exactly the next switch time +286 hNew = dt; +287 interpolator.rescale(hNew); +288 } +289 } else { +290 // accept the step +291 scaled = predictedScaled; +292 nordsieck = nordsieckTmp; +293 interpolator.reinitialize(stepEnd, stepSize, scaled, nordsieck); +294 loop = false; +295 } +296 +297 } else { +298 // reject the step and attempt to reduce error by stepsize control +299 final double factor = computeStepGrowShrinkFactor(error); +300 hNew = filterStep(stepSize * factor, forward, false); +301 interpolator.rescale(hNew); +302 } +303 +304 } +305 +306 // the step has been accepted (may have been truncated) +307 final double nextStep = stepStart + stepSize; +308 System.arraycopy(yTmp, 0, y, 0, n); +309 interpolator.storeTime(nextStep); +310 manager.stepAccepted(nextStep, y); +311 lastStep = manager.stop(); +312 +313 // provide the step data to the step handler +314 for (StepHandler handler : stepHandlers) { +315 interpolator.setInterpolatedTime(nextStep); +316 handler.handleStep(interpolator, lastStep); +317 } +318 stepStart = nextStep; +319 +320 if (!lastStep && manager.reset(stepStart, y)) { +321 +322 // some events handler has triggered changes that +323 // invalidate the derivatives, we need to restart from scratch +324 start(stepStart, y, t); +325 interpolator.reinitialize(stepStart, stepSize, scaled, nordsieck); +326 +327 } +328 +329 if (! lastStep) { +330 // in some rare cases we may get here with stepSize = 0, for example +331 // when an event occurs at integration start, reducing the first step +332 // to zero; we have to reset the step to some safe non zero value +333 stepSize = filterStep(stepSize, forward, true); +334 +335 // stepsize control for next step +336 final double factor = computeStepGrowShrinkFactor(error); +337 final double scaledH = stepSize * factor; +338 final double nextT = stepStart + scaledH; +339 final boolean nextIsLast = forward ? (nextT >= t) : (nextT <= t); +340 hNew = filterStep(scaledH, forward, nextIsLast); +341 interpolator.rescale(hNew); +342 } +343 +344 } +345 +346 final double stopTime = stepStart; +347 stepStart = Double.NaN; +348 stepSize = Double.NaN; +349 return stopTime; +350 +351 } +352 +353 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/AdamsIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/AdamsIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,197 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 import org.apache.commons.math.linear.Array2DRowRealMatrix; +021 import org.apache.commons.math.ode.DerivativeException; +022 import org.apache.commons.math.ode.FirstOrderDifferentialEquations; +023 import org.apache.commons.math.ode.IntegratorException; +024 import org.apache.commons.math.ode.MultistepIntegrator; +025 +026 +027 /** Base class for {@link AdamsBashforthIntegrator Adams-Bashforth} and +028 * {@link AdamsMoultonIntegrator Adams-Moulton} integrators. +029 * @version $Revision: 790368 $ $Date: 2009-07-01 16:31:50 -0400 (Wed, 01 Jul 2009) $ +030 * @since 2.0 +031 */ +032 public abstract class AdamsIntegrator extends MultistepIntegrator { +033 +034 /** Transformer. */ +035 private final AdamsNordsieckTransformer transformer; +036 +037 /** +038 * Build an Adams integrator with the given order and step control prameters. +039 * @param name name of the method +040 * @param nSteps number of steps of the method excluding the one being computed +041 * @param order order of the method +042 * @param minStep minimal step (must be positive even for backward +043 * integration), the last step can be smaller than this +044 * @param maxStep maximal step (must be positive even for backward +045 * integration) +046 * @param scalAbsoluteTolerance allowed absolute error +047 * @param scalRelativeTolerance allowed relative error +048 * @exception IllegalArgumentException if order is 1 or less +049 */ +050 public AdamsIntegrator(final String name, final int nSteps, final int order, +051 final double minStep, final double maxStep, +052 final double scalAbsoluteTolerance, +053 final double scalRelativeTolerance) +054 throws IllegalArgumentException { +055 super(name, nSteps, order, minStep, maxStep, +056 scalAbsoluteTolerance, scalRelativeTolerance); +057 transformer = AdamsNordsieckTransformer.getInstance(nSteps); +058 } +059 +060 /** +061 * Build an Adams integrator with the given order and step control parameters. +062 * @param name name of the method +063 * @param nSteps number of steps of the method excluding the one being computed +064 * @param order order of the method +065 * @param minStep minimal step (must be positive even for backward +066 * integration), the last step can be smaller than this +067 * @param maxStep maximal step (must be positive even for backward +068 * integration) +069 * @param vecAbsoluteTolerance allowed absolute error +070 * @param vecRelativeTolerance allowed relative error +071 * @exception IllegalArgumentException if order is 1 or less +072 */ +073 public AdamsIntegrator(final String name, final int nSteps, final int order, +074 final double minStep, final double maxStep, +075 final double[] vecAbsoluteTolerance, +076 final double[] vecRelativeTolerance) +077 throws IllegalArgumentException { +078 super(name, nSteps, order, minStep, maxStep, +079 vecAbsoluteTolerance, vecRelativeTolerance); +080 transformer = AdamsNordsieckTransformer.getInstance(nSteps); +081 } +082 +083 /** {@inheritDoc} */ +084 @Override +085 public abstract double integrate(final FirstOrderDifferentialEquations equations, +086 final double t0, final double[] y0, +087 final double t, final double[] y) +088 throws DerivativeException, IntegratorException; +089 +090 /** {@inheritDoc} */ +091 @Override +092 protected Array2DRowRealMatrix initializeHighOrderDerivatives(final double[] first, +093 final double[][] multistep) { +094 return transformer.initializeHighOrderDerivatives(first, multistep); +095 } +096 +097 /** Update the high order scaled derivatives for Adams integrators (phase 1). +098 * <p>The complete update of high order derivatives has a form similar to: +099 * <pre> +100 * 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> +101 * </pre> +102 * this method computes the P<sup>-1</sup> A P r<sub>n</sub> part.</p> +103 * @param highOrder high order scaled derivatives +104 * (h<sup>2</sup>/2 y'', ... h<sup>k</sup>/k! y(k)) +105 * @return updated high order derivatives +106 * @see #updateHighOrderDerivativesPhase2(double[], double[], Array2DRowRealMatrix) +107 */ +108 public Array2DRowRealMatrix updateHighOrderDerivativesPhase1(final Array2DRowRealMatrix highOrder) { +109 return transformer.updateHighOrderDerivativesPhase1(highOrder); +110 } +111 +112 /** Update the high order scaled derivatives Adams integrators (phase 2). +113 * <p>The complete update of high order derivatives has a form similar to: +114 * <pre> +115 * 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> +116 * </pre> +117 * this method computes the (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u part.</p> +118 * <p>Phase 1 of the update must already have been performed.</p> +119 * @param start first order scaled derivatives at step start +120 * @param end first order scaled derivatives at step end +121 * @param highOrder high order scaled derivatives, will be modified +122 * (h<sup>2</sup>/2 y'', ... h<sup>k</sup>/k! y(k)) +123 * @see #updateHighOrderDerivativesPhase1(Array2DRowRealMatrix) +124 */ +125 public void updateHighOrderDerivativesPhase2(final double[] start, +126 final double[] end, +127 final Array2DRowRealMatrix highOrder) { +128 transformer.updateHighOrderDerivativesPhase2(start, end, highOrder); +129 } +130 +131 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/AdamsMoultonIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/AdamsMoultonIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,514 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 import java.util.Arrays; +021 +022 import org.apache.commons.math.linear.Array2DRowRealMatrix; +023 import org.apache.commons.math.linear.MatrixVisitorException; +024 import org.apache.commons.math.linear.RealMatrixPreservingVisitor; +025 import org.apache.commons.math.ode.DerivativeException; +026 import org.apache.commons.math.ode.FirstOrderDifferentialEquations; +027 import org.apache.commons.math.ode.IntegratorException; +028 import org.apache.commons.math.ode.events.CombinedEventsManager; +029 import org.apache.commons.math.ode.sampling.NordsieckStepInterpolator; +030 import org.apache.commons.math.ode.sampling.StepHandler; +031 +032 +033 /** +034 * This class implements implicit Adams-Moulton integrators for Ordinary +035 * Differential Equations. +036 * +037 * <p>Adams-Moulton methods (in fact due to Adams alone) are implicit +038 * multistep ODE solvers. This implementation is a variation of the classical +039 * one: it uses adaptive stepsize to implement error control, whereas +040 * classical implementations are fixed step size. The value of state vector +041 * at step n+1 is a simple combination of the value at step n and of the +042 * derivatives at steps n+1, n, n-1 ... Since y'<sub>n+1</sub> is needed to +043 * compute y<sub>n+1</sub>,another method must be used to compute a first +044 * estimate of y<sub>n+1</sub>, then compute y'<sub>n+1</sub>, then compute +045 * a final estimate of y<sub>n+1</sub> using the following formulas. Depending +046 * on the number k of previous steps one wants to use for computing the next +047 * value, different formulas are available for the final estimate:</p> +048 * <ul> +049 * <li>k = 1: y<sub>n+1</sub> = y<sub>n</sub> + h y'<sub>n+1</sub></li> +050 * <li>k = 2: y<sub>n+1</sub> = y<sub>n</sub> + h (y'<sub>n+1</sub>+y'<sub>n</sub>)/2</li> +051 * <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> +052 * <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> +053 * <li>...</li> +054 * </ul> +055 * +056 * <p>A k-steps Adams-Moulton method is of order k+1.</p> +057 * +058 * <h3>Implementation details</h3> +059 * +060 * <p>We define scaled derivatives s<sub>i</sub>(n) at step n as: +061 * <pre> +062 * s<sub>1</sub>(n) = h y'<sub>n</sub> for first derivative +063 * s<sub>2</sub>(n) = h<sup>2</sup>/2 y''<sub>n</sub> for second derivative +064 * s<sub>3</sub>(n) = h<sup>3</sup>/6 y'''<sub>n</sub> for third derivative +065 * ... +066 * s<sub>k</sub>(n) = h<sup>k</sup>/k! y(k)<sub>n</sub> for k<sup>th</sup> derivative +067 * </pre></p> +068 * +069 * <p>The definitions above use the classical representation with several previous first +070 * derivatives. Lets define +071 * <pre> +072 * 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> +073 * </pre> +074 * (we omit the k index in the notation for clarity). With these definitions, +075 * Adams-Moulton methods can be written: +076 * <ul> +077 * <li>k = 1: y<sub>n+1</sub> = y<sub>n</sub> + s<sub>1</sub>(n+1)</li> +078 * <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> +079 * <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> +080 * <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> +081 * <li>...</li> +082 * </ul></p> +083 * +084 * <p>Instead of using the classical representation with first derivatives only (y<sub>n</sub>, +085 * s<sub>1</sub>(n+1) and q<sub>n+1</sub>), our implementation uses the Nordsieck vector with +086 * higher degrees scaled derivatives all taken at the same step (y<sub>n</sub>, s<sub>1</sub>(n) +087 * and r<sub>n</sub>) where r<sub>n</sub> is defined as: +088 * <pre> +089 * r<sub>n</sub> = [ s<sub>2</sub>(n), s<sub>3</sub>(n) ... s<sub>k</sub>(n) ]<sup>T</sup> +090 * </pre> +091 * (here again we omit the k index in the notation for clarity) +092 * </p> +093 * +094 * <p>Taylor series formulas show that for any index offset i, s<sub>1</sub>(n-i) can be +095 * computed from s<sub>1</sub>(n), s<sub>2</sub>(n) ... s<sub>k</sub>(n), the formula being exact +096 * for degree k polynomials. +097 * <pre> +098 * s<sub>1</sub>(n-i) = s<sub>1</sub>(n) + ∑<sub>j</sub> j (-i)<sup>j-1</sup> s<sub>j</sub>(n) +099 * </pre> +100 * The previous formula can be used with several values for i to compute the transform between +101 * classical representation and Nordsieck vector. The transform between r<sub>n</sub> +102 * and q<sub>n</sub> resulting from the Taylor series formulas above is: +103 * <pre> +104 * q<sub>n</sub> = s<sub>1</sub>(n) u + P r<sub>n</sub> +105 * </pre> +106 * where u is the [ 1 1 ... 1 ]<sup>T</sup> vector and P is the (k-1)×(k-1) matrix built +107 * with the j (-i)<sup>j-1</sup> terms: +108 * <pre> +109 * [ -2 3 -4 5 ... ] +110 * [ -4 12 -32 80 ... ] +111 * P = [ -6 27 -108 405 ... ] +112 * [ -8 48 -256 1280 ... ] +113 * [ ... ] +114 * </pre></p> +115 * +116 * <p>Using the Nordsieck vector has several advantages: +117 * <ul> +118 * <li>it greatly simplifies step interpolation as the interpolator mainly applies +119 * Taylor series formulas,</li> +120 * <li>it simplifies step changes that occur when discrete events that truncate +121 * the step are triggered,</li> +122 * <li>it allows to extend the methods in order to support adaptive stepsize.</li> +123 * </ul></p> +124 * +125 * <p>The predicted Nordsieck vector at step n+1 is computed from the Nordsieck vector at step +126 * n as follows: +127 * <ul> +128 * <li>Y<sub>n+1</sub> = y<sub>n</sub> + s<sub>1</sub>(n) + u<sup>T</sup> r<sub>n</sub></li> +129 * <li>S<sub>1</sub>(n+1) = h f(t<sub>n+1</sub>, Y<sub>n+1</sub>)</li> +130 * <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> +131 * </ul> +132 * where A is a rows shifting matrix (the lower left part is an identity matrix): +133 * <pre> +134 * [ 0 0 ... 0 0 | 0 ] +135 * [ ---------------+---] +136 * [ 1 0 ... 0 0 | 0 ] +137 * A = [ 0 1 ... 0 0 | 0 ] +138 * [ ... | 0 ] +139 * [ 0 0 ... 1 0 | 0 ] +140 * [ 0 0 ... 0 1 | 0 ] +141 * </pre> +142 * From this predicted vector, the corrected vector is computed as follows: +143 * <ul> +144 * <li>y<sub>n+1</sub> = y<sub>n</sub> + S<sub>1</sub>(n+1) + [ -1 +1 -1 +1 ... ±1 ] r<sub>n+1</sub></li> +145 * <li>s<sub>1</sub>(n+1) = h f(t<sub>n+1</sub>, y<sub>n+1</sub>)</li> +146 * <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> +147 * </ul> +148 * where the upper case Y<sub>n+1</sub>, S<sub>1</sub>(n+1) and R<sub>n+1</sub> represent the +149 * predicted states whereas the lower case y<sub>n+1</sub>, s<sub>n+1</sub> and r<sub>n+1</sub> +150 * represent the corrected states.</p> +151 * +152 * <p>The P<sup>-1</sup>u vector and the P<sup>-1</sup> A P matrix do not depend on the state, +153 * they only depend on k and therefore are precomputed once for all.</p> +154 * +155 * @version $Revision: 927202 $ $Date: 2010-03-24 18:11:51 -0400 (Wed, 24 Mar 2010) $ +156 * @since 2.0 +157 */ +158 public class AdamsMoultonIntegrator extends AdamsIntegrator { +159 +160 /** +161 * Build an Adams-Moulton integrator with the given order and error control parameters. +162 * @param nSteps number of steps of the method excluding the one being computed +163 * @param minStep minimal step (must be positive even for backward +164 * integration), the last step can be smaller than this +165 * @param maxStep maximal step (must be positive even for backward +166 * integration) +167 * @param scalAbsoluteTolerance allowed absolute error +168 * @param scalRelativeTolerance allowed relative error +169 * @exception IllegalArgumentException if order is 1 or less +170 */ +171 public AdamsMoultonIntegrator(final int nSteps, +172 final double minStep, final double maxStep, +173 final double scalAbsoluteTolerance, +174 final double scalRelativeTolerance) +175 throws IllegalArgumentException { +176 super("Adams-Moulton", nSteps, nSteps + 1, minStep, maxStep, +177 scalAbsoluteTolerance, scalRelativeTolerance); +178 } +179 +180 /** +181 * Build an Adams-Moulton integrator with the given order and error control parameters. +182 * @param nSteps number of steps of the method excluding the one being computed +183 * @param minStep minimal step (must be positive even for backward +184 * integration), the last step can be smaller than this +185 * @param maxStep maximal step (must be positive even for backward +186 * integration) +187 * @param vecAbsoluteTolerance allowed absolute error +188 * @param vecRelativeTolerance allowed relative error +189 * @exception IllegalArgumentException if order is 1 or less +190 */ +191 public AdamsMoultonIntegrator(final int nSteps, +192 final double minStep, final double maxStep, +193 final double[] vecAbsoluteTolerance, +194 final double[] vecRelativeTolerance) +195 throws IllegalArgumentException { +196 super("Adams-Moulton", nSteps, nSteps + 1, minStep, maxStep, +197 vecAbsoluteTolerance, vecRelativeTolerance); +198 } +199 +200 +201 /** {@inheritDoc} */ +202 @Override +203 public double integrate(final FirstOrderDifferentialEquations equations, +204 final double t0, final double[] y0, +205 final double t, final double[] y) +206 throws DerivativeException, IntegratorException { +207 +208 final int n = y0.length; +209 sanityChecks(equations, t0, y0, t, y); +210 setEquations(equations); +211 resetEvaluations(); +212 final boolean forward = t > t0; +213 +214 // initialize working arrays +215 if (y != y0) { +216 System.arraycopy(y0, 0, y, 0, n); +217 } +218 final double[] yDot = new double[y0.length]; +219 final double[] yTmp = new double[y0.length]; +220 +221 // set up two interpolators sharing the integrator arrays +222 final NordsieckStepInterpolator interpolator = new NordsieckStepInterpolator(); +223 interpolator.reinitialize(y, forward); +224 final NordsieckStepInterpolator interpolatorTmp = new NordsieckStepInterpolator(); +225 interpolatorTmp.reinitialize(yTmp, forward); +226 +227 // set up integration control objects +228 for (StepHandler handler : stepHandlers) { +229 handler.reset(); +230 } +231 CombinedEventsManager manager = addEndTimeChecker(t0, t, eventsHandlersManager); +232 +233 +234 // compute the initial Nordsieck vector using the configured starter integrator +235 start(t0, y, t); +236 interpolator.reinitialize(stepStart, stepSize, scaled, nordsieck); +237 interpolator.storeTime(stepStart); +238 +239 double hNew = stepSize; +240 interpolator.rescale(hNew); +241 +242 boolean lastStep = false; +243 while (!lastStep) { +244 +245 // shift all data +246 interpolator.shift(); +247 +248 double error = 0; +249 for (boolean loop = true; loop;) { +250 +251 stepSize = hNew; +252 +253 // predict a first estimate of the state at step end (P in the PECE sequence) +254 final double stepEnd = stepStart + stepSize; +255 interpolator.setInterpolatedTime(stepEnd); +256 System.arraycopy(interpolator.getInterpolatedState(), 0, yTmp, 0, y0.length); +257 +258 // evaluate a first estimate of the derivative (first E in the PECE sequence) +259 computeDerivatives(stepEnd, yTmp, yDot); +260 +261 // update Nordsieck vector +262 final double[] predictedScaled = new double[y0.length]; +263 for (int j = 0; j < y0.length; ++j) { +264 predictedScaled[j] = stepSize * yDot[j]; +265 } +266 final Array2DRowRealMatrix nordsieckTmp = updateHighOrderDerivativesPhase1(nordsieck); +267 updateHighOrderDerivativesPhase2(scaled, predictedScaled, nordsieckTmp); +268 +269 // apply correction (C in the PECE sequence) +270 error = nordsieckTmp.walkInOptimizedOrder(new Corrector(y, predictedScaled, yTmp)); +271 +272 if (error <= 1.0) { +273 +274 // evaluate a final estimate of the derivative (second E in the PECE sequence) +275 computeDerivatives(stepEnd, yTmp, yDot); +276 +277 // update Nordsieck vector +278 final double[] correctedScaled = new double[y0.length]; +279 for (int j = 0; j < y0.length; ++j) { +280 correctedScaled[j] = stepSize * yDot[j]; +281 } +282 updateHighOrderDerivativesPhase2(predictedScaled, correctedScaled, nordsieckTmp); +283 +284 // discrete events handling +285 interpolatorTmp.reinitialize(stepEnd, stepSize, correctedScaled, nordsieckTmp); +286 interpolatorTmp.storeTime(stepStart); +287 interpolatorTmp.shift(); +288 interpolatorTmp.storeTime(stepEnd); +289 if (manager.evaluateStep(interpolatorTmp)) { +290 final double dt = manager.getEventTime() - stepStart; +291 if (Math.abs(dt) <= Math.ulp(stepStart)) { +292 // we cannot simply truncate the step, reject the current computation +293 // and let the loop compute another state with the truncated step. +294 // it is so small (much probably exactly 0 due to limited accuracy) +295 // that the code above would fail handling it. +296 // So we set up an artificial 0 size step by copying states +297 interpolator.storeTime(stepStart); +298 System.arraycopy(y, 0, yTmp, 0, y0.length); +299 hNew = 0; +300 stepSize = 0; +301 loop = false; +302 } else { +303 // reject the step to match exactly the next switch time +304 hNew = dt; +305 interpolator.rescale(hNew); +306 } +307 } else { +308 // accept the step +309 scaled = correctedScaled; +310 nordsieck = nordsieckTmp; +311 interpolator.reinitialize(stepEnd, stepSize, scaled, nordsieck); +312 loop = false; +313 } +314 +315 } else { +316 // reject the step and attempt to reduce error by stepsize control +317 final double factor = computeStepGrowShrinkFactor(error); +318 hNew = filterStep(stepSize * factor, forward, false); +319 interpolator.rescale(hNew); +320 } +321 +322 } +323 +324 // the step has been accepted (may have been truncated) +325 final double nextStep = stepStart + stepSize; +326 System.arraycopy(yTmp, 0, y, 0, n); +327 interpolator.storeTime(nextStep); +328 manager.stepAccepted(nextStep, y); +329 lastStep = manager.stop(); +330 +331 // provide the step data to the step handler +332 for (StepHandler handler : stepHandlers) { +333 interpolator.setInterpolatedTime(nextStep); +334 handler.handleStep(interpolator, lastStep); +335 } +336 stepStart = nextStep; +337 +338 if (!lastStep && manager.reset(stepStart, y)) { +339 +340 // some events handler has triggered changes that +341 // invalidate the derivatives, we need to restart from scratch +342 start(stepStart, y, t); +343 interpolator.reinitialize(stepStart, stepSize, scaled, nordsieck); +344 +345 } +346 +347 if (! lastStep) { +348 // in some rare cases we may get here with stepSize = 0, for example +349 // when an event occurs at integration start, reducing the first step +350 // to zero; we have to reset the step to some safe non zero value +351 stepSize = filterStep(stepSize, forward, true); +352 +353 // stepsize control for next step +354 final double factor = computeStepGrowShrinkFactor(error); +355 final double scaledH = stepSize * factor; +356 final double nextT = stepStart + scaledH; +357 final boolean nextIsLast = forward ? (nextT >= t) : (nextT <= t); +358 hNew = filterStep(scaledH, forward, nextIsLast); +359 interpolator.rescale(hNew); +360 } +361 +362 } +363 +364 final double stopTime = stepStart; +365 stepStart = Double.NaN; +366 stepSize = Double.NaN; +367 return stopTime; +368 +369 } +370 +371 /** Corrector for current state in Adams-Moulton method. +372 * <p> +373 * This visitor implements the Taylor series formula: +374 * <pre> +375 * Y<sub>n+1</sub> = y<sub>n</sub> + s<sub>1</sub>(n+1) + [ -1 +1 -1 +1 ... ±1 ] r<sub>n+1</sub> +376 * </pre> +377 * </p> +378 */ +379 private class Corrector implements RealMatrixPreservingVisitor { +380 +381 /** Previous state. */ +382 private final double[] previous; +383 +384 /** Current scaled first derivative. */ +385 private final double[] scaled; +386 +387 /** Current state before correction. */ +388 private final double[] before; +389 +390 /** Current state after correction. */ +391 private final double[] after; +392 +393 /** Simple constructor. +394 * @param previous previous state +395 * @param scaled current scaled first derivative +396 * @param state state to correct (will be overwritten after visit) +397 */ +398 public Corrector(final double[] previous, final double[] scaled, final double[] state) { +399 this.previous = previous; +400 this.scaled = scaled; +401 this.after = state; +402 this.before = state.clone(); +403 } +404 +405 /** {@inheritDoc} */ +406 public void start(int rows, int columns, +407 int startRow, int endRow, int startColumn, int endColumn) { +408 Arrays.fill(after, 0.0); +409 } +410 +411 /** {@inheritDoc} */ +412 public void visit(int row, int column, double value) +413 throws MatrixVisitorException { +414 if ((row & 0x1) == 0) { +415 after[column] -= value; +416 } else { +417 after[column] += value; +418 } +419 } +420 +421 /** +422 * End visiting te Nordsieck vector. +423 * <p>The correction is used to control stepsize. So its amplitude is +424 * considered to be an error, which must be normalized according to +425 * error control settings. If the normalized value is greater than 1, +426 * the correction was too large and the step must be rejected.</p> +427 * @return the normalized correction, if greater than 1, the step +428 * must be rejected +429 */ +430 public double end() { +431 +432 double error = 0; +433 for (int i = 0; i < after.length; ++i) { +434 after[i] += previous[i] + scaled[i]; +435 final double yScale = Math.max(Math.abs(previous[i]), Math.abs(after[i])); +436 final double tol = (vecAbsoluteTolerance == null) ? +437 (scalAbsoluteTolerance + scalRelativeTolerance * yScale) : +438 (vecAbsoluteTolerance[i] + vecRelativeTolerance[i] * yScale); +439 final double ratio = (after[i] - before[i]) / tol; +440 error += ratio * ratio; +441 } +442 +443 return Math.sqrt(error / after.length); +444 +445 } +446 } +447 +448 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/AdamsNordsieckTransformer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/AdamsNordsieckTransformer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,378 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 import java.util.Arrays; +021 import java.util.HashMap; +022 import java.util.Map; +023 +024 import org.apache.commons.math.fraction.BigFraction; +025 import org.apache.commons.math.linear.Array2DRowFieldMatrix; +026 import org.apache.commons.math.linear.Array2DRowRealMatrix; +027 import org.apache.commons.math.linear.DefaultFieldMatrixChangingVisitor; +028 import org.apache.commons.math.linear.FieldDecompositionSolver; +029 import org.apache.commons.math.linear.FieldLUDecompositionImpl; +030 import org.apache.commons.math.linear.FieldMatrix; +031 import org.apache.commons.math.linear.MatrixUtils; +032 +033 /** Transformer to Nordsieck vectors for Adams integrators. +034 * <p>This class i used by {@link AdamsBashforthIntegrator Adams-Bashforth} and +035 * {@link AdamsMoultonIntegrator Adams-Moulton} integrators to convert between +036 * classical representation with several previous first derivatives and Nordsieck +037 * representation with higher order scaled derivatives.</p> +038 * +039 * <p>We define scaled derivatives s<sub>i</sub>(n) at step n as: +040 * <pre> +041 * s<sub>1</sub>(n) = h y'<sub>n</sub> for first derivative +042 * s<sub>2</sub>(n) = h<sup>2</sup>/2 y''<sub>n</sub> for second derivative +043 * s<sub>3</sub>(n) = h<sup>3</sup>/6 y'''<sub>n</sub> for third derivative +044 * ... +045 * s<sub>k</sub>(n) = h<sup>k</sup>/k! y(k)<sub>n</sub> for k<sup>th</sup> derivative +046 * </pre></p> +047 * +048 * <p>With the previous definition, the classical representation of multistep methods +049 * uses first derivatives only, i.e. it handles y<sub>n</sub>, s<sub>1</sub>(n) and +050 * q<sub>n</sub> where q<sub>n</sub> is defined as: +051 * <pre> +052 * 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> +053 * </pre> +054 * (we omit the k index in the notation for clarity).</p> +055 * +056 * <p>Another possible representation uses the Nordsieck vector with +057 * higher degrees scaled derivatives all taken at the same step, i.e it handles y<sub>n</sub>, +058 * s<sub>1</sub>(n) and r<sub>n</sub>) where r<sub>n</sub> is defined as: +059 * <pre> +060 * r<sub>n</sub> = [ s<sub>2</sub>(n), s<sub>3</sub>(n) ... s<sub>k</sub>(n) ]<sup>T</sup> +061 * </pre> +062 * (here again we omit the k index in the notation for clarity) +063 * </p> +064 * +065 * <p>Taylor series formulas show that for any index offset i, s<sub>1</sub>(n-i) can be +066 * computed from s<sub>1</sub>(n), s<sub>2</sub>(n) ... s<sub>k</sub>(n), the formula being exact +067 * for degree k polynomials. +068 * <pre> +069 * s<sub>1</sub>(n-i) = s<sub>1</sub>(n) + ∑<sub>j</sub> j (-i)<sup>j-1</sup> s<sub>j</sub>(n) +070 * </pre> +071 * The previous formula can be used with several values for i to compute the transform between +072 * classical representation and Nordsieck vector at step end. The transform between r<sub>n</sub> +073 * and q<sub>n</sub> resulting from the Taylor series formulas above is: +074 * <pre> +075 * q<sub>n</sub> = s<sub>1</sub>(n) u + P r<sub>n</sub> +076 * </pre> +077 * where u is the [ 1 1 ... 1 ]<sup>T</sup> vector and P is the (k-1)×(k-1) matrix built +078 * with the j (-i)<sup>j-1</sup> terms: +079 * <pre> +080 * [ -2 3 -4 5 ... ] +081 * [ -4 12 -32 80 ... ] +082 * P = [ -6 27 -108 405 ... ] +083 * [ -8 48 -256 1280 ... ] +084 * [ ... ] +085 * </pre></p> +086 * +087 * <p>Changing -i into +i in the formula above can be used to compute a similar transform between +088 * classical representation and Nordsieck vector at step start. The resulting matrix is simply +089 * the absolute value of matrix P.</p> +090 * +091 * <p>For {@link AdamsBashforthIntegrator Adams-Bashforth} method, the Nordsieck vector +092 * at step n+1 is computed from the Nordsieck vector at step n as follows: +093 * <ul> +094 * <li>y<sub>n+1</sub> = y<sub>n</sub> + s<sub>1</sub>(n) + u<sup>T</sup> r<sub>n</sub></li> +095 * <li>s<sub>1</sub>(n+1) = h f(t<sub>n+1</sub>, y<sub>n+1</sub>)</li> +096 * <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> +097 * </ul> +098 * where A is a rows shifting matrix (the lower left part is an identity matrix): +099 * <pre> +100 * [ 0 0 ... 0 0 | 0 ] +101 * [ ---------------+---] +102 * [ 1 0 ... 0 0 | 0 ] +103 * A = [ 0 1 ... 0 0 | 0 ] +104 * [ ... | 0 ] +105 * [ 0 0 ... 1 0 | 0 ] +106 * [ 0 0 ... 0 1 | 0 ] +107 * </pre></p> +108 * +109 * <p>For {@link AdamsMoultonIntegrator Adams-Moulton} method, the predicted Nordsieck vector +110 * at step n+1 is computed from the Nordsieck vector at step n as follows: +111 * <ul> +112 * <li>Y<sub>n+1</sub> = y<sub>n</sub> + s<sub>1</sub>(n) + u<sup>T</sup> r<sub>n</sub></li> +113 * <li>S<sub>1</sub>(n+1) = h f(t<sub>n+1</sub>, Y<sub>n+1</sub>)</li> +114 * <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> +115 * </ul> +116 * From this predicted vector, the corrected vector is computed as follows: +117 * <ul> +118 * <li>y<sub>n+1</sub> = y<sub>n</sub> + S<sub>1</sub>(n+1) + [ -1 +1 -1 +1 ... ±1 ] r<sub>n+1</sub></li> +119 * <li>s<sub>1</sub>(n+1) = h f(t<sub>n+1</sub>, y<sub>n+1</sub>)</li> +120 * <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> +121 * </ul> +122 * where the upper case Y<sub>n+1</sub>, S<sub>1</sub>(n+1) and R<sub>n+1</sub> represent the +123 * predicted states whereas the lower case y<sub>n+1</sub>, s<sub>n+1</sub> and r<sub>n+1</sub> +124 * represent the corrected states.</p> +125 * +126 * <p>We observe that both methods use similar update formulas. In both cases a P<sup>-1</sup>u +127 * vector and a P<sup>-1</sup> A P matrix are used that do not depend on the state, +128 * they only depend on k. This class handles these transformations.</p> +129 * +130 * @version $Revision: 810196 $ $Date: 2009-09-01 15:47:46 -0400 (Tue, 01 Sep 2009) $ +131 * @since 2.0 +132 */ +133 public class AdamsNordsieckTransformer { +134 +135 /** Cache for already computed coefficients. */ +136 private static final Map<Integer, AdamsNordsieckTransformer> CACHE = +137 new HashMap<Integer, AdamsNordsieckTransformer>(); +138 +139 /** Initialization matrix for the higher order derivatives wrt y'', y''' ... */ +140 private final Array2DRowRealMatrix initialization; +141 +142 /** Update matrix for the higher order derivatives h<sup>2</sup>/2y'', h<sup>3</sup>/6 y''' ... */ +143 private final Array2DRowRealMatrix update; +144 +145 /** Update coefficients of the higher order derivatives wrt y'. */ +146 private final double[] c1; +147 +148 /** Simple constructor. +149 * @param nSteps number of steps of the multistep method +150 * (excluding the one being computed) +151 */ +152 private AdamsNordsieckTransformer(final int nSteps) { +153 +154 // compute exact coefficients +155 FieldMatrix<BigFraction> bigP = buildP(nSteps); +156 FieldDecompositionSolver<BigFraction> pSolver = +157 new FieldLUDecompositionImpl<BigFraction>(bigP).getSolver(); +158 +159 BigFraction[] u = new BigFraction[nSteps]; +160 Arrays.fill(u, BigFraction.ONE); +161 BigFraction[] bigC1 = pSolver.solve(u); +162 +163 // update coefficients are computed by combining transform from +164 // Nordsieck to multistep, then shifting rows to represent step advance +165 // then applying inverse transform +166 BigFraction[][] shiftedP = bigP.getData(); +167 for (int i = shiftedP.length - 1; i > 0; --i) { +168 // shift rows +169 shiftedP[i] = shiftedP[i - 1]; +170 } +171 shiftedP[0] = new BigFraction[nSteps]; +172 Arrays.fill(shiftedP[0], BigFraction.ZERO); +173 FieldMatrix<BigFraction> bigMSupdate = +174 pSolver.solve(new Array2DRowFieldMatrix<BigFraction>(shiftedP, false)); +175 +176 // initialization coefficients, computed from a R matrix = abs(P) +177 bigP.walkInOptimizedOrder(new DefaultFieldMatrixChangingVisitor<BigFraction>(BigFraction.ZERO) { +178 /** {@inheritDoc} */ +179 @Override +180 public BigFraction visit(int row, int column, BigFraction value) { +181 return ((column & 0x1) == 0x1) ? value : value.negate(); +182 } +183 }); +184 FieldMatrix<BigFraction> bigRInverse = +185 new FieldLUDecompositionImpl<BigFraction>(bigP).getSolver().getInverse(); +186 +187 // convert coefficients to double +188 initialization = MatrixUtils.bigFractionMatrixToRealMatrix(bigRInverse); +189 update = MatrixUtils.bigFractionMatrixToRealMatrix(bigMSupdate); +190 c1 = new double[nSteps]; +191 for (int i = 0; i < nSteps; ++i) { +192 c1[i] = bigC1[i].doubleValue(); +193 } +194 +195 } +196 +197 /** Get the Nordsieck transformer for a given number of steps. +198 * @param nSteps number of steps of the multistep method +199 * (excluding the one being computed) +200 * @return Nordsieck transformer for the specified number of steps +201 */ +202 public static AdamsNordsieckTransformer getInstance(final int nSteps) { +203 synchronized(CACHE) { +204 AdamsNordsieckTransformer t = CACHE.get(nSteps); +205 if (t == null) { +206 t = new AdamsNordsieckTransformer(nSteps); +207 CACHE.put(nSteps, t); +208 } +209 return t; +210 } +211 } +212 +213 /** Get the number of steps of the method +214 * (excluding the one being computed). +215 * @return number of steps of the method +216 * (excluding the one being computed) +217 */ +218 public int getNSteps() { +219 return c1.length; +220 } +221 +222 /** Build the P matrix. +223 * <p>The P matrix general terms are shifted j (-i)<sup>j-1</sup> terms: +224 * <pre> +225 * [ -2 3 -4 5 ... ] +226 * [ -4 12 -32 80 ... ] +227 * P = [ -6 27 -108 405 ... ] +228 * [ -8 48 -256 1280 ... ] +229 * [ ... ] +230 * </pre></p> +231 * @param nSteps number of steps of the multistep method +232 * (excluding the one being computed) +233 * @return P matrix +234 */ +235 private FieldMatrix<BigFraction> buildP(final int nSteps) { +236 +237 final BigFraction[][] pData = new BigFraction[nSteps][nSteps]; +238 +239 for (int i = 0; i < pData.length; ++i) { +240 // build the P matrix elements from Taylor series formulas +241 final BigFraction[] pI = pData[i]; +242 final int factor = -(i + 1); +243 int aj = factor; +244 for (int j = 0; j < pI.length; ++j) { +245 pI[j] = new BigFraction(aj * (j + 2)); +246 aj *= factor; +247 } +248 } +249 +250 return new Array2DRowFieldMatrix<BigFraction>(pData, false); +251 +252 } +253 +254 /** Initialize the high order scaled derivatives at step start. +255 * @param first first scaled derivative at step start +256 * @param multistep scaled derivatives after step start (hy'1, ..., hy'k-1) +257 * will be modified +258 * @return high order derivatives at step start +259 */ +260 public Array2DRowRealMatrix initializeHighOrderDerivatives(final double[] first, +261 final double[][] multistep) { +262 for (int i = 0; i < multistep.length; ++i) { +263 final double[] msI = multistep[i]; +264 for (int j = 0; j < first.length; ++j) { +265 msI[j] -= first[j]; +266 } +267 } +268 return initialization.multiply(new Array2DRowRealMatrix(multistep, false)); +269 } +270 +271 /** Update the high order scaled derivatives for Adams integrators (phase 1). +272 * <p>The complete update of high order derivatives has a form similar to: +273 * <pre> +274 * 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> +275 * </pre> +276 * this method computes the P<sup>-1</sup> A P r<sub>n</sub> part.</p> +277 * @param highOrder high order scaled derivatives +278 * (h<sup>2</sup>/2 y'', ... h<sup>k</sup>/k! y(k)) +279 * @return updated high order derivatives +280 * @see #updateHighOrderDerivativesPhase2(double[], double[], Array2DRowRealMatrix) +281 */ +282 public Array2DRowRealMatrix updateHighOrderDerivativesPhase1(final Array2DRowRealMatrix highOrder) { +283 return update.multiply(highOrder); +284 } +285 +286 /** Update the high order scaled derivatives Adams integrators (phase 2). +287 * <p>The complete update of high order derivatives has a form similar to: +288 * <pre> +289 * 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> +290 * </pre> +291 * this method computes the (s<sub>1</sub>(n) - s<sub>1</sub>(n+1)) P<sup>-1</sup> u part.</p> +292 * <p>Phase 1 of the update must already have been performed.</p> +293 * @param start first order scaled derivatives at step start +294 * @param end first order scaled derivatives at step end +295 * @param highOrder high order scaled derivatives, will be modified +296 * (h<sup>2</sup>/2 y'', ... h<sup>k</sup>/k! y(k)) +297 * @see #updateHighOrderDerivativesPhase1(Array2DRowRealMatrix) +298 */ +299 public void updateHighOrderDerivativesPhase2(final double[] start, +300 final double[] end, +301 final Array2DRowRealMatrix highOrder) { +302 final double[][] data = highOrder.getDataRef(); +303 for (int i = 0; i < data.length; ++i) { +304 final double[] dataI = data[i]; +305 final double c1I = c1[i]; +306 for (int j = 0; j < dataI.length; ++j) { +307 dataI[j] += c1I * (start[j] - end[j]); +308 } +309 } +310 } +311 +312 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/AdaptiveStepsizeIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/AdaptiveStepsizeIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,399 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 import org.apache.commons.math.ode.AbstractIntegrator; +021 import org.apache.commons.math.ode.DerivativeException; +022 import org.apache.commons.math.ode.FirstOrderDifferentialEquations; +023 import org.apache.commons.math.ode.IntegratorException; +024 +025 /** +026 * This abstract class holds the common part of all adaptive +027 * stepsize integrators for Ordinary Differential Equations. +028 * +029 * <p>These algorithms perform integration with stepsize control, which +030 * means the user does not specify the integration step but rather a +031 * tolerance on error. The error threshold is computed as +032 * <pre> +033 * threshold_i = absTol_i + relTol_i * max (abs (ym), abs (ym+1)) +034 * </pre> +035 * where absTol_i is the absolute tolerance for component i of the +036 * state vector and relTol_i is the relative tolerance for the same +037 * component. The user can also use only two scalar values absTol and +038 * relTol which will be used for all components.</p> +039 * +040 * <p>If the estimated error for ym+1 is such that +041 * <pre> +042 * sqrt((sum (errEst_i / threshold_i)^2 ) / n) < 1 +043 * </pre> +044 * +045 * (where n is the state vector dimension) then the step is accepted, +046 * otherwise the step is rejected and a new attempt is made with a new +047 * stepsize.</p> +048 * +049 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +050 * @since 1.2 +051 * +052 */ +053 +054 public abstract class AdaptiveStepsizeIntegrator +055 extends AbstractIntegrator { +056 +057 /** Allowed absolute scalar error. */ +058 protected final double scalAbsoluteTolerance; +059 +060 /** Allowed relative scalar error. */ +061 protected final double scalRelativeTolerance; +062 +063 /** Allowed absolute vectorial error. */ +064 protected final double[] vecAbsoluteTolerance; +065 +066 /** Allowed relative vectorial error. */ +067 protected final double[] vecRelativeTolerance; +068 +069 /** User supplied initial step. */ +070 private double initialStep; +071 +072 /** Minimal step. */ +073 private final double minStep; +074 +075 /** Maximal step. */ +076 private final double maxStep; +077 +078 /** Build an integrator with the given stepsize bounds. +079 * The default step handler does nothing. +080 * @param name name of the method +081 * @param minStep minimal step (must be positive even for backward +082 * integration), the last step can be smaller than this +083 * @param maxStep maximal step (must be positive even for backward +084 * integration) +085 * @param scalAbsoluteTolerance allowed absolute error +086 * @param scalRelativeTolerance allowed relative error +087 */ +088 public AdaptiveStepsizeIntegrator(final String name, +089 final double minStep, final double maxStep, +090 final double scalAbsoluteTolerance, +091 final double scalRelativeTolerance) { +092 +093 super(name); +094 +095 this.minStep = Math.abs(minStep); +096 this.maxStep = Math.abs(maxStep); +097 this.initialStep = -1.0; +098 +099 this.scalAbsoluteTolerance = scalAbsoluteTolerance; +100 this.scalRelativeTolerance = scalRelativeTolerance; +101 this.vecAbsoluteTolerance = null; +102 this.vecRelativeTolerance = null; +103 +104 resetInternalState(); +105 +106 } +107 +108 /** Build an integrator with the given stepsize bounds. +109 * The default step handler does nothing. +110 * @param name name of the method +111 * @param minStep minimal step (must be positive even for backward +112 * integration), the last step can be smaller than this +113 * @param maxStep maximal step (must be positive even for backward +114 * integration) +115 * @param vecAbsoluteTolerance allowed absolute error +116 * @param vecRelativeTolerance allowed relative error +117 */ +118 public AdaptiveStepsizeIntegrator(final String name, +119 final double minStep, final double maxStep, +120 final double[] vecAbsoluteTolerance, +121 final double[] vecRelativeTolerance) { +122 +123 super(name); +124 +125 this.minStep = minStep; +126 this.maxStep = maxStep; +127 this.initialStep = -1.0; +128 +129 this.scalAbsoluteTolerance = 0; +130 this.scalRelativeTolerance = 0; +131 this.vecAbsoluteTolerance = vecAbsoluteTolerance.clone(); +132 this.vecRelativeTolerance = vecRelativeTolerance.clone(); +133 +134 resetInternalState(); +135 +136 } +137 +138 /** Set the initial step size. +139 * <p>This method allows the user to specify an initial positive +140 * step size instead of letting the integrator guess it by +141 * itself. If this method is not called before integration is +142 * started, the initial step size will be estimated by the +143 * integrator.</p> +144 * @param initialStepSize initial step size to use (must be positive even +145 * for backward integration ; providing a negative value or a value +146 * outside of the min/max step interval will lead the integrator to +147 * ignore the value and compute the initial step size by itself) +148 */ +149 public void setInitialStepSize(final double initialStepSize) { +150 if ((initialStepSize < minStep) || (initialStepSize > maxStep)) { +151 initialStep = -1.0; +152 } else { +153 initialStep = initialStepSize; +154 } +155 } +156 +157 /** Perform some sanity checks on the integration parameters. +158 * @param equations differential equations set +159 * @param t0 start time +160 * @param y0 state vector at t0 +161 * @param t target time for the integration +162 * @param y placeholder where to put the state vector +163 * @exception IntegratorException if some inconsistency is detected +164 */ +165 @Override +166 protected void sanityChecks(final FirstOrderDifferentialEquations equations, +167 final double t0, final double[] y0, +168 final double t, final double[] y) +169 throws IntegratorException { +170 +171 super.sanityChecks(equations, t0, y0, t, y); +172 +173 if ((vecAbsoluteTolerance != null) && (vecAbsoluteTolerance.length != y0.length)) { +174 throw new IntegratorException( +175 "dimensions mismatch: state vector has dimension {0}," + +176 " absolute tolerance vector has dimension {1}", +177 y0.length, vecAbsoluteTolerance.length); +178 } +179 +180 if ((vecRelativeTolerance != null) && (vecRelativeTolerance.length != y0.length)) { +181 throw new IntegratorException( +182 "dimensions mismatch: state vector has dimension {0}," + +183 " relative tolerance vector has dimension {1}", +184 y0.length, vecRelativeTolerance.length); +185 } +186 +187 } +188 +189 /** Initialize the integration step. +190 * @param equations differential equations set +191 * @param forward forward integration indicator +192 * @param order order of the method +193 * @param scale scaling vector for the state vector +194 * @param t0 start time +195 * @param y0 state vector at t0 +196 * @param yDot0 first time derivative of y0 +197 * @param y1 work array for a state vector +198 * @param yDot1 work array for the first time derivative of y1 +199 * @return first integration step +200 * @exception DerivativeException this exception is propagated to +201 * the caller if the underlying user function triggers one +202 */ +203 public double initializeStep(final FirstOrderDifferentialEquations equations, +204 final boolean forward, final int order, final double[] scale, +205 final double t0, final double[] y0, final double[] yDot0, +206 final double[] y1, final double[] yDot1) +207 throws DerivativeException { +208 +209 if (initialStep > 0) { +210 // use the user provided value +211 return forward ? initialStep : -initialStep; +212 } +213 +214 // very rough first guess : h = 0.01 * ||y/scale|| / ||y'/scale|| +215 // this guess will be used to perform an Euler step +216 double ratio; +217 double yOnScale2 = 0; +218 double yDotOnScale2 = 0; +219 for (int j = 0; j < y0.length; ++j) { +220 ratio = y0[j] / scale[j]; +221 yOnScale2 += ratio * ratio; +222 ratio = yDot0[j] / scale[j]; +223 yDotOnScale2 += ratio * ratio; +224 } +225 +226 double h = ((yOnScale2 < 1.0e-10) || (yDotOnScale2 < 1.0e-10)) ? +227 1.0e-6 : (0.01 * Math.sqrt(yOnScale2 / yDotOnScale2)); +228 if (! forward) { +229 h = -h; +230 } +231 +232 // perform an Euler step using the preceding rough guess +233 for (int j = 0; j < y0.length; ++j) { +234 y1[j] = y0[j] + h * yDot0[j]; +235 } +236 computeDerivatives(t0 + h, y1, yDot1); +237 +238 // estimate the second derivative of the solution +239 double yDDotOnScale = 0; +240 for (int j = 0; j < y0.length; ++j) { +241 ratio = (yDot1[j] - yDot0[j]) / scale[j]; +242 yDDotOnScale += ratio * ratio; +243 } +244 yDDotOnScale = Math.sqrt(yDDotOnScale) / h; +245 +246 // step size is computed such that +247 // h^order * max (||y'/tol||, ||y''/tol||) = 0.01 +248 final double maxInv2 = Math.max(Math.sqrt(yDotOnScale2), yDDotOnScale); +249 final double h1 = (maxInv2 < 1.0e-15) ? +250 Math.max(1.0e-6, 0.001 * Math.abs(h)) : +251 Math.pow(0.01 / maxInv2, 1.0 / order); +252 h = Math.min(100.0 * Math.abs(h), h1); +253 h = Math.max(h, 1.0e-12 * Math.abs(t0)); // avoids cancellation when computing t1 - t0 +254 if (h < getMinStep()) { +255 h = getMinStep(); +256 } +257 if (h > getMaxStep()) { +258 h = getMaxStep(); +259 } +260 if (! forward) { +261 h = -h; +262 } +263 +264 return h; +265 +266 } +267 +268 /** Filter the integration step. +269 * @param h signed step +270 * @param forward forward integration indicator +271 * @param acceptSmall if true, steps smaller than the minimal value +272 * are silently increased up to this value, if false such small +273 * steps generate an exception +274 * @return a bounded integration step (h if no bound is reach, or a bounded value) +275 * @exception IntegratorException if the step is too small and acceptSmall is false +276 */ +277 protected double filterStep(final double h, final boolean forward, final boolean acceptSmall) +278 throws IntegratorException { +279 +280 double filteredH = h; +281 if (Math.abs(h) < minStep) { +282 if (acceptSmall) { +283 filteredH = forward ? minStep : -minStep; +284 } else { +285 throw new IntegratorException( +286 "minimal step size ({0,number,0.00E00}) reached, integration needs {1,number,0.00E00}", +287 minStep, Math.abs(h)); +288 } +289 } +290 +291 if (filteredH > maxStep) { +292 filteredH = maxStep; +293 } else if (filteredH < -maxStep) { +294 filteredH = -maxStep; +295 } +296 +297 return filteredH; +298 +299 } +300 +301 /** {@inheritDoc} */ +302 public abstract double integrate (FirstOrderDifferentialEquations equations, +303 double t0, double[] y0, +304 double t, double[] y) +305 throws DerivativeException, IntegratorException; +306 +307 /** {@inheritDoc} */ +308 @Override +309 public double getCurrentStepStart() { +310 return stepStart; +311 } +312 +313 /** Reset internal state to dummy values. */ +314 protected void resetInternalState() { +315 stepStart = Double.NaN; +316 stepSize = Math.sqrt(minStep * maxStep); +317 } +318 +319 /** Get the minimal step. +320 * @return minimal step +321 */ +322 public double getMinStep() { +323 return minStep; +324 } +325 +326 /** Get the maximal step. +327 * @return maximal step +328 */ +329 public double getMaxStep() { +330 return maxStep; +331 } +332 +333 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,141 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 +021 /** +022 * This class implements the classical fourth order Runge-Kutta +023 * integrator for Ordinary Differential Equations (it is the most +024 * often used Runge-Kutta method). +025 * +026 * <p>This method is an explicit Runge-Kutta method, its Butcher-array +027 * is the following one : +028 * <pre> +029 * 0 | 0 0 0 0 +030 * 1/2 | 1/2 0 0 0 +031 * 1/2 | 0 1/2 0 0 +032 * 1 | 0 0 1 0 +033 * |-------------------- +034 * | 1/6 1/3 1/3 1/6 +035 * </pre> +036 * </p> +037 * +038 * @see EulerIntegrator +039 * @see GillIntegrator +040 * @see MidpointIntegrator +041 * @see ThreeEighthesIntegrator +042 * @version $Revision: 810196 $ $Date: 2009-09-01 15:47:46 -0400 (Tue, 01 Sep 2009) $ +043 * @since 1.2 +044 */ +045 +046 public class ClassicalRungeKuttaIntegrator extends RungeKuttaIntegrator { +047 +048 /** Time steps Butcher array. */ +049 private static final double[] STATIC_C = { +050 1.0 / 2.0, 1.0 / 2.0, 1.0 +051 }; +052 +053 /** Internal weights Butcher array. */ +054 private static final double[][] STATIC_A = { +055 { 1.0 / 2.0 }, +056 { 0.0, 1.0 / 2.0 }, +057 { 0.0, 0.0, 1.0 } +058 }; +059 +060 /** Propagation weights Butcher array. */ +061 private static final double[] STATIC_B = { +062 1.0 / 6.0, 1.0 / 3.0, 1.0 / 3.0, 1.0 / 6.0 +063 }; +064 +065 /** Simple constructor. +066 * Build a fourth-order Runge-Kutta integrator with the given +067 * step. +068 * @param step integration step +069 */ +070 public ClassicalRungeKuttaIntegrator(final double step) { +071 super("classical Runge-Kutta", STATIC_C, STATIC_A, STATIC_B, +072 new ClassicalRungeKuttaStepInterpolator(), step); +073 } +074 +075 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/DormandPrince54Integrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/DormandPrince54Integrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,222 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 +021 /** +022 * This class implements the 5(4) Dormand-Prince integrator for Ordinary +023 * Differential Equations. +024 +025 * <p>This integrator is an embedded Runge-Kutta integrator +026 * of order 5(4) used in local extrapolation mode (i.e. the solution +027 * is computed using the high order formula) with stepsize control +028 * (and automatic step initialization) and continuous output. This +029 * method uses 7 functions evaluations per step. However, since this +030 * is an <i>fsal</i>, the last evaluation of one step is the same as +031 * the first evaluation of the next step and hence can be avoided. So +032 * the cost is really 6 functions evaluations per step.</p> +033 * +034 * <p>This method has been published (whithout the continuous output +035 * that was added by Shampine in 1986) in the following article : +036 * <pre> +037 * A family of embedded Runge-Kutta formulae +038 * J. R. Dormand and P. J. Prince +039 * Journal of Computational and Applied Mathematics +040 * volume 6, no 1, 1980, pp. 19-26 +041 * </pre></p> +042 * +043 * @version $Revision: 810196 $ $Date: 2009-09-01 15:47:46 -0400 (Tue, 01 Sep 2009) $ +044 * @since 1.2 +045 */ +046 +047 public class DormandPrince54Integrator extends EmbeddedRungeKuttaIntegrator { +048 +049 /** Integrator method name. */ +050 private static final String METHOD_NAME = "Dormand-Prince 5(4)"; +051 +052 /** Time steps Butcher array. */ +053 private static final double[] STATIC_C = { +054 1.0/5.0, 3.0/10.0, 4.0/5.0, 8.0/9.0, 1.0, 1.0 +055 }; +056 +057 /** Internal weights Butcher array. */ +058 private static final double[][] STATIC_A = { +059 {1.0/5.0}, +060 {3.0/40.0, 9.0/40.0}, +061 {44.0/45.0, -56.0/15.0, 32.0/9.0}, +062 {19372.0/6561.0, -25360.0/2187.0, 64448.0/6561.0, -212.0/729.0}, +063 {9017.0/3168.0, -355.0/33.0, 46732.0/5247.0, 49.0/176.0, -5103.0/18656.0}, +064 {35.0/384.0, 0.0, 500.0/1113.0, 125.0/192.0, -2187.0/6784.0, 11.0/84.0} +065 }; +066 +067 /** Propagation weights Butcher array. */ +068 private static final double[] STATIC_B = { +069 35.0/384.0, 0.0, 500.0/1113.0, 125.0/192.0, -2187.0/6784.0, 11.0/84.0, 0.0 +070 }; +071 +072 /** Error array, element 1. */ +073 private static final double E1 = 71.0 / 57600.0; +074 +075 // element 2 is zero, so it is neither stored nor used +076 +077 /** Error array, element 3. */ +078 private static final double E3 = -71.0 / 16695.0; +079 +080 /** Error array, element 4. */ +081 private static final double E4 = 71.0 / 1920.0; +082 +083 /** Error array, element 5. */ +084 private static final double E5 = -17253.0 / 339200.0; +085 +086 /** Error array, element 6. */ +087 private static final double E6 = 22.0 / 525.0; +088 +089 /** Error array, element 7. */ +090 private static final double E7 = -1.0 / 40.0; +091 +092 /** Simple constructor. +093 * Build a fifth order Dormand-Prince integrator with the given step bounds +094 * @param minStep minimal step (must be positive even for backward +095 * integration), the last step can be smaller than this +096 * @param maxStep maximal step (must be positive even for backward +097 * integration) +098 * @param scalAbsoluteTolerance allowed absolute error +099 * @param scalRelativeTolerance allowed relative error +100 */ +101 public DormandPrince54Integrator(final double minStep, final double maxStep, +102 final double scalAbsoluteTolerance, +103 final double scalRelativeTolerance) { +104 super(METHOD_NAME, true, STATIC_C, STATIC_A, STATIC_B, new DormandPrince54StepInterpolator(), +105 minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); +106 } +107 +108 /** Simple constructor. +109 * Build a fifth order Dormand-Prince integrator with the given step bounds +110 * @param minStep minimal step (must be positive even for backward +111 * integration), the last step can be smaller than this +112 * @param maxStep maximal step (must be positive even for backward +113 * integration) +114 * @param vecAbsoluteTolerance allowed absolute error +115 * @param vecRelativeTolerance allowed relative error +116 */ +117 public DormandPrince54Integrator(final double minStep, final double maxStep, +118 final double[] vecAbsoluteTolerance, +119 final double[] vecRelativeTolerance) { +120 super(METHOD_NAME, true, STATIC_C, STATIC_A, STATIC_B, new DormandPrince54StepInterpolator(), +121 minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); +122 } +123 +124 /** {@inheritDoc} */ +125 @Override +126 public int getOrder() { +127 return 5; +128 } +129 +130 /** {@inheritDoc} */ +131 @Override +132 protected double estimateError(final double[][] yDotK, +133 final double[] y0, final double[] y1, +134 final double h) { +135 +136 double error = 0; +137 +138 for (int j = 0; j < y0.length; ++j) { +139 final double errSum = E1 * yDotK[0][j] + E3 * yDotK[2][j] + +140 E4 * yDotK[3][j] + E5 * yDotK[4][j] + +141 E6 * yDotK[5][j] + E7 * yDotK[6][j]; +142 +143 final double yScale = Math.max(Math.abs(y0[j]), Math.abs(y1[j])); +144 final double tol = (vecAbsoluteTolerance == null) ? +145 (scalAbsoluteTolerance + scalRelativeTolerance * yScale) : +146 (vecAbsoluteTolerance[j] + vecRelativeTolerance[j] * yScale); +147 final double ratio = h * errSum / tol; +148 error += ratio * ratio; +149 +150 } +151 +152 return Math.sqrt(error / y0.length); +153 +154 } +155 +156 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/DormandPrince853Integrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/DormandPrince853Integrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,347 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 +021 /** +022 * This class implements the 8(5,3) Dormand-Prince integrator for Ordinary +023 * Differential Equations. +024 * +025 * <p>This integrator is an embedded Runge-Kutta integrator +026 * of order 8(5,3) used in local extrapolation mode (i.e. the solution +027 * is computed using the high order formula) with stepsize control +028 * (and automatic step initialization) and continuous output. This +029 * method uses 12 functions evaluations per step for integration and 4 +030 * evaluations for interpolation. However, since the first +031 * interpolation evaluation is the same as the first integration +032 * evaluation of the next step, we have included it in the integrator +033 * rather than in the interpolator and specified the method was an +034 * <i>fsal</i>. Hence, despite we have 13 stages here, the cost is +035 * really 12 evaluations per step even if no interpolation is done, +036 * and the overcost of interpolation is only 3 evaluations.</p> +037 * +038 * <p>This method is based on an 8(6) method by Dormand and Prince +039 * (i.e. order 8 for the integration and order 6 for error estimation) +040 * modified by Hairer and Wanner to use a 5th order error estimator +041 * with 3rd order correction. This modification was introduced because +042 * the original method failed in some cases (wrong steps can be +043 * accepted when step size is too large, for example in the +044 * Brusselator problem) and also had <i>severe difficulties when +045 * applied to problems with discontinuities</i>. This modification is +046 * explained in the second edition of the first volume (Nonstiff +047 * Problems) of the reference book by Hairer, Norsett and Wanner: +048 * <i>Solving Ordinary Differential Equations</i> (Springer-Verlag, +049 * ISBN 3-540-56670-8).</p> +050 * +051 * @version $Revision: 810196 $ $Date: 2009-09-01 15:47:46 -0400 (Tue, 01 Sep 2009) $ +052 * @since 1.2 +053 */ +054 +055 public class DormandPrince853Integrator extends EmbeddedRungeKuttaIntegrator { +056 +057 /** Integrator method name. */ +058 private static final String METHOD_NAME = "Dormand-Prince 8 (5, 3)"; +059 +060 /** Time steps Butcher array. */ +061 private static final double[] STATIC_C = { +062 (12.0 - 2.0 * Math.sqrt(6.0)) / 135.0, (6.0 - Math.sqrt(6.0)) / 45.0, (6.0 - Math.sqrt(6.0)) / 30.0, +063 (6.0 + Math.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, +064 6.0/7.0, 1.0, 1.0 +065 }; +066 +067 /** Internal weights Butcher array. */ +068 private static final double[][] STATIC_A = { +069 +070 // k2 +071 {(12.0 - 2.0 * Math.sqrt(6.0)) / 135.0}, +072 +073 // k3 +074 {(6.0 - Math.sqrt(6.0)) / 180.0, (6.0 - Math.sqrt(6.0)) / 60.0}, +075 +076 // k4 +077 {(6.0 - Math.sqrt(6.0)) / 120.0, 0.0, (6.0 - Math.sqrt(6.0)) / 40.0}, +078 +079 // k5 +080 {(462.0 + 107.0 * Math.sqrt(6.0)) / 3000.0, 0.0, +081 (-402.0 - 197.0 * Math.sqrt(6.0)) / 1000.0, (168.0 + 73.0 * Math.sqrt(6.0)) / 375.0}, +082 +083 // k6 +084 {1.0 / 27.0, 0.0, 0.0, (16.0 + Math.sqrt(6.0)) / 108.0, (16.0 - Math.sqrt(6.0)) / 108.0}, +085 +086 // k7 +087 {19.0 / 512.0, 0.0, 0.0, (118.0 + 23.0 * Math.sqrt(6.0)) / 1024.0, +088 (118.0 - 23.0 * Math.sqrt(6.0)) / 1024.0, -9.0 / 512.0}, +089 +090 // k8 +091 {13772.0 / 371293.0, 0.0, 0.0, (51544.0 + 4784.0 * Math.sqrt(6.0)) / 371293.0, +092 (51544.0 - 4784.0 * Math.sqrt(6.0)) / 371293.0, -5688.0 / 371293.0, 3072.0 / 371293.0}, +093 +094 // k9 +095 {58656157643.0 / 93983540625.0, 0.0, 0.0, +096 (-1324889724104.0 - 318801444819.0 * Math.sqrt(6.0)) / 626556937500.0, +097 (-1324889724104.0 + 318801444819.0 * Math.sqrt(6.0)) / 626556937500.0, +098 96044563816.0 / 3480871875.0, 5682451879168.0 / 281950621875.0, +099 -165125654.0 / 3796875.0}, +100 +101 // k10 +102 {8909899.0 / 18653125.0, 0.0, 0.0, +103 (-4521408.0 - 1137963.0 * Math.sqrt(6.0)) / 2937500.0, +104 (-4521408.0 + 1137963.0 * Math.sqrt(6.0)) / 2937500.0, +105 96663078.0 / 4553125.0, 2107245056.0 / 137915625.0, +106 -4913652016.0 / 147609375.0, -78894270.0 / 3880452869.0}, +107 +108 // k11 +109 {-20401265806.0 / 21769653311.0, 0.0, 0.0, +110 (354216.0 + 94326.0 * Math.sqrt(6.0)) / 112847.0, +111 (354216.0 - 94326.0 * Math.sqrt(6.0)) / 112847.0, +112 -43306765128.0 / 5313852383.0, -20866708358144.0 / 1126708119789.0, +113 14886003438020.0 / 654632330667.0, 35290686222309375.0 / 14152473387134411.0, +114 -1477884375.0 / 485066827.0}, +115 +116 // k12 +117 {39815761.0 / 17514443.0, 0.0, 0.0, +118 (-3457480.0 - 960905.0 * Math.sqrt(6.0)) / 551636.0, +119 (-3457480.0 + 960905.0 * Math.sqrt(6.0)) / 551636.0, +120 -844554132.0 / 47026969.0, 8444996352.0 / 302158619.0, +121 -2509602342.0 / 877790785.0, -28388795297996250.0 / 3199510091356783.0, +122 226716250.0 / 18341897.0, 1371316744.0 / 2131383595.0}, +123 +124 // k13 should be for interpolation only, but since it is the same +125 // stage as the first evaluation of the next step, we perform it +126 // here at no cost by specifying this is an fsal method +127 {104257.0/1920240.0, 0.0, 0.0, 0.0, 0.0, 3399327.0/763840.0, +128 66578432.0/35198415.0, -1674902723.0/288716400.0, +129 54980371265625.0/176692375811392.0, -734375.0/4826304.0, +130 171414593.0/851261400.0, 137909.0/3084480.0} +131 +132 }; +133 +134 /** Propagation weights Butcher array. */ +135 private static final double[] STATIC_B = { +136 104257.0/1920240.0, +137 0.0, +138 0.0, +139 0.0, +140 0.0, +141 3399327.0/763840.0, +142 66578432.0/35198415.0, +143 -1674902723.0/288716400.0, +144 54980371265625.0/176692375811392.0, +145 -734375.0/4826304.0, +146 171414593.0/851261400.0, +147 137909.0/3084480.0, +148 0.0 +149 }; +150 +151 /** First error weights array, element 1. */ +152 private static final double E1_01 = 116092271.0 / 8848465920.0; +153 +154 // elements 2 to 5 are zero, so they are neither stored nor used +155 +156 /** First error weights array, element 6. */ +157 private static final double E1_06 = -1871647.0 / 1527680.0; +158 +159 /** First error weights array, element 7. */ +160 private static final double E1_07 = -69799717.0 / 140793660.0; +161 +162 /** First error weights array, element 8. */ +163 private static final double E1_08 = 1230164450203.0 / 739113984000.0; +164 +165 /** First error weights array, element 9. */ +166 private static final double E1_09 = -1980813971228885.0 / 5654156025964544.0; +167 +168 /** First error weights array, element 10. */ +169 private static final double E1_10 = 464500805.0 / 1389975552.0; +170 +171 /** First error weights array, element 11. */ +172 private static final double E1_11 = 1606764981773.0 / 19613062656000.0; +173 +174 /** First error weights array, element 12. */ +175 private static final double E1_12 = -137909.0 / 6168960.0; +176 +177 +178 /** Second error weights array, element 1. */ +179 private static final double E2_01 = -364463.0 / 1920240.0; +180 +181 // elements 2 to 5 are zero, so they are neither stored nor used +182 +183 /** Second error weights array, element 6. */ +184 private static final double E2_06 = 3399327.0 / 763840.0; +185 +186 /** Second error weights array, element 7. */ +187 private static final double E2_07 = 66578432.0 / 35198415.0; +188 +189 /** Second error weights array, element 8. */ +190 private static final double E2_08 = -1674902723.0 / 288716400.0; +191 +192 /** Second error weights array, element 9. */ +193 private static final double E2_09 = -74684743568175.0 / 176692375811392.0; +194 +195 /** Second error weights array, element 10. */ +196 private static final double E2_10 = -734375.0 / 4826304.0; +197 +198 /** Second error weights array, element 11. */ +199 private static final double E2_11 = 171414593.0 / 851261400.0; +200 +201 /** Second error weights array, element 12. */ +202 private static final double E2_12 = 69869.0 / 3084480.0; +203 +204 /** Simple constructor. +205 * Build an eighth order Dormand-Prince integrator with the given step bounds +206 * @param minStep minimal step (must be positive even for backward +207 * integration), the last step can be smaller than this +208 * @param maxStep maximal step (must be positive even for backward +209 * integration) +210 * @param scalAbsoluteTolerance allowed absolute error +211 * @param scalRelativeTolerance allowed relative error +212 */ +213 public DormandPrince853Integrator(final double minStep, final double maxStep, +214 final double scalAbsoluteTolerance, +215 final double scalRelativeTolerance) { +216 super(METHOD_NAME, true, STATIC_C, STATIC_A, STATIC_B, +217 new DormandPrince853StepInterpolator(), +218 minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); +219 } +220 +221 /** Simple constructor. +222 * Build an eighth order Dormand-Prince integrator with the given step bounds +223 * @param minStep minimal step (must be positive even for backward +224 * integration), the last step can be smaller than this +225 * @param maxStep maximal step (must be positive even for backward +226 * integration) +227 * @param vecAbsoluteTolerance allowed absolute error +228 * @param vecRelativeTolerance allowed relative error +229 */ +230 public DormandPrince853Integrator(final double minStep, final double maxStep, +231 final double[] vecAbsoluteTolerance, +232 final double[] vecRelativeTolerance) { +233 super(METHOD_NAME, true, STATIC_C, STATIC_A, STATIC_B, +234 new DormandPrince853StepInterpolator(), +235 minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); +236 } +237 +238 /** {@inheritDoc} */ +239 @Override +240 public int getOrder() { +241 return 8; +242 } +243 +244 /** {@inheritDoc} */ +245 @Override +246 protected double estimateError(final double[][] yDotK, +247 final double[] y0, final double[] y1, +248 final double h) { +249 double error1 = 0; +250 double error2 = 0; +251 +252 for (int j = 0; j < y0.length; ++j) { +253 final double errSum1 = E1_01 * yDotK[0][j] + E1_06 * yDotK[5][j] + +254 E1_07 * yDotK[6][j] + E1_08 * yDotK[7][j] + +255 E1_09 * yDotK[8][j] + E1_10 * yDotK[9][j] + +256 E1_11 * yDotK[10][j] + E1_12 * yDotK[11][j]; +257 final double errSum2 = E2_01 * yDotK[0][j] + E2_06 * yDotK[5][j] + +258 E2_07 * yDotK[6][j] + E2_08 * yDotK[7][j] + +259 E2_09 * yDotK[8][j] + E2_10 * yDotK[9][j] + +260 E2_11 * yDotK[10][j] + E2_12 * yDotK[11][j]; +261 +262 final double yScale = Math.max(Math.abs(y0[j]), Math.abs(y1[j])); +263 final double tol = (vecAbsoluteTolerance == null) ? +264 (scalAbsoluteTolerance + scalRelativeTolerance * yScale) : +265 (vecAbsoluteTolerance[j] + vecRelativeTolerance[j] * yScale); +266 final double ratio1 = errSum1 / tol; +267 error1 += ratio1 * ratio1; +268 final double ratio2 = errSum2 / tol; +269 error2 += ratio2 * ratio2; +270 } +271 +272 double den = error1 + 0.01 * error2; +273 if (den <= 0.0) { +274 den = 1.0; +275 } +276 +277 return Math.abs(h) * error1 / Math.sqrt(y0.length * den); +278 +279 } +280 +281 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/EmbeddedRungeKuttaIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/EmbeddedRungeKuttaIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,477 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 import org.apache.commons.math.ode.DerivativeException; +021 import org.apache.commons.math.ode.FirstOrderDifferentialEquations; +022 import org.apache.commons.math.ode.IntegratorException; +023 import org.apache.commons.math.ode.events.CombinedEventsManager; +024 import org.apache.commons.math.ode.sampling.AbstractStepInterpolator; +025 import org.apache.commons.math.ode.sampling.DummyStepInterpolator; +026 import org.apache.commons.math.ode.sampling.StepHandler; +027 +028 /** +029 * This class implements the common part of all embedded Runge-Kutta +030 * integrators for Ordinary Differential Equations. +031 * +032 * <p>These methods are embedded explicit Runge-Kutta methods with two +033 * sets of coefficients allowing to estimate the error, their Butcher +034 * arrays are as follows : +035 * <pre> +036 * 0 | +037 * c2 | a21 +038 * c3 | a31 a32 +039 * ... | ... +040 * cs | as1 as2 ... ass-1 +041 * |-------------------------- +042 * | b1 b2 ... bs-1 bs +043 * | b'1 b'2 ... b's-1 b's +044 * </pre> +045 * </p> +046 * +047 * <p>In fact, we rather use the array defined by ej = bj - b'j to +048 * compute directly the error rather than computing two estimates and +049 * then comparing them.</p> +050 * +051 * <p>Some methods are qualified as <i>fsal</i> (first same as last) +052 * methods. This means the last evaluation of the derivatives in one +053 * step is the same as the first in the next step. Then, this +054 * evaluation can be reused from one step to the next one and the cost +055 * of such a method is really s-1 evaluations despite the method still +056 * has s stages. This behaviour is true only for successful steps, if +057 * the step is rejected after the error estimation phase, no +058 * evaluation is saved. For an <i>fsal</i> method, we have cs = 1 and +059 * asi = bi for all i.</p> +060 * +061 * @version $Revision: 927202 $ $Date: 2010-03-24 18:11:51 -0400 (Wed, 24 Mar 2010) $ +062 * @since 1.2 +063 */ +064 +065 public abstract class EmbeddedRungeKuttaIntegrator +066 extends AdaptiveStepsizeIntegrator { +067 +068 /** Indicator for <i>fsal</i> methods. */ +069 private final boolean fsal; +070 +071 /** Time steps from Butcher array (without the first zero). */ +072 private final double[] c; +073 +074 /** Internal weights from Butcher array (without the first empty row). */ +075 private final double[][] a; +076 +077 /** External weights for the high order method from Butcher array. */ +078 private final double[] b; +079 +080 /** Prototype of the step interpolator. */ +081 private final RungeKuttaStepInterpolator prototype; +082 +083 /** Stepsize control exponent. */ +084 private final double exp; +085 +086 /** Safety factor for stepsize control. */ +087 private double safety; +088 +089 /** Minimal reduction factor for stepsize control. */ +090 private double minReduction; +091 +092 /** Maximal growth factor for stepsize control. */ +093 private double maxGrowth; +094 +095 /** Build a Runge-Kutta integrator with the given Butcher array. +096 * @param name name of the method +097 * @param fsal indicate that the method is an <i>fsal</i> +098 * @param c time steps from Butcher array (without the first zero) +099 * @param a internal weights from Butcher array (without the first empty row) +100 * @param b propagation weights for the high order method from Butcher array +101 * @param prototype prototype of the step interpolator to use +102 * @param minStep minimal step (must be positive even for backward +103 * integration), the last step can be smaller than this +104 * @param maxStep maximal step (must be positive even for backward +105 * integration) +106 * @param scalAbsoluteTolerance allowed absolute error +107 * @param scalRelativeTolerance allowed relative error +108 */ +109 protected EmbeddedRungeKuttaIntegrator(final String name, final boolean fsal, +110 final double[] c, final double[][] a, final double[] b, +111 final RungeKuttaStepInterpolator prototype, +112 final double minStep, final double maxStep, +113 final double scalAbsoluteTolerance, +114 final double scalRelativeTolerance) { +115 +116 super(name, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); +117 +118 this.fsal = fsal; +119 this.c = c; +120 this.a = a; +121 this.b = b; +122 this.prototype = prototype; +123 +124 exp = -1.0 / getOrder(); +125 +126 // set the default values of the algorithm control parameters +127 setSafety(0.9); +128 setMinReduction(0.2); +129 setMaxGrowth(10.0); +130 +131 } +132 +133 /** Build a Runge-Kutta integrator with the given Butcher array. +134 * @param name name of the method +135 * @param fsal indicate that the method is an <i>fsal</i> +136 * @param c time steps from Butcher array (without the first zero) +137 * @param a internal weights from Butcher array (without the first empty row) +138 * @param b propagation weights for the high order method from Butcher array +139 * @param prototype prototype of the step interpolator to use +140 * @param minStep minimal step (must be positive even for backward +141 * integration), the last step can be smaller than this +142 * @param maxStep maximal step (must be positive even for backward +143 * integration) +144 * @param vecAbsoluteTolerance allowed absolute error +145 * @param vecRelativeTolerance allowed relative error +146 */ +147 protected EmbeddedRungeKuttaIntegrator(final String name, final boolean fsal, +148 final double[] c, final double[][] a, final double[] b, +149 final RungeKuttaStepInterpolator prototype, +150 final double minStep, final double maxStep, +151 final double[] vecAbsoluteTolerance, +152 final double[] vecRelativeTolerance) { +153 +154 super(name, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); +155 +156 this.fsal = fsal; +157 this.c = c; +158 this.a = a; +159 this.b = b; +160 this.prototype = prototype; +161 +162 exp = -1.0 / getOrder(); +163 +164 // set the default values of the algorithm control parameters +165 setSafety(0.9); +166 setMinReduction(0.2); +167 setMaxGrowth(10.0); +168 +169 } +170 +171 /** Get the order of the method. +172 * @return order of the method +173 */ +174 public abstract int getOrder(); +175 +176 /** Get the safety factor for stepsize control. +177 * @return safety factor +178 */ +179 public double getSafety() { +180 return safety; +181 } +182 +183 /** Set the safety factor for stepsize control. +184 * @param safety safety factor +185 */ +186 public void setSafety(final double safety) { +187 this.safety = safety; +188 } +189 +190 /** {@inheritDoc} */ +191 @Override +192 public double integrate(final FirstOrderDifferentialEquations equations, +193 final double t0, final double[] y0, +194 final double t, final double[] y) +195 throws DerivativeException, IntegratorException { +196 +197 sanityChecks(equations, t0, y0, t, y); +198 setEquations(equations); +199 resetEvaluations(); +200 final boolean forward = t > t0; +201 +202 // create some internal working arrays +203 final int stages = c.length + 1; +204 if (y != y0) { +205 System.arraycopy(y0, 0, y, 0, y0.length); +206 } +207 final double[][] yDotK = new double[stages][y0.length]; +208 final double[] yTmp = new double[y0.length]; +209 +210 // set up an interpolator sharing the integrator arrays +211 AbstractStepInterpolator interpolator; +212 if (requiresDenseOutput() || (! eventsHandlersManager.isEmpty())) { +213 final RungeKuttaStepInterpolator rki = (RungeKuttaStepInterpolator) prototype.copy(); +214 rki.reinitialize(this, yTmp, yDotK, forward); +215 interpolator = rki; +216 } else { +217 interpolator = new DummyStepInterpolator(yTmp, yDotK[stages - 1], forward); +218 } +219 interpolator.storeTime(t0); +220 +221 // set up integration control objects +222 stepStart = t0; +223 double hNew = 0; +224 boolean firstTime = true; +225 for (StepHandler handler : stepHandlers) { +226 handler.reset(); +227 } +228 CombinedEventsManager manager = addEndTimeChecker(t0, t, eventsHandlersManager); +229 boolean lastStep = false; +230 +231 // main integration loop +232 while (!lastStep) { +233 +234 interpolator.shift(); +235 +236 double error = 0; +237 for (boolean loop = true; loop;) { +238 +239 if (firstTime || !fsal) { +240 // first stage +241 computeDerivatives(stepStart, y, yDotK[0]); +242 } +243 +244 if (firstTime) { +245 final double[] scale = new double[y0.length]; +246 if (vecAbsoluteTolerance == null) { +247 for (int i = 0; i < scale.length; ++i) { +248 scale[i] = scalAbsoluteTolerance + scalRelativeTolerance * Math.abs(y[i]); +249 } +250 } else { +251 for (int i = 0; i < scale.length; ++i) { +252 scale[i] = vecAbsoluteTolerance[i] + vecRelativeTolerance[i] * Math.abs(y[i]); +253 } +254 } +255 hNew = initializeStep(equations, forward, getOrder(), scale, +256 stepStart, y, yDotK[0], yTmp, yDotK[1]); +257 firstTime = false; +258 } +259 +260 stepSize = hNew; +261 +262 // next stages +263 for (int k = 1; k < stages; ++k) { +264 +265 for (int j = 0; j < y0.length; ++j) { +266 double sum = a[k-1][0] * yDotK[0][j]; +267 for (int l = 1; l < k; ++l) { +268 sum += a[k-1][l] * yDotK[l][j]; +269 } +270 yTmp[j] = y[j] + stepSize * sum; +271 } +272 +273 computeDerivatives(stepStart + c[k-1] * stepSize, yTmp, yDotK[k]); +274 +275 } +276 +277 // estimate the state at the end of the step +278 for (int j = 0; j < y0.length; ++j) { +279 double sum = b[0] * yDotK[0][j]; +280 for (int l = 1; l < stages; ++l) { +281 sum += b[l] * yDotK[l][j]; +282 } +283 yTmp[j] = y[j] + stepSize * sum; +284 } +285 +286 // estimate the error at the end of the step +287 error = estimateError(yDotK, y, yTmp, stepSize); +288 if (error <= 1.0) { +289 +290 // discrete events handling +291 interpolator.storeTime(stepStart + stepSize); +292 if (manager.evaluateStep(interpolator)) { +293 final double dt = manager.getEventTime() - stepStart; +294 if (Math.abs(dt) <= Math.ulp(stepStart)) { +295 // we cannot simply truncate the step, reject the current computation +296 // and let the loop compute another state with the truncated step. +297 // it is so small (much probably exactly 0 due to limited accuracy) +298 // that the code above would fail handling it. +299 // So we set up an artificial 0 size step by copying states +300 interpolator.storeTime(stepStart); +301 System.arraycopy(y, 0, yTmp, 0, y0.length); +302 hNew = 0; +303 stepSize = 0; +304 loop = false; +305 } else { +306 // reject the step to match exactly the next switch time +307 hNew = dt; +308 } +309 } else { +310 // accept the step +311 loop = false; +312 } +313 +314 } else { +315 // reject the step and attempt to reduce error by stepsize control +316 final double factor = +317 Math.min(maxGrowth, +318 Math.max(minReduction, safety * Math.pow(error, exp))); +319 hNew = filterStep(stepSize * factor, forward, false); +320 } +321 +322 } +323 +324 // the step has been accepted +325 final double nextStep = stepStart + stepSize; +326 System.arraycopy(yTmp, 0, y, 0, y0.length); +327 manager.stepAccepted(nextStep, y); +328 lastStep = manager.stop(); +329 +330 // provide the step data to the step handler +331 interpolator.storeTime(nextStep); +332 for (StepHandler handler : stepHandlers) { +333 handler.handleStep(interpolator, lastStep); +334 } +335 stepStart = nextStep; +336 +337 if (fsal) { +338 // save the last evaluation for the next step +339 System.arraycopy(yDotK[stages - 1], 0, yDotK[0], 0, y0.length); +340 } +341 +342 if (manager.reset(stepStart, y) && ! lastStep) { +343 // some event handler has triggered changes that +344 // invalidate the derivatives, we need to recompute them +345 computeDerivatives(stepStart, y, yDotK[0]); +346 } +347 +348 if (! lastStep) { +349 // in some rare cases we may get here with stepSize = 0, for example +350 // when an event occurs at integration start, reducing the first step +351 // to zero; we have to reset the step to some safe non zero value +352 stepSize = filterStep(stepSize, forward, true); +353 +354 // stepsize control for next step +355 final double factor = Math.min(maxGrowth, +356 Math.max(minReduction, +357 safety * Math.pow(error, exp))); +358 final double scaledH = stepSize * factor; +359 final double nextT = stepStart + scaledH; +360 final boolean nextIsLast = forward ? (nextT >= t) : (nextT <= t); +361 hNew = filterStep(scaledH, forward, nextIsLast); +362 } +363 +364 } +365 +366 final double stopTime = stepStart; +367 resetInternalState(); +368 return stopTime; +369 +370 } +371 +372 /** Get the minimal reduction factor for stepsize control. +373 * @return minimal reduction factor +374 */ +375 public double getMinReduction() { +376 return minReduction; +377 } +378 +379 /** Set the minimal reduction factor for stepsize control. +380 * @param minReduction minimal reduction factor +381 */ +382 public void setMinReduction(final double minReduction) { +383 this.minReduction = minReduction; +384 } +385 +386 /** Get the maximal growth factor for stepsize control. +387 * @return maximal growth factor +388 */ +389 public double getMaxGrowth() { +390 return maxGrowth; +391 } +392 +393 /** Set the maximal growth factor for stepsize control. +394 * @param maxGrowth maximal growth factor +395 */ +396 public void setMaxGrowth(final double maxGrowth) { +397 this.maxGrowth = maxGrowth; +398 } +399 +400 /** Compute the error ratio. +401 * @param yDotK derivatives computed during the first stages +402 * @param y0 estimate of the step at the start of the step +403 * @param y1 estimate of the step at the end of the step +404 * @param h current step +405 * @return error ratio, greater than 1 if step should be rejected +406 */ +407 protected abstract double estimateError(double[][] yDotK, +408 double[] y0, double[] y1, +409 double h); +410 +411 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/EulerIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/EulerIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,138 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 +021 /** +022 * This class implements a simple Euler integrator for Ordinary +023 * Differential Equations. +024 * +025 * <p>The Euler algorithm is the simplest one that can be used to +026 * integrate ordinary differential equations. It is a simple inversion +027 * of the forward difference expression : +028 * <code>f'=(f(t+h)-f(t))/h</code> which leads to +029 * <code>f(t+h)=f(t)+hf'</code>. The interpolation scheme used for +030 * dense output is the linear scheme already used for integration.</p> +031 * +032 * <p>This algorithm looks cheap because it needs only one function +033 * evaluation per step. However, as it uses linear estimates, it needs +034 * very small steps to achieve high accuracy, and small steps lead to +035 * numerical errors and instabilities.</p> +036 * +037 * <p>This algorithm is almost never used and has been included in +038 * this package only as a comparison reference for more useful +039 * integrators.</p> +040 * +041 * @see MidpointIntegrator +042 * @see ClassicalRungeKuttaIntegrator +043 * @see GillIntegrator +044 * @see ThreeEighthesIntegrator +045 * @version $Revision: 810196 $ $Date: 2009-09-01 15:47:46 -0400 (Tue, 01 Sep 2009) $ +046 * @since 1.2 +047 */ +048 +049 public class EulerIntegrator extends RungeKuttaIntegrator { +050 +051 /** Time steps Butcher array. */ +052 private static final double[] STATIC_C = { +053 }; +054 +055 /** Internal weights Butcher array. */ +056 private static final double[][] STATIC_A = { +057 }; +058 +059 /** Propagation weights Butcher array. */ +060 private static final double[] STATIC_B = { +061 1.0 +062 }; +063 +064 /** Simple constructor. +065 * Build an Euler integrator with the given step. +066 * @param step integration step +067 */ +068 public EulerIntegrator(final double step) { +069 super("Euler", STATIC_C, STATIC_A, STATIC_B, new EulerStepInterpolator(), step); +070 } +071 +072 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/GillIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/GillIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,138 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 +021 /** +022 * This class implements the Gill fourth order Runge-Kutta +023 * integrator for Ordinary Differential Equations . +024 +025 * <p>This method is an explicit Runge-Kutta method, its Butcher-array +026 * is the following one : +027 * <pre> +028 * 0 | 0 0 0 0 +029 * 1/2 | 1/2 0 0 0 +030 * 1/2 | (q-1)/2 (2-q)/2 0 0 +031 * 1 | 0 -q/2 (2+q)/2 0 +032 * |------------------------------- +033 * | 1/6 (2-q)/6 (2+q)/6 1/6 +034 * </pre> +035 * where q = sqrt(2)</p> +036 * +037 * @see EulerIntegrator +038 * @see ClassicalRungeKuttaIntegrator +039 * @see MidpointIntegrator +040 * @see ThreeEighthesIntegrator +041 * @version $Revision: 810196 $ $Date: 2009-09-01 15:47:46 -0400 (Tue, 01 Sep 2009) $ +042 * @since 1.2 +043 */ +044 +045 public class GillIntegrator extends RungeKuttaIntegrator { +046 +047 /** Time steps Butcher array. */ +048 private static final double[] STATIC_C = { +049 1.0 / 2.0, 1.0 / 2.0, 1.0 +050 }; +051 +052 /** Internal weights Butcher array. */ +053 private static final double[][] STATIC_A = { +054 { 1.0 / 2.0 }, +055 { (Math.sqrt(2.0) - 1.0) / 2.0, (2.0 - Math.sqrt(2.0)) / 2.0 }, +056 { 0.0, -Math.sqrt(2.0) / 2.0, (2.0 + Math.sqrt(2.0)) / 2.0 } +057 }; +058 +059 /** Propagation weights Butcher array. */ +060 private static final double[] STATIC_B = { +061 1.0 / 6.0, (2.0 - Math.sqrt(2.0)) / 6.0, (2.0 + Math.sqrt(2.0)) / 6.0, 1.0 / 6.0 +062 }; +063 +064 /** Simple constructor. +065 * Build a fourth-order Gill integrator with the given step. +066 * @param step integration step +067 */ +068 public GillIntegrator(final double step) { +069 super("Gill", STATIC_C, STATIC_A, STATIC_B, new GillStepInterpolator(), step); +070 } +071 +072 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1067 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 import org.apache.commons.math.ode.DerivativeException; +021 import org.apache.commons.math.ode.FirstOrderDifferentialEquations; +022 import org.apache.commons.math.ode.IntegratorException; +023 import org.apache.commons.math.ode.events.EventHandler; +024 import org.apache.commons.math.ode.sampling.AbstractStepInterpolator; +025 import org.apache.commons.math.ode.sampling.DummyStepInterpolator; +026 import org.apache.commons.math.ode.sampling.StepHandler; +027 +028 /** +029 * This class implements a Gragg-Bulirsch-Stoer integrator for +030 * Ordinary Differential Equations. +031 * +032 * <p>The Gragg-Bulirsch-Stoer algorithm is one of the most efficient +033 * ones currently available for smooth problems. It uses Richardson +034 * extrapolation to estimate what would be the solution if the step +035 * size could be decreased down to zero.</p> +036 * +037 * <p> +038 * This method changes both the step size and the order during +039 * integration, in order to minimize computation cost. It is +040 * particularly well suited when a very high precision is needed. The +041 * limit where this method becomes more efficient than high-order +042 * embedded Runge-Kutta methods like {@link DormandPrince853Integrator +043 * Dormand-Prince 8(5,3)} depends on the problem. Results given in the +044 * Hairer, Norsett and Wanner book show for example that this limit +045 * occurs for accuracy around 1e-6 when integrating Saltzam-Lorenz +046 * equations (the authors note this problem is <i>extremely sensitive +047 * to the errors in the first integration steps</i>), and around 1e-11 +048 * for a two dimensional celestial mechanics problems with seven +049 * bodies (pleiades problem, involving quasi-collisions for which +050 * <i>automatic step size control is essential</i>). +051 * </p> +052 * +053 * <p> +054 * This implementation is basically a reimplementation in Java of the +055 * <a +056 * href="http://www.unige.ch/math/folks/hairer/prog/nonstiff/odex.f">odex</a> +057 * fortran code by E. Hairer and G. Wanner. The redistribution policy +058 * for this code is available <a +059 * href="http://www.unige.ch/~hairer/prog/licence.txt">here</a>, for +060 * convenience, it is reproduced below.</p> +061 * </p> +062 * +063 * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0"> +064 * <tr><td>Copyright (c) 2004, Ernst Hairer</td></tr> +065 * +066 * <tr><td>Redistribution and use in source and binary forms, with or +067 * without modification, are permitted provided that the following +068 * conditions are met: +069 * <ul> +070 * <li>Redistributions of source code must retain the above copyright +071 * notice, this list of conditions and the following disclaimer.</li> +072 * <li>Redistributions in binary form must reproduce the above copyright +073 * notice, this list of conditions and the following disclaimer in the +074 * documentation and/or other materials provided with the distribution.</li> +075 * </ul></td></tr> +076 * +077 * <tr><td><strong>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +078 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +079 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +080 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +081 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +082 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +083 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +084 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +085 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +086 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +087 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</strong></td></tr> +088 * </table> +089 * +090 * @version $Revision: 919479 $ $Date: 2010-03-05 11:35:56 -0500 (Fri, 05 Mar 2010) $ +091 * @since 1.2 +092 */ +093 +094 public class GraggBulirschStoerIntegrator extends AdaptiveStepsizeIntegrator { +095 +096 /** Integrator method name. */ +097 private static final String METHOD_NAME = "Gragg-Bulirsch-Stoer"; +098 +099 /** maximal order. */ +100 private int maxOrder; +101 +102 /** step size sequence. */ +103 private int[] sequence; +104 +105 /** overall cost of applying step reduction up to iteration k+1, in number of calls. */ +106 private int[] costPerStep; +107 +108 /** cost per unit step. */ +109 private double[] costPerTimeUnit; +110 +111 /** optimal steps for each order. */ +112 private double[] optimalStep; +113 +114 /** extrapolation coefficients. */ +115 private double[][] coeff; +116 +117 /** stability check enabling parameter. */ +118 private boolean performTest; +119 +120 /** maximal number of checks for each iteration. */ +121 private int maxChecks; +122 +123 /** maximal number of iterations for which checks are performed. */ +124 private int maxIter; +125 +126 /** stepsize reduction factor in case of stability check failure. */ +127 private double stabilityReduction; +128 +129 /** first stepsize control factor. */ +130 private double stepControl1; +131 +132 /** second stepsize control factor. */ +133 private double stepControl2; +134 +135 /** third stepsize control factor. */ +136 private double stepControl3; +137 +138 /** fourth stepsize control factor. */ +139 private double stepControl4; +140 +141 /** first order control factor. */ +142 private double orderControl1; +143 +144 /** second order control factor. */ +145 private double orderControl2; +146 +147 /** dense outpute required. */ +148 private boolean denseOutput; +149 +150 /** use interpolation error in stepsize control. */ +151 private boolean useInterpolationError; +152 +153 /** interpolation order control parameter. */ +154 private int mudif; +155 +156 /** Simple constructor. +157 * Build a Gragg-Bulirsch-Stoer integrator with the given step +158 * bounds. All tuning parameters are set to their default +159 * values. The default step handler does nothing. +160 * @param minStep minimal step (must be positive even for backward +161 * integration), the last step can be smaller than this +162 * @param maxStep maximal step (must be positive even for backward +163 * integration) +164 * @param scalAbsoluteTolerance allowed absolute error +165 * @param scalRelativeTolerance allowed relative error +166 */ +167 public GraggBulirschStoerIntegrator(final double minStep, final double maxStep, +168 final double scalAbsoluteTolerance, +169 final double scalRelativeTolerance) { +170 super(METHOD_NAME, minStep, maxStep, +171 scalAbsoluteTolerance, scalRelativeTolerance); +172 denseOutput = requiresDenseOutput() || (! eventsHandlersManager.isEmpty()); +173 setStabilityCheck(true, -1, -1, -1); +174 setStepsizeControl(-1, -1, -1, -1); +175 setOrderControl(-1, -1, -1); +176 setInterpolationControl(true, -1); +177 } +178 +179 /** Simple constructor. +180 * Build a Gragg-Bulirsch-Stoer integrator with the given step +181 * bounds. All tuning parameters are set to their default +182 * values. The default step handler does nothing. +183 * @param minStep minimal step (must be positive even for backward +184 * integration), the last step can be smaller than this +185 * @param maxStep maximal step (must be positive even for backward +186 * integration) +187 * @param vecAbsoluteTolerance allowed absolute error +188 * @param vecRelativeTolerance allowed relative error +189 */ +190 public GraggBulirschStoerIntegrator(final double minStep, final double maxStep, +191 final double[] vecAbsoluteTolerance, +192 final double[] vecRelativeTolerance) { +193 super(METHOD_NAME, minStep, maxStep, +194 vecAbsoluteTolerance, vecRelativeTolerance); +195 denseOutput = requiresDenseOutput() || (! eventsHandlersManager.isEmpty()); +196 setStabilityCheck(true, -1, -1, -1); +197 setStepsizeControl(-1, -1, -1, -1); +198 setOrderControl(-1, -1, -1); +199 setInterpolationControl(true, -1); +200 } +201 +202 /** Set the stability check controls. +203 * <p>The stability check is performed on the first few iterations of +204 * the extrapolation scheme. If this test fails, the step is rejected +205 * and the stepsize is reduced.</p> +206 * <p>By default, the test is performed, at most during two +207 * iterations at each step, and at most once for each of these +208 * iterations. The default stepsize reduction factor is 0.5.</p> +209 * @param performStabilityCheck if true, stability check will be performed, +210 if false, the check will be skipped +211 * @param maxNumIter maximal number of iterations for which checks are +212 * performed (the number of iterations is reset to default if negative +213 * or null) +214 * @param maxNumChecks maximal number of checks for each iteration +215 * (the number of checks is reset to default if negative or null) +216 * @param stepsizeReductionFactor stepsize reduction factor in case of +217 * failure (the factor is reset to default if lower than 0.0001 or +218 * greater than 0.9999) +219 */ +220 public void setStabilityCheck(final boolean performStabilityCheck, +221 final int maxNumIter, final int maxNumChecks, +222 final double stepsizeReductionFactor) { +223 +224 this.performTest = performStabilityCheck; +225 this.maxIter = (maxNumIter <= 0) ? 2 : maxNumIter; +226 this.maxChecks = (maxNumChecks <= 0) ? 1 : maxNumChecks; +227 +228 if ((stepsizeReductionFactor < 0.0001) || (stepsizeReductionFactor > 0.9999)) { +229 this.stabilityReduction = 0.5; +230 } else { +231 this.stabilityReduction = stepsizeReductionFactor; +232 } +233 +234 } +235 +236 /** Set the step size control factors. +237 +238 * <p>The new step size hNew is computed from the old one h by: +239 * <pre> +240 * hNew = h * stepControl2 / (err/stepControl1)^(1/(2k+1)) +241 * </pre> +242 * where err is the scaled error and k the iteration number of the +243 * extrapolation scheme (counting from 0). The default values are +244 * 0.65 for stepControl1 and 0.94 for stepControl2.</p> +245 * <p>The step size is subject to the restriction: +246 * <pre> +247 * stepControl3^(1/(2k+1))/stepControl4 <= hNew/h <= 1/stepControl3^(1/(2k+1)) +248 * </pre> +249 * The default values are 0.02 for stepControl3 and 4.0 for +250 * stepControl4.</p> +251 * @param control1 first stepsize control factor (the factor is +252 * reset to default if lower than 0.0001 or greater than 0.9999) +253 * @param control2 second stepsize control factor (the factor +254 * is reset to default if lower than 0.0001 or greater than 0.9999) +255 * @param control3 third stepsize control factor (the factor is +256 * reset to default if lower than 0.0001 or greater than 0.9999) +257 * @param control4 fourth stepsize control factor (the factor +258 * is reset to default if lower than 1.0001 or greater than 999.9) +259 */ +260 public void setStepsizeControl(final double control1, final double control2, +261 final double control3, final double control4) { +262 +263 if ((control1 < 0.0001) || (control1 > 0.9999)) { +264 this.stepControl1 = 0.65; +265 } else { +266 this.stepControl1 = control1; +267 } +268 +269 if ((control2 < 0.0001) || (control2 > 0.9999)) { +270 this.stepControl2 = 0.94; +271 } else { +272 this.stepControl2 = control2; +273 } +274 +275 if ((control3 < 0.0001) || (control3 > 0.9999)) { +276 this.stepControl3 = 0.02; +277 } else { +278 this.stepControl3 = control3; +279 } +280 +281 if ((control4 < 1.0001) || (control4 > 999.9)) { +282 this.stepControl4 = 4.0; +283 } else { +284 this.stepControl4 = control4; +285 } +286 +287 } +288 +289 /** Set the order control parameters. +290 * <p>The Gragg-Bulirsch-Stoer method changes both the step size and +291 * the order during integration, in order to minimize computation +292 * cost. Each extrapolation step increases the order by 2, so the +293 * maximal order that will be used is always even, it is twice the +294 * maximal number of columns in the extrapolation table.</p> +295 * <pre> +296 * order is decreased if w(k-1) <= w(k) * orderControl1 +297 * order is increased if w(k) <= w(k-1) * orderControl2 +298 * </pre> +299 * <p>where w is the table of work per unit step for each order +300 * (number of function calls divided by the step length), and k is +301 * the current order.</p> +302 * <p>The default maximal order after construction is 18 (i.e. the +303 * maximal number of columns is 9). The default values are 0.8 for +304 * orderControl1 and 0.9 for orderControl2.</p> +305 * @param maximalOrder maximal order in the extrapolation table (the +306 * maximal order is reset to default if order <= 6 or odd) +307 * @param control1 first order control factor (the factor is +308 * reset to default if lower than 0.0001 or greater than 0.9999) +309 * @param control2 second order control factor (the factor +310 * is reset to default if lower than 0.0001 or greater than 0.9999) +311 */ +312 public void setOrderControl(final int maximalOrder, +313 final double control1, final double control2) { +314 +315 if ((maximalOrder <= 6) || (maximalOrder % 2 != 0)) { +316 this.maxOrder = 18; +317 } +318 +319 if ((control1 < 0.0001) || (control1 > 0.9999)) { +320 this.orderControl1 = 0.8; +321 } else { +322 this.orderControl1 = control1; +323 } +324 +325 if ((control2 < 0.0001) || (control2 > 0.9999)) { +326 this.orderControl2 = 0.9; +327 } else { +328 this.orderControl2 = control2; +329 } +330 +331 // reinitialize the arrays +332 initializeArrays(); +333 +334 } +335 +336 /** {@inheritDoc} */ +337 @Override +338 public void addStepHandler (final StepHandler handler) { +339 +340 super.addStepHandler(handler); +341 denseOutput = requiresDenseOutput() || (! eventsHandlersManager.isEmpty()); +342 +343 // reinitialize the arrays +344 initializeArrays(); +345 +346 } +347 +348 /** {@inheritDoc} */ +349 @Override +350 public void addEventHandler(final EventHandler function, +351 final double maxCheckInterval, +352 final double convergence, +353 final int maxIterationCount) { +354 super.addEventHandler(function, maxCheckInterval, convergence, maxIterationCount); +355 denseOutput = requiresDenseOutput() || (! eventsHandlersManager.isEmpty()); +356 +357 // reinitialize the arrays +358 initializeArrays(); +359 +360 } +361 +362 /** Initialize the integrator internal arrays. */ +363 private void initializeArrays() { +364 +365 final int size = maxOrder / 2; +366 +367 if ((sequence == null) || (sequence.length != size)) { +368 // all arrays should be reallocated with the right size +369 sequence = new int[size]; +370 costPerStep = new int[size]; +371 coeff = new double[size][]; +372 costPerTimeUnit = new double[size]; +373 optimalStep = new double[size]; +374 } +375 +376 if (denseOutput) { +377 // step size sequence: 2, 6, 10, 14, ... +378 for (int k = 0; k < size; ++k) { +379 sequence[k] = 4 * k + 2; +380 } +381 } else { +382 // step size sequence: 2, 4, 6, 8, ... +383 for (int k = 0; k < size; ++k) { +384 sequence[k] = 2 * (k + 1); +385 } +386 } +387 +388 // initialize the order selection cost array +389 // (number of function calls for each column of the extrapolation table) +390 costPerStep[0] = sequence[0] + 1; +391 for (int k = 1; k < size; ++k) { +392 costPerStep[k] = costPerStep[k-1] + sequence[k]; +393 } +394 +395 // initialize the extrapolation tables +396 for (int k = 0; k < size; ++k) { +397 coeff[k] = (k > 0) ? new double[k] : null; +398 for (int l = 0; l < k; ++l) { +399 final double ratio = ((double) sequence[k]) / sequence[k-l-1]; +400 coeff[k][l] = 1.0 / (ratio * ratio - 1.0); +401 } +402 } +403 +404 } +405 +406 /** Set the interpolation order control parameter. +407 * The interpolation order for dense output is 2k - mudif + 1. The +408 * default value for mudif is 4 and the interpolation error is used +409 * in stepsize control by default. +410 +411 * @param useInterpolationErrorForControl if true, interpolation error is used +412 * for stepsize control +413 * @param mudifControlParameter interpolation order control parameter (the parameter +414 * is reset to default if <= 0 or >= 7) +415 */ +416 public void setInterpolationControl(final boolean useInterpolationErrorForControl, +417 final int mudifControlParameter) { +418 +419 this.useInterpolationError = useInterpolationErrorForControl; +420 +421 if ((mudifControlParameter <= 0) || (mudifControlParameter >= 7)) { +422 this.mudif = 4; +423 } else { +424 this.mudif = mudifControlParameter; +425 } +426 +427 } +428 +429 /** Update scaling array. +430 * @param y1 first state vector to use for scaling +431 * @param y2 second state vector to use for scaling +432 * @param scale scaling array to update +433 */ +434 private void rescale(final double[] y1, final double[] y2, final double[] scale) { +435 if (vecAbsoluteTolerance == null) { +436 for (int i = 0; i < scale.length; ++i) { +437 final double yi = Math.max(Math.abs(y1[i]), Math.abs(y2[i])); +438 scale[i] = scalAbsoluteTolerance + scalRelativeTolerance * yi; +439 } +440 } else { +441 for (int i = 0; i < scale.length; ++i) { +442 final double yi = Math.max(Math.abs(y1[i]), Math.abs(y2[i])); +443 scale[i] = vecAbsoluteTolerance[i] + vecRelativeTolerance[i] * yi; +444 } +445 } +446 } +447 +448 /** Perform integration over one step using substeps of a modified +449 * midpoint method. +450 * @param t0 initial time +451 * @param y0 initial value of the state vector at t0 +452 * @param step global step +453 * @param k iteration number (from 0 to sequence.length - 1) +454 * @param scale scaling array +455 * @param f placeholder where to put the state vector derivatives at each substep +456 * (element 0 already contains initial derivative) +457 * @param yMiddle placeholder where to put the state vector at the middle of the step +458 * @param yEnd placeholder where to put the state vector at the end +459 * @param yTmp placeholder for one state vector +460 * @return true if computation was done properly, +461 * false if stability check failed before end of computation +462 * @throws DerivativeException this exception is propagated to the caller if the +463 * underlying user function triggers one +464 */ +465 private boolean tryStep(final double t0, final double[] y0, final double step, final int k, +466 final double[] scale, final double[][] f, +467 final double[] yMiddle, final double[] yEnd, +468 final double[] yTmp) +469 throws DerivativeException { +470 +471 final int n = sequence[k]; +472 final double subStep = step / n; +473 final double subStep2 = 2 * subStep; +474 +475 // first substep +476 double t = t0 + subStep; +477 for (int i = 0; i < y0.length; ++i) { +478 yTmp[i] = y0[i]; +479 yEnd[i] = y0[i] + subStep * f[0][i]; +480 } +481 computeDerivatives(t, yEnd, f[1]); +482 +483 // other substeps +484 for (int j = 1; j < n; ++j) { +485 +486 if (2 * j == n) { +487 // save the point at the middle of the step +488 System.arraycopy(yEnd, 0, yMiddle, 0, y0.length); +489 } +490 +491 t += subStep; +492 for (int i = 0; i < y0.length; ++i) { +493 final double middle = yEnd[i]; +494 yEnd[i] = yTmp[i] + subStep2 * f[j][i]; +495 yTmp[i] = middle; +496 } +497 +498 computeDerivatives(t, yEnd, f[j+1]); +499 +500 // stability check +501 if (performTest && (j <= maxChecks) && (k < maxIter)) { +502 double initialNorm = 0.0; +503 for (int l = 0; l < y0.length; ++l) { +504 final double ratio = f[0][l] / scale[l]; +505 initialNorm += ratio * ratio; +506 } +507 double deltaNorm = 0.0; +508 for (int l = 0; l < y0.length; ++l) { +509 final double ratio = (f[j+1][l] - f[0][l]) / scale[l]; +510 deltaNorm += ratio * ratio; +511 } +512 if (deltaNorm > 4 * Math.max(1.0e-15, initialNorm)) { +513 return false; +514 } +515 } +516 +517 } +518 +519 // correction of the last substep (at t0 + step) +520 for (int i = 0; i < y0.length; ++i) { +521 yEnd[i] = 0.5 * (yTmp[i] + yEnd[i] + subStep * f[n][i]); +522 } +523 +524 return true; +525 +526 } +527 +528 /** Extrapolate a vector. +529 * @param offset offset to use in the coefficients table +530 * @param k index of the last updated point +531 * @param diag working diagonal of the Aitken-Neville's +532 * triangle, without the last element +533 * @param last last element +534 */ +535 private void extrapolate(final int offset, final int k, +536 final double[][] diag, final double[] last) { +537 +538 // update the diagonal +539 for (int j = 1; j < k; ++j) { +540 for (int i = 0; i < last.length; ++i) { +541 // Aitken-Neville's recursive formula +542 diag[k-j-1][i] = diag[k-j][i] + +543 coeff[k+offset][j-1] * (diag[k-j][i] - diag[k-j-1][i]); +544 } +545 } +546 +547 // update the last element +548 for (int i = 0; i < last.length; ++i) { +549 // Aitken-Neville's recursive formula +550 last[i] = diag[0][i] + coeff[k+offset][k-1] * (diag[0][i] - last[i]); +551 } +552 } +553 +554 /** {@inheritDoc} */ +555 @Override +556 public double integrate(final FirstOrderDifferentialEquations equations, +557 final double t0, final double[] y0, final double t, final double[] y) +558 throws DerivativeException, IntegratorException { +559 +560 sanityChecks(equations, t0, y0, t, y); +561 setEquations(equations); +562 resetEvaluations(); +563 final boolean forward = t > t0; +564 +565 // create some internal working arrays +566 final double[] yDot0 = new double[y0.length]; +567 final double[] y1 = new double[y0.length]; +568 final double[] yTmp = new double[y0.length]; +569 final double[] yTmpDot = new double[y0.length]; +570 +571 final double[][] diagonal = new double[sequence.length-1][]; +572 final double[][] y1Diag = new double[sequence.length-1][]; +573 for (int k = 0; k < sequence.length-1; ++k) { +574 diagonal[k] = new double[y0.length]; +575 y1Diag[k] = new double[y0.length]; +576 } +577 +578 final double[][][] fk = new double[sequence.length][][]; +579 for (int k = 0; k < sequence.length; ++k) { +580 +581 fk[k] = new double[sequence[k] + 1][]; +582 +583 // all substeps start at the same point, so share the first array +584 fk[k][0] = yDot0; +585 +586 for (int l = 0; l < sequence[k]; ++l) { +587 fk[k][l+1] = new double[y0.length]; +588 } +589 +590 } +591 +592 if (y != y0) { +593 System.arraycopy(y0, 0, y, 0, y0.length); +594 } +595 +596 double[] yDot1 = null; +597 double[][] yMidDots = null; +598 if (denseOutput) { +599 yDot1 = new double[y0.length]; +600 yMidDots = new double[1 + 2 * sequence.length][]; +601 for (int j = 0; j < yMidDots.length; ++j) { +602 yMidDots[j] = new double[y0.length]; +603 } +604 } else { +605 yMidDots = new double[1][]; +606 yMidDots[0] = new double[y0.length]; +607 } +608 +609 // initial scaling +610 final double[] scale = new double[y0.length]; +611 rescale(y, y, scale); +612 +613 // initial order selection +614 final double tol = +615 (vecRelativeTolerance == null) ? scalRelativeTolerance : vecRelativeTolerance[0]; +616 final double log10R = Math.log(Math.max(1.0e-10, tol)) / Math.log(10.0); +617 int targetIter = Math.max(1, +618 Math.min(sequence.length - 2, +619 (int) Math.floor(0.5 - 0.6 * log10R))); +620 // set up an interpolator sharing the integrator arrays +621 AbstractStepInterpolator interpolator = null; +622 if (denseOutput || (! eventsHandlersManager.isEmpty())) { +623 interpolator = new GraggBulirschStoerStepInterpolator(y, yDot0, +624 y1, yDot1, +625 yMidDots, forward); +626 } else { +627 interpolator = new DummyStepInterpolator(y, yDot1, forward); +628 } +629 interpolator.storeTime(t0); +630 +631 stepStart = t0; +632 double hNew = 0; +633 double maxError = Double.MAX_VALUE; +634 boolean previousRejected = false; +635 boolean firstTime = true; +636 boolean newStep = true; +637 boolean lastStep = false; +638 boolean firstStepAlreadyComputed = false; +639 for (StepHandler handler : stepHandlers) { +640 handler.reset(); +641 } +642 costPerTimeUnit[0] = 0; +643 while (! lastStep) { +644 +645 double error; +646 boolean reject = false; +647 +648 if (newStep) { +649 +650 interpolator.shift(); +651 +652 // first evaluation, at the beginning of the step +653 if (! firstStepAlreadyComputed) { +654 computeDerivatives(stepStart, y, yDot0); +655 } +656 +657 if (firstTime) { +658 +659 hNew = initializeStep(equations, forward, +660 2 * targetIter + 1, scale, +661 stepStart, y, yDot0, yTmp, yTmpDot); +662 +663 if (! forward) { +664 hNew = -hNew; +665 } +666 +667 } +668 +669 newStep = false; +670 +671 } +672 +673 stepSize = hNew; +674 +675 // step adjustment near bounds +676 if ((forward && (stepStart + stepSize > t)) || +677 ((! forward) && (stepStart + stepSize < t))) { +678 stepSize = t - stepStart; +679 } +680 final double nextT = stepStart + stepSize; +681 lastStep = forward ? (nextT >= t) : (nextT <= t); +682 +683 // iterate over several substep sizes +684 int k = -1; +685 for (boolean loop = true; loop; ) { +686 +687 ++k; +688 +689 // modified midpoint integration with the current substep +690 if ( ! tryStep(stepStart, y, stepSize, k, scale, fk[k], +691 (k == 0) ? yMidDots[0] : diagonal[k-1], +692 (k == 0) ? y1 : y1Diag[k-1], +693 yTmp)) { +694 +695 // the stability check failed, we reduce the global step +696 hNew = Math.abs(filterStep(stepSize * stabilityReduction, forward, false)); +697 reject = true; +698 loop = false; +699 +700 } else { +701 +702 // the substep was computed successfully +703 if (k > 0) { +704 +705 // extrapolate the state at the end of the step +706 // using last iteration data +707 extrapolate(0, k, y1Diag, y1); +708 rescale(y, y1, scale); +709 +710 // estimate the error at the end of the step. +711 error = 0; +712 for (int j = 0; j < y0.length; ++j) { +713 final double e = Math.abs(y1[j] - y1Diag[0][j]) / scale[j]; +714 error += e * e; +715 } +716 error = Math.sqrt(error / y0.length); +717 +718 if ((error > 1.0e15) || ((k > 1) && (error > maxError))) { +719 // error is too big, we reduce the global step +720 hNew = Math.abs(filterStep(stepSize * stabilityReduction, forward, false)); +721 reject = true; +722 loop = false; +723 } else { +724 +725 maxError = Math.max(4 * error, 1.0); +726 +727 // compute optimal stepsize for this order +728 final double exp = 1.0 / (2 * k + 1); +729 double fac = stepControl2 / Math.pow(error / stepControl1, exp); +730 final double pow = Math.pow(stepControl3, exp); +731 fac = Math.max(pow / stepControl4, Math.min(1 / pow, fac)); +732 optimalStep[k] = Math.abs(filterStep(stepSize * fac, forward, true)); +733 costPerTimeUnit[k] = costPerStep[k] / optimalStep[k]; +734 +735 // check convergence +736 switch (k - targetIter) { +737 +738 case -1 : +739 if ((targetIter > 1) && ! previousRejected) { +740 +741 // check if we can stop iterations now +742 if (error <= 1.0) { +743 // convergence have been reached just before targetIter +744 loop = false; +745 } else { +746 // estimate if there is a chance convergence will +747 // be reached on next iteration, using the +748 // asymptotic evolution of error +749 final double ratio = ((double) sequence [targetIter] * sequence[targetIter + 1]) / +750 (sequence[0] * sequence[0]); +751 if (error > ratio * ratio) { +752 // we don't expect to converge on next iteration +753 // we reject the step immediately and reduce order +754 reject = true; +755 loop = false; +756 targetIter = k; +757 if ((targetIter > 1) && +758 (costPerTimeUnit[targetIter-1] < +759 orderControl1 * costPerTimeUnit[targetIter])) { +760 --targetIter; +761 } +762 hNew = optimalStep[targetIter]; +763 } +764 } +765 } +766 break; +767 +768 case 0: +769 if (error <= 1.0) { +770 // convergence has been reached exactly at targetIter +771 loop = false; +772 } else { +773 // estimate if there is a chance convergence will +774 // be reached on next iteration, using the +775 // asymptotic evolution of error +776 final double ratio = ((double) sequence[k+1]) / sequence[0]; +777 if (error > ratio * ratio) { +778 // we don't expect to converge on next iteration +779 // we reject the step immediately +780 reject = true; +781 loop = false; +782 if ((targetIter > 1) && +783 (costPerTimeUnit[targetIter-1] < +784 orderControl1 * costPerTimeUnit[targetIter])) { +785 --targetIter; +786 } +787 hNew = optimalStep[targetIter]; +788 } +789 } +790 break; +791 +792 case 1 : +793 if (error > 1.0) { +794 reject = true; +795 if ((targetIter > 1) && +796 (costPerTimeUnit[targetIter-1] < +797 orderControl1 * costPerTimeUnit[targetIter])) { +798 --targetIter; +799 } +800 hNew = optimalStep[targetIter]; +801 } +802 loop = false; +803 break; +804 +805 default : +806 if ((firstTime || lastStep) && (error <= 1.0)) { +807 loop = false; +808 } +809 break; +810 +811 } +812 +813 } +814 } +815 } +816 } +817 +818 // dense output handling +819 double hInt = getMaxStep(); +820 if (denseOutput && ! reject) { +821 +822 // extrapolate state at middle point of the step +823 for (int j = 1; j <= k; ++j) { +824 extrapolate(0, j, diagonal, yMidDots[0]); +825 } +826 +827 // derivative at end of step +828 computeDerivatives(stepStart + stepSize, y1, yDot1); +829 +830 final int mu = 2 * k - mudif + 3; +831 +832 for (int l = 0; l < mu; ++l) { +833 +834 // derivative at middle point of the step +835 final int l2 = l / 2; +836 double factor = Math.pow(0.5 * sequence[l2], l); +837 int middleIndex = fk[l2].length / 2; +838 for (int i = 0; i < y0.length; ++i) { +839 yMidDots[l+1][i] = factor * fk[l2][middleIndex + l][i]; +840 } +841 for (int j = 1; j <= k - l2; ++j) { +842 factor = Math.pow(0.5 * sequence[j + l2], l); +843 middleIndex = fk[l2+j].length / 2; +844 for (int i = 0; i < y0.length; ++i) { +845 diagonal[j-1][i] = factor * fk[l2+j][middleIndex+l][i]; +846 } +847 extrapolate(l2, j, diagonal, yMidDots[l+1]); +848 } +849 for (int i = 0; i < y0.length; ++i) { +850 yMidDots[l+1][i] *= stepSize; +851 } +852 +853 // compute centered differences to evaluate next derivatives +854 for (int j = (l + 1) / 2; j <= k; ++j) { +855 for (int m = fk[j].length - 1; m >= 2 * (l + 1); --m) { +856 for (int i = 0; i < y0.length; ++i) { +857 fk[j][m][i] -= fk[j][m-2][i]; +858 } +859 } +860 } +861 +862 } +863 +864 if (mu >= 0) { +865 +866 // estimate the dense output coefficients +867 final GraggBulirschStoerStepInterpolator gbsInterpolator +868 = (GraggBulirschStoerStepInterpolator) interpolator; +869 gbsInterpolator.computeCoefficients(mu, stepSize); +870 +871 if (useInterpolationError) { +872 // use the interpolation error to limit stepsize +873 final double interpError = gbsInterpolator.estimateError(scale); +874 hInt = Math.abs(stepSize / Math.max(Math.pow(interpError, 1.0 / (mu+4)), +875 0.01)); +876 if (interpError > 10.0) { +877 hNew = hInt; +878 reject = true; +879 } +880 } +881 +882 // Discrete events handling +883 if (!reject) { +884 interpolator.storeTime(stepStart + stepSize); +885 if (eventsHandlersManager.evaluateStep(interpolator)) { +886 final double dt = eventsHandlersManager.getEventTime() - stepStart; +887 if (Math.abs(dt) > Math.ulp(stepStart)) { +888 // reject the step to match exactly the next switch time +889 hNew = Math.abs(dt); +890 reject = true; +891 } +892 } +893 } +894 +895 } +896 +897 if (!reject) { +898 // we will reuse the slope for the beginning of next step +899 firstStepAlreadyComputed = true; +900 System.arraycopy(yDot1, 0, yDot0, 0, y0.length); +901 } +902 +903 } +904 +905 if (! reject) { +906 +907 // store end of step state +908 final double nextStep = stepStart + stepSize; +909 System.arraycopy(y1, 0, y, 0, y0.length); +910 +911 eventsHandlersManager.stepAccepted(nextStep, y); +912 if (eventsHandlersManager.stop()) { +913 lastStep = true; +914 } +915 +916 // provide the step data to the step handler +917 interpolator.storeTime(nextStep); +918 for (StepHandler handler : stepHandlers) { +919 handler.handleStep(interpolator, lastStep); +920 } +921 stepStart = nextStep; +922 +923 if (eventsHandlersManager.reset(stepStart, y) && ! lastStep) { +924 // some switching function has triggered changes that +925 // invalidate the derivatives, we need to recompute them +926 firstStepAlreadyComputed = false; +927 } +928 +929 int optimalIter; +930 if (k == 1) { +931 optimalIter = 2; +932 if (previousRejected) { +933 optimalIter = 1; +934 } +935 } else if (k <= targetIter) { +936 optimalIter = k; +937 if (costPerTimeUnit[k-1] < orderControl1 * costPerTimeUnit[k]) { +938 optimalIter = k-1; +939 } else if (costPerTimeUnit[k] < orderControl2 * costPerTimeUnit[k-1]) { +940 optimalIter = Math.min(k+1, sequence.length - 2); +941 } +942 } else { +943 optimalIter = k - 1; +944 if ((k > 2) && +945 (costPerTimeUnit[k-2] < orderControl1 * costPerTimeUnit[k-1])) { +946 optimalIter = k - 2; +947 } +948 if (costPerTimeUnit[k] < orderControl2 * costPerTimeUnit[optimalIter]) { +949 optimalIter = Math.min(k, sequence.length - 2); +950 } +951 } +952 +953 if (previousRejected) { +954 // after a rejected step neither order nor stepsize +955 // should increase +956 targetIter = Math.min(optimalIter, k); +957 hNew = Math.min(Math.abs(stepSize), optimalStep[targetIter]); +958 } else { +959 // stepsize control +960 if (optimalIter <= k) { +961 hNew = optimalStep[optimalIter]; +962 } else { +963 if ((k < targetIter) && +964 (costPerTimeUnit[k] < orderControl2 * costPerTimeUnit[k-1])) { +965 hNew = filterStep(optimalStep[k] * costPerStep[optimalIter+1] / costPerStep[k], +966 forward, false); +967 } else { +968 hNew = filterStep(optimalStep[k] * costPerStep[optimalIter] / costPerStep[k], +969 forward, false); +970 } +971 } +972 +973 targetIter = optimalIter; +974 +975 } +976 +977 newStep = true; +978 +979 } +980 +981 hNew = Math.min(hNew, hInt); +982 if (! forward) { +983 hNew = -hNew; +984 } +985 +986 firstTime = false; +987 +988 if (reject) { +989 lastStep = false; +990 previousRejected = true; +991 } else { +992 previousRejected = false; +993 } +994 +995 } +996 +997 return stepStart; +998 +999 } +1000 +1001 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/HighamHall54Integrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/HighamHall54Integrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,196 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 +021 /** +022 * This class implements the 5(4) Higham and Hall integrator for +023 * Ordinary Differential Equations. +024 * +025 * <p>This integrator is an embedded Runge-Kutta integrator +026 * of order 5(4) used in local extrapolation mode (i.e. the solution +027 * is computed using the high order formula) with stepsize control +028 * (and automatic step initialization) and continuous output. This +029 * method uses 7 functions evaluations per step.</p> +030 * +031 * @version $Revision: 810196 $ $Date: 2009-09-01 15:47:46 -0400 (Tue, 01 Sep 2009) $ +032 * @since 1.2 +033 */ +034 +035 public class HighamHall54Integrator extends EmbeddedRungeKuttaIntegrator { +036 +037 /** Integrator method name. */ +038 private static final String METHOD_NAME = "Higham-Hall 5(4)"; +039 +040 /** Time steps Butcher array. */ +041 private static final double[] STATIC_C = { +042 2.0/9.0, 1.0/3.0, 1.0/2.0, 3.0/5.0, 1.0, 1.0 +043 }; +044 +045 /** Internal weights Butcher array. */ +046 private static final double[][] STATIC_A = { +047 {2.0/9.0}, +048 {1.0/12.0, 1.0/4.0}, +049 {1.0/8.0, 0.0, 3.0/8.0}, +050 {91.0/500.0, -27.0/100.0, 78.0/125.0, 8.0/125.0}, +051 {-11.0/20.0, 27.0/20.0, 12.0/5.0, -36.0/5.0, 5.0}, +052 {1.0/12.0, 0.0, 27.0/32.0, -4.0/3.0, 125.0/96.0, 5.0/48.0} +053 }; +054 +055 /** Propagation weights Butcher array. */ +056 private static final double[] STATIC_B = { +057 1.0/12.0, 0.0, 27.0/32.0, -4.0/3.0, 125.0/96.0, 5.0/48.0, 0.0 +058 }; +059 +060 /** Error weights Butcher array. */ +061 private static final double[] STATIC_E = { +062 -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 +063 }; +064 +065 /** Simple constructor. +066 * Build a fifth order Higham and Hall integrator with the given step bounds +067 * @param minStep minimal step (must be positive even for backward +068 * integration), the last step can be smaller than this +069 * @param maxStep maximal step (must be positive even for backward +070 * integration) +071 * @param scalAbsoluteTolerance allowed absolute error +072 * @param scalRelativeTolerance allowed relative error +073 */ +074 public HighamHall54Integrator(final double minStep, final double maxStep, +075 final double scalAbsoluteTolerance, +076 final double scalRelativeTolerance) { +077 super(METHOD_NAME, false, STATIC_C, STATIC_A, STATIC_B, new HighamHall54StepInterpolator(), +078 minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); +079 } +080 +081 /** Simple constructor. +082 * Build a fifth order Higham and Hall integrator with the given step bounds +083 * @param minStep minimal step (must be positive even for backward +084 * integration), the last step can be smaller than this +085 * @param maxStep maximal step (must be positive even for backward +086 * integration) +087 * @param vecAbsoluteTolerance allowed absolute error +088 * @param vecRelativeTolerance allowed relative error +089 */ +090 public HighamHall54Integrator(final double minStep, final double maxStep, +091 final double[] vecAbsoluteTolerance, +092 final double[] vecRelativeTolerance) { +093 super(METHOD_NAME, false, STATIC_C, STATIC_A, STATIC_B, new HighamHall54StepInterpolator(), +094 minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); +095 } +096 +097 /** {@inheritDoc} */ +098 @Override +099 public int getOrder() { +100 return 5; +101 } +102 +103 /** {@inheritDoc} */ +104 @Override +105 protected double estimateError(final double[][] yDotK, +106 final double[] y0, final double[] y1, +107 final double h) { +108 +109 double error = 0; +110 +111 for (int j = 0; j < y0.length; ++j) { +112 double errSum = STATIC_E[0] * yDotK[0][j]; +113 for (int l = 1; l < STATIC_E.length; ++l) { +114 errSum += STATIC_E[l] * yDotK[l][j]; +115 } +116 +117 final double yScale = Math.max(Math.abs(y0[j]), Math.abs(y1[j])); +118 final double tol = (vecAbsoluteTolerance == null) ? +119 (scalAbsoluteTolerance + scalRelativeTolerance * yScale) : +120 (vecAbsoluteTolerance[j] + vecRelativeTolerance[j] * yScale); +121 final double ratio = h * errSum / tol; +122 error += ratio * ratio; +123 +124 } +125 +126 return Math.sqrt(error / y0.length); +127 +128 } +129 +130 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/MidpointIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/MidpointIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,134 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 +021 /** +022 * This class implements a second order Runge-Kutta integrator for +023 * Ordinary Differential Equations. +024 * +025 * <p>This method is an explicit Runge-Kutta method, its Butcher-array +026 * is the following one : +027 * <pre> +028 * 0 | 0 0 +029 * 1/2 | 1/2 0 +030 * |---------- +031 * | 0 1 +032 * </pre> +033 * </p> +034 * +035 * @see EulerIntegrator +036 * @see ClassicalRungeKuttaIntegrator +037 * @see GillIntegrator +038 * +039 * @version $Revision: 810196 $ $Date: 2009-09-01 15:47:46 -0400 (Tue, 01 Sep 2009) $ +040 * @since 1.2 +041 */ +042 +043 public class MidpointIntegrator extends RungeKuttaIntegrator { +044 +045 /** Time steps Butcher array. */ +046 private static final double[] STATIC_C = { +047 1.0 / 2.0 +048 }; +049 +050 /** Internal weights Butcher array. */ +051 private static final double[][] STATIC_A = { +052 { 1.0 / 2.0 } +053 }; +054 +055 /** Propagation weights Butcher array. */ +056 private static final double[] STATIC_B = { +057 0.0, 1.0 +058 }; +059 +060 /** Simple constructor. +061 * Build a midpoint integrator with the given step. +062 * @param step integration step +063 */ +064 public MidpointIntegrator(final double step) { +065 super("midpoint", STATIC_C, STATIC_A, STATIC_B, new MidpointStepInterpolator(), step); +066 } +067 +068 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,291 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 +021 import org.apache.commons.math.ode.AbstractIntegrator; +022 import org.apache.commons.math.ode.DerivativeException; +023 import org.apache.commons.math.ode.FirstOrderDifferentialEquations; +024 import org.apache.commons.math.ode.IntegratorException; +025 import org.apache.commons.math.ode.events.CombinedEventsManager; +026 import org.apache.commons.math.ode.sampling.AbstractStepInterpolator; +027 import org.apache.commons.math.ode.sampling.DummyStepInterpolator; +028 import org.apache.commons.math.ode.sampling.StepHandler; +029 +030 /** +031 * This class implements the common part of all fixed step Runge-Kutta +032 * integrators for Ordinary Differential Equations. +033 * +034 * <p>These methods are explicit Runge-Kutta methods, their Butcher +035 * arrays are as follows : +036 * <pre> +037 * 0 | +038 * c2 | a21 +039 * c3 | a31 a32 +040 * ... | ... +041 * cs | as1 as2 ... ass-1 +042 * |-------------------------- +043 * | b1 b2 ... bs-1 bs +044 * </pre> +045 * </p> +046 * +047 * @see EulerIntegrator +048 * @see ClassicalRungeKuttaIntegrator +049 * @see GillIntegrator +050 * @see MidpointIntegrator +051 * @version $Revision: 927202 $ $Date: 2010-03-24 18:11:51 -0400 (Wed, 24 Mar 2010) $ +052 * @since 1.2 +053 */ +054 +055 public abstract class RungeKuttaIntegrator extends AbstractIntegrator { +056 +057 /** Time steps from Butcher array (without the first zero). */ +058 private final double[] c; +059 +060 /** Internal weights from Butcher array (without the first empty row). */ +061 private final double[][] a; +062 +063 /** External weights for the high order method from Butcher array. */ +064 private final double[] b; +065 +066 /** Prototype of the step interpolator. */ +067 private final RungeKuttaStepInterpolator prototype; +068 +069 /** Integration step. */ +070 private final double step; +071 +072 /** Simple constructor. +073 * Build a Runge-Kutta integrator with the given +074 * step. The default step handler does nothing. +075 * @param name name of the method +076 * @param c time steps from Butcher array (without the first zero) +077 * @param a internal weights from Butcher array (without the first empty row) +078 * @param b propagation weights for the high order method from Butcher array +079 * @param prototype prototype of the step interpolator to use +080 * @param step integration step +081 */ +082 protected RungeKuttaIntegrator(final String name, +083 final double[] c, final double[][] a, final double[] b, +084 final RungeKuttaStepInterpolator prototype, +085 final double step) { +086 super(name); +087 this.c = c; +088 this.a = a; +089 this.b = b; +090 this.prototype = prototype; +091 this.step = Math.abs(step); +092 } +093 +094 /** {@inheritDoc} */ +095 public double integrate(final FirstOrderDifferentialEquations equations, +096 final double t0, final double[] y0, +097 final double t, final double[] y) +098 throws DerivativeException, IntegratorException { +099 +100 sanityChecks(equations, t0, y0, t, y); +101 setEquations(equations); +102 resetEvaluations(); +103 final boolean forward = t > t0; +104 +105 // create some internal working arrays +106 final int stages = c.length + 1; +107 if (y != y0) { +108 System.arraycopy(y0, 0, y, 0, y0.length); +109 } +110 final double[][] yDotK = new double[stages][]; +111 for (int i = 0; i < stages; ++i) { +112 yDotK [i] = new double[y0.length]; +113 } +114 final double[] yTmp = new double[y0.length]; +115 +116 // set up an interpolator sharing the integrator arrays +117 AbstractStepInterpolator interpolator; +118 if (requiresDenseOutput() || (! eventsHandlersManager.isEmpty())) { +119 final RungeKuttaStepInterpolator rki = (RungeKuttaStepInterpolator) prototype.copy(); +120 rki.reinitialize(this, yTmp, yDotK, forward); +121 interpolator = rki; +122 } else { +123 interpolator = new DummyStepInterpolator(yTmp, yDotK[stages - 1], forward); +124 } +125 interpolator.storeTime(t0); +126 +127 // set up integration control objects +128 stepStart = t0; +129 stepSize = forward ? step : -step; +130 for (StepHandler handler : stepHandlers) { +131 handler.reset(); +132 } +133 CombinedEventsManager manager = addEndTimeChecker(t0, t, eventsHandlersManager); +134 boolean lastStep = false; +135 +136 // main integration loop +137 while (!lastStep) { +138 +139 interpolator.shift(); +140 +141 for (boolean loop = true; loop;) { +142 +143 // first stage +144 computeDerivatives(stepStart, y, yDotK[0]); +145 +146 // next stages +147 for (int k = 1; k < stages; ++k) { +148 +149 for (int j = 0; j < y0.length; ++j) { +150 double sum = a[k-1][0] * yDotK[0][j]; +151 for (int l = 1; l < k; ++l) { +152 sum += a[k-1][l] * yDotK[l][j]; +153 } +154 yTmp[j] = y[j] + stepSize * sum; +155 } +156 +157 computeDerivatives(stepStart + c[k-1] * stepSize, yTmp, yDotK[k]); +158 +159 } +160 +161 // estimate the state at the end of the step +162 for (int j = 0; j < y0.length; ++j) { +163 double sum = b[0] * yDotK[0][j]; +164 for (int l = 1; l < stages; ++l) { +165 sum += b[l] * yDotK[l][j]; +166 } +167 yTmp[j] = y[j] + stepSize * sum; +168 } +169 +170 // discrete events handling +171 interpolator.storeTime(stepStart + stepSize); +172 if (manager.evaluateStep(interpolator)) { +173 final double dt = manager.getEventTime() - stepStart; +174 if (Math.abs(dt) <= Math.ulp(stepStart)) { +175 // we cannot simply truncate the step, reject the current computation +176 // and let the loop compute another state with the truncated step. +177 // it is so small (much probably exactly 0 due to limited accuracy) +178 // that the code above would fail handling it. +179 // So we set up an artificial 0 size step by copying states +180 interpolator.storeTime(stepStart); +181 System.arraycopy(y, 0, yTmp, 0, y0.length); +182 stepSize = 0; +183 loop = false; +184 } else { +185 // reject the step to match exactly the next switch time +186 stepSize = dt; +187 } +188 } else { +189 loop = false; +190 } +191 +192 } +193 +194 // the step has been accepted +195 final double nextStep = stepStart + stepSize; +196 System.arraycopy(yTmp, 0, y, 0, y0.length); +197 manager.stepAccepted(nextStep, y); +198 lastStep = manager.stop(); +199 +200 // provide the step data to the step handler +201 interpolator.storeTime(nextStep); +202 for (StepHandler handler : stepHandlers) { +203 handler.handleStep(interpolator, lastStep); +204 } +205 stepStart = nextStep; +206 +207 if (manager.reset(stepStart, y) && ! lastStep) { +208 // some events handler has triggered changes that +209 // invalidate the derivatives, we need to recompute them +210 computeDerivatives(stepStart, y, yDotK[0]); +211 } +212 +213 // make sure step size is set to default before next step +214 stepSize = forward ? step : -step; +215 +216 } +217 +218 final double stopTime = stepStart; +219 stepStart = Double.NaN; +220 stepSize = Double.NaN; +221 return stopTime; +222 +223 } +224 +225 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegrator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegrator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,138 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.nonstiff; +019 +020 +021 /** +022 * This class implements the 3/8 fourth order Runge-Kutta +023 * integrator for Ordinary Differential Equations. +024 * +025 * <p>This method is an explicit Runge-Kutta method, its Butcher-array +026 * is the following one : +027 * <pre> +028 * 0 | 0 0 0 0 +029 * 1/3 | 1/3 0 0 0 +030 * 2/3 |-1/3 1 0 0 +031 * 1 | 1 -1 1 0 +032 * |-------------------- +033 * | 1/8 3/8 3/8 1/8 +034 * </pre> +035 * </p> +036 * +037 * @see EulerIntegrator +038 * @see ClassicalRungeKuttaIntegrator +039 * @see GillIntegrator +040 * @see MidpointIntegrator +041 * @version $Revision: 810196 $ $Date: 2009-09-01 15:47:46 -0400 (Tue, 01 Sep 2009) $ +042 * @since 1.2 +043 */ +044 +045 public class ThreeEighthesIntegrator extends RungeKuttaIntegrator { +046 +047 /** Time steps Butcher array. */ +048 private static final double[] STATIC_C = { +049 1.0 / 3.0, 2.0 / 3.0, 1.0 +050 }; +051 +052 /** Internal weights Butcher array. */ +053 private static final double[][] STATIC_A = { +054 { 1.0 / 3.0 }, +055 { -1.0 / 3.0, 1.0 }, +056 { 1.0, -1.0, 1.0 } +057 }; +058 +059 /** Propagation weights Butcher array. */ +060 private static final double[] STATIC_B = { +061 1.0 / 8.0, 3.0 / 8.0, 3.0 / 8.0, 1.0 / 8.0 +062 }; +063 +064 /** Simple constructor. +065 * Build a 3/8 integrator with the given step. +066 * @param step integration step +067 */ +068 public ThreeEighthesIntegrator(final double step) { +069 super("3/8", STATIC_C, STATIC_A, STATIC_B, new ThreeEighthesStepInterpolator(), step); +070 } +071 +072 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/AbstractStepInterpolator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/AbstractStepInterpolator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,509 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.sampling; +019 +020 import java.io.IOException; +021 import java.io.ObjectInput; +022 import java.io.ObjectOutput; +023 +024 import org.apache.commons.math.MathRuntimeException; +025 import org.apache.commons.math.ode.DerivativeException; +026 +027 /** This abstract class represents an interpolator over the last step +028 * during an ODE integration. +029 * +030 * <p>The various ODE integrators provide objects extending this class +031 * to the step handlers. The handlers can use these objects to +032 * retrieve the state vector at intermediate times between the +033 * previous and the current grid points (dense output).</p> +034 * +035 * @see org.apache.commons.math.ode.FirstOrderIntegrator +036 * @see org.apache.commons.math.ode.SecondOrderIntegrator +037 * @see StepHandler +038 * +039 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +040 * @since 1.2 +041 * +042 */ +043 +044 public abstract class AbstractStepInterpolator +045 implements StepInterpolator { +046 +047 /** previous time */ +048 protected double previousTime; +049 +050 /** current time */ +051 protected double currentTime; +052 +053 /** current time step */ +054 protected double h; +055 +056 /** current state */ +057 protected double[] currentState; +058 +059 /** interpolated time */ +060 protected double interpolatedTime; +061 +062 /** interpolated state */ +063 protected double[] interpolatedState; +064 +065 /** interpolated derivatives */ +066 protected double[] interpolatedDerivatives; +067 +068 /** indicate if the step has been finalized or not. */ +069 private boolean finalized; +070 +071 /** integration direction. */ +072 private boolean forward; +073 +074 /** indicator for dirty state. */ +075 private boolean dirtyState; +076 +077 +078 /** Simple constructor. +079 * This constructor builds an instance that is not usable yet, the +080 * {@link #reinitialize} method should be called before using the +081 * instance in order to initialize the internal arrays. This +082 * constructor is used only in order to delay the initialization in +083 * some cases. As an example, the {@link +084 * org.apache.commons.math.ode.nonstiff.EmbeddedRungeKuttaIntegrator} +085 * class uses the prototyping design pattern to create the step +086 * interpolators by cloning an uninitialized model and latter +087 * initializing the copy. +088 */ +089 protected AbstractStepInterpolator() { +090 previousTime = Double.NaN; +091 currentTime = Double.NaN; +092 h = Double.NaN; +093 interpolatedTime = Double.NaN; +094 currentState = null; +095 interpolatedState = null; +096 interpolatedDerivatives = null; +097 finalized = false; +098 this.forward = true; +099 this.dirtyState = true; +100 } +101 +102 /** Simple constructor. +103 * @param y reference to the integrator array holding the state at +104 * the end of the step +105 * @param forward integration direction indicator +106 */ +107 protected AbstractStepInterpolator(final double[] y, final boolean forward) { +108 +109 previousTime = Double.NaN; +110 currentTime = Double.NaN; +111 h = Double.NaN; +112 interpolatedTime = Double.NaN; +113 +114 currentState = y; +115 interpolatedState = new double[y.length]; +116 interpolatedDerivatives = new double[y.length]; +117 +118 finalized = false; +119 this.forward = forward; +120 this.dirtyState = true; +121 +122 } +123 +124 /** Copy constructor. +125 +126 * <p>The copied interpolator should have been finalized before the +127 * copy, otherwise the copy will not be able to perform correctly +128 * any derivative computation and will throw a {@link +129 * NullPointerException} later. Since we don't want this constructor +130 * to throw the exceptions finalization may involve and since we +131 * don't want this method to modify the state of the copied +132 * interpolator, finalization is <strong>not</strong> done +133 * automatically, it remains under user control.</p> +134 +135 * <p>The copy is a deep copy: its arrays are separated from the +136 * original arrays of the instance.</p> +137 +138 * @param interpolator interpolator to copy from. +139 +140 */ +141 protected AbstractStepInterpolator(final AbstractStepInterpolator interpolator) { +142 +143 previousTime = interpolator.previousTime; +144 currentTime = interpolator.currentTime; +145 h = interpolator.h; +146 interpolatedTime = interpolator.interpolatedTime; +147 +148 if (interpolator.currentState != null) { +149 currentState = interpolator.currentState.clone(); +150 interpolatedState = interpolator.interpolatedState.clone(); +151 interpolatedDerivatives = interpolator.interpolatedDerivatives.clone(); +152 } else { +153 currentState = null; +154 interpolatedState = null; +155 interpolatedDerivatives = null; +156 } +157 +158 finalized = interpolator.finalized; +159 forward = interpolator.forward; +160 dirtyState = interpolator.dirtyState; +161 +162 } +163 +164 /** Reinitialize the instance +165 * @param y reference to the integrator array holding the state at +166 * the end of the step +167 * @param isForward integration direction indicator +168 */ +169 protected void reinitialize(final double[] y, final boolean isForward) { +170 +171 previousTime = Double.NaN; +172 currentTime = Double.NaN; +173 h = Double.NaN; +174 interpolatedTime = Double.NaN; +175 +176 currentState = y; +177 interpolatedState = new double[y.length]; +178 interpolatedDerivatives = new double[y.length]; +179 +180 finalized = false; +181 this.forward = isForward; +182 this.dirtyState = true; +183 +184 } +185 +186 /** {@inheritDoc} */ +187 public StepInterpolator copy() throws DerivativeException { +188 +189 // finalize the step before performing copy +190 finalizeStep(); +191 +192 // create the new independent instance +193 return doCopy(); +194 +195 } +196 +197 /** Really copy the finalized instance. +198 * <p>This method is called by {@link #copy()} after the +199 * step has been finalized. It must perform a deep copy +200 * to have an new instance completely independent for the +201 * original instance. +202 * @return a copy of the finalized instance +203 */ +204 protected abstract StepInterpolator doCopy(); +205 +206 /** Shift one step forward. +207 * Copy the current time into the previous time, hence preparing the +208 * interpolator for future calls to {@link #storeTime storeTime} +209 */ +210 public void shift() { +211 previousTime = currentTime; +212 } +213 +214 /** Store the current step time. +215 * @param t current time +216 */ +217 public void storeTime(final double t) { +218 +219 currentTime = t; +220 h = currentTime - previousTime; +221 setInterpolatedTime(t); +222 +223 // the step is not finalized anymore +224 finalized = false; +225 +226 } +227 +228 /** {@inheritDoc} */ +229 public double getPreviousTime() { +230 return previousTime; +231 } +232 +233 /** {@inheritDoc} */ +234 public double getCurrentTime() { +235 return currentTime; +236 } +237 +238 /** {@inheritDoc} */ +239 public double getInterpolatedTime() { +240 return interpolatedTime; +241 } +242 +243 /** {@inheritDoc} */ +244 public void setInterpolatedTime(final double time) { +245 interpolatedTime = time; +246 dirtyState = true; +247 } +248 +249 /** {@inheritDoc} */ +250 public boolean isForward() { +251 return forward; +252 } +253 +254 /** Compute the state and derivatives at the interpolated time. +255 * This is the main processing method that should be implemented by +256 * the derived classes to perform the interpolation. +257 * @param theta normalized interpolation abscissa within the step +258 * (theta is zero at the previous time step and one at the current time step) +259 * @param oneMinusThetaH time gap between the interpolated time and +260 * the current time +261 * @throws DerivativeException this exception is propagated to the caller if the +262 * underlying user function triggers one +263 */ +264 protected abstract void computeInterpolatedStateAndDerivatives(double theta, +265 double oneMinusThetaH) +266 throws DerivativeException; +267 +268 /** {@inheritDoc} */ +269 public double[] getInterpolatedState() throws DerivativeException { +270 +271 // lazy evaluation of the state +272 if (dirtyState) { +273 final double oneMinusThetaH = currentTime - interpolatedTime; +274 final double theta = (h == 0) ? 0 : (h - oneMinusThetaH) / h; +275 computeInterpolatedStateAndDerivatives(theta, oneMinusThetaH); +276 dirtyState = false; +277 } +278 +279 return interpolatedState; +280 +281 } +282 +283 /** {@inheritDoc} */ +284 public double[] getInterpolatedDerivatives() throws DerivativeException { +285 +286 // lazy evaluation of the state +287 if (dirtyState) { +288 final double oneMinusThetaH = currentTime - interpolatedTime; +289 final double theta = (h == 0) ? 0 : (h - oneMinusThetaH) / h; +290 computeInterpolatedStateAndDerivatives(theta, oneMinusThetaH); +291 dirtyState = false; +292 } +293 +294 return interpolatedDerivatives; +295 +296 } +297 +298 /** +299 * Finalize the step. +300 +301 * <p>Some embedded Runge-Kutta integrators need fewer functions +302 * evaluations than their counterpart step interpolators. These +303 * interpolators should perform the last evaluations they need by +304 * themselves only if they need them. This method triggers these +305 * extra evaluations. It can be called directly by the user step +306 * handler and it is called automatically if {@link +307 * #setInterpolatedTime} is called.</p> +308 +309 * <p>Once this method has been called, <strong>no</strong> other +310 * evaluation will be performed on this step. If there is a need to +311 * have some side effects between the step handler and the +312 * differential equations (for example update some data in the +313 * equations once the step has been done), it is advised to call +314 * this method explicitly from the step handler before these side +315 * effects are set up. If the step handler induces no side effect, +316 * then this method can safely be ignored, it will be called +317 * transparently as needed.</p> +318 +319 * <p><strong>Warning</strong>: since the step interpolator provided +320 * to the step handler as a parameter of the {@link +321 * StepHandler#handleStep handleStep} is valid only for the duration +322 * of the {@link StepHandler#handleStep handleStep} call, one cannot +323 * simply store a reference and reuse it later. One should first +324 * finalize the instance, then copy this finalized instance into a +325 * new object that can be kept.</p> +326 +327 * <p>This method calls the protected <code>doFinalize</code> method +328 * if it has never been called during this step and set a flag +329 * indicating that it has been called once. It is the <code> +330 * doFinalize</code> method which should perform the evaluations. +331 * This wrapping prevents from calling <code>doFinalize</code> several +332 * times and hence evaluating the differential equations too often. +333 * Therefore, subclasses are not allowed not reimplement it, they +334 * should rather reimplement <code>doFinalize</code>.</p> +335 +336 * @throws DerivativeException this exception is propagated to the +337 * caller if the underlying user function triggers one +338 */ +339 public final void finalizeStep() +340 throws DerivativeException { +341 if (! finalized) { +342 doFinalize(); +343 finalized = true; +344 } +345 } +346 +347 /** +348 * Really finalize the step. +349 * The default implementation of this method does nothing. +350 * @throws DerivativeException this exception is propagated to the +351 * caller if the underlying user function triggers one +352 */ +353 protected void doFinalize() +354 throws DerivativeException { +355 } +356 +357 /** {@inheritDoc} */ +358 public abstract void writeExternal(ObjectOutput out) +359 throws IOException; +360 +361 /** {@inheritDoc} */ +362 public abstract void readExternal(ObjectInput in) +363 throws IOException, ClassNotFoundException; +364 +365 /** Save the base state of the instance. +366 * This method performs step finalization if it has not been done +367 * before. +368 * @param out stream where to save the state +369 * @exception IOException in case of write error +370 */ +371 protected void writeBaseExternal(final ObjectOutput out) +372 throws IOException { +373 +374 if (currentState == null) { +375 out.writeInt(-1); +376 } else { +377 out.writeInt(currentState.length); +378 } +379 out.writeDouble(previousTime); +380 out.writeDouble(currentTime); +381 out.writeDouble(h); +382 out.writeBoolean(forward); +383 +384 if (currentState != null) { +385 for (int i = 0; i < currentState.length; ++i) { +386 out.writeDouble(currentState[i]); +387 } +388 } +389 +390 out.writeDouble(interpolatedTime); +391 +392 // we do not store the interpolated state, +393 // it will be recomputed as needed after reading +394 +395 // finalize the step (and don't bother saving the now true flag) +396 try { +397 finalizeStep(); +398 } catch (DerivativeException e) { +399 throw MathRuntimeException.createIOException(e); +400 } +401 +402 } +403 +404 /** Read the base state of the instance. +405 * This method does <strong>neither</strong> set the interpolated +406 * time nor state. It is up to the derived class to reset it +407 * properly calling the {@link #setInterpolatedTime} method later, +408 * once all rest of the object state has been set up properly. +409 * @param in stream where to read the state from +410 * @return interpolated time be set later by the caller +411 * @exception IOException in case of read error +412 */ +413 protected double readBaseExternal(final ObjectInput in) +414 throws IOException { +415 +416 final int dimension = in.readInt(); +417 previousTime = in.readDouble(); +418 currentTime = in.readDouble(); +419 h = in.readDouble(); +420 forward = in.readBoolean(); +421 dirtyState = true; +422 +423 if (dimension < 0) { +424 currentState = null; +425 } else { +426 currentState = new double[dimension]; +427 for (int i = 0; i < currentState.length; ++i) { +428 currentState[i] = in.readDouble(); +429 } +430 } +431 +432 // we do NOT handle the interpolated time and state here +433 interpolatedTime = Double.NaN; +434 interpolatedState = (dimension < 0) ? null : new double[dimension]; +435 interpolatedDerivatives = (dimension < 0) ? null : new double[dimension]; +436 +437 finalized = true; +438 +439 return in.readDouble(); +440 +441 } +442 +443 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/DummyStepHandler.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/DummyStepHandler.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,167 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.sampling; +019 +020 /** +021 * This class is a step handler that does nothing. +022 +023 * <p>This class is provided as a convenience for users who are only +024 * interested in the final state of an integration and not in the +025 * intermediate steps. Its handleStep method does nothing.</p> +026 * +027 * <p>Since this class has no internal state, it is implemented using +028 * the Singleton design pattern. This means that only one instance is +029 * ever created, which can be retrieved using the getInstance +030 * method. This explains why there is no public constructor.</p> +031 * +032 * @see StepHandler +033 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +034 * @since 1.2 +035 */ +036 +037 public class DummyStepHandler implements StepHandler { +038 +039 /** Private constructor. +040 * The constructor is private to prevent users from creating +041 * instances (Singleton design-pattern). +042 */ +043 private DummyStepHandler() { +044 } +045 +046 /** Get the only instance. +047 * @return the only instance +048 */ +049 public static DummyStepHandler getInstance() { +050 return LazyHolder.INSTANCE; +051 } +052 +053 /** Determines whether this handler needs dense output. +054 * Since this handler does nothing, it does not require dense output. +055 * @return always false +056 */ +057 public boolean requiresDenseOutput() { +058 return false; +059 } +060 +061 /** Reset the step handler. +062 * Initialize the internal data as required before the first step is +063 * handled. +064 */ +065 public void reset() { +066 } +067 +068 /** +069 * Handle the last accepted step. +070 * This method does nothing in this class. +071 * @param interpolator interpolator for the last accepted step. For +072 * efficiency purposes, the various integrators reuse the same +073 * object on each call, so if the instance wants to keep it across +074 * all calls (for example to provide at the end of the integration a +075 * continuous model valid throughout the integration range), it +076 * should build a local copy using the clone method and store this +077 * copy. +078 * @param isLast true if the step is the last one +079 */ +080 public void handleStep(final StepInterpolator interpolator, final boolean isLast) { +081 } +082 +083 // CHECKSTYLE: stop HideUtilityClassConstructor +084 /** Holder for the instance. +085 * <p>We use here the Initialization On Demand Holder Idiom.</p> +086 */ +087 private static class LazyHolder { +088 /** Cached field instance. */ +089 private static final DummyStepHandler INSTANCE = new DummyStepHandler(); +090 } +091 // CHECKSTYLE: resume HideUtilityClassConstructor +092 +093 /** Handle deserialization of the singleton. +094 * @return the singleton instance +095 */ +096 private Object readResolve() { +097 // return the singleton instance +098 return LazyHolder.INSTANCE; +099 } +100 +101 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/DummyStepInterpolator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/DummyStepInterpolator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,221 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.sampling; +019 +020 import java.io.IOException; +021 import java.io.ObjectInput; +022 import java.io.ObjectOutput; +023 +024 import org.apache.commons.math.ode.DerivativeException; +025 +026 /** This class is a step interpolator that does nothing. +027 * +028 * <p>This class is used when the {@link StepHandler "step handler"} +029 * set up by the user does not need step interpolation. It does not +030 * recompute the state when {@link AbstractStepInterpolator#setInterpolatedTime +031 * setInterpolatedTime} is called. This implies the interpolated state +032 * is always the state at the end of the current step.</p> +033 * +034 * @see StepHandler +035 * +036 * @version $Revision: 919479 $ $Date: 2010-03-05 11:35:56 -0500 (Fri, 05 Mar 2010) $ +037 * @since 1.2 +038 */ +039 +040 public class DummyStepInterpolator +041 extends AbstractStepInterpolator { +042 +043 /** Serializable version identifier. */ +044 private static final long serialVersionUID = 1708010296707839488L; +045 +046 /** Current derivative. */ +047 private double[] currentDerivative; +048 +049 /** Simple constructor. +050 * This constructor builds an instance that is not usable yet, the +051 * <code>AbstractStepInterpolator.reinitialize</code> protected method +052 * should be called before using the instance in order to initialize +053 * the internal arrays. This constructor is used only in order to delay +054 * the initialization in some cases. As an example, the {@link +055 * org.apache.commons.math.ode.nonstiff.EmbeddedRungeKuttaIntegrator} uses +056 * the prototyping design pattern to create the step interpolators by +057 * cloning an uninitialized model and latter initializing the copy. +058 */ +059 public DummyStepInterpolator() { +060 super(); +061 currentDerivative = null; +062 } +063 +064 /** Simple constructor. +065 * @param y reference to the integrator array holding the state at +066 * the end of the step +067 * @param yDot reference to the integrator array holding the state +068 * derivative at some arbitrary point within the step +069 * @param forward integration direction indicator +070 */ +071 public DummyStepInterpolator(final double[] y, final double[] yDot, final boolean forward) { +072 super(y, forward); +073 currentDerivative = yDot; +074 } +075 +076 /** Copy constructor. +077 * @param interpolator interpolator to copy from. The copy is a deep +078 * copy: its arrays are separated from the original arrays of the +079 * instance +080 */ +081 public DummyStepInterpolator(final DummyStepInterpolator interpolator) { +082 super(interpolator); +083 currentDerivative = interpolator.currentDerivative.clone(); +084 } +085 +086 /** Really copy the finalized instance. +087 * @return a copy of the finalized instance +088 */ +089 @Override +090 protected StepInterpolator doCopy() { +091 return new DummyStepInterpolator(this); +092 } +093 +094 /** Compute the state at the interpolated time. +095 * In this class, this method does nothing: the interpolated state +096 * is always the state at the end of the current step. +097 * @param theta normalized interpolation abscissa within the step +098 * (theta is zero at the previous time step and one at the current time step) +099 * @param oneMinusThetaH time gap between the interpolated time and +100 * the current time +101 * @throws DerivativeException this exception is propagated to the caller if the +102 * underlying user function triggers one +103 */ +104 @Override +105 protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) +106 throws DerivativeException { +107 System.arraycopy(currentState, 0, interpolatedState, 0, currentState.length); +108 System.arraycopy(currentDerivative, 0, interpolatedDerivatives, 0, currentDerivative.length); +109 } +110 +111 /** Write the instance to an output channel. +112 * @param out output channel +113 * @exception IOException if the instance cannot be written +114 */ +115 @Override +116 public void writeExternal(final ObjectOutput out) +117 throws IOException { +118 +119 // save the state of the base class +120 writeBaseExternal(out); +121 +122 if (currentDerivative != null) { +123 for (int i = 0; i < currentDerivative.length; ++i) { +124 out.writeDouble(currentDerivative[i]); +125 } +126 } +127 +128 } +129 +130 /** Read the instance from an input channel. +131 * @param in input channel +132 * @exception IOException if the instance cannot be read +133 */ +134 @Override +135 public void readExternal(final ObjectInput in) +136 throws IOException { +137 +138 // read the base class +139 final double t = readBaseExternal(in); +140 +141 if (currentState == null) { +142 currentDerivative = null; +143 } else { +144 currentDerivative = new double[currentState.length]; +145 for (int i = 0; i < currentDerivative.length; ++i) { +146 currentDerivative[i] = in.readDouble(); +147 } +148 } +149 +150 // we can now set the interpolated time and state +151 setInterpolatedTime(t); +152 +153 } +154 +155 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/FixedStepHandler.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/FixedStepHandler.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,128 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.sampling; +019 +020 import org.apache.commons.math.ode.DerivativeException; +021 +022 /** +023 * This interface represents a handler that should be called after +024 * each successful fixed step. +025 +026 * <p>This interface should be implemented by anyone who is interested +027 * in getting the solution of an ordinary differential equation at +028 * fixed time steps. Objects implementing this interface should be +029 * wrapped within an instance of {@link StepNormalizer} that itself +030 * is used as the general {@link StepHandler} by the integrator. The +031 * {@link StepNormalizer} object is called according to the integrator +032 * internal algorithms and it calls objects implementing this +033 * interface as necessary at fixed time steps.</p> +034 * +035 * @see StepHandler +036 * @see StepNormalizer +037 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +038 * @since 1.2 +039 */ +040 +041 public interface FixedStepHandler { +042 +043 /** +044 * Handle the last accepted step +045 * @param t time of the current step +046 * @param y state vector at t. For efficiency purposes, the {@link +047 * StepNormalizer} class reuses the same array on each call, so if +048 * the instance wants to keep it across all calls (for example to +049 * provide at the end of the integration a complete array of all +050 * steps), it should build a local copy store this copy. +051 * @param yDot derivatives of the state vector state vector at t. +052 * For efficiency purposes, the {@link StepNormalizer} class reuses +053 * the same array on each call, so if +054 * the instance wants to keep it across all calls (for example to +055 * provide at the end of the integration a complete array of all +056 * steps), it should build a local copy store this copy. +057 * @param isLast true if the step is the last one +058 * @throws DerivativeException if some error condition is encountered +059 */ +060 void handleStep(double t, double[] y, double[] yDot, boolean isLast) throws DerivativeException; +061 +062 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/NordsieckStepInterpolator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/NordsieckStepInterpolator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,356 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.sampling; +019 +020 import java.io.IOException; +021 import java.io.ObjectInput; +022 import java.io.ObjectOutput; +023 import java.util.Arrays; +024 +025 import org.apache.commons.math.linear.Array2DRowRealMatrix; +026 import org.apache.commons.math.ode.DerivativeException; +027 +028 /** +029 * This class implements an interpolator for integrators using Nordsieck representation. +030 * +031 * <p>This interpolator computes dense output around the current point. +032 * The interpolation equation is based on Taylor series formulas. +033 * +034 * @see org.apache.commons.math.ode.nonstiff.AdamsBashforthIntegrator +035 * @see org.apache.commons.math.ode.nonstiff.AdamsMoultonIntegrator +036 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +037 * @since 2.0 +038 */ +039 +040 public class NordsieckStepInterpolator extends AbstractStepInterpolator { +041 +042 /** Serializable version identifier */ +043 private static final long serialVersionUID = -7179861704951334960L; +044 +045 /** State variation. */ +046 protected double[] stateVariation; +047 +048 /** Step size used in the first scaled derivative and Nordsieck vector. */ +049 private double scalingH; +050 +051 /** Reference time for all arrays. +052 * <p>Sometimes, the reference time is the same as previousTime, +053 * sometimes it is the same as currentTime, so we use a separate +054 * field to avoid any confusion. +055 * </p> +056 */ +057 private double referenceTime; +058 +059 /** First scaled derivative. */ +060 private double[] scaled; +061 +062 /** Nordsieck vector. */ +063 private Array2DRowRealMatrix nordsieck; +064 +065 /** Simple constructor. +066 * This constructor builds an instance that is not usable yet, the +067 * {@link AbstractStepInterpolator#reinitialize} method should be called +068 * before using the instance in order to initialize the internal arrays. This +069 * constructor is used only in order to delay the initialization in +070 * some cases. +071 */ +072 public NordsieckStepInterpolator() { +073 } +074 +075 /** Copy constructor. +076 * @param interpolator interpolator to copy from. The copy is a deep +077 * copy: its arrays are separated from the original arrays of the +078 * instance +079 */ +080 public NordsieckStepInterpolator(final NordsieckStepInterpolator interpolator) { +081 super(interpolator); +082 scalingH = interpolator.scalingH; +083 referenceTime = interpolator.referenceTime; +084 if (interpolator.scaled != null) { +085 scaled = interpolator.scaled.clone(); +086 } +087 if (interpolator.nordsieck != null) { +088 nordsieck = new Array2DRowRealMatrix(interpolator.nordsieck.getDataRef(), true); +089 } +090 if (interpolator.stateVariation != null) { +091 stateVariation = interpolator.stateVariation.clone(); +092 } +093 } +094 +095 /** {@inheritDoc} */ +096 @Override +097 protected StepInterpolator doCopy() { +098 return new NordsieckStepInterpolator(this); +099 } +100 +101 /** Reinitialize the instance. +102 * <p>Beware that all arrays <em>must</em> be references to integrator +103 * arrays, in order to ensure proper update without copy.</p> +104 * @param y reference to the integrator array holding the state at +105 * the end of the step +106 * @param forward integration direction indicator +107 */ +108 @Override +109 public void reinitialize(final double[] y, final boolean forward) { +110 super.reinitialize(y, forward); +111 stateVariation = new double[y.length]; +112 } +113 +114 /** Reinitialize the instance. +115 * <p>Beware that all arrays <em>must</em> be references to integrator +116 * arrays, in order to ensure proper update without copy.</p> +117 * @param time time at which all arrays are defined +118 * @param stepSize step size used in the scaled and nordsieck arrays +119 * @param scaledDerivative reference to the integrator array holding the first +120 * scaled derivative +121 * @param nordsieckVector reference to the integrator matrix holding the +122 * nordsieck vector +123 */ +124 public void reinitialize(final double time, final double stepSize, +125 final double[] scaledDerivative, +126 final Array2DRowRealMatrix nordsieckVector) { +127 this.referenceTime = time; +128 this.scalingH = stepSize; +129 this.scaled = scaledDerivative; +130 this.nordsieck = nordsieckVector; +131 +132 // make sure the state and derivatives will depend on the new arrays +133 setInterpolatedTime(getInterpolatedTime()); +134 +135 } +136 +137 /** Rescale the instance. +138 * <p>Since the scaled and Nordiseck arrays are shared with the caller, +139 * this method has the side effect of rescaling this arrays in the caller too.</p> +140 * @param stepSize new step size to use in the scaled and nordsieck arrays +141 */ +142 public void rescale(final double stepSize) { +143 +144 final double ratio = stepSize / scalingH; +145 for (int i = 0; i < scaled.length; ++i) { +146 scaled[i] *= ratio; +147 } +148 +149 final double[][] nData = nordsieck.getDataRef(); +150 double power = ratio; +151 for (int i = 0; i < nData.length; ++i) { +152 power *= ratio; +153 final double[] nDataI = nData[i]; +154 for (int j = 0; j < nDataI.length; ++j) { +155 nDataI[j] *= power; +156 } +157 } +158 +159 scalingH = stepSize; +160 +161 } +162 +163 /** +164 * Get the state vector variation from current to interpolated state. +165 * <p>This method is aimed at computing y(t<sub>interpolation</sub>) +166 * -y(t<sub>current</sub>) accurately by avoiding the cancellation errors +167 * that would occur if the subtraction were performed explicitly.</p> +168 * <p>The returned vector is a reference to a reused array, so +169 * it should not be modified and it should be copied if it needs +170 * to be preserved across several calls.</p> +171 * @return state vector at time {@link #getInterpolatedTime} +172 * @see #getInterpolatedDerivatives() +173 * @throws DerivativeException if this call induces an automatic +174 * step finalization that throws one +175 */ +176 public double[] getInterpolatedStateVariation() +177 throws DerivativeException { +178 // compute and ignore interpolated state +179 // to make sure state variation is computed as a side effect +180 getInterpolatedState(); +181 return stateVariation; +182 } +183 +184 /** {@inheritDoc} */ +185 @Override +186 protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) { +187 +188 final double x = interpolatedTime - referenceTime; +189 final double normalizedAbscissa = x / scalingH; +190 +191 Arrays.fill(stateVariation, 0.0); +192 Arrays.fill(interpolatedDerivatives, 0.0); +193 +194 // apply Taylor formula from high order to low order, +195 // for the sake of numerical accuracy +196 final double[][] nData = nordsieck.getDataRef(); +197 for (int i = nData.length - 1; i >= 0; --i) { +198 final int order = i + 2; +199 final double[] nDataI = nData[i]; +200 final double power = Math.pow(normalizedAbscissa, order); +201 for (int j = 0; j < nDataI.length; ++j) { +202 final double d = nDataI[j] * power; +203 stateVariation[j] += d; +204 interpolatedDerivatives[j] += order * d; +205 } +206 } +207 +208 for (int j = 0; j < currentState.length; ++j) { +209 stateVariation[j] += scaled[j] * normalizedAbscissa; +210 interpolatedState[j] = currentState[j] + stateVariation[j]; +211 interpolatedDerivatives[j] = +212 (interpolatedDerivatives[j] + scaled[j] * normalizedAbscissa) / x; +213 } +214 +215 } +216 +217 /** {@inheritDoc} */ +218 @Override +219 public void writeExternal(final ObjectOutput out) +220 throws IOException { +221 +222 // save the state of the base class +223 writeBaseExternal(out); +224 +225 // save the local attributes +226 out.writeDouble(scalingH); +227 out.writeDouble(referenceTime); +228 +229 final int n = (currentState == null) ? -1 : currentState.length; +230 if (scaled == null) { +231 out.writeBoolean(false); +232 } else { +233 out.writeBoolean(true); +234 for (int j = 0; j < n; ++j) { +235 out.writeDouble(scaled[j]); +236 } +237 } +238 +239 if (nordsieck == null) { +240 out.writeBoolean(false); +241 } else { +242 out.writeBoolean(true); +243 out.writeObject(nordsieck); +244 } +245 +246 // we don't save state variation, it will be recomputed +247 +248 } +249 +250 /** {@inheritDoc} */ +251 @Override +252 public void readExternal(final ObjectInput in) +253 throws IOException, ClassNotFoundException { +254 +255 // read the base class +256 final double t = readBaseExternal(in); +257 +258 // read the local attributes +259 scalingH = in.readDouble(); +260 referenceTime = in.readDouble(); +261 +262 final int n = (currentState == null) ? -1 : currentState.length; +263 final boolean hasScaled = in.readBoolean(); +264 if (hasScaled) { +265 scaled = new double[n]; +266 for (int j = 0; j < n; ++j) { +267 scaled[j] = in.readDouble(); +268 } +269 } else { +270 scaled = null; +271 } +272 +273 final boolean hasNordsieck = in.readBoolean(); +274 if (hasNordsieck) { +275 nordsieck = (Array2DRowRealMatrix) in.readObject(); +276 } else { +277 nordsieck = null; +278 } +279 +280 if (hasScaled && hasNordsieck) { +281 // we can now set the interpolated time and state +282 stateVariation = new double[n]; +283 setInterpolatedTime(t); +284 } else { +285 stateVariation = null; +286 } +287 +288 } +289 +290 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/StepHandler.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/StepHandler.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,144 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.sampling; +019 +020 import org.apache.commons.math.ode.DerivativeException; +021 +022 /** +023 * This interface represents a handler that should be called after +024 * each successful step. +025 * +026 * <p>The ODE integrators compute the evolution of the state vector at +027 * some grid points that depend on their own internal algorithm. Once +028 * they have found a new grid point (possibly after having computed +029 * several evaluation of the derivative at intermediate points), they +030 * provide it to objects implementing this interface. These objects +031 * typically either ignore the intermediate steps and wait for the +032 * last one, store the points in an ephemeris, or forward them to +033 * specialized processing or output methods.</p> +034 * +035 * @see org.apache.commons.math.ode.FirstOrderIntegrator +036 * @see org.apache.commons.math.ode.SecondOrderIntegrator +037 * @see StepInterpolator +038 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +039 * @since 1.2 +040 */ +041 +042 public interface StepHandler { +043 +044 /** Determines whether this handler needs dense output. +045 * <p>This method allows the integrator to avoid performing extra +046 * computation if the handler does not need dense output. If this +047 * method returns false, the integrator will call the {@link +048 * #handleStep} method with a {@link DummyStepInterpolator} rather +049 * than a custom interpolator.</p> +050 * @return true if the handler needs dense output +051 */ +052 boolean requiresDenseOutput(); +053 +054 /** Reset the step handler. +055 * Initialize the internal data as required before the first step is +056 * handled. +057 */ +058 void reset(); +059 +060 /** +061 * Handle the last accepted step +062 * @param interpolator interpolator for the last accepted step. For +063 * efficiency purposes, the various integrators reuse the same +064 * object on each call, so if the instance wants to keep it across +065 * all calls (for example to provide at the end of the integration a +066 * continuous model valid throughout the integration range, as the +067 * {@link org.apache.commons.math.ode.ContinuousOutputModel +068 * ContinuousOutputModel} class does), it should build a local copy +069 * using the clone method of the interpolator and store this copy. +070 * Keeping only a reference to the interpolator and reusing it will +071 * result in unpredictable behavior (potentially crashing the application). +072 * @param isLast true if the step is the last one +073 * @throws DerivativeException this exception is propagated to the +074 * caller if the underlying user function triggers one +075 */ +076 void handleStep(StepInterpolator interpolator, boolean isLast) throws DerivativeException; +077 +078 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/StepInterpolator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/StepInterpolator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,198 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.sampling; +019 +020 import java.io.Externalizable; +021 +022 import org.apache.commons.math.ode.DerivativeException; +023 +024 /** This interface represents an interpolator over the last step +025 * during an ODE integration. +026 * +027 * <p>The various ODE integrators provide objects implementing this +028 * interface to the step handlers. These objects are often custom +029 * objects tightly bound to the integrator internal algorithms. The +030 * handlers can use these objects to retrieve the state vector at +031 * intermediate times between the previous and the current grid points +032 * (this feature is often called dense output).</p> +033 * <p>One important thing to note is that the step handlers may be so +034 * tightly bound to the integrators that they often share some internal +035 * state arrays. This imply that one should <em>never</em> use a direct +036 * reference to a step interpolator outside of the step handler, either +037 * for future use or for use in another thread. If such a need arise, the +038 * step interpolator <em>must</em> be copied using the dedicated +039 * {@link #copy()} method. +040 * </p> +041 * +042 * @see org.apache.commons.math.ode.FirstOrderIntegrator +043 * @see org.apache.commons.math.ode.SecondOrderIntegrator +044 * @see StepHandler +045 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +046 * @since 1.2 +047 */ +048 +049 public interface StepInterpolator extends Externalizable { +050 +051 /** +052 * Get the previous grid point time. +053 * @return previous grid point time +054 */ +055 double getPreviousTime(); +056 +057 /** +058 * Get the current grid point time. +059 * @return current grid point time +060 */ +061 double getCurrentTime(); +062 +063 /** +064 * Get the time of the interpolated point. +065 * If {@link #setInterpolatedTime} has not been called, it returns +066 * the current grid point time. +067 * @return interpolation point time +068 */ +069 double getInterpolatedTime(); +070 +071 /** +072 * Set the time of the interpolated point. +073 * <p>Setting the time outside of the current step is now allowed, but +074 * should be used with care since the accuracy of the interpolator will +075 * probably be very poor far from this step. This allowance has been +076 * added to simplify implementation of search algorithms near the +077 * step endpoints.</p> +078 * <p>Setting the time changes the instance internal state. If a +079 * specific state must be preserved, a copy of the instance must be +080 * created using {@link #copy()}.</p> +081 * @param time time of the interpolated point +082 */ +083 void setInterpolatedTime(double time); +084 +085 /** +086 * Get the state vector of the interpolated point. +087 * <p>The returned vector is a reference to a reused array, so +088 * it should not be modified and it should be copied if it needs +089 * to be preserved across several calls.</p> +090 * @return state vector at time {@link #getInterpolatedTime} +091 * @see #getInterpolatedDerivatives() +092 * @throws DerivativeException if this call induces an automatic +093 * step finalization that throws one +094 */ +095 double[] getInterpolatedState() throws DerivativeException; +096 +097 /** +098 * Get the derivatives of the state vector of the interpolated point. +099 * <p>The returned vector is a reference to a reused array, so +100 * it should not be modified and it should be copied if it needs +101 * to be preserved across several calls.</p> +102 * @return derivatives of the state vector at time {@link #getInterpolatedTime} +103 * @see #getInterpolatedState() +104 * @throws DerivativeException if this call induces an automatic +105 * step finalization that throws one +106 * @since 2.0 +107 */ +108 double[] getInterpolatedDerivatives() throws DerivativeException; +109 +110 /** Check if the natural integration direction is forward. +111 * <p>This method provides the integration direction as specified by +112 * the integrator itself, it avoid some nasty problems in +113 * degenerated cases like null steps due to cancellation at step +114 * initialization, step control or discrete events +115 * triggering.</p> +116 * @return true if the integration variable (time) increases during +117 * integration +118 */ +119 boolean isForward(); +120 +121 /** Copy the instance. +122 * <p>The copied instance is guaranteed to be independent from the +123 * original one. Both can be used with different settings for +124 * interpolated time without any side effect.</p> +125 * @return a deep copy of the instance, which can be used independently. +126 * @throws DerivativeException if this call induces an automatic +127 * step finalization that throws one +128 * @see #setInterpolatedTime(double) +129 */ +130 StepInterpolator copy() throws DerivativeException; +131 +132 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/StepNormalizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/ode/sampling/StepNormalizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,226 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.ode.sampling; +019 +020 import org.apache.commons.math.ode.DerivativeException; +021 +022 /** +023 * This class wraps an object implementing {@link FixedStepHandler} +024 * into a {@link StepHandler}. +025 +026 * <p>This wrapper allows to use fixed step handlers with general +027 * integrators which cannot guaranty their integration steps will +028 * remain constant and therefore only accept general step +029 * handlers.</p> +030 * +031 * <p>The stepsize used is selected at construction time. The {@link +032 * FixedStepHandler#handleStep handleStep} method of the underlying +033 * {@link FixedStepHandler} object is called at the beginning time of +034 * the integration t0 and also at times t0+h, t0+2h, ... If the +035 * integration range is an integer multiple of the stepsize, then the +036 * last point handled will be the endpoint of the integration tend, if +037 * not, the last point will belong to the interval [tend - h ; +038 * tend].</p> +039 * +040 * <p>There is no constraint on the integrator, it can use any +041 * timestep it needs (time steps longer or shorter than the fixed time +042 * step and non-integer ratios are all allowed).</p> +043 * +044 * @see StepHandler +045 * @see FixedStepHandler +046 * @version $Revision: 811833 $ $Date: 2009-09-06 12:27:50 -0400 (Sun, 06 Sep 2009) $ +047 * @since 1.2 +048 */ +049 +050 public class StepNormalizer implements StepHandler { +051 +052 /** Fixed time step. */ +053 private double h; +054 +055 /** Underlying step handler. */ +056 private final FixedStepHandler handler; +057 +058 /** Last step time. */ +059 private double lastTime; +060 +061 /** Last State vector. */ +062 private double[] lastState; +063 +064 /** Last Derivatives vector. */ +065 private double[] lastDerivatives; +066 +067 /** Integration direction indicator. */ +068 private boolean forward; +069 +070 /** Simple constructor. +071 * @param h fixed time step (sign is not used) +072 * @param handler fixed time step handler to wrap +073 */ +074 public StepNormalizer(final double h, final FixedStepHandler handler) { +075 this.h = Math.abs(h); +076 this.handler = handler; +077 reset(); +078 } +079 +080 /** Determines whether this handler needs dense output. +081 * This handler needs dense output in order to provide data at +082 * regularly spaced steps regardless of the steps the integrator +083 * uses, so this method always returns true. +084 * @return always true +085 */ +086 public boolean requiresDenseOutput() { +087 return true; +088 } +089 +090 /** Reset the step handler. +091 * Initialize the internal data as required before the first step is +092 * handled. +093 */ +094 public void reset() { +095 lastTime = Double.NaN; +096 lastState = null; +097 lastDerivatives = null; +098 forward = true; +099 } +100 +101 /** +102 * Handle the last accepted step +103 * @param interpolator interpolator for the last accepted step. For +104 * efficiency purposes, the various integrators reuse the same +105 * object on each call, so if the instance wants to keep it across +106 * all calls (for example to provide at the end of the integration a +107 * continuous model valid throughout the integration range), it +108 * should build a local copy using the clone method and store this +109 * copy. +110 * @param isLast true if the step is the last one +111 * @throws DerivativeException this exception is propagated to the +112 * caller if the underlying user function triggers one +113 */ +114 public void handleStep(final StepInterpolator interpolator, final boolean isLast) +115 throws DerivativeException { +116 +117 if (lastState == null) { +118 +119 lastTime = interpolator.getPreviousTime(); +120 interpolator.setInterpolatedTime(lastTime); +121 lastState = interpolator.getInterpolatedState().clone(); +122 lastDerivatives = interpolator.getInterpolatedDerivatives().clone(); +123 +124 // take the integration direction into account +125 forward = interpolator.getCurrentTime() >= lastTime; +126 if (! forward) { +127 h = -h; +128 } +129 +130 } +131 +132 double nextTime = lastTime + h; +133 boolean nextInStep = forward ^ (nextTime > interpolator.getCurrentTime()); +134 while (nextInStep) { +135 +136 // output the stored previous step +137 handler.handleStep(lastTime, lastState, lastDerivatives, false); +138 +139 // store the next step +140 lastTime = nextTime; +141 interpolator.setInterpolatedTime(lastTime); +142 System.arraycopy(interpolator.getInterpolatedState(), 0, +143 lastState, 0, lastState.length); +144 System.arraycopy(interpolator.getInterpolatedDerivatives(), 0, +145 lastDerivatives, 0, lastDerivatives.length); +146 +147 nextTime += h; +148 nextInStep = forward ^ (nextTime > interpolator.getCurrentTime()); +149 +150 } +151 +152 if (isLast) { +153 // there will be no more steps, +154 // the stored one should be flagged as being the last +155 handler.handleStep(lastTime, lastState, lastDerivatives, true); +156 } +157 +158 } +159 +160 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/DifferentiableMultivariateRealOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/DifferentiableMultivariateRealOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,177 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction; +022 +023 /** +024 * This interface represents an optimization algorithm for {@link DifferentiableMultivariateRealFunction +025 * scalar differentiable objective functions}. +026 * <p>Optimization algorithms find the input point set that either {@link GoalType +027 * maximize or minimize} an objective function.</p> +028 * @see MultivariateRealOptimizer +029 * @see DifferentiableMultivariateVectorialOptimizer +030 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +031 * @since 2.0 +032 */ +033 public interface DifferentiableMultivariateRealOptimizer { +034 +035 /** Set the maximal number of iterations of the algorithm. +036 * @param maxIterations maximal number of function calls +037 */ +038 void setMaxIterations(int maxIterations); +039 +040 /** Get the maximal number of iterations of the algorithm. +041 * @return maximal number of iterations +042 */ +043 int getMaxIterations(); +044 +045 /** Get the number of iterations realized by the algorithm. +046 * <p> +047 * The number of evaluations corresponds to the last call to the +048 * {@link #optimize(DifferentiableMultivariateRealFunction, GoalType, double[]) optimize} +049 * method. It is 0 if the method has not been called yet. +050 * </p> +051 * @return number of iterations +052 */ +053 int getIterations(); +054 +055 /** Set the maximal number of functions evaluations. +056 * @param maxEvaluations maximal number of function evaluations +057 */ +058 void setMaxEvaluations(int maxEvaluations); +059 +060 /** Get the maximal number of functions evaluations. +061 * @return maximal number of functions evaluations +062 */ +063 int getMaxEvaluations(); +064 +065 /** Get the number of evaluations of the objective function. +066 * <p> +067 * The number of evaluations corresponds to the last call to the +068 * {@link #optimize(DifferentiableMultivariateRealFunction, GoalType, double[]) optimize} +069 * method. It is 0 if the method has not been called yet. +070 * </p> +071 * @return number of evaluations of the objective function +072 */ +073 int getEvaluations(); +074 +075 /** Get the number of evaluations of the objective function gradient. +076 * <p> +077 * The number of evaluations corresponds to the last call to the +078 * {@link #optimize(DifferentiableMultivariateRealFunction, GoalType, double[]) optimize} +079 * method. It is 0 if the method has not been called yet. +080 * </p> +081 * @return number of evaluations of the objective function gradient +082 */ +083 int getGradientEvaluations(); +084 +085 /** Set the convergence checker. +086 * @param checker object to use to check for convergence +087 */ +088 void setConvergenceChecker(RealConvergenceChecker checker); +089 +090 /** Get the convergence checker. +091 * @return object used to check for convergence +092 */ +093 RealConvergenceChecker getConvergenceChecker(); +094 +095 /** Optimizes an objective function. +096 * @param f objective function +097 * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE} +098 * or {@link GoalType#MINIMIZE} +099 * @param startPoint the start point for optimization +100 * @return the point/value pair giving the optimal value for objective function +101 * @exception FunctionEvaluationException if the objective function throws one during +102 * the search +103 * @exception OptimizationException if the algorithm failed to converge +104 * @exception IllegalArgumentException if the start point dimension is wrong +105 */ +106 RealPointValuePair optimize(DifferentiableMultivariateRealFunction f, +107 GoalType goalType, +108 double[] startPoint) +109 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; +110 +111 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/DifferentiableMultivariateVectorialOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/DifferentiableMultivariateVectorialOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,180 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction; +022 +023 /** +024 * This interface represents an optimization algorithm for {@link DifferentiableMultivariateVectorialFunction +025 * vectorial differentiable objective functions}. +026 * <p>Optimization algorithms find the input point set that either {@link GoalType +027 * maximize or minimize} an objective function.</p> +028 * @see MultivariateRealOptimizer +029 * @see DifferentiableMultivariateRealOptimizer +030 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +031 * @since 2.0 +032 */ +033 public interface DifferentiableMultivariateVectorialOptimizer { +034 +035 /** Set the maximal number of iterations of the algorithm. +036 * @param maxIterations maximal number of function calls +037 * . +038 */ +039 void setMaxIterations(int maxIterations); +040 +041 /** Get the maximal number of iterations of the algorithm. +042 * @return maximal number of iterations +043 */ +044 int getMaxIterations(); +045 +046 /** Get the number of iterations realized by the algorithm. +047 * @return number of iterations +048 */ +049 int getIterations(); +050 +051 /** Set the maximal number of functions evaluations. +052 * @param maxEvaluations maximal number of function evaluations +053 */ +054 void setMaxEvaluations(int maxEvaluations); +055 +056 /** Get the maximal number of functions evaluations. +057 * @return maximal number of functions evaluations +058 */ +059 int getMaxEvaluations(); +060 +061 /** Get the number of evaluations of the objective function. +062 * <p> +063 * The number of evaluation correspond to the last call to the +064 * {@link #optimize(DifferentiableMultivariateVectorialFunction, +065 * double[], double[], double[]) optimize} method. It is 0 if +066 * the method has not been called yet. +067 * </p> +068 * @return number of evaluations of the objective function +069 */ +070 int getEvaluations(); +071 +072 /** Get the number of evaluations of the objective function jacobian . +073 * <p> +074 * The number of evaluation correspond to the last call to the +075 * {@link #optimize(DifferentiableMultivariateVectorialFunction, +076 * double[], double[], double[]) optimize} method. It is 0 if +077 * the method has not been called yet. +078 * </p> +079 * @return number of evaluations of the objective function jacobian +080 */ +081 int getJacobianEvaluations(); +082 +083 /** Set the convergence checker. +084 * @param checker object to use to check for convergence +085 */ +086 void setConvergenceChecker(VectorialConvergenceChecker checker); +087 +088 /** Get the convergence checker. +089 * @return object used to check for convergence +090 */ +091 VectorialConvergenceChecker getConvergenceChecker(); +092 +093 /** Optimizes an objective function. +094 * <p> +095 * Optimization is considered to be a weighted least-squares minimization. +096 * The cost function to be minimized is +097 * ∑weight<sub>i</sub>(objective<sub>i</sub>-target<sub>i</sub>)<sup>2</sup> +098 * </p> +099 * @param f objective function +100 * @param target target value for the objective functions at optimum +101 * @param weights weight for the least squares cost computation +102 * @param startPoint the start point for optimization +103 * @return the point/value pair giving the optimal value for objective function +104 * @exception FunctionEvaluationException if the objective function throws one during +105 * the search +106 * @exception OptimizationException if the algorithm failed to converge +107 * @exception IllegalArgumentException if the start point dimension is wrong +108 */ +109 VectorialPointValuePair optimize(DifferentiableMultivariateVectorialFunction f, +110 double[] target, double[] weights, +111 double[] startPoint) +112 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; +113 +114 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/GoalType.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/GoalType.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,101 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import java.io.Serializable; +021 +022 /** +023 * Goal type for an optimization problem. +024 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +025 * @since 2.0 +026 */ +027 public enum GoalType implements Serializable { +028 +029 /** Maximization goal. */ +030 MAXIMIZE, +031 +032 /** Minimization goal. */ +033 MINIMIZE +034 +035 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/LeastSquaresConverter.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/LeastSquaresConverter.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,258 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.analysis.MultivariateRealFunction; +023 import org.apache.commons.math.analysis.MultivariateVectorialFunction; +024 import org.apache.commons.math.linear.RealMatrix; +025 +026 /** This class converts {@link MultivariateVectorialFunction vectorial +027 * objective functions} to {@link MultivariateRealFunction scalar objective functions} +028 * when the goal is to minimize them. +029 * <p> +030 * This class is mostly used when the vectorial objective function represents +031 * a theoretical result computed from a point set applied to a model and +032 * the models point must be adjusted to fit the theoretical result to some +033 * reference observations. The observations may be obtained for example from +034 * physical measurements whether the model is built from theoretical +035 * considerations. +036 * </p> +037 * <p> +038 * This class computes a possibly weighted squared sum of the residuals, which is +039 * a scalar value. The residuals are the difference between the theoretical model +040 * (i.e. the output of the vectorial objective function) and the observations. The +041 * class implements the {@link MultivariateRealFunction} interface and can therefore be +042 * minimized by any optimizer supporting scalar objectives functions.This is one way +043 * to perform a least square estimation. There are other ways to do this without using +044 * this converter, as some optimization algorithms directly support vectorial objective +045 * functions. +046 * </p> +047 * <p> +048 * This class support combination of residuals with or without weights and correlations. +049 * </p> +050 * +051 * @see MultivariateRealFunction +052 * @see MultivariateVectorialFunction +053 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +054 * @since 2.0 +055 */ +056 +057 public class LeastSquaresConverter implements MultivariateRealFunction { +058 +059 /** Underlying vectorial function. */ +060 private final MultivariateVectorialFunction function; +061 +062 /** Observations to be compared to objective function to compute residuals. */ +063 private final double[] observations; +064 +065 /** Optional weights for the residuals. */ +066 private final double[] weights; +067 +068 /** Optional scaling matrix (weight and correlations) for the residuals. */ +069 private final RealMatrix scale; +070 +071 /** Build a simple converter for uncorrelated residuals with the same weight. +072 * @param function vectorial residuals function to wrap +073 * @param observations observations to be compared to objective function to compute residuals +074 */ +075 public LeastSquaresConverter(final MultivariateVectorialFunction function, +076 final double[] observations) { +077 this.function = function; +078 this.observations = observations.clone(); +079 this.weights = null; +080 this.scale = null; +081 } +082 +083 /** Build a simple converter for uncorrelated residuals with the specific weights. +084 * <p> +085 * The scalar objective function value is computed as: +086 * <pre> +087 * objective = ∑weight<sub>i</sub>(observation<sub>i</sub>-objective<sub>i</sub>)<sup>2</sup> +088 * </pre> +089 * </p> +090 * <p> +091 * Weights can be used for example to combine residuals with different standard +092 * deviations. As an example, consider a residuals array in which even elements +093 * are angular measurements in degrees with a 0.01° standard deviation and +094 * odd elements are distance measurements in meters with a 15m standard deviation. +095 * In this case, the weights array should be initialized with value +096 * 1.0/(0.01<sup>2</sup>) in the even elements and 1.0/(15.0<sup>2</sup>) in the +097 * odd elements (i.e. reciprocals of variances). +098 * </p> +099 * <p> +100 * The array computed by the objective function, the observations array and the +101 * weights array must have consistent sizes or a {@link FunctionEvaluationException} will be +102 * triggered while computing the scalar objective. +103 * </p> +104 * @param function vectorial residuals function to wrap +105 * @param observations observations to be compared to objective function to compute residuals +106 * @param weights weights to apply to the residuals +107 * @exception IllegalArgumentException if the observations vector and the weights +108 * vector dimensions don't match (objective function dimension is checked only when +109 * the {@link #value(double[])} method is called) +110 */ +111 public LeastSquaresConverter(final MultivariateVectorialFunction function, +112 final double[] observations, final double[] weights) +113 throws IllegalArgumentException { +114 if (observations.length != weights.length) { +115 throw MathRuntimeException.createIllegalArgumentException( +116 "dimension mismatch {0} != {1}", +117 observations.length, weights.length); +118 } +119 this.function = function; +120 this.observations = observations.clone(); +121 this.weights = weights.clone(); +122 this.scale = null; +123 } +124 +125 /** Build a simple converter for correlated residuals with the specific weights. +126 * <p> +127 * The scalar objective function value is computed as: +128 * <pre> +129 * objective = y<sup>T</sup>y with y = scale×(observation-objective) +130 * </pre> +131 * </p> +132 * <p> +133 * The array computed by the objective function, the observations array and the +134 * the scaling matrix must have consistent sizes or a {@link FunctionEvaluationException} +135 * will be triggered while computing the scalar objective. +136 * </p> +137 * @param function vectorial residuals function to wrap +138 * @param observations observations to be compared to objective function to compute residuals +139 * @param scale scaling matrix +140 * @exception IllegalArgumentException if the observations vector and the scale +141 * matrix dimensions don't match (objective function dimension is checked only when +142 * the {@link #value(double[])} method is called) +143 */ +144 public LeastSquaresConverter(final MultivariateVectorialFunction function, +145 final double[] observations, final RealMatrix scale) +146 throws IllegalArgumentException { +147 if (observations.length != scale.getColumnDimension()) { +148 throw MathRuntimeException.createIllegalArgumentException( +149 "dimension mismatch {0} != {1}", +150 observations.length, scale.getColumnDimension()); +151 } +152 this.function = function; +153 this.observations = observations.clone(); +154 this.weights = null; +155 this.scale = scale.copy(); +156 } +157 +158 /** {@inheritDoc} */ +159 public double value(final double[] point) throws FunctionEvaluationException { +160 +161 // compute residuals +162 final double[] residuals = function.value(point); +163 if (residuals.length != observations.length) { +164 throw new FunctionEvaluationException(point, "dimension mismatch {0} != {1}", +165 residuals.length, observations.length); +166 } +167 for (int i = 0; i < residuals.length; ++i) { +168 residuals[i] -= observations[i]; +169 } +170 +171 // compute sum of squares +172 double sumSquares = 0; +173 if (weights != null) { +174 for (int i = 0; i < residuals.length; ++i) { +175 final double ri = residuals[i]; +176 sumSquares += weights[i] * ri * ri; +177 } +178 } else if (scale != null) { +179 for (final double yi : scale.operate(residuals)) { +180 sumSquares += yi * yi; +181 } +182 } else { +183 for (final double ri : residuals) { +184 sumSquares += ri * ri; +185 } +186 } +187 +188 return sumSquares; +189 +190 } +191 +192 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,293 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import java.util.Arrays; +021 import java.util.Comparator; +022 +023 import org.apache.commons.math.FunctionEvaluationException; +024 import org.apache.commons.math.MathRuntimeException; +025 import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction; +026 import org.apache.commons.math.random.RandomVectorGenerator; +027 +028 /** +029 * Special implementation of the {@link DifferentiableMultivariateRealOptimizer} interface adding +030 * multi-start features to an existing optimizer. +031 * <p> +032 * This class wraps a classical optimizer to use it several times in +033 * turn with different starting points in order to avoid being trapped +034 * into a local extremum when looking for a global one. +035 * </p> +036 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +037 * @since 2.0 +038 */ +039 public class MultiStartDifferentiableMultivariateRealOptimizer +040 implements DifferentiableMultivariateRealOptimizer { +041 +042 /** Underlying classical optimizer. */ +043 private final DifferentiableMultivariateRealOptimizer optimizer; +044 +045 /** Maximal number of iterations allowed. */ +046 private int maxIterations; +047 +048 /** Number of iterations already performed for all starts. */ +049 private int totalIterations; +050 +051 /** Maximal number of evaluations allowed. */ +052 private int maxEvaluations; +053 +054 /** Number of evaluations already performed for all starts. */ +055 private int totalEvaluations; +056 +057 /** Number of gradient evaluations already performed for all starts. */ +058 private int totalGradientEvaluations; +059 +060 /** Number of starts to go. */ +061 private int starts; +062 +063 /** Random generator for multi-start. */ +064 private RandomVectorGenerator generator; +065 +066 /** Found optima. */ +067 private RealPointValuePair[] optima; +068 +069 /** +070 * Create a multi-start optimizer from a single-start optimizer +071 * @param optimizer single-start optimizer to wrap +072 * @param starts number of starts to perform (including the +073 * first one), multi-start is disabled if value is less than or +074 * equal to 1 +075 * @param generator random vector generator to use for restarts +076 */ +077 public MultiStartDifferentiableMultivariateRealOptimizer(final DifferentiableMultivariateRealOptimizer optimizer, +078 final int starts, +079 final RandomVectorGenerator generator) { +080 this.optimizer = optimizer; +081 this.totalIterations = 0; +082 this.totalEvaluations = 0; +083 this.totalGradientEvaluations = 0; +084 this.starts = starts; +085 this.generator = generator; +086 this.optima = null; +087 setMaxIterations(Integer.MAX_VALUE); +088 setMaxEvaluations(Integer.MAX_VALUE); +089 } +090 +091 /** Get all the optima found during the last call to {@link +092 * #optimize(DifferentiableMultivariateRealFunction, GoalType, double[]) +093 * optimize}. +094 * <p>The optimizer stores all the optima found during a set of +095 * restarts. The {@link #optimize(DifferentiableMultivariateRealFunction, +096 * GoalType, double[]) optimize} method returns the best point only. This +097 * method returns all the points found at the end of each starts, +098 * including the best one already returned by the {@link +099 * #optimize(DifferentiableMultivariateRealFunction, GoalType, double[]) +100 * optimize} method. +101 * </p> +102 * <p> +103 * The returned array as one element for each start as specified +104 * in the constructor. It is ordered with the results from the +105 * runs that did converge first, sorted from best to worst +106 * objective value (i.e in ascending order if minimizing and in +107 * descending order if maximizing), followed by and null elements +108 * corresponding to the runs that did not converge. This means all +109 * elements will be null if the {@link #optimize(DifferentiableMultivariateRealFunction, +110 * GoalType, double[]) optimize} method did throw a {@link +111 * org.apache.commons.math.ConvergenceException ConvergenceException}). +112 * This also means that if the first element is non null, it is the best +113 * point found across all starts.</p> +114 * @return array containing the optima +115 * @exception IllegalStateException if {@link #optimize(DifferentiableMultivariateRealFunction, +116 * GoalType, double[]) optimize} has not been called +117 */ +118 public RealPointValuePair[] getOptima() throws IllegalStateException { +119 if (optima == null) { +120 throw MathRuntimeException.createIllegalStateException("no optimum computed yet"); +121 } +122 return optima.clone(); +123 } +124 +125 /** {@inheritDoc} */ +126 public void setMaxIterations(int maxIterations) { +127 this.maxIterations = maxIterations; +128 } +129 +130 /** {@inheritDoc} */ +131 public int getMaxIterations() { +132 return maxIterations; +133 } +134 +135 /** {@inheritDoc} */ +136 public int getIterations() { +137 return totalIterations; +138 } +139 +140 /** {@inheritDoc} */ +141 public void setMaxEvaluations(int maxEvaluations) { +142 this.maxEvaluations = maxEvaluations; +143 } +144 +145 /** {@inheritDoc} */ +146 public int getMaxEvaluations() { +147 return maxEvaluations; +148 } +149 +150 /** {@inheritDoc} */ +151 public int getEvaluations() { +152 return totalEvaluations; +153 } +154 +155 /** {@inheritDoc} */ +156 public int getGradientEvaluations() { +157 return totalGradientEvaluations; +158 } +159 +160 /** {@inheritDoc} */ +161 public void setConvergenceChecker(RealConvergenceChecker checker) { +162 optimizer.setConvergenceChecker(checker); +163 } +164 +165 /** {@inheritDoc} */ +166 public RealConvergenceChecker getConvergenceChecker() { +167 return optimizer.getConvergenceChecker(); +168 } +169 +170 /** {@inheritDoc} */ +171 public RealPointValuePair optimize(final DifferentiableMultivariateRealFunction f, +172 final GoalType goalType, +173 double[] startPoint) +174 throws FunctionEvaluationException, OptimizationException { +175 +176 optima = new RealPointValuePair[starts]; +177 totalIterations = 0; +178 totalEvaluations = 0; +179 totalGradientEvaluations = 0; +180 +181 // multi-start loop +182 for (int i = 0; i < starts; ++i) { +183 +184 try { +185 optimizer.setMaxIterations(maxIterations - totalIterations); +186 optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations); +187 optima[i] = optimizer.optimize(f, goalType, +188 (i == 0) ? startPoint : generator.nextVector()); +189 } catch (FunctionEvaluationException fee) { +190 optima[i] = null; +191 } catch (OptimizationException oe) { +192 optima[i] = null; +193 } +194 +195 totalIterations += optimizer.getIterations(); +196 totalEvaluations += optimizer.getEvaluations(); +197 totalGradientEvaluations += optimizer.getGradientEvaluations(); +198 +199 } +200 +201 // sort the optima from best to worst, followed by null elements +202 Arrays.sort(optima, new Comparator<RealPointValuePair>() { +203 public int compare(final RealPointValuePair o1, final RealPointValuePair o2) { +204 if (o1 == null) { +205 return (o2 == null) ? 0 : +1; +206 } else if (o2 == null) { +207 return -1; +208 } +209 final double v1 = o1.getValue(); +210 final double v2 = o2.getValue(); +211 return (goalType == GoalType.MINIMIZE) ? +212 Double.compare(v1, v2) : Double.compare(v2, v1); +213 } +214 }); +215 +216 if (optima[0] == null) { +217 throw new OptimizationException( +218 "none of the {0} start points lead to convergence", +219 starts); +220 } +221 +222 // return the found point given the best objective function value +223 return optima[0]; +224 +225 } +226 +227 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateVectorialOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateVectorialOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,303 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import java.util.Arrays; +021 import java.util.Comparator; +022 +023 import org.apache.commons.math.FunctionEvaluationException; +024 import org.apache.commons.math.MathRuntimeException; +025 import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction; +026 import org.apache.commons.math.random.RandomVectorGenerator; +027 +028 /** +029 * Special implementation of the {@link DifferentiableMultivariateVectorialOptimizer} interface adding +030 * multi-start features to an existing optimizer. +031 * <p> +032 * This class wraps a classical optimizer to use it several times in +033 * turn with different starting points in order to avoid being trapped +034 * into a local extremum when looking for a global one. +035 * </p> +036 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +037 * @since 2.0 +038 */ +039 public class MultiStartDifferentiableMultivariateVectorialOptimizer +040 implements DifferentiableMultivariateVectorialOptimizer { +041 +042 /** Serializable version identifier. */ +043 private static final long serialVersionUID = 9206382258980561530L; +044 +045 /** Underlying classical optimizer. */ +046 private final DifferentiableMultivariateVectorialOptimizer optimizer; +047 +048 /** Maximal number of iterations allowed. */ +049 private int maxIterations; +050 +051 /** Number of iterations already performed for all starts. */ +052 private int totalIterations; +053 +054 /** Maximal number of evaluations allowed. */ +055 private int maxEvaluations; +056 +057 /** Number of evaluations already performed for all starts. */ +058 private int totalEvaluations; +059 +060 /** Number of jacobian evaluations already performed for all starts. */ +061 private int totalJacobianEvaluations; +062 +063 /** Number of starts to go. */ +064 private int starts; +065 +066 /** Random generator for multi-start. */ +067 private RandomVectorGenerator generator; +068 +069 /** Found optima. */ +070 private VectorialPointValuePair[] optima; +071 +072 /** +073 * Create a multi-start optimizer from a single-start optimizer +074 * @param optimizer single-start optimizer to wrap +075 * @param starts number of starts to perform (including the +076 * first one), multi-start is disabled if value is less than or +077 * equal to 1 +078 * @param generator random vector generator to use for restarts +079 */ +080 public MultiStartDifferentiableMultivariateVectorialOptimizer( +081 final DifferentiableMultivariateVectorialOptimizer optimizer, +082 final int starts, +083 final RandomVectorGenerator generator) { +084 this.optimizer = optimizer; +085 this.totalIterations = 0; +086 this.totalEvaluations = 0; +087 this.totalJacobianEvaluations = 0; +088 this.starts = starts; +089 this.generator = generator; +090 this.optima = null; +091 setMaxIterations(Integer.MAX_VALUE); +092 setMaxEvaluations(Integer.MAX_VALUE); +093 } +094 +095 /** Get all the optima found during the last call to {@link +096 * #optimize(DifferentiableMultivariateVectorialFunction, +097 * double[], double[], double[]) optimize}. +098 * <p>The optimizer stores all the optima found during a set of +099 * restarts. The {@link #optimize(DifferentiableMultivariateVectorialFunction, +100 * double[], double[], double[]) optimize} method returns the +101 * best point only. This method returns all the points found at the +102 * end of each starts, including the best one already returned by the {@link +103 * #optimize(DifferentiableMultivariateVectorialFunction, double[], +104 * double[], double[]) optimize} method. +105 * </p> +106 * <p> +107 * The returned array as one element for each start as specified +108 * in the constructor. It is ordered with the results from the +109 * runs that did converge first, sorted from best to worst +110 * objective value (i.e in ascending order if minimizing and in +111 * descending order if maximizing), followed by and null elements +112 * corresponding to the runs that did not converge. This means all +113 * elements will be null if the {@link #optimize(DifferentiableMultivariateVectorialFunction, +114 * double[], double[], double[]) optimize} method did throw a {@link +115 * org.apache.commons.math.ConvergenceException ConvergenceException}). +116 * This also means that if the first element is non null, it is the best +117 * point found across all starts.</p> +118 * @return array containing the optima +119 * @exception IllegalStateException if {@link #optimize(DifferentiableMultivariateVectorialFunction, +120 * double[], double[], double[]) optimize} has not been called +121 */ +122 public VectorialPointValuePair[] getOptima() throws IllegalStateException { +123 if (optima == null) { +124 throw MathRuntimeException.createIllegalStateException("no optimum computed yet"); +125 } +126 return optima.clone(); +127 } +128 +129 /** {@inheritDoc} */ +130 public void setMaxIterations(int maxIterations) { +131 this.maxIterations = maxIterations; +132 } +133 +134 /** {@inheritDoc} */ +135 public int getMaxIterations() { +136 return maxIterations; +137 } +138 +139 /** {@inheritDoc} */ +140 public int getIterations() { +141 return totalIterations; +142 } +143 +144 /** {@inheritDoc} */ +145 public void setMaxEvaluations(int maxEvaluations) { +146 this.maxEvaluations = maxEvaluations; +147 } +148 +149 /** {@inheritDoc} */ +150 public int getMaxEvaluations() { +151 return maxEvaluations; +152 } +153 +154 /** {@inheritDoc} */ +155 public int getEvaluations() { +156 return totalEvaluations; +157 } +158 +159 /** {@inheritDoc} */ +160 public int getJacobianEvaluations() { +161 return totalJacobianEvaluations; +162 } +163 +164 /** {@inheritDoc} */ +165 public void setConvergenceChecker(VectorialConvergenceChecker checker) { +166 optimizer.setConvergenceChecker(checker); +167 } +168 +169 /** {@inheritDoc} */ +170 public VectorialConvergenceChecker getConvergenceChecker() { +171 return optimizer.getConvergenceChecker(); +172 } +173 +174 /** {@inheritDoc} */ +175 public VectorialPointValuePair optimize(final DifferentiableMultivariateVectorialFunction f, +176 final double[] target, final double[] weights, +177 final double[] startPoint) +178 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { +179 +180 optima = new VectorialPointValuePair[starts]; +181 totalIterations = 0; +182 totalEvaluations = 0; +183 totalJacobianEvaluations = 0; +184 +185 // multi-start loop +186 for (int i = 0; i < starts; ++i) { +187 +188 try { +189 optimizer.setMaxIterations(maxIterations - totalIterations); +190 optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations); +191 optima[i] = optimizer.optimize(f, target, weights, +192 (i == 0) ? startPoint : generator.nextVector()); +193 } catch (FunctionEvaluationException fee) { +194 optima[i] = null; +195 } catch (OptimizationException oe) { +196 optima[i] = null; +197 } +198 +199 totalIterations += optimizer.getIterations(); +200 totalEvaluations += optimizer.getEvaluations(); +201 totalJacobianEvaluations += optimizer.getJacobianEvaluations(); +202 +203 } +204 +205 // sort the optima from best to worst, followed by null elements +206 Arrays.sort(optima, new Comparator<VectorialPointValuePair>() { +207 public int compare(final VectorialPointValuePair o1, final VectorialPointValuePair o2) { +208 if (o1 == null) { +209 return (o2 == null) ? 0 : +1; +210 } else if (o2 == null) { +211 return -1; +212 } +213 return Double.compare(weightedResidual(o1), weightedResidual(o2)); +214 } +215 private double weightedResidual(final VectorialPointValuePair pv) { +216 final double[] value = pv.getValueRef(); +217 double sum = 0; +218 for (int i = 0; i < value.length; ++i) { +219 final double ri = value[i] - target[i]; +220 sum += weights[i] * ri * ri; +221 } +222 return sum; +223 } +224 }); +225 +226 if (optima[0] == null) { +227 throw new OptimizationException( +228 "none of the {0} start points lead to convergence", +229 starts); +230 } +231 +232 // return the found point given the best objective function value +233 return optima[0]; +234 +235 } +236 +237 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/MultiStartMultivariateRealOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/MultiStartMultivariateRealOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,281 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import java.util.Arrays; +021 import java.util.Comparator; +022 +023 import org.apache.commons.math.FunctionEvaluationException; +024 import org.apache.commons.math.MathRuntimeException; +025 import org.apache.commons.math.analysis.MultivariateRealFunction; +026 import org.apache.commons.math.random.RandomVectorGenerator; +027 +028 /** +029 * Special implementation of the {@link MultivariateRealOptimizer} interface adding +030 * multi-start features to an existing optimizer. +031 * <p> +032 * This class wraps a classical optimizer to use it several times in +033 * turn with different starting points in order to avoid being trapped +034 * into a local extremum when looking for a global one. +035 * </p> +036 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +037 * @since 2.0 +038 */ +039 public class MultiStartMultivariateRealOptimizer +040 implements MultivariateRealOptimizer { +041 +042 /** Underlying classical optimizer. */ +043 private final MultivariateRealOptimizer optimizer; +044 +045 /** Maximal number of iterations allowed. */ +046 private int maxIterations; +047 +048 /** Maximal number of evaluations allowed. */ +049 private int maxEvaluations; +050 +051 /** Number of iterations already performed for all starts. */ +052 private int totalIterations; +053 +054 /** Number of evaluations already performed for all starts. */ +055 private int totalEvaluations; +056 +057 /** Number of starts to go. */ +058 private int starts; +059 +060 /** Random generator for multi-start. */ +061 private RandomVectorGenerator generator; +062 +063 /** Found optima. */ +064 private RealPointValuePair[] optima; +065 +066 /** +067 * Create a multi-start optimizer from a single-start optimizer +068 * @param optimizer single-start optimizer to wrap +069 * @param starts number of starts to perform (including the +070 * first one), multi-start is disabled if value is less than or +071 * equal to 1 +072 * @param generator random vector generator to use for restarts +073 */ +074 public MultiStartMultivariateRealOptimizer(final MultivariateRealOptimizer optimizer, +075 final int starts, +076 final RandomVectorGenerator generator) { +077 this.optimizer = optimizer; +078 this.totalIterations = 0; +079 this.totalEvaluations = 0; +080 this.starts = starts; +081 this.generator = generator; +082 this.optima = null; +083 setMaxIterations(Integer.MAX_VALUE); +084 setMaxEvaluations(Integer.MAX_VALUE); +085 } +086 +087 /** Get all the optima found during the last call to {@link +088 * #optimize(MultivariateRealFunction, GoalType, double[]) optimize}. +089 * <p>The optimizer stores all the optima found during a set of +090 * restarts. The {@link #optimize(MultivariateRealFunction, GoalType, +091 * double[]) optimize} method returns the best point only. This +092 * method returns all the points found at the end of each starts, +093 * including the best one already returned by the {@link +094 * #optimize(MultivariateRealFunction, GoalType, double[]) optimize} +095 * method. +096 * </p> +097 * <p> +098 * The returned array as one element for each start as specified +099 * in the constructor. It is ordered with the results from the +100 * runs that did converge first, sorted from best to worst +101 * objective value (i.e in ascending order if minimizing and in +102 * descending order if maximizing), followed by and null elements +103 * corresponding to the runs that did not converge. This means all +104 * elements will be null if the {@link #optimize(MultivariateRealFunction, +105 * GoalType, double[]) optimize} method did throw a {@link +106 * org.apache.commons.math.ConvergenceException ConvergenceException}). +107 * This also means that if the first element is non null, it is the best +108 * point found across all starts.</p> +109 * @return array containing the optima +110 * @exception IllegalStateException if {@link #optimize(MultivariateRealFunction, +111 * GoalType, double[]) optimize} has not been called +112 */ +113 public RealPointValuePair[] getOptima() throws IllegalStateException { +114 if (optima == null) { +115 throw MathRuntimeException.createIllegalStateException("no optimum computed yet"); +116 } +117 return optima.clone(); +118 } +119 +120 /** {@inheritDoc} */ +121 public void setMaxIterations(int maxIterations) { +122 this.maxIterations = maxIterations; +123 } +124 +125 /** {@inheritDoc} */ +126 public int getMaxIterations() { +127 return maxIterations; +128 } +129 +130 /** {@inheritDoc} */ +131 public void setMaxEvaluations(int maxEvaluations) { +132 this.maxEvaluations = maxEvaluations; +133 } +134 +135 /** {@inheritDoc} */ +136 public int getMaxEvaluations() { +137 return maxEvaluations; +138 } +139 +140 /** {@inheritDoc} */ +141 public int getIterations() { +142 return totalIterations; +143 } +144 +145 /** {@inheritDoc} */ +146 public int getEvaluations() { +147 return totalEvaluations; +148 } +149 +150 /** {@inheritDoc} */ +151 public void setConvergenceChecker(RealConvergenceChecker checker) { +152 optimizer.setConvergenceChecker(checker); +153 } +154 +155 /** {@inheritDoc} */ +156 public RealConvergenceChecker getConvergenceChecker() { +157 return optimizer.getConvergenceChecker(); +158 } +159 +160 /** {@inheritDoc} */ +161 public RealPointValuePair optimize(final MultivariateRealFunction f, +162 final GoalType goalType, +163 double[] startPoint) +164 throws FunctionEvaluationException, OptimizationException { +165 +166 optima = new RealPointValuePair[starts]; +167 totalIterations = 0; +168 totalEvaluations = 0; +169 +170 // multi-start loop +171 for (int i = 0; i < starts; ++i) { +172 +173 try { +174 optimizer.setMaxIterations(maxIterations - totalIterations); +175 optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations); +176 optima[i] = optimizer.optimize(f, goalType, +177 (i == 0) ? startPoint : generator.nextVector()); +178 } catch (FunctionEvaluationException fee) { +179 optima[i] = null; +180 } catch (OptimizationException oe) { +181 optima[i] = null; +182 } +183 +184 totalIterations += optimizer.getIterations(); +185 totalEvaluations += optimizer.getEvaluations(); +186 +187 } +188 +189 // sort the optima from best to worst, followed by null elements +190 Arrays.sort(optima, new Comparator<RealPointValuePair>() { +191 public int compare(final RealPointValuePair o1, final RealPointValuePair o2) { +192 if (o1 == null) { +193 return (o2 == null) ? 0 : +1; +194 } else if (o2 == null) { +195 return -1; +196 } +197 final double v1 = o1.getValue(); +198 final double v2 = o2.getValue(); +199 return (goalType == GoalType.MINIMIZE) ? +200 Double.compare(v1, v2) : Double.compare(v2, v1); +201 } +202 }); +203 +204 if (optima[0] == null) { +205 throw new OptimizationException( +206 "none of the {0} start points lead to convergence", +207 starts); +208 } +209 +210 // return the found point given the best objective function value +211 return optima[0]; +212 +213 } +214 +215 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/MultiStartUnivariateRealOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/MultiStartUnivariateRealOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,384 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import org.apache.commons.math.ConvergenceException; +021 import org.apache.commons.math.FunctionEvaluationException; +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.analysis.UnivariateRealFunction; +024 import org.apache.commons.math.random.RandomGenerator; +025 +026 /** +027 * Special implementation of the {@link UnivariateRealOptimizer} interface adding +028 * multi-start features to an existing optimizer. +029 * <p> +030 * This class wraps a classical optimizer to use it several times in +031 * turn with different starting points in order to avoid being trapped +032 * into a local extremum when looking for a global one. +033 * </p> +034 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +035 * @since 2.0 +036 */ +037 public class MultiStartUnivariateRealOptimizer implements UnivariateRealOptimizer { +038 +039 /** Serializable version identifier. */ +040 private static final long serialVersionUID = 5983375963110961019L; +041 +042 /** Underlying classical optimizer. */ +043 private final UnivariateRealOptimizer optimizer; +044 +045 /** Maximal number of iterations allowed. */ +046 private int maxIterations; +047 +048 /** Maximal number of evaluations allowed. */ +049 private int maxEvaluations; +050 +051 /** Number of iterations already performed for all starts. */ +052 private int totalIterations; +053 +054 /** Number of evaluations already performed for all starts. */ +055 private int totalEvaluations; +056 +057 /** Number of starts to go. */ +058 private int starts; +059 +060 /** Random generator for multi-start. */ +061 private RandomGenerator generator; +062 +063 /** Found optima. */ +064 private double[] optima; +065 +066 /** Found function values at optima. */ +067 private double[] optimaValues; +068 +069 /** +070 * Create a multi-start optimizer from a single-start optimizer +071 * @param optimizer single-start optimizer to wrap +072 * @param starts number of starts to perform (including the +073 * first one), multi-start is disabled if value is less than or +074 * equal to 1 +075 * @param generator random generator to use for restarts +076 */ +077 public MultiStartUnivariateRealOptimizer(final UnivariateRealOptimizer optimizer, +078 final int starts, +079 final RandomGenerator generator) { +080 this.optimizer = optimizer; +081 this.totalIterations = 0; +082 this.starts = starts; +083 this.generator = generator; +084 this.optima = null; +085 setMaximalIterationCount(Integer.MAX_VALUE); +086 setMaxEvaluations(Integer.MAX_VALUE); +087 } +088 +089 /** {@inheritDoc} */ +090 public double getFunctionValue() { +091 return optimizer.getFunctionValue(); +092 } +093 +094 /** {@inheritDoc} */ +095 public double getResult() { +096 return optimizer.getResult(); +097 } +098 +099 /** {@inheritDoc} */ +100 public double getAbsoluteAccuracy() { +101 return optimizer.getAbsoluteAccuracy(); +102 } +103 +104 /** {@inheritDoc} */ +105 public int getIterationCount() { +106 return totalIterations; +107 } +108 +109 /** {@inheritDoc} */ +110 public int getMaximalIterationCount() { +111 return maxIterations; +112 } +113 +114 /** {@inheritDoc} */ +115 public int getMaxEvaluations() { +116 return maxEvaluations; +117 } +118 +119 /** {@inheritDoc} */ +120 public int getEvaluations() { +121 return totalEvaluations; +122 } +123 +124 /** {@inheritDoc} */ +125 public double getRelativeAccuracy() { +126 return optimizer.getRelativeAccuracy(); +127 } +128 +129 /** {@inheritDoc} */ +130 public void resetAbsoluteAccuracy() { +131 optimizer.resetAbsoluteAccuracy(); +132 } +133 +134 /** {@inheritDoc} */ +135 public void resetMaximalIterationCount() { +136 optimizer.resetMaximalIterationCount(); +137 } +138 +139 /** {@inheritDoc} */ +140 public void resetRelativeAccuracy() { +141 optimizer.resetRelativeAccuracy(); +142 } +143 +144 /** {@inheritDoc} */ +145 public void setAbsoluteAccuracy(double accuracy) { +146 optimizer.setAbsoluteAccuracy(accuracy); +147 } +148 +149 /** {@inheritDoc} */ +150 public void setMaximalIterationCount(int count) { +151 this.maxIterations = count; +152 } +153 +154 /** {@inheritDoc} */ +155 public void setMaxEvaluations(int maxEvaluations) { +156 this.maxEvaluations = maxEvaluations; +157 } +158 +159 /** {@inheritDoc} */ +160 public void setRelativeAccuracy(double accuracy) { +161 optimizer.setRelativeAccuracy(accuracy); +162 } +163 +164 /** Get all the optima found during the last call to {@link +165 * #optimize(UnivariateRealFunction, GoalType, double, double) optimize}. +166 * <p>The optimizer stores all the optima found during a set of +167 * restarts. The {@link #optimize(UnivariateRealFunction, GoalType, +168 * double, double) optimize} method returns the best point only. This +169 * method returns all the points found at the end of each starts, +170 * including the best one already returned by the {@link +171 * #optimize(UnivariateRealFunction, GoalType, double, double) optimize} +172 * method. +173 * </p> +174 * <p> +175 * The returned array as one element for each start as specified +176 * in the constructor. It is ordered with the results from the +177 * runs that did converge first, sorted from best to worst +178 * objective value (i.e in ascending order if minimizing and in +179 * descending order if maximizing), followed by Double.NaN elements +180 * corresponding to the runs that did not converge. This means all +181 * elements will be NaN if the {@link #optimize(UnivariateRealFunction, +182 * GoalType, double, double) optimize} method did throw a {@link +183 * ConvergenceException ConvergenceException}). This also means that +184 * if the first element is not NaN, it is the best point found across +185 * all starts.</p> +186 * @return array containing the optima +187 * @exception IllegalStateException if {@link #optimize(UnivariateRealFunction, +188 * GoalType, double, double) optimize} has not been called +189 * @see #getOptimaValues() +190 */ +191 public double[] getOptima() throws IllegalStateException { +192 if (optima == null) { +193 throw MathRuntimeException.createIllegalStateException("no optimum computed yet"); +194 } +195 return optima.clone(); +196 } +197 +198 /** Get all the function values at optima found during the last call to {@link +199 * #optimize(UnivariateRealFunction, GoalType, double, double) optimize}. +200 * <p> +201 * The returned array as one element for each start as specified +202 * in the constructor. It is ordered with the results from the +203 * runs that did converge first, sorted from best to worst +204 * objective value (i.e in ascending order if minimizing and in +205 * descending order if maximizing), followed by Double.NaN elements +206 * corresponding to the runs that did not converge. This means all +207 * elements will be NaN if the {@link #optimize(UnivariateRealFunction, +208 * GoalType, double, double) optimize} method did throw a {@link +209 * ConvergenceException ConvergenceException}). This also means that +210 * if the first element is not NaN, it is the best point found across +211 * all starts.</p> +212 * @return array containing the optima +213 * @exception IllegalStateException if {@link #optimize(UnivariateRealFunction, +214 * GoalType, double, double) optimize} has not been called +215 * @see #getOptima() +216 */ +217 public double[] getOptimaValues() throws IllegalStateException { +218 if (optimaValues == null) { +219 throw MathRuntimeException.createIllegalStateException("no optimum computed yet"); +220 } +221 return optimaValues.clone(); +222 } +223 +224 /** {@inheritDoc} */ +225 public double optimize(final UnivariateRealFunction f, final GoalType goalType, +226 final double min, final double max) +227 throws ConvergenceException, +228 FunctionEvaluationException { +229 +230 optima = new double[starts]; +231 optimaValues = new double[starts]; +232 totalIterations = 0; +233 totalEvaluations = 0; +234 +235 // multi-start loop +236 for (int i = 0; i < starts; ++i) { +237 +238 try { +239 optimizer.setMaximalIterationCount(maxIterations - totalIterations); +240 optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations); +241 final double bound1 = (i == 0) ? min : min + generator.nextDouble() * (max - min); +242 final double bound2 = (i == 0) ? max : min + generator.nextDouble() * (max - min); +243 optima[i] = optimizer.optimize(f, goalType, +244 Math.min(bound1, bound2), +245 Math.max(bound1, bound2)); +246 optimaValues[i] = optimizer.getFunctionValue(); +247 } catch (FunctionEvaluationException fee) { +248 optima[i] = Double.NaN; +249 optimaValues[i] = Double.NaN; +250 } catch (ConvergenceException ce) { +251 optima[i] = Double.NaN; +252 optimaValues[i] = Double.NaN; +253 } +254 +255 totalIterations += optimizer.getIterationCount(); +256 totalEvaluations += optimizer.getEvaluations(); +257 +258 } +259 +260 // sort the optima from best to worst, followed by NaN elements +261 int lastNaN = optima.length; +262 for (int i = 0; i < lastNaN; ++i) { +263 if (Double.isNaN(optima[i])) { +264 optima[i] = optima[--lastNaN]; +265 optima[lastNaN + 1] = Double.NaN; +266 optimaValues[i] = optimaValues[--lastNaN]; +267 optimaValues[lastNaN + 1] = Double.NaN; +268 } +269 } +270 +271 double currX = optima[0]; +272 double currY = optimaValues[0]; +273 for (int j = 1; j < lastNaN; ++j) { +274 final double prevY = currY; +275 currX = optima[j]; +276 currY = optimaValues[j]; +277 if ((goalType == GoalType.MAXIMIZE) ^ (currY < prevY)) { +278 // the current element should be inserted closer to the beginning +279 int i = j - 1; +280 double mIX = optima[i]; +281 double mIY = optimaValues[i]; +282 while ((i >= 0) && ((goalType == GoalType.MAXIMIZE) ^ (currY < mIY))) { +283 optima[i + 1] = mIX; +284 optimaValues[i + 1] = mIY; +285 if (i-- != 0) { +286 mIX = optima[i]; +287 mIY = optimaValues[i]; +288 } else { +289 mIX = Double.NaN; +290 mIY = Double.NaN; +291 } +292 } +293 optima[i + 1] = currX; +294 optimaValues[i + 1] = currY; +295 currX = optima[j]; +296 currY = optimaValues[j]; +297 } +298 } +299 +300 if (Double.isNaN(optima[0])) { +301 throw new OptimizationException( +302 "none of the {0} start points lead to convergence", +303 starts); +304 } +305 +306 // return the found point given the best objective function value +307 return optima[0]; +308 +309 } +310 +311 /** {@inheritDoc} */ +312 public double optimize(final UnivariateRealFunction f, final GoalType goalType, +313 final double min, final double max, final double startValue) +314 throws ConvergenceException, FunctionEvaluationException { +315 return optimize(f, goalType, min, max); +316 } +317 +318 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/MultivariateRealOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/MultivariateRealOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,167 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.analysis.MultivariateRealFunction; +022 +023 /** +024 * This interface represents an optimization algorithm for {@link MultivariateRealFunction +025 * scalar objective functions}. +026 * <p>Optimization algorithms find the input point set that either {@link GoalType +027 * maximize or minimize} an objective function.</p> +028 * @see DifferentiableMultivariateRealOptimizer +029 * @see DifferentiableMultivariateVectorialOptimizer +030 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +031 * @since 2.0 +032 */ +033 public interface MultivariateRealOptimizer { +034 +035 /** Set the maximal number of iterations of the algorithm. +036 * @param maxIterations maximal number of algorithm iterations +037 */ +038 void setMaxIterations(int maxIterations); +039 +040 /** Get the maximal number of iterations of the algorithm. +041 * @return maximal number of iterations +042 */ +043 int getMaxIterations(); +044 +045 /** Set the maximal number of functions evaluations. +046 * @param maxEvaluations maximal number of function evaluations +047 */ +048 void setMaxEvaluations(int maxEvaluations); +049 +050 /** Get the maximal number of functions evaluations. +051 * @return maximal number of functions evaluations +052 */ +053 int getMaxEvaluations(); +054 +055 /** Get the number of iterations realized by the algorithm. +056 * <p> +057 * The number of evaluations corresponds to the last call to the +058 * {@link #optimize(MultivariateRealFunction, GoalType, double[]) optimize} +059 * method. It is 0 if the method has not been called yet. +060 * </p> +061 * @return number of iterations +062 */ +063 int getIterations(); +064 +065 /** Get the number of evaluations of the objective function. +066 * <p> +067 * The number of evaluations corresponds to the last call to the +068 * {@link #optimize(MultivariateRealFunction, GoalType, double[]) optimize} +069 * method. It is 0 if the method has not been called yet. +070 * </p> +071 * @return number of evaluations of the objective function +072 */ +073 int getEvaluations(); +074 +075 /** Set the convergence checker. +076 * @param checker object to use to check for convergence +077 */ +078 void setConvergenceChecker(RealConvergenceChecker checker); +079 +080 /** Get the convergence checker. +081 * @return object used to check for convergence +082 */ +083 RealConvergenceChecker getConvergenceChecker(); +084 +085 /** Optimizes an objective function. +086 * @param f objective function +087 * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE} +088 * or {@link GoalType#MINIMIZE} +089 * @param startPoint the start point for optimization +090 * @return the point/value pair giving the optimal value for objective function +091 * @exception FunctionEvaluationException if the objective function throws one during +092 * the search +093 * @exception OptimizationException if the algorithm failed to converge +094 * @exception IllegalArgumentException if the start point dimension is wrong +095 */ +096 RealPointValuePair optimize(MultivariateRealFunction f, +097 GoalType goalType, +098 double[] startPoint) +099 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; +100 +101 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/OptimizationException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/OptimizationException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,119 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import org.apache.commons.math.ConvergenceException; +021 +022 /** +023 * This class represents exceptions thrown by optimizers. +024 * +025 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +026 * @since 1.2 +027 * +028 */ +029 +030 public class OptimizationException extends ConvergenceException { +031 +032 /** Serializable version identifier. */ +033 private static final long serialVersionUID = -357696069587075016L; +034 +035 /** +036 * Simple constructor. +037 * Build an exception by translating and formating a message +038 * @param specifier format specifier (to be translated) +039 * @param parts to insert in the format (no translation) +040 */ +041 public OptimizationException(String specifier, Object ... parts) { +042 super(specifier, parts); +043 } +044 +045 /** +046 * Create an exception with a given root cause. +047 * @param cause the exception or error that caused this exception to be thrown +048 */ +049 public OptimizationException(Throwable cause) { +050 super(cause); +051 } +052 +053 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/RealConvergenceChecker.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/RealConvergenceChecker.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,121 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 /** This interface specifies how to check if an {@link MultivariateRealOptimizer optimization +021 * algorithm} has converged. +022 * +023 * <p>Deciding if convergence has been reached is a problem-dependent issue. The +024 * user should provide a class implementing this interface to allow the optimization +025 * algorithm to stop its search according to the problem at hand.</p> +026 * <p>For convenience, two implementations that fit simple needs are already provided: +027 * {@link SimpleScalarValueChecker} and {@link SimpleRealPointChecker}. The first +028 * one considers convergence is reached when the objective function value does not +029 * change much anymore, it does not use the point set at all. The second one +030 * considers convergence is reached when the input point set does not change +031 * much anymore, it does not use objective function value at all.</p> +032 * +033 * @version $Revision: 799857 $ $Date: 2009-08-01 09:07:12 -0400 (Sat, 01 Aug 2009) $ +034 * @since 2.0 +035 */ +036 +037 public interface RealConvergenceChecker { +038 +039 /** Check if the optimization algorithm has converged considering the last points. +040 * <p> +041 * This method may be called several time from the same algorithm iteration with +042 * different points. This can be detected by checking the iteration number at each +043 * call if needed. Each time this method is called, the previous and current point +044 * correspond to points with the same role at each iteration, so they can be +045 * compared. As an example, simplex-based algorithms call this method for all +046 * points of the simplex, not only for the best or worst ones. +047 * </p> +048 * @param iteration index of current iteration +049 * @param previous point from previous iteration +050 * @param current point from current iteration +051 * @return true if the algorithm is considered to have converged +052 */ +053 boolean converged(int iteration, RealPointValuePair previous, RealPointValuePair current); +054 +055 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/RealPointValuePair.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/RealPointValuePair.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,154 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import java.io.Serializable; +021 +022 +023 /** +024 * This class holds a point and the value of an objective function at this point. +025 * <p>This is a simple immutable container.</p> +026 * @see VectorialPointValuePair +027 * @see org.apache.commons.math.analysis.MultivariateRealFunction +028 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +029 * @since 2.0 +030 */ +031 public class RealPointValuePair implements Serializable { +032 +033 /** Serializable version identifier. */ +034 private static final long serialVersionUID = 1003888396256744753L; +035 +036 /** Point coordinates. */ +037 private final double[] point; +038 +039 /** Value of the objective function at the point. */ +040 private final double value; +041 +042 /** Build a point/objective function value pair. +043 * @param point point coordinates (the built instance will store +044 * a copy of the array, not the array passed as argument) +045 * @param value value of an objective function at the point +046 */ +047 public RealPointValuePair(final double[] point, final double value) { +048 this.point = point.clone(); +049 this.value = value; +050 } +051 +052 /** Build a point/objective function value pair. +053 * @param point point coordinates (the built instance will store +054 * a copy of the array, not the array passed as argument) +055 * @param value value of an objective function at the point +056 * @param copyArray if true, the input array will be copied, otherwise +057 * it will be referenced +058 */ +059 public RealPointValuePair(final double[] point, final double value, +060 final boolean copyArray) { +061 this.point = copyArray ? point.clone() : point; +062 this.value = value; +063 } +064 +065 /** Get the point. +066 * @return a copy of the stored point +067 */ +068 public double[] getPoint() { +069 return point.clone(); +070 } +071 +072 /** Get a reference to the point. +073 * <p>This method is provided as a convenience to avoid copying +074 * the array, the elements of the array should <em>not</em> be modified.</p> +075 * @return a reference to the internal array storing the point +076 */ +077 public double[] getPointRef() { +078 return point; +079 } +080 +081 /** Get the value of the objective function. +082 * @return the stored value of the objective function +083 */ +084 public double getValue() { +085 return value; +086 } +087 +088 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/SimpleRealPointChecker.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/SimpleRealPointChecker.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,152 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import org.apache.commons.math.util.MathUtils; +021 +022 /** +023 * Simple implementation of the {@link RealConvergenceChecker} interface using +024 * only point coordinates. +025 * <p> +026 * Convergence is considered to have been reached if either the relative +027 * difference between each point coordinate are smaller than a threshold +028 * or if either the absolute difference between the point coordinates are +029 * smaller than another threshold. +030 * </p> +031 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +032 * @since 2.0 +033 */ +034 public class SimpleRealPointChecker implements RealConvergenceChecker { +035 +036 /** Default relative threshold. */ +037 private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON; +038 +039 /** Default absolute threshold. */ +040 private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN; +041 +042 /** Relative tolerance threshold. */ +043 private final double relativeThreshold; +044 +045 /** Absolute tolerance threshold. */ +046 private final double absoluteThreshold; +047 +048 /** Build an instance with default threshold. +049 */ +050 public SimpleRealPointChecker() { +051 this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD; +052 this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD; +053 } +054 +055 /** Build an instance with a specified threshold. +056 * <p> +057 * In order to perform only relative checks, the absolute tolerance +058 * must be set to a negative value. In order to perform only absolute +059 * checks, the relative tolerance must be set to a negative value. +060 * </p> +061 * @param relativeThreshold relative tolerance threshold +062 * @param absoluteThreshold absolute tolerance threshold +063 */ +064 public SimpleRealPointChecker(final double relativeThreshold, +065 final double absoluteThreshold) { +066 this.relativeThreshold = relativeThreshold; +067 this.absoluteThreshold = absoluteThreshold; +068 } +069 +070 /** {@inheritDoc} */ +071 public boolean converged(final int iteration, +072 final RealPointValuePair previous, +073 final RealPointValuePair current) { +074 final double[] p = previous.getPoint(); +075 final double[] c = current.getPoint(); +076 for (int i = 0; i < p.length; ++i) { +077 final double difference = Math.abs(p[i] - c[i]); +078 final double size = Math.max(Math.abs(p[i]), Math.abs(c[i])); +079 if ((difference > (size * relativeThreshold)) && (difference > absoluteThreshold)) { +080 return false; +081 } +082 } +083 return true; +084 } +085 +086 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/SimpleScalarValueChecker.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/SimpleScalarValueChecker.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,147 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import org.apache.commons.math.util.MathUtils; +021 +022 /** +023 * Simple implementation of the {@link RealConvergenceChecker} interface using +024 * only objective function values. +025 * <p> +026 * Convergence is considered to have been reached if either the relative +027 * difference between the objective function values is smaller than a +028 * threshold or if either the absolute difference between the objective +029 * function values is smaller than another threshold. +030 * </p> +031 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +032 * @since 2.0 +033 */ +034 public class SimpleScalarValueChecker implements RealConvergenceChecker { +035 +036 /** Default relative threshold. */ +037 private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON; +038 +039 /** Default absolute threshold. */ +040 private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN; +041 +042 /** Relative tolerance threshold. */ +043 private final double relativeThreshold; +044 +045 /** Absolute tolerance threshold. */ +046 private final double absoluteThreshold; +047 +048 /** Build an instance with default threshold. +049 */ +050 public SimpleScalarValueChecker() { +051 this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD; +052 this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD; +053 } +054 +055 /** Build an instance with a specified threshold. +056 * <p> +057 * In order to perform only relative checks, the absolute tolerance +058 * must be set to a negative value. In order to perform only absolute +059 * checks, the relative tolerance must be set to a negative value. +060 * </p> +061 * @param relativeThreshold relative tolerance threshold +062 * @param absoluteThreshold absolute tolerance threshold +063 */ +064 public SimpleScalarValueChecker(final double relativeThreshold, +065 final double absoluteThreshold) { +066 this.relativeThreshold = relativeThreshold; +067 this.absoluteThreshold = absoluteThreshold; +068 } +069 +070 /** {@inheritDoc} */ +071 public boolean converged(final int iteration, +072 final RealPointValuePair previous, +073 final RealPointValuePair current) { +074 final double p = previous.getValue(); +075 final double c = current.getValue(); +076 final double difference = Math.abs(p - c); +077 final double size = Math.max(Math.abs(p), Math.abs(c)); +078 return (difference <= (size * relativeThreshold)) || (difference <= absoluteThreshold); +079 } +080 +081 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/SimpleVectorialPointChecker.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/SimpleVectorialPointChecker.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,155 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import org.apache.commons.math.util.MathUtils; +021 +022 /** +023 * Simple implementation of the {@link VectorialConvergenceChecker} interface using +024 * only point coordinates. +025 * <p> +026 * Convergence is considered to have been reached if either the relative +027 * difference between each point coordinate are smaller than a threshold +028 * or if either the absolute difference between the point coordinates are +029 * smaller than another threshold. +030 * </p> +031 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +032 * @since 2.0 +033 */ +034 public class SimpleVectorialPointChecker implements VectorialConvergenceChecker { +035 +036 /** Default relative threshold. */ +037 private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON; +038 +039 /** Default absolute threshold. */ +040 private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN; +041 +042 /** Relative tolerance threshold. */ +043 private final double relativeThreshold; +044 +045 /** Absolute tolerance threshold. */ +046 private final double absoluteThreshold; +047 +048 /** Build an instance with default threshold. +049 */ +050 public SimpleVectorialPointChecker() { +051 this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD; +052 this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD; +053 } +054 +055 /** Build an instance with a specified threshold. +056 * <p> +057 * In order to perform only relative checks, the absolute tolerance +058 * must be set to a negative value. In order to perform only absolute +059 * checks, the relative tolerance must be set to a negative value. +060 * </p> +061 * @param relativeThreshold relative tolerance threshold +062 * @param absoluteThreshold absolute tolerance threshold +063 */ +064 public SimpleVectorialPointChecker(final double relativeThreshold, +065 final double absoluteThreshold) { +066 this.relativeThreshold = relativeThreshold; +067 this.absoluteThreshold = absoluteThreshold; +068 } +069 +070 /** {@inheritDoc} */ +071 public boolean converged(final int iteration, +072 final VectorialPointValuePair previous, +073 final VectorialPointValuePair current) { +074 final double[] p = previous.getPointRef(); +075 final double[] c = current.getPointRef(); +076 for (int i = 0; i < p.length; ++i) { +077 final double pi = p[i]; +078 final double ci = c[i]; +079 final double difference = Math.abs(pi - ci); +080 final double size = Math.max(Math.abs(pi), Math.abs(ci)); +081 if ((difference > (size * relativeThreshold)) && +082 (difference > absoluteThreshold)) { +083 return false; +084 } +085 } +086 return true; +087 } +088 +089 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/SimpleVectorialValueChecker.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/SimpleVectorialValueChecker.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,155 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import org.apache.commons.math.util.MathUtils; +021 +022 /** +023 * Simple implementation of the {@link VectorialConvergenceChecker} interface using +024 * only objective function values. +025 * <p> +026 * Convergence is considered to have been reached if either the relative +027 * difference between the objective function values is smaller than a +028 * threshold or if either the absolute difference between the objective +029 * function values is smaller than another threshold for all vectors elements. +030 * </p> +031 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +032 * @since 2.0 +033 */ +034 public class SimpleVectorialValueChecker implements VectorialConvergenceChecker { +035 +036 /** Default relative threshold. */ +037 private static final double DEFAULT_RELATIVE_THRESHOLD = 100 * MathUtils.EPSILON; +038 +039 /** Default absolute threshold. */ +040 private static final double DEFAULT_ABSOLUTE_THRESHOLD = 100 * MathUtils.SAFE_MIN; +041 +042 /** Relative tolerance threshold. */ +043 private final double relativeThreshold; +044 +045 /** Absolute tolerance threshold. */ +046 private final double absoluteThreshold; +047 +048 /** Build an instance with default threshold. +049 */ +050 public SimpleVectorialValueChecker() { +051 this.relativeThreshold = DEFAULT_RELATIVE_THRESHOLD; +052 this.absoluteThreshold = DEFAULT_ABSOLUTE_THRESHOLD; +053 } +054 +055 /** Build an instance with a specified threshold. +056 * <p> +057 * In order to perform only relative checks, the absolute tolerance +058 * must be set to a negative value. In order to perform only absolute +059 * checks, the relative tolerance must be set to a negative value. +060 * </p> +061 * @param relativeThreshold relative tolerance threshold +062 * @param absoluteThreshold absolute tolerance threshold +063 */ +064 public SimpleVectorialValueChecker(final double relativeThreshold, +065 final double absoluteThreshold) { +066 this.relativeThreshold = relativeThreshold; +067 this.absoluteThreshold = absoluteThreshold; +068 } +069 +070 /** {@inheritDoc} */ +071 public boolean converged(final int iteration, +072 final VectorialPointValuePair previous, +073 final VectorialPointValuePair current) { +074 final double[] p = previous.getValueRef(); +075 final double[] c = current.getValueRef(); +076 for (int i = 0; i < p.length; ++i) { +077 final double pi = p[i]; +078 final double ci = c[i]; +079 final double difference = Math.abs(pi - ci); +080 final double size = Math.max(Math.abs(pi), Math.abs(ci)); +081 if ((difference > (size * relativeThreshold)) && +082 (difference > absoluteThreshold)) { +083 return false; +084 } +085 } +086 return true; +087 } +088 +089 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/UnivariateRealOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/UnivariateRealOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,182 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.optimization; +018 +019 import org.apache.commons.math.ConvergenceException; +020 import org.apache.commons.math.ConvergingAlgorithm; +021 import org.apache.commons.math.FunctionEvaluationException; +022 import org.apache.commons.math.analysis.UnivariateRealFunction; +023 +024 +025 /** +026 * Interface for (univariate real) optimization algorithms. +027 * +028 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +029 * @since 2.0 +030 */ +031 public interface UnivariateRealOptimizer extends ConvergingAlgorithm { +032 +033 /** Set the maximal number of functions evaluations. +034 * @param maxEvaluations maximal number of function evaluations +035 */ +036 void setMaxEvaluations(int maxEvaluations); +037 +038 /** Get the maximal number of functions evaluations. +039 * @return maximal number of functions evaluations +040 */ +041 int getMaxEvaluations(); +042 +043 /** Get the number of evaluations of the objective function. +044 * <p> +045 * The number of evaluations corresponds to the last call to the +046 * {@link #optimize(UnivariateRealFunction, GoalType, double, double) optimize} +047 * method. It is 0 if the method has not been called yet. +048 * </p> +049 * @return number of evaluations of the objective function +050 */ +051 int getEvaluations(); +052 +053 /** +054 * Find an optimum in the given interval. +055 * <p> +056 * An optimizer may require that the interval brackets a single optimum. +057 * </p> +058 * @param f the function to optimize. +059 * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE} +060 * or {@link GoalType#MINIMIZE} +061 * @param min the lower bound for the interval. +062 * @param max the upper bound for the interval. +063 * @return a value where the function is optimum +064 * @throws ConvergenceException if the maximum iteration count is exceeded +065 * or the optimizer detects convergence problems otherwise. +066 * @throws FunctionEvaluationException if an error occurs evaluating the +067 * function +068 * @throws IllegalArgumentException if min > max or the endpoints do not +069 * satisfy the requirements specified by the optimizer +070 */ +071 double optimize(UnivariateRealFunction f, GoalType goalType, +072 double min, double max) +073 throws ConvergenceException, FunctionEvaluationException; +074 +075 /** +076 * Find an optimum in the given interval, start at startValue. +077 * <p> +078 * An optimizer may require that the interval brackets a single optimum. +079 * </p> +080 * @param f the function to optimize. +081 * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE} +082 * or {@link GoalType#MINIMIZE} +083 * @param min the lower bound for the interval. +084 * @param max the upper bound for the interval. +085 * @param startValue the start value to use +086 * @return a value where the function is optimum +087 * @throws ConvergenceException if the maximum iteration count is exceeded +088 * or the optimizer detects convergence problems otherwise. +089 * @throws FunctionEvaluationException if an error occurs evaluating the +090 * function +091 * @throws IllegalArgumentException if min > max or the arguments do not +092 * satisfy the requirements specified by the optimizer +093 */ +094 double optimize(UnivariateRealFunction f, GoalType goalType, +095 double min, double max, double startValue) +096 throws ConvergenceException, FunctionEvaluationException; +097 +098 /** +099 * Get the result of the last run of the optimizer. +100 * +101 * @return the last result. +102 * @throws IllegalStateException if there is no result available, either +103 * because no result was yet computed or the last attempt failed. +104 */ +105 double getResult(); +106 +107 /** +108 * Get the result of the last run of the optimizer. +109 * +110 * @return the value of the function at the last result. +111 * @throws IllegalStateException if there is no result available, either +112 * because no result was yet computed or the last attempt failed. +113 */ +114 double getFunctionValue(); +115 +116 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/VectorialConvergenceChecker.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/VectorialConvergenceChecker.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,121 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 /** This interface specifies how to check if a {@link +021 * DifferentiableMultivariateVectorialOptimizer optimization algorithm} has converged. +022 * +023 * <p>Deciding if convergence has been reached is a problem-dependent issue. The +024 * user should provide a class implementing this interface to allow the optimization +025 * algorithm to stop its search according to the problem at hand.</p> +026 * <p>For convenience, two implementations that fit simple needs are already provided: +027 * {@link SimpleVectorialValueChecker} and {@link SimpleVectorialPointChecker}. The first +028 * one considers convergence is reached when the objective function value does not +029 * change much anymore, it does not use the point set at all. The second one +030 * considers convergence is reached when the input point set does not change +031 * much anymore, it does not use objective function value at all.</p> +032 * +033 * @version $Revision: 780674 $ $Date: 2009-06-01 11:10:55 -0400 (Mon, 01 Jun 2009) $ +034 * @since 2.0 +035 */ +036 +037 public interface VectorialConvergenceChecker { +038 +039 /** Check if the optimization algorithm has converged considering the last points. +040 * <p> +041 * This method may be called several time from the same algorithm iteration with +042 * different points. This can be detected by checking the iteration number at each +043 * call if needed. Each time this method is called, the previous and current point +044 * correspond to points with the same role at each iteration, so they can be +045 * compared. As an example, simplex-based algorithms call this method for all +046 * points of the simplex, not only for the best or worst ones. +047 * </p> +048 * @param iteration index of current iteration +049 * @param previous point from previous iteration +050 * @param current point from current iteration +051 * @return true if the algorithm is considered to have converged +052 */ +053 boolean converged(int iteration, VectorialPointValuePair previous, VectorialPointValuePair current); +054 +055 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/VectorialPointValuePair.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/VectorialPointValuePair.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,162 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization; +019 +020 import java.io.Serializable; +021 +022 /** +023 * This class holds a point and the vectorial value of an objective function at this point. +024 * <p>This is a simple immutable container.</p> +025 * @see RealPointValuePair +026 * @see org.apache.commons.math.analysis.MultivariateVectorialFunction +027 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +028 * @since 2.0 +029 */ +030 public class VectorialPointValuePair implements Serializable { +031 +032 /** Serializable version identifier. */ +033 private static final long serialVersionUID = 1003888396256744753L; +034 +035 /** Point coordinates. */ +036 private final double[] point; +037 +038 /** Vectorial value of the objective function at the point. */ +039 private final double[] value; +040 +041 /** Build a point/objective function value pair. +042 * @param point point coordinates (the built instance will store +043 * a copy of the array, not the array passed as argument) +044 * @param value value of an objective function at the point +045 */ +046 public VectorialPointValuePair(final double[] point, final double[] value) { +047 this.point = point.clone(); +048 this.value = value.clone(); +049 } +050 +051 /** Build a point/objective function value pair. +052 * @param point point coordinates (the built instance will store +053 * a copy of the array, not the array passed as argument) +054 * @param value value of an objective function at the point +055 * @param copyArray if true, the input arrays will be copied, otherwise +056 * they will be referenced +057 */ +058 public VectorialPointValuePair(final double[] point, final double[] value, +059 final boolean copyArray) { +060 this.point = copyArray ? point.clone() : point; +061 this.value = copyArray ? value.clone() : value; +062 } +063 +064 /** Get the point. +065 * @return a copy of the stored point +066 */ +067 public double[] getPoint() { +068 return point.clone(); +069 } +070 +071 /** Get a reference to the point. +072 * <p>This method is provided as a convenience to avoid copying +073 * the array, the elements of the array should <em>not</em> be modified.</p> +074 * @return a reference to the internal array storing the point +075 */ +076 public double[] getPointRef() { +077 return point; +078 } +079 +080 /** Get the value of the objective function. +081 * @return a copy of the stored value of the objective function +082 */ +083 public double[] getValue() { +084 return value.clone(); +085 } +086 +087 /** Get a reference to the value of the objective function. +088 * <p>This method is provided as a convenience to avoid copying +089 * the array, the elements of the array should <em>not</em> be modified.</p> +090 * @return a reference to the internal array storing the value of the objective function +091 */ +092 public double[] getValueRef() { +093 return value; +094 } +095 +096 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/direct/DirectSearchOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/direct/DirectSearchOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,492 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.direct; +019 +020 import java.util.Arrays; +021 import java.util.Comparator; +022 +023 import org.apache.commons.math.FunctionEvaluationException; +024 import org.apache.commons.math.MathRuntimeException; +025 import org.apache.commons.math.MaxEvaluationsExceededException; +026 import org.apache.commons.math.MaxIterationsExceededException; +027 import org.apache.commons.math.analysis.MultivariateRealFunction; +028 import org.apache.commons.math.optimization.GoalType; +029 import org.apache.commons.math.optimization.MultivariateRealOptimizer; +030 import org.apache.commons.math.optimization.OptimizationException; +031 import org.apache.commons.math.optimization.RealConvergenceChecker; +032 import org.apache.commons.math.optimization.RealPointValuePair; +033 import org.apache.commons.math.optimization.SimpleScalarValueChecker; +034 +035 /** +036 * This class implements simplex-based direct search optimization +037 * algorithms. +038 * +039 * <p>Direct search methods only use objective function values, they don't +040 * need derivatives and don't either try to compute approximation of +041 * the derivatives. According to a 1996 paper by Margaret H. Wright +042 * (<a href="http://cm.bell-labs.com/cm/cs/doc/96/4-02.ps.gz">Direct +043 * Search Methods: Once Scorned, Now Respectable</a>), they are used +044 * when either the computation of the derivative is impossible (noisy +045 * functions, unpredictable discontinuities) or difficult (complexity, +046 * computation cost). In the first cases, rather than an optimum, a +047 * <em>not too bad</em> point is desired. In the latter cases, an +048 * optimum is desired but cannot be reasonably found. In all cases +049 * direct search methods can be useful.</p> +050 * +051 * <p>Simplex-based direct search methods are based on comparison of +052 * the objective function values at the vertices of a simplex (which is a +053 * set of n+1 points in dimension n) that is updated by the algorithms +054 * steps.<p> +055 * +056 * <p>The initial configuration of the simplex can be set using either +057 * {@link #setStartConfiguration(double[])} or {@link +058 * #setStartConfiguration(double[][])}. If neither method has been called +059 * before optimization is attempted, an explicit call to the first method +060 * with all steps set to +1 is triggered, thus building a default +061 * configuration from a unit hypercube. Each call to {@link +062 * #optimize(MultivariateRealFunction, GoalType, double[]) optimize} will reuse +063 * the current start configuration and move it such that its first vertex +064 * is at the provided start point of the optimization. If the same optimizer +065 * is used to solve different problems and the number of parameters change, +066 * the start configuration <em>must</em> be reset or a dimension mismatch +067 * will occur.</p> +068 * +069 * <p>If {@link #setConvergenceChecker(RealConvergenceChecker)} is not called, +070 * a default {@link SimpleScalarValueChecker} is used.</p> +071 * +072 * <p>Convergence is checked by providing the <em>worst</em> points of +073 * previous and current simplex to the convergence checker, not the best ones.</p> +074 * +075 * <p>This class is the base class performing the boilerplate simplex +076 * initialization and handling. The simplex update by itself is +077 * performed by the derived classes according to the implemented +078 * algorithms.</p> +079 * +080 * implements MultivariateRealOptimizer since 2.0 +081 * +082 * @see MultivariateRealFunction +083 * @see NelderMead +084 * @see MultiDirectional +085 * @version $Revision: 885278 $ $Date: 2009-11-29 16:47:51 -0500 (Sun, 29 Nov 2009) $ +086 * @since 1.2 +087 */ +088 public abstract class DirectSearchOptimizer implements MultivariateRealOptimizer { +089 +090 /** Message for equal vertices. */ +091 private static final String EQUAL_VERTICES_MESSAGE = +092 "equal vertices {0} and {1} in simplex configuration"; +093 +094 /** Message for dimension mismatch. */ +095 private static final String DIMENSION_MISMATCH_MESSAGE = +096 "dimension mismatch {0} != {1}"; +097 +098 /** Simplex. */ +099 protected RealPointValuePair[] simplex; +100 +101 /** Objective function. */ +102 private MultivariateRealFunction f; +103 +104 /** Convergence checker. */ +105 private RealConvergenceChecker checker; +106 +107 /** Maximal number of iterations allowed. */ +108 private int maxIterations; +109 +110 /** Number of iterations already performed. */ +111 private int iterations; +112 +113 /** Maximal number of evaluations allowed. */ +114 private int maxEvaluations; +115 +116 /** Number of evaluations already performed. */ +117 private int evaluations; +118 +119 /** Start simplex configuration. */ +120 private double[][] startConfiguration; +121 +122 /** Simple constructor. +123 */ +124 protected DirectSearchOptimizer() { +125 setConvergenceChecker(new SimpleScalarValueChecker()); +126 setMaxIterations(Integer.MAX_VALUE); +127 setMaxEvaluations(Integer.MAX_VALUE); +128 } +129 +130 /** Set start configuration for simplex. +131 * <p>The start configuration for simplex is built from a box parallel to +132 * the canonical axes of the space. The simplex is the subset of vertices +133 * of a box parallel to the canonical axes. It is built as the path followed +134 * while traveling from one vertex of the box to the diagonally opposite +135 * vertex moving only along the box edges. The first vertex of the box will +136 * be located at the start point of the optimization.</p> +137 * <p>As an example, in dimension 3 a simplex has 4 vertices. Setting the +138 * steps to (1, 10, 2) and the start point to (1, 1, 1) would imply the +139 * start simplex would be: { (1, 1, 1), (2, 1, 1), (2, 11, 1), (2, 11, 3) }. +140 * The first vertex would be set to the start point at (1, 1, 1) and the +141 * last vertex would be set to the diagonally opposite vertex at (2, 11, 3).</p> +142 * @param steps steps along the canonical axes representing box edges, +143 * they may be negative but not null +144 * @exception IllegalArgumentException if one step is null +145 */ +146 public void setStartConfiguration(final double[] steps) +147 throws IllegalArgumentException { +148 // only the relative position of the n final vertices with respect +149 // to the first one are stored +150 final int n = steps.length; +151 startConfiguration = new double[n][n]; +152 for (int i = 0; i < n; ++i) { +153 final double[] vertexI = startConfiguration[i]; +154 for (int j = 0; j < i + 1; ++j) { +155 if (steps[j] == 0.0) { +156 throw MathRuntimeException.createIllegalArgumentException( +157 EQUAL_VERTICES_MESSAGE, j, j + 1); +158 } +159 System.arraycopy(steps, 0, vertexI, 0, j + 1); +160 } +161 } +162 } +163 +164 /** Set start configuration for simplex. +165 * <p>The real initial simplex will be set up by moving the reference +166 * simplex such that its first point is located at the start point of the +167 * optimization.</p> +168 * @param referenceSimplex reference simplex +169 * @exception IllegalArgumentException if the reference simplex does not +170 * contain at least one point, or if there is a dimension mismatch +171 * in the reference simplex or if one of its vertices is duplicated +172 */ +173 public void setStartConfiguration(final double[][] referenceSimplex) +174 throws IllegalArgumentException { +175 +176 // only the relative position of the n final vertices with respect +177 // to the first one are stored +178 final int n = referenceSimplex.length - 1; +179 if (n < 0) { +180 throw MathRuntimeException.createIllegalArgumentException( +181 "simplex must contain at least one point"); +182 } +183 startConfiguration = new double[n][n]; +184 final double[] ref0 = referenceSimplex[0]; +185 +186 // vertices loop +187 for (int i = 0; i < n + 1; ++i) { +188 +189 final double[] refI = referenceSimplex[i]; +190 +191 // safety checks +192 if (refI.length != n) { +193 throw MathRuntimeException.createIllegalArgumentException( +194 DIMENSION_MISMATCH_MESSAGE, refI.length, n); +195 } +196 for (int j = 0; j < i; ++j) { +197 final double[] refJ = referenceSimplex[j]; +198 boolean allEquals = true; +199 for (int k = 0; k < n; ++k) { +200 if (refI[k] != refJ[k]) { +201 allEquals = false; +202 break; +203 } +204 } +205 if (allEquals) { +206 throw MathRuntimeException.createIllegalArgumentException( +207 EQUAL_VERTICES_MESSAGE, i, j); +208 } +209 } +210 +211 // store vertex i position relative to vertex 0 position +212 if (i > 0) { +213 final double[] confI = startConfiguration[i - 1]; +214 for (int k = 0; k < n; ++k) { +215 confI[k] = refI[k] - ref0[k]; +216 } +217 } +218 +219 } +220 +221 } +222 +223 /** {@inheritDoc} */ +224 public void setMaxIterations(int maxIterations) { +225 this.maxIterations = maxIterations; +226 } +227 +228 /** {@inheritDoc} */ +229 public int getMaxIterations() { +230 return maxIterations; +231 } +232 +233 /** {@inheritDoc} */ +234 public void setMaxEvaluations(int maxEvaluations) { +235 this.maxEvaluations = maxEvaluations; +236 } +237 +238 /** {@inheritDoc} */ +239 public int getMaxEvaluations() { +240 return maxEvaluations; +241 } +242 +243 /** {@inheritDoc} */ +244 public int getIterations() { +245 return iterations; +246 } +247 +248 /** {@inheritDoc} */ +249 public int getEvaluations() { +250 return evaluations; +251 } +252 +253 /** {@inheritDoc} */ +254 public void setConvergenceChecker(RealConvergenceChecker convergenceChecker) { +255 this.checker = convergenceChecker; +256 } +257 +258 /** {@inheritDoc} */ +259 public RealConvergenceChecker getConvergenceChecker() { +260 return checker; +261 } +262 +263 /** {@inheritDoc} */ +264 public RealPointValuePair optimize(final MultivariateRealFunction function, +265 final GoalType goalType, +266 final double[] startPoint) +267 throws FunctionEvaluationException, OptimizationException, +268 IllegalArgumentException { +269 +270 if (startConfiguration == null) { +271 // no initial configuration has been set up for simplex +272 // build a default one from a unit hypercube +273 final double[] unit = new double[startPoint.length]; +274 Arrays.fill(unit, 1.0); +275 setStartConfiguration(unit); +276 } +277 +278 this.f = function; +279 final Comparator<RealPointValuePair> comparator = +280 new Comparator<RealPointValuePair>() { +281 public int compare(final RealPointValuePair o1, +282 final RealPointValuePair o2) { +283 final double v1 = o1.getValue(); +284 final double v2 = o2.getValue(); +285 return (goalType == GoalType.MINIMIZE) ? +286 Double.compare(v1, v2) : Double.compare(v2, v1); +287 } +288 }; +289 +290 // initialize search +291 iterations = 0; +292 evaluations = 0; +293 buildSimplex(startPoint); +294 evaluateSimplex(comparator); +295 +296 RealPointValuePair[] previous = new RealPointValuePair[simplex.length]; +297 while (true) { +298 +299 if (iterations > 0) { +300 boolean converged = true; +301 for (int i = 0; i < simplex.length; ++i) { +302 converged &= checker.converged(iterations, previous[i], simplex[i]); +303 } +304 if (converged) { +305 // we have found an optimum +306 return simplex[0]; +307 } +308 } +309 +310 // we still need to search +311 System.arraycopy(simplex, 0, previous, 0, simplex.length); +312 iterateSimplex(comparator); +313 +314 } +315 +316 } +317 +318 /** Increment the iterations counter by 1. +319 * @exception OptimizationException if the maximal number +320 * of iterations is exceeded +321 */ +322 protected void incrementIterationsCounter() +323 throws OptimizationException { +324 if (++iterations > maxIterations) { +325 throw new OptimizationException(new MaxIterationsExceededException(maxIterations)); +326 } +327 } +328 +329 /** Compute the next simplex of the algorithm. +330 * @param comparator comparator to use to sort simplex vertices from best to worst +331 * @exception FunctionEvaluationException if the function cannot be evaluated at +332 * some point +333 * @exception OptimizationException if the algorithm fails to converge +334 * @exception IllegalArgumentException if the start point dimension is wrong +335 */ +336 protected abstract void iterateSimplex(final Comparator<RealPointValuePair> comparator) +337 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; +338 +339 /** Evaluate the objective function on one point. +340 * <p>A side effect of this method is to count the number of +341 * function evaluations</p> +342 * @param x point on which the objective function should be evaluated +343 * @return objective function value at the given point +344 * @exception FunctionEvaluationException if no value can be computed for the +345 * parameters or if the maximal number of evaluations is exceeded +346 * @exception IllegalArgumentException if the start point dimension is wrong +347 */ +348 protected double evaluate(final double[] x) +349 throws FunctionEvaluationException, IllegalArgumentException { +350 if (++evaluations > maxEvaluations) { +351 throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), +352 x); +353 } +354 return f.value(x); +355 } +356 +357 /** Build an initial simplex. +358 * @param startPoint the start point for optimization +359 * @exception IllegalArgumentException if the start point does not match +360 * simplex dimension +361 */ +362 private void buildSimplex(final double[] startPoint) +363 throws IllegalArgumentException { +364 +365 final int n = startPoint.length; +366 if (n != startConfiguration.length) { +367 throw MathRuntimeException.createIllegalArgumentException( +368 DIMENSION_MISMATCH_MESSAGE, n, startConfiguration.length); +369 } +370 +371 // set first vertex +372 simplex = new RealPointValuePair[n + 1]; +373 simplex[0] = new RealPointValuePair(startPoint, Double.NaN); +374 +375 // set remaining vertices +376 for (int i = 0; i < n; ++i) { +377 final double[] confI = startConfiguration[i]; +378 final double[] vertexI = new double[n]; +379 for (int k = 0; k < n; ++k) { +380 vertexI[k] = startPoint[k] + confI[k]; +381 } +382 simplex[i + 1] = new RealPointValuePair(vertexI, Double.NaN); +383 } +384 +385 } +386 +387 /** Evaluate all the non-evaluated points of the simplex. +388 * @param comparator comparator to use to sort simplex vertices from best to worst +389 * @exception FunctionEvaluationException if no value can be computed for the parameters +390 * @exception OptimizationException if the maximal number of evaluations is exceeded +391 */ +392 protected void evaluateSimplex(final Comparator<RealPointValuePair> comparator) +393 throws FunctionEvaluationException, OptimizationException { +394 +395 // evaluate the objective function at all non-evaluated simplex points +396 for (int i = 0; i < simplex.length; ++i) { +397 final RealPointValuePair vertex = simplex[i]; +398 final double[] point = vertex.getPointRef(); +399 if (Double.isNaN(vertex.getValue())) { +400 simplex[i] = new RealPointValuePair(point, evaluate(point), false); +401 } +402 } +403 +404 // sort the simplex from best to worst +405 Arrays.sort(simplex, comparator); +406 +407 } +408 +409 /** Replace the worst point of the simplex by a new point. +410 * @param pointValuePair point to insert +411 * @param comparator comparator to use to sort simplex vertices from best to worst +412 */ +413 protected void replaceWorstPoint(RealPointValuePair pointValuePair, +414 final Comparator<RealPointValuePair> comparator) { +415 int n = simplex.length - 1; +416 for (int i = 0; i < n; ++i) { +417 if (comparator.compare(simplex[i], pointValuePair) > 0) { +418 RealPointValuePair tmp = simplex[i]; +419 simplex[i] = pointValuePair; +420 pointValuePair = tmp; +421 } +422 } +423 simplex[n] = pointValuePair; +424 } +425 +426 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/direct/MultiDirectional.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/direct/MultiDirectional.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,211 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.direct; +019 +020 import java.util.Comparator; +021 +022 import org.apache.commons.math.FunctionEvaluationException; +023 import org.apache.commons.math.optimization.OptimizationException; +024 import org.apache.commons.math.optimization.RealConvergenceChecker; +025 import org.apache.commons.math.optimization.RealPointValuePair; +026 +027 /** +028 * This class implements the multi-directional direct search method. +029 * +030 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +031 * @see NelderMead +032 * @since 1.2 +033 */ +034 public class MultiDirectional extends DirectSearchOptimizer { +035 +036 /** Expansion coefficient. */ +037 private final double khi; +038 +039 /** Contraction coefficient. */ +040 private final double gamma; +041 +042 /** Build a multi-directional optimizer with default coefficients. +043 * <p>The default values are 2.0 for khi and 0.5 for gamma.</p> +044 */ +045 public MultiDirectional() { +046 this.khi = 2.0; +047 this.gamma = 0.5; +048 } +049 +050 /** Build a multi-directional optimizer with specified coefficients. +051 * @param khi expansion coefficient +052 * @param gamma contraction coefficient +053 */ +054 public MultiDirectional(final double khi, final double gamma) { +055 this.khi = khi; +056 this.gamma = gamma; +057 } +058 +059 /** {@inheritDoc} */ +060 @Override +061 protected void iterateSimplex(final Comparator<RealPointValuePair> comparator) +062 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { +063 +064 final RealConvergenceChecker checker = getConvergenceChecker(); +065 while (true) { +066 +067 incrementIterationsCounter(); +068 +069 // save the original vertex +070 final RealPointValuePair[] original = simplex; +071 final RealPointValuePair best = original[0]; +072 +073 // perform a reflection step +074 final RealPointValuePair reflected = evaluateNewSimplex(original, 1.0, comparator); +075 if (comparator.compare(reflected, best) < 0) { +076 +077 // compute the expanded simplex +078 final RealPointValuePair[] reflectedSimplex = simplex; +079 final RealPointValuePair expanded = evaluateNewSimplex(original, khi, comparator); +080 if (comparator.compare(reflected, expanded) <= 0) { +081 // accept the reflected simplex +082 simplex = reflectedSimplex; +083 } +084 +085 return; +086 +087 } +088 +089 // compute the contracted simplex +090 final RealPointValuePair contracted = evaluateNewSimplex(original, gamma, comparator); +091 if (comparator.compare(contracted, best) < 0) { +092 // accept the contracted simplex +093 return; +094 } +095 +096 // check convergence +097 final int iter = getIterations(); +098 boolean converged = true; +099 for (int i = 0; i < simplex.length; ++i) { +100 converged &= checker.converged(iter, original[i], simplex[i]); +101 } +102 if (converged) { +103 return; +104 } +105 +106 } +107 +108 } +109 +110 /** Compute and evaluate a new simplex. +111 * @param original original simplex (to be preserved) +112 * @param coeff linear coefficient +113 * @param comparator comparator to use to sort simplex vertices from best to poorest +114 * @return best point in the transformed simplex +115 * @exception FunctionEvaluationException if the function cannot be evaluated at +116 * some point +117 * @exception OptimizationException if the maximal number of evaluations is exceeded +118 */ +119 private RealPointValuePair evaluateNewSimplex(final RealPointValuePair[] original, +120 final double coeff, +121 final Comparator<RealPointValuePair> comparator) +122 throws FunctionEvaluationException, OptimizationException { +123 +124 final double[] xSmallest = original[0].getPointRef(); +125 final int n = xSmallest.length; +126 +127 // create the linearly transformed simplex +128 simplex = new RealPointValuePair[n + 1]; +129 simplex[0] = original[0]; +130 for (int i = 1; i <= n; ++i) { +131 final double[] xOriginal = original[i].getPointRef(); +132 final double[] xTransformed = new double[n]; +133 for (int j = 0; j < n; ++j) { +134 xTransformed[j] = xSmallest[j] + coeff * (xSmallest[j] - xOriginal[j]); +135 } +136 simplex[i] = new RealPointValuePair(xTransformed, Double.NaN, false); +137 } +138 +139 // evaluate it +140 evaluateSimplex(comparator); +141 return simplex[0]; +142 +143 } +144 +145 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/direct/NelderMead.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/direct/NelderMead.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,247 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.direct; +019 +020 import java.util.Comparator; +021 +022 import org.apache.commons.math.FunctionEvaluationException; +023 import org.apache.commons.math.optimization.OptimizationException; +024 import org.apache.commons.math.optimization.RealPointValuePair; +025 +026 /** +027 * This class implements the Nelder-Mead direct search method. +028 * +029 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +030 * @see MultiDirectional +031 * @since 1.2 +032 */ +033 public class NelderMead extends DirectSearchOptimizer { +034 +035 /** Reflection coefficient. */ +036 private final double rho; +037 +038 /** Expansion coefficient. */ +039 private final double khi; +040 +041 /** Contraction coefficient. */ +042 private final double gamma; +043 +044 /** Shrinkage coefficient. */ +045 private final double sigma; +046 +047 /** Build a Nelder-Mead optimizer with default coefficients. +048 * <p>The default coefficients are 1.0 for rho, 2.0 for khi and 0.5 +049 * for both gamma and sigma.</p> +050 */ +051 public NelderMead() { +052 this.rho = 1.0; +053 this.khi = 2.0; +054 this.gamma = 0.5; +055 this.sigma = 0.5; +056 } +057 +058 /** Build a Nelder-Mead optimizer with specified coefficients. +059 * @param rho reflection coefficient +060 * @param khi expansion coefficient +061 * @param gamma contraction coefficient +062 * @param sigma shrinkage coefficient +063 */ +064 public NelderMead(final double rho, final double khi, +065 final double gamma, final double sigma) { +066 this.rho = rho; +067 this.khi = khi; +068 this.gamma = gamma; +069 this.sigma = sigma; +070 } +071 +072 /** {@inheritDoc} */ +073 @Override +074 protected void iterateSimplex(final Comparator<RealPointValuePair> comparator) +075 throws FunctionEvaluationException, OptimizationException { +076 +077 incrementIterationsCounter(); +078 +079 // the simplex has n+1 point if dimension is n +080 final int n = simplex.length - 1; +081 +082 // interesting values +083 final RealPointValuePair best = simplex[0]; +084 final RealPointValuePair secondBest = simplex[n-1]; +085 final RealPointValuePair worst = simplex[n]; +086 final double[] xWorst = worst.getPointRef(); +087 +088 // compute the centroid of the best vertices +089 // (dismissing the worst point at index n) +090 final double[] centroid = new double[n]; +091 for (int i = 0; i < n; ++i) { +092 final double[] x = simplex[i].getPointRef(); +093 for (int j = 0; j < n; ++j) { +094 centroid[j] += x[j]; +095 } +096 } +097 final double scaling = 1.0 / n; +098 for (int j = 0; j < n; ++j) { +099 centroid[j] *= scaling; +100 } +101 +102 // compute the reflection point +103 final double[] xR = new double[n]; +104 for (int j = 0; j < n; ++j) { +105 xR[j] = centroid[j] + rho * (centroid[j] - xWorst[j]); +106 } +107 final RealPointValuePair reflected = new RealPointValuePair(xR, evaluate(xR), false); +108 +109 if ((comparator.compare(best, reflected) <= 0) && +110 (comparator.compare(reflected, secondBest) < 0)) { +111 +112 // accept the reflected point +113 replaceWorstPoint(reflected, comparator); +114 +115 } else if (comparator.compare(reflected, best) < 0) { +116 +117 // compute the expansion point +118 final double[] xE = new double[n]; +119 for (int j = 0; j < n; ++j) { +120 xE[j] = centroid[j] + khi * (xR[j] - centroid[j]); +121 } +122 final RealPointValuePair expanded = new RealPointValuePair(xE, evaluate(xE), false); +123 +124 if (comparator.compare(expanded, reflected) < 0) { +125 // accept the expansion point +126 replaceWorstPoint(expanded, comparator); +127 } else { +128 // accept the reflected point +129 replaceWorstPoint(reflected, comparator); +130 } +131 +132 } else { +133 +134 if (comparator.compare(reflected, worst) < 0) { +135 +136 // perform an outside contraction +137 final double[] xC = new double[n]; +138 for (int j = 0; j < n; ++j) { +139 xC[j] = centroid[j] + gamma * (xR[j] - centroid[j]); +140 } +141 final RealPointValuePair outContracted = new RealPointValuePair(xC, evaluate(xC), false); +142 +143 if (comparator.compare(outContracted, reflected) <= 0) { +144 // accept the contraction point +145 replaceWorstPoint(outContracted, comparator); +146 return; +147 } +148 +149 } else { +150 +151 // perform an inside contraction +152 final double[] xC = new double[n]; +153 for (int j = 0; j < n; ++j) { +154 xC[j] = centroid[j] - gamma * (centroid[j] - xWorst[j]); +155 } +156 final RealPointValuePair inContracted = new RealPointValuePair(xC, evaluate(xC), false); +157 +158 if (comparator.compare(inContracted, worst) < 0) { +159 // accept the contraction point +160 replaceWorstPoint(inContracted, comparator); +161 return; +162 } +163 +164 } +165 +166 // perform a shrink +167 final double[] xSmallest = simplex[0].getPointRef(); +168 for (int i = 1; i < simplex.length; ++i) { +169 final double[] x = simplex[i].getPoint(); +170 for (int j = 0; j < n; ++j) { +171 x[j] = xSmallest[j] + sigma * (x[j] - xSmallest[j]); +172 } +173 simplex[i] = new RealPointValuePair(x, Double.NaN, false); +174 } +175 evaluateSimplex(comparator); +176 +177 } +178 +179 } +180 +181 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/CurveFitter.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/CurveFitter.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,265 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.fitting; +019 +020 import java.util.ArrayList; +021 import java.util.List; +022 +023 import org.apache.commons.math.FunctionEvaluationException; +024 import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction; +025 import org.apache.commons.math.analysis.MultivariateMatrixFunction; +026 import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer; +027 import org.apache.commons.math.optimization.OptimizationException; +028 import org.apache.commons.math.optimization.VectorialPointValuePair; +029 +030 /** Fitter for parametric univariate real functions y = f(x). +031 * <p>When a univariate real function y = f(x) does depend on some +032 * unknown parameters p<sub>0</sub>, p<sub>1</sub> ... p<sub>n-1</sub>, +033 * this class can be used to find these parameters. It does this +034 * by <em>fitting</em> the curve so it remains very close to a set of +035 * observed points (x<sub>0</sub>, y<sub>0</sub>), (x<sub>1</sub>, +036 * y<sub>1</sub>) ... (x<sub>k-1</sub>, y<sub>k-1</sub>). This fitting +037 * is done by finding the parameters values that minimizes the objective +038 * function ∑(y<sub>i</sub>-f(x<sub>i</sub>))<sup>2</sup>. This is +039 * really a least squares problem.</p> +040 * @version $Revision: 927009 $ $Date: 2010-03-24 07:14:07 -0400 (Wed, 24 Mar 2010) $ +041 * @since 2.0 +042 */ +043 public class CurveFitter { +044 +045 /** Optimizer to use for the fitting. */ +046 private final DifferentiableMultivariateVectorialOptimizer optimizer; +047 +048 /** Observed points. */ +049 private final List<WeightedObservedPoint> observations; +050 +051 /** Simple constructor. +052 * @param optimizer optimizer to use for the fitting +053 */ +054 public CurveFitter(final DifferentiableMultivariateVectorialOptimizer optimizer) { +055 this.optimizer = optimizer; +056 observations = new ArrayList<WeightedObservedPoint>(); +057 } +058 +059 /** Add an observed (x,y) point to the sample with unit weight. +060 * <p>Calling this method is equivalent to call +061 * <code>addObservedPoint(1.0, x, y)</code>.</p> +062 * @param x abscissa of the point +063 * @param y observed value of the point at x, after fitting we should +064 * have f(x) as close as possible to this value +065 * @see #addObservedPoint(double, double, double) +066 * @see #addObservedPoint(WeightedObservedPoint) +067 * @see #getObservations() +068 */ +069 public void addObservedPoint(double x, double y) { +070 addObservedPoint(1.0, x, y); +071 } +072 +073 /** Add an observed weighted (x,y) point to the sample. +074 * @param weight weight of the observed point in the fit +075 * @param x abscissa of the point +076 * @param y observed value of the point at x, after fitting we should +077 * have f(x) as close as possible to this value +078 * @see #addObservedPoint(double, double) +079 * @see #addObservedPoint(WeightedObservedPoint) +080 * @see #getObservations() +081 */ +082 public void addObservedPoint(double weight, double x, double y) { +083 observations.add(new WeightedObservedPoint(weight, x, y)); +084 } +085 +086 /** Add an observed weighted (x,y) point to the sample. +087 * @param observed observed point to add +088 * @see #addObservedPoint(double, double) +089 * @see #addObservedPoint(double, double, double) +090 * @see #getObservations() +091 */ +092 public void addObservedPoint(WeightedObservedPoint observed) { +093 observations.add(observed); +094 } +095 +096 /** Get the observed points. +097 * @return observed points +098 * @see #addObservedPoint(double, double) +099 * @see #addObservedPoint(double, double, double) +100 * @see #addObservedPoint(WeightedObservedPoint) +101 */ +102 public WeightedObservedPoint[] getObservations() { +103 return observations.toArray(new WeightedObservedPoint[observations.size()]); +104 } +105 +106 /** +107 * Remove all observations. +108 */ +109 public void clearObservations() { +110 observations.clear(); +111 } +112 +113 /** Fit a curve. +114 * <p>This method compute the coefficients of the curve that best +115 * fit the sample of observed points previously given through calls +116 * to the {@link #addObservedPoint(WeightedObservedPoint) +117 * addObservedPoint} method.</p> +118 * @param f parametric function to fit +119 * @param initialGuess first guess of the function parameters +120 * @return fitted parameters +121 * @exception FunctionEvaluationException if the objective function throws one during +122 * the search +123 * @exception OptimizationException if the algorithm failed to converge +124 * @exception IllegalArgumentException if the start point dimension is wrong +125 */ +126 public double[] fit(final ParametricRealFunction f, +127 final double[] initialGuess) +128 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { +129 +130 // prepare least squares problem +131 double[] target = new double[observations.size()]; +132 double[] weights = new double[observations.size()]; +133 int i = 0; +134 for (WeightedObservedPoint point : observations) { +135 target[i] = point.getY(); +136 weights[i] = point.getWeight(); +137 ++i; +138 } +139 +140 // perform the fit +141 VectorialPointValuePair optimum = +142 optimizer.optimize(new TheoreticalValuesFunction(f), target, weights, initialGuess); +143 +144 // extract the coefficients +145 return optimum.getPointRef(); +146 +147 } +148 +149 /** Vectorial function computing function theoretical values. */ +150 private class TheoreticalValuesFunction +151 implements DifferentiableMultivariateVectorialFunction { +152 +153 /** Function to fit. */ +154 private final ParametricRealFunction f; +155 +156 /** Simple constructor. +157 * @param f function to fit. +158 */ +159 public TheoreticalValuesFunction(final ParametricRealFunction f) { +160 this.f = f; +161 } +162 +163 /** {@inheritDoc} */ +164 public MultivariateMatrixFunction jacobian() { +165 return new MultivariateMatrixFunction() { +166 public double[][] value(double[] point) +167 throws FunctionEvaluationException, IllegalArgumentException { +168 +169 final double[][] jacobian = new double[observations.size()][]; +170 +171 int i = 0; +172 for (WeightedObservedPoint observed : observations) { +173 jacobian[i++] = f.gradient(observed.getX(), point); +174 } +175 +176 return jacobian; +177 +178 } +179 }; +180 } +181 +182 /** {@inheritDoc} */ +183 public double[] value(double[] point) +184 throws FunctionEvaluationException, IllegalArgumentException { +185 +186 // compute the residuals +187 final double[] values = new double[observations.size()]; +188 int i = 0; +189 for (WeightedObservedPoint observed : observations) { +190 values[i++] = f.value(observed.getX(), point); +191 } +192 +193 return values; +194 +195 } +196 +197 } +198 +199 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/HarmonicCoefficientsGuesser.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/HarmonicCoefficientsGuesser.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,366 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.fitting; +019 +020 import org.apache.commons.math.optimization.OptimizationException; +021 +022 /** This class guesses harmonic coefficients from a sample. +023 +024 * <p>The algorithm used to guess the coefficients is as follows:</p> +025 +026 * <p>We know f (t) at some sampling points t<sub>i</sub> and want to find a, +027 * ω and φ such that f (t) = a cos (ω t + φ). +028 * </p> +029 * +030 * <p>From the analytical expression, we can compute two primitives : +031 * <pre> +032 * If2 (t) = ∫ f<sup>2</sup> = a<sup>2</sup> × [t + S (t)] / 2 +033 * If'2 (t) = ∫ f'<sup>2</sup> = a<sup>2</sup> ω<sup>2</sup> × [t - S (t)] / 2 +034 * where S (t) = sin (2 (ω t + φ)) / (2 ω) +035 * </pre> +036 * </p> +037 * +038 * <p>We can remove S between these expressions : +039 * <pre> +040 * If'2 (t) = a<sup>2</sup> ω<sup>2</sup> t - ω<sup>2</sup> If2 (t) +041 * </pre> +042 * </p> +043 * +044 * <p>The preceding expression shows that If'2 (t) is a linear +045 * combination of both t and If2 (t): If'2 (t) = A × t + B × If2 (t) +046 * </p> +047 * +048 * <p>From the primitive, we can deduce the same form for definite +049 * integrals between t<sub>1</sub> and t<sub>i</sub> for each t<sub>i</sub> : +050 * <pre> +051 * If2 (t<sub>i</sub>) - If2 (t<sub>1</sub>) = A × (t<sub>i</sub> - t<sub>1</sub>) + B × (If2 (t<sub>i</sub>) - If2 (t<sub>1</sub>)) +052 * </pre> +053 * </p> +054 * +055 * <p>We can find the coefficients A and B that best fit the sample +056 * to this linear expression by computing the definite integrals for +057 * each sample points. +058 * </p> +059 * +060 * <p>For a bilinear expression z (x<sub>i</sub>, y<sub>i</sub>) = A × x<sub>i</sub> + B × y<sub>i</sub>, the +061 * coefficients A and B that minimize a least square criterion +062 * ∑ (z<sub>i</sub> - z (x<sub>i</sub>, y<sub>i</sub>))<sup>2</sup> are given by these expressions:</p> +063 * <pre> +064 * +065 * ∑y<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>z<sub>i</sub> - ∑x<sub>i</sub>y<sub>i</sub> ∑y<sub>i</sub>z<sub>i</sub> +066 * A = ------------------------ +067 * ∑x<sub>i</sub>x<sub>i</sub> ∑y<sub>i</sub>y<sub>i</sub> - ∑x<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>y<sub>i</sub> +068 * +069 * ∑x<sub>i</sub>x<sub>i</sub> ∑y<sub>i</sub>z<sub>i</sub> - ∑x<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>z<sub>i</sub> +070 * B = ------------------------ +071 * ∑x<sub>i</sub>x<sub>i</sub> ∑y<sub>i</sub>y<sub>i</sub> - ∑x<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>y<sub>i</sub> +072 * </pre> +073 * </p> +074 * +075 * +076 * <p>In fact, we can assume both a and ω are positive and +077 * compute them directly, knowing that A = a<sup>2</sup> ω<sup>2</sup> and that +078 * B = - ω<sup>2</sup>. The complete algorithm is therefore:</p> +079 * <pre> +080 * +081 * for each t<sub>i</sub> from t<sub>1</sub> to t<sub>n-1</sub>, compute: +082 * f (t<sub>i</sub>) +083 * 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>) +084 * x<sub>i</sub> = t<sub>i</sub> - t<sub>1</sub> +085 * y<sub>i</sub> = ∫ f<sup>2</sup> from t<sub>1</sub> to t<sub>i</sub> +086 * z<sub>i</sub> = ∫ f'<sup>2</sup> from t<sub>1</sub> to t<sub>i</sub> +087 * update the sums ∑x<sub>i</sub>x<sub>i</sub>, ∑y<sub>i</sub>y<sub>i</sub>, ∑x<sub>i</sub>y<sub>i</sub>, ∑x<sub>i</sub>z<sub>i</sub> and ∑y<sub>i</sub>z<sub>i</sub> +088 * end for +089 * +090 * |-------------------------- +091 * \ | ∑y<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>z<sub>i</sub> - ∑x<sub>i</sub>y<sub>i</sub> ∑y<sub>i</sub>z<sub>i</sub> +092 * a = \ | ------------------------ +093 * \| ∑x<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>z<sub>i</sub> - ∑x<sub>i</sub>x<sub>i</sub> ∑y<sub>i</sub>z<sub>i</sub> +094 * +095 * +096 * |-------------------------- +097 * \ | ∑x<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>z<sub>i</sub> - ∑x<sub>i</sub>x<sub>i</sub> ∑y<sub>i</sub>z<sub>i</sub> +098 * ω = \ | ------------------------ +099 * \| ∑x<sub>i</sub>x<sub>i</sub> ∑y<sub>i</sub>y<sub>i</sub> - ∑x<sub>i</sub>y<sub>i</sub> ∑x<sub>i</sub>y<sub>i</sub> +100 * +101 * </pre> +102 * </p> +103 +104 * <p>Once we know ω, we can compute: +105 * <pre> +106 * fc = ω f (t) cos (ω t) - f' (t) sin (ω t) +107 * fs = ω f (t) sin (ω t) + f' (t) cos (ω t) +108 * </pre> +109 * </p> +110 +111 * <p>It appears that <code>fc = a ω cos (φ)</code> and +112 * <code>fs = -a ω sin (φ)</code>, so we can use these +113 * expressions to compute φ. The best estimate over the sample is +114 * given by averaging these expressions. +115 * </p> +116 +117 * <p>Since integrals and means are involved in the preceding +118 * estimations, these operations run in O(n) time, where n is the +119 * number of measurements.</p> +120 +121 * @version $Revision: 786479 $ $Date: 2009-06-19 08:36:16 -0400 (Fri, 19 Jun 2009) $ +122 * @since 2.0 +123 +124 */ +125 public class HarmonicCoefficientsGuesser { +126 +127 /** Sampled observations. */ +128 private final WeightedObservedPoint[] observations; +129 +130 /** Guessed amplitude. */ +131 private double a; +132 +133 /** Guessed pulsation ω. */ +134 private double omega; +135 +136 /** Guessed phase φ. */ +137 private double phi; +138 +139 /** Simple constructor. +140 * @param observations sampled observations +141 */ +142 public HarmonicCoefficientsGuesser(WeightedObservedPoint[] observations) { +143 this.observations = observations.clone(); +144 a = Double.NaN; +145 omega = Double.NaN; +146 } +147 +148 /** Estimate a first guess of the coefficients. +149 * @exception OptimizationException if the sample is too short or if +150 * the first guess cannot be computed (when the elements under the +151 * square roots are negative). +152 * */ +153 public void guess() throws OptimizationException { +154 sortObservations(); +155 guessAOmega(); +156 guessPhi(); +157 } +158 +159 /** Sort the observations with respect to the abscissa. +160 */ +161 private void sortObservations() { +162 +163 // Since the samples are almost always already sorted, this +164 // method is implemented as an insertion sort that reorders the +165 // elements in place. Insertion sort is very efficient in this case. +166 WeightedObservedPoint curr = observations[0]; +167 for (int j = 1; j < observations.length; ++j) { +168 WeightedObservedPoint prec = curr; +169 curr = observations[j]; +170 if (curr.getX() < prec.getX()) { +171 // the current element should be inserted closer to the beginning +172 int i = j - 1; +173 WeightedObservedPoint mI = observations[i]; +174 while ((i >= 0) && (curr.getX() < mI.getX())) { +175 observations[i + 1] = mI; +176 if (i-- != 0) { +177 mI = observations[i]; +178 } else { +179 mI = null; +180 } +181 } +182 observations[i + 1] = curr; +183 curr = observations[j]; +184 } +185 } +186 +187 } +188 +189 /** Estimate a first guess of the a and ω coefficients. +190 * @exception OptimizationException if the sample is too short or if +191 * the first guess cannot be computed (when the elements under the +192 * square roots are negative). +193 */ +194 private void guessAOmega() throws OptimizationException { +195 +196 // initialize the sums for the linear model between the two integrals +197 double sx2 = 0.0; +198 double sy2 = 0.0; +199 double sxy = 0.0; +200 double sxz = 0.0; +201 double syz = 0.0; +202 +203 double currentX = observations[0].getX(); +204 double currentY = observations[0].getY(); +205 double f2Integral = 0; +206 double fPrime2Integral = 0; +207 final double startX = currentX; +208 for (int i = 1; i < observations.length; ++i) { +209 +210 // one step forward +211 final double previousX = currentX; +212 final double previousY = currentY; +213 currentX = observations[i].getX(); +214 currentY = observations[i].getY(); +215 +216 // update the integrals of f<sup>2</sup> and f'<sup>2</sup> +217 // considering a linear model for f (and therefore constant f') +218 final double dx = currentX - previousX; +219 final double dy = currentY - previousY; +220 final double f2StepIntegral = +221 dx * (previousY * previousY + previousY * currentY + currentY * currentY) / 3; +222 final double fPrime2StepIntegral = dy * dy / dx; +223 +224 final double x = currentX - startX; +225 f2Integral += f2StepIntegral; +226 fPrime2Integral += fPrime2StepIntegral; +227 +228 sx2 += x * x; +229 sy2 += f2Integral * f2Integral; +230 sxy += x * f2Integral; +231 sxz += x * fPrime2Integral; +232 syz += f2Integral * fPrime2Integral; +233 +234 } +235 +236 // compute the amplitude and pulsation coefficients +237 double c1 = sy2 * sxz - sxy * syz; +238 double c2 = sxy * sxz - sx2 * syz; +239 double c3 = sx2 * sy2 - sxy * sxy; +240 if ((c1 / c2 < 0.0) || (c2 / c3 < 0.0)) { +241 throw new OptimizationException("unable to first guess the harmonic coefficients"); +242 } +243 a = Math.sqrt(c1 / c2); +244 omega = Math.sqrt(c2 / c3); +245 +246 } +247 +248 /** Estimate a first guess of the φ coefficient. +249 */ +250 private void guessPhi() { +251 +252 // initialize the means +253 double fcMean = 0.0; +254 double fsMean = 0.0; +255 +256 double currentX = observations[0].getX(); +257 double currentY = observations[0].getY(); +258 for (int i = 1; i < observations.length; ++i) { +259 +260 // one step forward +261 final double previousX = currentX; +262 final double previousY = currentY; +263 currentX = observations[i].getX(); +264 currentY = observations[i].getY(); +265 final double currentYPrime = (currentY - previousY) / (currentX - previousX); +266 +267 double omegaX = omega * currentX; +268 double cosine = Math.cos(omegaX); +269 double sine = Math.sin(omegaX); +270 fcMean += omega * currentY * cosine - currentYPrime * sine; +271 fsMean += omega * currentY * sine + currentYPrime * cosine; +272 +273 } +274 +275 phi = Math.atan2(-fsMean, fcMean); +276 +277 } +278 +279 /** Get the guessed amplitude a. +280 * @return guessed amplitude a; +281 */ +282 public double getGuessedAmplitude() { +283 return a; +284 } +285 +286 /** Get the guessed pulsation ω. +287 * @return guessed pulsation ω +288 */ +289 public double getGuessedPulsation() { +290 return omega; +291 } +292 +293 /** Get the guessed phase φ. +294 * @return guessed phase φ +295 */ +296 public double getGuessedPhase() { +297 return phi; +298 } +299 +300 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/HarmonicFitter.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/HarmonicFitter.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,198 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.fitting; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer; +023 import org.apache.commons.math.optimization.OptimizationException; +024 +025 /** This class implements a curve fitting specialized for sinusoids. +026 * <p>Harmonic fitting is a very simple case of curve fitting. The +027 * estimated coefficients are the amplitude a, the pulsation ω and +028 * the phase φ: <code>f (t) = a cos (ω t + φ)</code>. They are +029 * searched by a least square estimator initialized with a rough guess +030 * based on integrals.</p> +031 * @version $Revision: 786479 $ $Date: 2009-06-19 08:36:16 -0400 (Fri, 19 Jun 2009) $ +032 * @since 2.0 +033 */ +034 public class HarmonicFitter { +035 +036 /** Fitter for the coefficients. */ +037 private final CurveFitter fitter; +038 +039 /** Values for amplitude, pulsation ω and phase φ. */ +040 private double[] parameters; +041 +042 /** Simple constructor. +043 * @param optimizer optimizer to use for the fitting +044 */ +045 public HarmonicFitter(final DifferentiableMultivariateVectorialOptimizer optimizer) { +046 this.fitter = new CurveFitter(optimizer); +047 parameters = null; +048 } +049 +050 /** Simple constructor. +051 * <p>This constructor can be used when a first guess of the +052 * coefficients is already known.</p> +053 * @param optimizer optimizer to use for the fitting +054 * @param initialGuess guessed values for amplitude (index 0), +055 * pulsation ω (index 1) and phase φ (index 2) +056 */ +057 public HarmonicFitter(final DifferentiableMultivariateVectorialOptimizer optimizer, +058 final double[] initialGuess) { +059 this.fitter = new CurveFitter(optimizer); +060 this.parameters = initialGuess.clone(); +061 } +062 +063 /** Add an observed weighted (x,y) point to the sample. +064 * @param weight weight of the observed point in the fit +065 * @param x abscissa of the point +066 * @param y observed value of the point at x, after fitting we should +067 * have P(x) as close as possible to this value +068 */ +069 public void addObservedPoint(double weight, double x, double y) { +070 fitter.addObservedPoint(weight, x, y); +071 } +072 +073 /** Fit an harmonic function to the observed points. +074 * @return harmonic function best fitting the observed points +075 * @throws OptimizationException if the sample is too short or if +076 * the first guess cannot be computed +077 */ +078 public HarmonicFunction fit() throws OptimizationException { +079 try { +080 +081 // shall we compute the first guess of the parameters ourselves ? +082 if (parameters == null) { +083 final WeightedObservedPoint[] observations = fitter.getObservations(); +084 if (observations.length < 4) { +085 throw new OptimizationException("sample contains {0} observed points, at least {1} are required", +086 observations.length, 4); +087 } +088 +089 HarmonicCoefficientsGuesser guesser = new HarmonicCoefficientsGuesser(observations); +090 guesser.guess(); +091 parameters = new double[] { +092 guesser.getGuessedAmplitude(), +093 guesser.getGuessedPulsation(), +094 guesser.getGuessedPhase() +095 }; +096 +097 } +098 +099 double[] fitted = fitter.fit(new ParametricHarmonicFunction(), parameters); +100 return new HarmonicFunction(fitted[0], fitted[1], fitted[2]); +101 +102 } catch (FunctionEvaluationException fee) { +103 // this should never happen +104 throw MathRuntimeException.createInternalError(fee); +105 } +106 } +107 +108 /** Parametric harmonic function. */ +109 private static class ParametricHarmonicFunction implements ParametricRealFunction { +110 +111 /** {@inheritDoc} */ +112 public double value(double x, double[] parameters) { +113 final double a = parameters[0]; +114 final double omega = parameters[1]; +115 final double phi = parameters[2]; +116 return a * Math.cos(omega * x + phi); +117 } +118 +119 /** {@inheritDoc} */ +120 public double[] gradient(double x, double[] parameters) { +121 final double a = parameters[0]; +122 final double omega = parameters[1]; +123 final double phi = parameters[2]; +124 final double alpha = omega * x + phi; +125 final double cosAlpha = Math.cos(alpha); +126 final double sinAlpha = Math.sin(alpha); +127 return new double[] { cosAlpha, -a * x * sinAlpha, -a * sinAlpha }; +128 } +129 +130 } +131 +132 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/HarmonicFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/HarmonicFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,145 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.fitting; +019 +020 import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction; +021 +022 /** Harmonic function of the form <code>f (t) = a cos (ω t + φ)</code>. +023 * @version $Revision: 786479 $ $Date: 2009-06-19 08:36:16 -0400 (Fri, 19 Jun 2009) $ +024 * @since 2.0 +025 */ +026 public class HarmonicFunction implements DifferentiableUnivariateRealFunction { +027 +028 /** Amplitude a. */ +029 private final double a; +030 +031 /** Pulsation ω. */ +032 private final double omega; +033 +034 /** Phase φ. */ +035 private final double phi; +036 +037 /** Simple constructor. +038 * @param a amplitude +039 * @param omega pulsation +040 * @param phi phase +041 */ +042 public HarmonicFunction(double a, double omega, double phi) { +043 this.a = a; +044 this.omega = omega; +045 this.phi = phi; +046 } +047 +048 /** {@inheritDoc} */ +049 public double value(double x) { +050 return a * Math.cos(omega * x + phi); +051 } +052 +053 /** {@inheritDoc} */ +054 public HarmonicFunction derivative() { +055 return new HarmonicFunction(a * omega, omega, phi + Math.PI / 2); +056 } +057 +058 /** Get the amplitude a. +059 * @return amplitude a; +060 */ +061 public double getAmplitude() { +062 return a; +063 } +064 +065 /** Get the pulsation ω. +066 * @return pulsation ω +067 */ +068 public double getPulsation() { +069 return omega; +070 } +071 +072 /** Get the phase φ. +073 * @return phase φ +074 */ +075 public double getPhase() { +076 return phi; +077 } +078 +079 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/ParametricRealFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/ParametricRealFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,116 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.fitting; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 +022 /** +023 * An interface representing a real function that depends on one independent +024 * variable plus some extra parameters. +025 * +026 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +027 */ +028 public interface ParametricRealFunction { +029 +030 /** +031 * Compute the value of the function. +032 * @param x the point for which the function value should be computed +033 * @param parameters function parameters +034 * @return the value +035 * @throws FunctionEvaluationException if the function evaluation fails +036 */ +037 double value(double x, double[] parameters) +038 throws FunctionEvaluationException; +039 +040 /** +041 * Compute the gradient of the function with respect to its parameters. +042 * @param x the point for which the function value should be computed +043 * @param parameters function parameters +044 * @return the value +045 * @throws FunctionEvaluationException if the function evaluation fails +046 */ +047 double[] gradient(double x, double[] parameters) +048 throws FunctionEvaluationException; +049 +050 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/PolynomialFitter.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/PolynomialFitter.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,169 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.fitting; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.analysis.polynomials.PolynomialFunction; +023 import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer; +024 import org.apache.commons.math.optimization.OptimizationException; +025 +026 /** This class implements a curve fitting specialized for polynomials. +027 * <p>Polynomial fitting is a very simple case of curve fitting. The +028 * estimated coefficients are the polynomial coefficients. They are +029 * searched by a least square estimator.</p> +030 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +031 * @since 2.0 +032 */ +033 +034 public class PolynomialFitter { +035 +036 /** Fitter for the coefficients. */ +037 private final CurveFitter fitter; +038 +039 /** Polynomial degree. */ +040 private final int degree; +041 +042 /** Simple constructor. +043 * <p>The polynomial fitter built this way are complete polynomials, +044 * ie. a n-degree polynomial has n+1 coefficients.</p> +045 * @param degree maximal degree of the polynomial +046 * @param optimizer optimizer to use for the fitting +047 */ +048 public PolynomialFitter(int degree, final DifferentiableMultivariateVectorialOptimizer optimizer) { +049 this.fitter = new CurveFitter(optimizer); +050 this.degree = degree; +051 } +052 +053 /** Add an observed weighted (x,y) point to the sample. +054 * @param weight weight of the observed point in the fit +055 * @param x abscissa of the point +056 * @param y observed value of the point at x, after fitting we should +057 * have P(x) as close as possible to this value +058 */ +059 public void addObservedPoint(double weight, double x, double y) { +060 fitter.addObservedPoint(weight, x, y); +061 } +062 +063 /** Get the polynomial fitting the weighted (x, y) points. +064 * @return polynomial function best fitting the observed points +065 * @exception OptimizationException if the algorithm failed to converge +066 */ +067 public PolynomialFunction fit() +068 throws OptimizationException { +069 try { +070 return new PolynomialFunction(fitter.fit(new ParametricPolynomial(), new double[degree + 1])); +071 } catch (FunctionEvaluationException fee) { +072 // this should never happen +073 throw MathRuntimeException.createInternalError(fee); +074 } +075 } +076 +077 /** Dedicated parametric polynomial class. */ +078 private static class ParametricPolynomial implements ParametricRealFunction { +079 +080 /** {@inheritDoc} */ +081 public double[] gradient(double x, double[] parameters) +082 throws FunctionEvaluationException { +083 final double[] gradient = new double[parameters.length]; +084 double xn = 1.0; +085 for (int i = 0; i < parameters.length; ++i) { +086 gradient[i] = xn; +087 xn *= x; +088 } +089 return gradient; +090 } +091 +092 /** {@inheritDoc} */ +093 public double value(final double x, final double[] parameters) { +094 double y = 0; +095 for (int i = parameters.length - 1; i >= 0; --i) { +096 y = y * x + parameters[i]; +097 } +098 return y; +099 } +100 +101 } +102 +103 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/WeightedObservedPoint.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/WeightedObservedPoint.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,141 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.fitting; +019 +020 import java.io.Serializable; +021 +022 /** This class is a simple container for weighted observed point in +023 * {@link CurveFitter curve fitting}. +024 * <p>Instances of this class are guaranteed to be immutable.</p> +025 * @version $Revision: 786479 $ $Date: 2009-06-19 08:36:16 -0400 (Fri, 19 Jun 2009) $ +026 * @since 2.0 +027 */ +028 public class WeightedObservedPoint implements Serializable { +029 +030 /** Serializable version id. */ +031 private static final long serialVersionUID = 5306874947404636157L; +032 +033 /** Weight of the measurement in the fitting process. */ +034 private final double weight; +035 +036 /** Abscissa of the point. */ +037 private final double x; +038 +039 /** Observed value of the function at x. */ +040 private final double y; +041 +042 /** Simple constructor. +043 * @param weight weight of the measurement in the fitting process +044 * @param x abscissa of the measurement +045 * @param y ordinate of the measurement +046 */ +047 public WeightedObservedPoint(final double weight, final double x, final double y) { +048 this.weight = weight; +049 this.x = x; +050 this.y = y; +051 } +052 +053 /** Get the weight of the measurement in the fitting process. +054 * @return weight of the measurement in the fitting process +055 */ +056 public double getWeight() { +057 return weight; +058 } +059 +060 /** Get the abscissa of the point. +061 * @return abscissa of the point +062 */ +063 public double getX() { +064 return x; +065 } +066 +067 /** Get the observed value of the function at x. +068 * @return observed value of the function at x +069 */ +070 public double getY() { +071 return y; +072 } +073 +074 } +075 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/general/AbstractLeastSquaresOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,434 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.general; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.MaxEvaluationsExceededException; +022 import org.apache.commons.math.MaxIterationsExceededException; +023 import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction; +024 import org.apache.commons.math.analysis.MultivariateMatrixFunction; +025 import org.apache.commons.math.linear.InvalidMatrixException; +026 import org.apache.commons.math.linear.LUDecompositionImpl; +027 import org.apache.commons.math.linear.MatrixUtils; +028 import org.apache.commons.math.linear.RealMatrix; +029 import org.apache.commons.math.optimization.OptimizationException; +030 import org.apache.commons.math.optimization.SimpleVectorialValueChecker; +031 import org.apache.commons.math.optimization.VectorialConvergenceChecker; +032 import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer; +033 import org.apache.commons.math.optimization.VectorialPointValuePair; +034 +035 /** +036 * Base class for implementing least squares optimizers. +037 * <p>This base class handles the boilerplate methods associated to thresholds +038 * settings, jacobian and error estimation.</p> +039 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +040 * @since 1.2 +041 * +042 */ +043 public abstract class AbstractLeastSquaresOptimizer implements DifferentiableMultivariateVectorialOptimizer { +044 +045 /** Default maximal number of iterations allowed. */ +046 public static final int DEFAULT_MAX_ITERATIONS = 100; +047 +048 /** Convergence checker. */ +049 protected VectorialConvergenceChecker checker; +050 +051 /** +052 * Jacobian matrix. +053 * <p>This matrix is in canonical form just after the calls to +054 * {@link #updateJacobian()}, but may be modified by the solver +055 * in the derived class (the {@link LevenbergMarquardtOptimizer +056 * Levenberg-Marquardt optimizer} does this).</p> +057 */ +058 protected double[][] jacobian; +059 +060 /** Number of columns of the jacobian matrix. */ +061 protected int cols; +062 +063 /** Number of rows of the jacobian matrix. */ +064 protected int rows; +065 +066 /** +067 * Target value for the objective functions at optimum. +068 * @since 2.1 +069 */ +070 protected double[] targetValues; +071 +072 /** +073 * Weight for the least squares cost computation. +074 * @since 2.1 +075 */ +076 protected double[] residualsWeights; +077 +078 /** Current point. */ +079 protected double[] point; +080 +081 /** Current objective function value. */ +082 protected double[] objective; +083 +084 /** Current residuals. */ +085 protected double[] residuals; +086 +087 /** Cost value (square root of the sum of the residuals). */ +088 protected double cost; +089 +090 /** Maximal number of iterations allowed. */ +091 private int maxIterations; +092 +093 /** Number of iterations already performed. */ +094 private int iterations; +095 +096 /** Maximal number of evaluations allowed. */ +097 private int maxEvaluations; +098 +099 /** Number of evaluations already performed. */ +100 private int objectiveEvaluations; +101 +102 /** Number of jacobian evaluations. */ +103 private int jacobianEvaluations; +104 +105 /** Objective function. */ +106 private DifferentiableMultivariateVectorialFunction function; +107 +108 /** Objective function derivatives. */ +109 private MultivariateMatrixFunction jF; +110 +111 /** Simple constructor with default settings. +112 * <p>The convergence check is set to a {@link SimpleVectorialValueChecker} +113 * and the maximal number of evaluation is set to its default value.</p> +114 */ +115 protected AbstractLeastSquaresOptimizer() { +116 setConvergenceChecker(new SimpleVectorialValueChecker()); +117 setMaxIterations(DEFAULT_MAX_ITERATIONS); +118 setMaxEvaluations(Integer.MAX_VALUE); +119 } +120 +121 /** {@inheritDoc} */ +122 public void setMaxIterations(int maxIterations) { +123 this.maxIterations = maxIterations; +124 } +125 +126 /** {@inheritDoc} */ +127 public int getMaxIterations() { +128 return maxIterations; +129 } +130 +131 /** {@inheritDoc} */ +132 public int getIterations() { +133 return iterations; +134 } +135 +136 /** {@inheritDoc} */ +137 public void setMaxEvaluations(int maxEvaluations) { +138 this.maxEvaluations = maxEvaluations; +139 } +140 +141 /** {@inheritDoc} */ +142 public int getMaxEvaluations() { +143 return maxEvaluations; +144 } +145 +146 /** {@inheritDoc} */ +147 public int getEvaluations() { +148 return objectiveEvaluations; +149 } +150 +151 /** {@inheritDoc} */ +152 public int getJacobianEvaluations() { +153 return jacobianEvaluations; +154 } +155 +156 /** {@inheritDoc} */ +157 public void setConvergenceChecker(VectorialConvergenceChecker convergenceChecker) { +158 this.checker = convergenceChecker; +159 } +160 +161 /** {@inheritDoc} */ +162 public VectorialConvergenceChecker getConvergenceChecker() { +163 return checker; +164 } +165 +166 /** Increment the iterations counter by 1. +167 * @exception OptimizationException if the maximal number +168 * of iterations is exceeded +169 */ +170 protected void incrementIterationsCounter() +171 throws OptimizationException { +172 if (++iterations > maxIterations) { +173 throw new OptimizationException(new MaxIterationsExceededException(maxIterations)); +174 } +175 } +176 +177 /** +178 * Update the jacobian matrix. +179 * @exception FunctionEvaluationException if the function jacobian +180 * cannot be evaluated or its dimension doesn't match problem dimension +181 */ +182 protected void updateJacobian() throws FunctionEvaluationException { +183 ++jacobianEvaluations; +184 jacobian = jF.value(point); +185 if (jacobian.length != rows) { +186 throw new FunctionEvaluationException(point, "dimension mismatch {0} != {1}", +187 jacobian.length, rows); +188 } +189 for (int i = 0; i < rows; i++) { +190 final double[] ji = jacobian[i]; +191 final double factor = -Math.sqrt(residualsWeights[i]); +192 for (int j = 0; j < cols; ++j) { +193 ji[j] *= factor; +194 } +195 } +196 } +197 +198 /** +199 * Update the residuals array and cost function value. +200 * @exception FunctionEvaluationException if the function cannot be evaluated +201 * or its dimension doesn't match problem dimension or maximal number of +202 * of evaluations is exceeded +203 */ +204 protected void updateResidualsAndCost() +205 throws FunctionEvaluationException { +206 +207 if (++objectiveEvaluations > maxEvaluations) { +208 throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), +209 point); +210 } +211 objective = function.value(point); +212 if (objective.length != rows) { +213 throw new FunctionEvaluationException(point, "dimension mismatch {0} != {1}", +214 objective.length, rows); +215 } +216 cost = 0; +217 int index = 0; +218 for (int i = 0; i < rows; i++) { +219 final double residual = targetValues[i] - objective[i]; +220 residuals[i] = residual; +221 cost += residualsWeights[i] * residual * residual; +222 index += cols; +223 } +224 cost = Math.sqrt(cost); +225 +226 } +227 +228 /** +229 * Get the Root Mean Square value. +230 * Get the Root Mean Square value, i.e. the root of the arithmetic +231 * mean of the square of all weighted residuals. This is related to the +232 * criterion that is minimized by the optimizer as follows: if +233 * <em>c</em> if the criterion, and <em>n</em> is the number of +234 * measurements, then the RMS is <em>sqrt (c/n)</em>. +235 * +236 * @return RMS value +237 */ +238 public double getRMS() { +239 double criterion = 0; +240 for (int i = 0; i < rows; ++i) { +241 final double residual = residuals[i]; +242 criterion += residualsWeights[i] * residual * residual; +243 } +244 return Math.sqrt(criterion / rows); +245 } +246 +247 /** +248 * Get the Chi-Square value. +249 * @return chi-square value +250 */ +251 public double getChiSquare() { +252 double chiSquare = 0; +253 for (int i = 0; i < rows; ++i) { +254 final double residual = residuals[i]; +255 chiSquare += residual * residual / residualsWeights[i]; +256 } +257 return chiSquare; +258 } +259 +260 /** +261 * Get the covariance matrix of optimized parameters. +262 * @return covariance matrix +263 * @exception FunctionEvaluationException if the function jacobian cannot +264 * be evaluated +265 * @exception OptimizationException if the covariance matrix +266 * cannot be computed (singular problem) +267 */ +268 public double[][] getCovariances() +269 throws FunctionEvaluationException, OptimizationException { +270 +271 // set up the jacobian +272 updateJacobian(); +273 +274 // compute transpose(J).J, avoiding building big intermediate matrices +275 double[][] jTj = new double[cols][cols]; +276 for (int i = 0; i < cols; ++i) { +277 for (int j = i; j < cols; ++j) { +278 double sum = 0; +279 for (int k = 0; k < rows; ++k) { +280 sum += jacobian[k][i] * jacobian[k][j]; +281 } +282 jTj[i][j] = sum; +283 jTj[j][i] = sum; +284 } +285 } +286 +287 try { +288 // compute the covariances matrix +289 RealMatrix inverse = +290 new LUDecompositionImpl(MatrixUtils.createRealMatrix(jTj)).getSolver().getInverse(); +291 return inverse.getData(); +292 } catch (InvalidMatrixException ime) { +293 throw new OptimizationException("unable to compute covariances: singular problem"); +294 } +295 +296 } +297 +298 /** +299 * Guess the errors in optimized parameters. +300 * <p>Guessing is covariance-based, it only gives rough order of magnitude.</p> +301 * @return errors in optimized parameters +302 * @exception FunctionEvaluationException if the function jacobian cannot b evaluated +303 * @exception OptimizationException if the covariances matrix cannot be computed +304 * or the number of degrees of freedom is not positive (number of measurements +305 * lesser or equal to number of parameters) +306 */ +307 public double[] guessParametersErrors() +308 throws FunctionEvaluationException, OptimizationException { +309 if (rows <= cols) { +310 throw new OptimizationException( +311 "no degrees of freedom ({0} measurements, {1} parameters)", +312 rows, cols); +313 } +314 double[] errors = new double[cols]; +315 final double c = Math.sqrt(getChiSquare() / (rows - cols)); +316 double[][] covar = getCovariances(); +317 for (int i = 0; i < errors.length; ++i) { +318 errors[i] = Math.sqrt(covar[i][i]) * c; +319 } +320 return errors; +321 } +322 +323 /** {@inheritDoc} */ +324 public VectorialPointValuePair optimize(final DifferentiableMultivariateVectorialFunction f, +325 final double[] target, final double[] weights, +326 final double[] startPoint) +327 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { +328 +329 if (target.length != weights.length) { +330 throw new OptimizationException("dimension mismatch {0} != {1}", +331 target.length, weights.length); +332 } +333 +334 // reset counters +335 iterations = 0; +336 objectiveEvaluations = 0; +337 jacobianEvaluations = 0; +338 +339 // store least squares problem characteristics +340 function = f; +341 jF = f.jacobian(); +342 targetValues = target.clone(); +343 residualsWeights = weights.clone(); +344 this.point = startPoint.clone(); +345 this.residuals = new double[target.length]; +346 +347 // arrays shared with the other private methods +348 rows = target.length; +349 cols = point.length; +350 jacobian = new double[rows][cols]; +351 +352 cost = Double.POSITIVE_INFINITY; +353 +354 return doOptimize(); +355 +356 } +357 +358 /** Perform the bulk of optimization algorithm. +359 * @return the point/value pair giving the optimal value for objective function +360 * @exception FunctionEvaluationException if the objective function throws one during +361 * the search +362 * @exception OptimizationException if the algorithm failed to converge +363 * @exception IllegalArgumentException if the start point dimension is wrong +364 */ +365 protected abstract VectorialPointValuePair doOptimize() +366 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; +367 +368 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/general/AbstractScalarDifferentiableOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/general/AbstractScalarDifferentiableOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,270 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.general; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.MaxEvaluationsExceededException; +022 import org.apache.commons.math.MaxIterationsExceededException; +023 import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction; +024 import org.apache.commons.math.analysis.MultivariateVectorialFunction; +025 import org.apache.commons.math.optimization.GoalType; +026 import org.apache.commons.math.optimization.OptimizationException; +027 import org.apache.commons.math.optimization.RealConvergenceChecker; +028 import org.apache.commons.math.optimization.DifferentiableMultivariateRealOptimizer; +029 import org.apache.commons.math.optimization.RealPointValuePair; +030 import org.apache.commons.math.optimization.SimpleScalarValueChecker; +031 +032 /** +033 * Base class for implementing optimizers for multivariate scalar functions. +034 * <p>This base class handles the boilerplate methods associated to thresholds +035 * settings, iterations and evaluations counting.</p> +036 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +037 * @since 2.0 +038 */ +039 public abstract class AbstractScalarDifferentiableOptimizer +040 implements DifferentiableMultivariateRealOptimizer { +041 +042 /** Default maximal number of iterations allowed. */ +043 public static final int DEFAULT_MAX_ITERATIONS = 100; +044 +045 /** Convergence checker. */ +046 protected RealConvergenceChecker checker; +047 +048 /** +049 * Type of optimization. +050 * @since 2.1 +051 */ +052 protected GoalType goal; +053 +054 /** Current point set. */ +055 protected double[] point; +056 +057 /** Maximal number of iterations allowed. */ +058 private int maxIterations; +059 +060 /** Number of iterations already performed. */ +061 private int iterations; +062 +063 /** Maximal number of evaluations allowed. */ +064 private int maxEvaluations; +065 +066 /** Number of evaluations already performed. */ +067 private int evaluations; +068 +069 /** Number of gradient evaluations. */ +070 private int gradientEvaluations; +071 +072 /** Objective function. */ +073 private DifferentiableMultivariateRealFunction function; +074 +075 /** Objective function gradient. */ +076 private MultivariateVectorialFunction gradient; +077 +078 /** Simple constructor with default settings. +079 * <p>The convergence check is set to a {@link SimpleScalarValueChecker} +080 * and the maximal number of evaluation is set to its default value.</p> +081 */ +082 protected AbstractScalarDifferentiableOptimizer() { +083 setConvergenceChecker(new SimpleScalarValueChecker()); +084 setMaxIterations(DEFAULT_MAX_ITERATIONS); +085 setMaxEvaluations(Integer.MAX_VALUE); +086 } +087 +088 /** {@inheritDoc} */ +089 public void setMaxIterations(int maxIterations) { +090 this.maxIterations = maxIterations; +091 } +092 +093 /** {@inheritDoc} */ +094 public int getMaxIterations() { +095 return maxIterations; +096 } +097 +098 /** {@inheritDoc} */ +099 public int getIterations() { +100 return iterations; +101 } +102 +103 /** {@inheritDoc} */ +104 public void setMaxEvaluations(int maxEvaluations) { +105 this.maxEvaluations = maxEvaluations; +106 } +107 +108 /** {@inheritDoc} */ +109 public int getMaxEvaluations() { +110 return maxEvaluations; +111 } +112 +113 /** {@inheritDoc} */ +114 public int getEvaluations() { +115 return evaluations; +116 } +117 +118 /** {@inheritDoc} */ +119 public int getGradientEvaluations() { +120 return gradientEvaluations; +121 } +122 +123 /** {@inheritDoc} */ +124 public void setConvergenceChecker(RealConvergenceChecker convergenceChecker) { +125 this.checker = convergenceChecker; +126 } +127 +128 /** {@inheritDoc} */ +129 public RealConvergenceChecker getConvergenceChecker() { +130 return checker; +131 } +132 +133 /** Increment the iterations counter by 1. +134 * @exception OptimizationException if the maximal number +135 * of iterations is exceeded +136 */ +137 protected void incrementIterationsCounter() +138 throws OptimizationException { +139 if (++iterations > maxIterations) { +140 throw new OptimizationException(new MaxIterationsExceededException(maxIterations)); +141 } +142 } +143 +144 /** +145 * Compute the gradient vector. +146 * @param evaluationPoint point at which the gradient must be evaluated +147 * @return gradient at the specified point +148 * @exception FunctionEvaluationException if the function gradient +149 */ +150 protected double[] computeObjectiveGradient(final double[] evaluationPoint) +151 throws FunctionEvaluationException { +152 ++gradientEvaluations; +153 return gradient.value(evaluationPoint); +154 } +155 +156 /** +157 * Compute the objective function value. +158 * @param evaluationPoint point at which the objective function must be evaluated +159 * @return objective function value at specified point +160 * @exception FunctionEvaluationException if the function cannot be evaluated +161 * or its dimension doesn't match problem dimension or the maximal number +162 * of iterations is exceeded +163 */ +164 protected double computeObjectiveValue(final double[] evaluationPoint) +165 throws FunctionEvaluationException { +166 if (++evaluations > maxEvaluations) { +167 throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), +168 evaluationPoint); +169 } +170 return function.value(evaluationPoint); +171 } +172 +173 /** {@inheritDoc} */ +174 public RealPointValuePair optimize(final DifferentiableMultivariateRealFunction f, +175 final GoalType goalType, +176 final double[] startPoint) +177 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { +178 +179 // reset counters +180 iterations = 0; +181 evaluations = 0; +182 gradientEvaluations = 0; +183 +184 // store optimization problem characteristics +185 function = f; +186 gradient = f.gradient(); +187 goal = goalType; +188 point = startPoint.clone(); +189 +190 return doOptimize(); +191 +192 } +193 +194 /** Perform the bulk of optimization algorithm. +195 * @return the point/value pair giving the optimal value for objective function +196 * @exception FunctionEvaluationException if the objective function throws one during +197 * the search +198 * @exception OptimizationException if the algorithm failed to converge +199 * @exception IllegalArgumentException if the start point dimension is wrong +200 */ +201 protected abstract RealPointValuePair doOptimize() +202 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException; +203 +204 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/general/ConjugateGradientFormula.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/general/ConjugateGradientFormula.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,115 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.general; +019 +020 /** +021 * Available choices of update formulas for the β parameter +022 * in {@link NonLinearConjugateGradientOptimizer}. +023 * <p> +024 * The β parameter is used to compute the successive conjugate +025 * search directions. For non-linear conjugate gradients, there are +026 * two formulas to compute β: +027 * <ul> +028 * <li>Fletcher-Reeves formula</li> +029 * <li>Polak-Ribière formula</li> +030 * </ul> +031 * On the one hand, the Fletcher-Reeves formula is guaranteed to converge +032 * if the start point is close enough of the optimum whether the +033 * Polak-Ribière formula may not converge in rare cases. On the +034 * other hand, the Polak-Ribière formula is often faster when it +035 * does converge. Polak-Ribière is often used. +036 * <p> +037 * @see NonLinearConjugateGradientOptimizer +038 * @version $Revision: 758059 $ $Date: 2009-03-24 18:16:21 -0400 (Tue, 24 Mar 2009) $ +039 * @since 2.0 +040 */ +041 public enum ConjugateGradientFormula { +042 +043 /** Fletcher-Reeves formula. */ +044 FLETCHER_REEVES, +045 +046 /** Polak-Ribière formula. */ +047 POLAK_RIBIERE +048 +049 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/general/GaussNewtonOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/general/GaussNewtonOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,200 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.general; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 import org.apache.commons.math.linear.BlockRealMatrix; +022 import org.apache.commons.math.linear.DecompositionSolver; +023 import org.apache.commons.math.linear.InvalidMatrixException; +024 import org.apache.commons.math.linear.LUDecompositionImpl; +025 import org.apache.commons.math.linear.QRDecompositionImpl; +026 import org.apache.commons.math.linear.RealMatrix; +027 import org.apache.commons.math.optimization.OptimizationException; +028 import org.apache.commons.math.optimization.VectorialPointValuePair; +029 +030 /** +031 * Gauss-Newton least-squares solver. +032 * <p> +033 * This class solve a least-square problem by solving the normal equations +034 * of the linearized problem at each iteration. Either LU decomposition or +035 * QR decomposition can be used to solve the normal equations. LU decomposition +036 * is faster but QR decomposition is more robust for difficult problems. +037 * </p> +038 * +039 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +040 * @since 2.0 +041 * +042 */ +043 +044 public class GaussNewtonOptimizer extends AbstractLeastSquaresOptimizer { +045 +046 /** Indicator for using LU decomposition. */ +047 private final boolean useLU; +048 +049 /** Simple constructor with default settings. +050 * <p>The convergence check is set to a {@link +051 * org.apache.commons.math.optimization.SimpleVectorialValueChecker} +052 * and the maximal number of evaluation is set to +053 * {@link AbstractLeastSquaresOptimizer#DEFAULT_MAX_ITERATIONS}. +054 * @param useLU if true, the normal equations will be solved using LU +055 * decomposition, otherwise they will be solved using QR decomposition +056 */ +057 public GaussNewtonOptimizer(final boolean useLU) { +058 this.useLU = useLU; +059 } +060 +061 /** {@inheritDoc} */ +062 @Override +063 public VectorialPointValuePair doOptimize() +064 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { +065 +066 // iterate until convergence is reached +067 VectorialPointValuePair current = null; +068 for (boolean converged = false; !converged;) { +069 +070 incrementIterationsCounter(); +071 +072 // evaluate the objective function and its jacobian +073 VectorialPointValuePair previous = current; +074 updateResidualsAndCost(); +075 updateJacobian(); +076 current = new VectorialPointValuePair(point, objective); +077 +078 // build the linear problem +079 final double[] b = new double[cols]; +080 final double[][] a = new double[cols][cols]; +081 for (int i = 0; i < rows; ++i) { +082 +083 final double[] grad = jacobian[i]; +084 final double weight = residualsWeights[i]; +085 final double residual = objective[i] - targetValues[i]; +086 +087 // compute the normal equation +088 final double wr = weight * residual; +089 for (int j = 0; j < cols; ++j) { +090 b[j] += wr * grad[j]; +091 } +092 +093 // build the contribution matrix for measurement i +094 for (int k = 0; k < cols; ++k) { +095 double[] ak = a[k]; +096 double wgk = weight * grad[k]; +097 for (int l = 0; l < cols; ++l) { +098 ak[l] += wgk * grad[l]; +099 } +100 } +101 +102 } +103 +104 try { +105 +106 // solve the linearized least squares problem +107 RealMatrix mA = new BlockRealMatrix(a); +108 DecompositionSolver solver = useLU ? +109 new LUDecompositionImpl(mA).getSolver() : +110 new QRDecompositionImpl(mA).getSolver(); +111 final double[] dX = solver.solve(b); +112 +113 // update the estimated parameters +114 for (int i = 0; i < cols; ++i) { +115 point[i] += dX[i]; +116 } +117 +118 } catch(InvalidMatrixException e) { +119 throw new OptimizationException("unable to solve: singular problem"); +120 } +121 +122 // check convergence +123 if (previous != null) { +124 converged = checker.converged(getIterations(), previous, current); +125 } +126 +127 } +128 +129 // we have converged +130 return current; +131 +132 } +133 +134 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/general/LevenbergMarquardtOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,908 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.optimization.general; +018 +019 import java.util.Arrays; +020 +021 import org.apache.commons.math.FunctionEvaluationException; +022 import org.apache.commons.math.optimization.OptimizationException; +023 import org.apache.commons.math.optimization.VectorialPointValuePair; +024 +025 +026 /** +027 * This class solves a least squares problem using the Levenberg-Marquardt algorithm. +028 * +029 * <p>This implementation <em>should</em> work even for over-determined systems +030 * (i.e. systems having more point than equations). Over-determined systems +031 * are solved by ignoring the point which have the smallest impact according +032 * to their jacobian column norm. Only the rank of the matrix and some loop bounds +033 * are changed to implement this.</p> +034 * +035 * <p>The resolution engine is a simple translation of the MINPACK <a +036 * href="http://www.netlib.org/minpack/lmder.f">lmder</a> routine with minor +037 * changes. The changes include the over-determined resolution and the Q.R. +038 * decomposition which has been rewritten following the algorithm described in the +039 * P. Lascaux and R. Theodor book <i>Analyse numérique matricielle +040 * appliquée à l'art de l'ingénieur</i>, Masson 1986.</p> +041 * <p>The authors of the original fortran version are: +042 * <ul> +043 * <li>Argonne National Laboratory. MINPACK project. March 1980</li> +044 * <li>Burton S. Garbow</li> +045 * <li>Kenneth E. Hillstrom</li> +046 * <li>Jorge J. More</li> +047 * </ul> +048 * The redistribution policy for MINPACK is available <a +049 * href="http://www.netlib.org/minpack/disclaimer">here</a>, for convenience, it +050 * is reproduced below.</p> +051 * +052 * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0"> +053 * <tr><td> +054 * Minpack Copyright Notice (1999) University of Chicago. +055 * All rights reserved +056 * </td></tr> +057 * <tr><td> +058 * Redistribution and use in source and binary forms, with or without +059 * modification, are permitted provided that the following conditions +060 * are met: +061 * <ol> +062 * <li>Redistributions of source code must retain the above copyright +063 * notice, this list of conditions and the following disclaimer.</li> +064 * <li>Redistributions in binary form must reproduce the above +065 * copyright notice, this list of conditions and the following +066 * disclaimer in the documentation and/or other materials provided +067 * with the distribution.</li> +068 * <li>The end-user documentation included with the redistribution, if any, +069 * must include the following acknowledgment: +070 * <code>This product includes software developed by the University of +071 * Chicago, as Operator of Argonne National Laboratory.</code> +072 * Alternately, this acknowledgment may appear in the software itself, +073 * if and wherever such third-party acknowledgments normally appear.</li> +074 * <li><strong>WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" +075 * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE +076 * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND +077 * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR +078 * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES +079 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE +080 * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY +081 * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR +082 * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF +083 * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) +084 * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION +085 * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL +086 * BE CORRECTED.</strong></li> +087 * <li><strong>LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT +088 * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF +089 * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, +090 * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF +091 * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF +092 * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER +093 * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT +094 * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, +095 * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE +096 * POSSIBILITY OF SUCH LOSS OR DAMAGES.</strong></li> +097 * <ol></td></tr> +098 * </table> +099 * @version $Revision: 825919 $ $Date: 2009-10-16 10:51:55 -0400 (Fri, 16 Oct 2009) $ +100 * @since 2.0 +101 * +102 */ +103 public class LevenbergMarquardtOptimizer extends AbstractLeastSquaresOptimizer { +104 +105 /** Number of solved point. */ +106 private int solvedCols; +107 +108 /** Diagonal elements of the R matrix in the Q.R. decomposition. */ +109 private double[] diagR; +110 +111 /** Norms of the columns of the jacobian matrix. */ +112 private double[] jacNorm; +113 +114 /** Coefficients of the Householder transforms vectors. */ +115 private double[] beta; +116 +117 /** Columns permutation array. */ +118 private int[] permutation; +119 +120 /** Rank of the jacobian matrix. */ +121 private int rank; +122 +123 /** Levenberg-Marquardt parameter. */ +124 private double lmPar; +125 +126 /** Parameters evolution direction associated with lmPar. */ +127 private double[] lmDir; +128 +129 /** Positive input variable used in determining the initial step bound. */ +130 private double initialStepBoundFactor; +131 +132 /** Desired relative error in the sum of squares. */ +133 private double costRelativeTolerance; +134 +135 /** Desired relative error in the approximate solution parameters. */ +136 private double parRelativeTolerance; +137 +138 /** Desired max cosine on the orthogonality between the function vector +139 * and the columns of the jacobian. */ +140 private double orthoTolerance; +141 +142 /** +143 * Build an optimizer for least squares problems. +144 * <p>The default values for the algorithm settings are: +145 * <ul> +146 * <li>{@link #setInitialStepBoundFactor initial step bound factor}: 100.0</li> +147 * <li>{@link #setMaxIterations maximal iterations}: 1000</li> +148 * <li>{@link #setCostRelativeTolerance cost relative tolerance}: 1.0e-10</li> +149 * <li>{@link #setParRelativeTolerance parameters relative tolerance}: 1.0e-10</li> +150 * <li>{@link #setOrthoTolerance orthogonality tolerance}: 1.0e-10</li> +151 * </ul> +152 * </p> +153 */ +154 public LevenbergMarquardtOptimizer() { +155 +156 // set up the superclass with a default max cost evaluations setting +157 setMaxIterations(1000); +158 +159 // default values for the tuning parameters +160 setInitialStepBoundFactor(100.0); +161 setCostRelativeTolerance(1.0e-10); +162 setParRelativeTolerance(1.0e-10); +163 setOrthoTolerance(1.0e-10); +164 +165 } +166 +167 /** +168 * Set the positive input variable used in determining the initial step bound. +169 * This bound is set to the product of initialStepBoundFactor and the euclidean +170 * norm of diag*x if nonzero, or else to initialStepBoundFactor itself. In most +171 * cases factor should lie in the interval (0.1, 100.0). 100.0 is a generally +172 * recommended value. +173 * +174 * @param initialStepBoundFactor initial step bound factor +175 */ +176 public void setInitialStepBoundFactor(double initialStepBoundFactor) { +177 this.initialStepBoundFactor = initialStepBoundFactor; +178 } +179 +180 /** +181 * Set the desired relative error in the sum of squares. +182 * +183 * @param costRelativeTolerance desired relative error in the sum of squares +184 */ +185 public void setCostRelativeTolerance(double costRelativeTolerance) { +186 this.costRelativeTolerance = costRelativeTolerance; +187 } +188 +189 /** +190 * Set the desired relative error in the approximate solution parameters. +191 * +192 * @param parRelativeTolerance desired relative error +193 * in the approximate solution parameters +194 */ +195 public void setParRelativeTolerance(double parRelativeTolerance) { +196 this.parRelativeTolerance = parRelativeTolerance; +197 } +198 +199 /** +200 * Set the desired max cosine on the orthogonality. +201 * +202 * @param orthoTolerance desired max cosine on the orthogonality +203 * between the function vector and the columns of the jacobian +204 */ +205 public void setOrthoTolerance(double orthoTolerance) { +206 this.orthoTolerance = orthoTolerance; +207 } +208 +209 /** {@inheritDoc} */ +210 @Override +211 protected VectorialPointValuePair doOptimize() +212 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { +213 +214 // arrays shared with the other private methods +215 solvedCols = Math.min(rows, cols); +216 diagR = new double[cols]; +217 jacNorm = new double[cols]; +218 beta = new double[cols]; +219 permutation = new int[cols]; +220 lmDir = new double[cols]; +221 +222 // local point +223 double delta = 0; +224 double xNorm = 0; +225 double[] diag = new double[cols]; +226 double[] oldX = new double[cols]; +227 double[] oldRes = new double[rows]; +228 double[] work1 = new double[cols]; +229 double[] work2 = new double[cols]; +230 double[] work3 = new double[cols]; +231 +232 // evaluate the function at the starting point and calculate its norm +233 updateResidualsAndCost(); +234 +235 // outer loop +236 lmPar = 0; +237 boolean firstIteration = true; +238 while (true) { +239 +240 incrementIterationsCounter(); +241 +242 // compute the Q.R. decomposition of the jacobian matrix +243 updateJacobian(); +244 qrDecomposition(); +245 +246 // compute Qt.res +247 qTy(residuals); +248 +249 // now we don't need Q anymore, +250 // so let jacobian contain the R matrix with its diagonal elements +251 for (int k = 0; k < solvedCols; ++k) { +252 int pk = permutation[k]; +253 jacobian[k][pk] = diagR[pk]; +254 } +255 +256 if (firstIteration) { +257 +258 // scale the point according to the norms of the columns +259 // of the initial jacobian +260 xNorm = 0; +261 for (int k = 0; k < cols; ++k) { +262 double dk = jacNorm[k]; +263 if (dk == 0) { +264 dk = 1.0; +265 } +266 double xk = dk * point[k]; +267 xNorm += xk * xk; +268 diag[k] = dk; +269 } +270 xNorm = Math.sqrt(xNorm); +271 +272 // initialize the step bound delta +273 delta = (xNorm == 0) ? initialStepBoundFactor : (initialStepBoundFactor * xNorm); +274 +275 } +276 +277 // check orthogonality between function vector and jacobian columns +278 double maxCosine = 0; +279 if (cost != 0) { +280 for (int j = 0; j < solvedCols; ++j) { +281 int pj = permutation[j]; +282 double s = jacNorm[pj]; +283 if (s != 0) { +284 double sum = 0; +285 for (int i = 0; i <= j; ++i) { +286 sum += jacobian[i][pj] * residuals[i]; +287 } +288 maxCosine = Math.max(maxCosine, Math.abs(sum) / (s * cost)); +289 } +290 } +291 } +292 if (maxCosine <= orthoTolerance) { +293 // convergence has been reached +294 return new VectorialPointValuePair(point, objective); +295 } +296 +297 // rescale if necessary +298 for (int j = 0; j < cols; ++j) { +299 diag[j] = Math.max(diag[j], jacNorm[j]); +300 } +301 +302 // inner loop +303 for (double ratio = 0; ratio < 1.0e-4;) { +304 +305 // save the state +306 for (int j = 0; j < solvedCols; ++j) { +307 int pj = permutation[j]; +308 oldX[pj] = point[pj]; +309 } +310 double previousCost = cost; +311 double[] tmpVec = residuals; +312 residuals = oldRes; +313 oldRes = tmpVec; +314 +315 // determine the Levenberg-Marquardt parameter +316 determineLMParameter(oldRes, delta, diag, work1, work2, work3); +317 +318 // compute the new point and the norm of the evolution direction +319 double lmNorm = 0; +320 for (int j = 0; j < solvedCols; ++j) { +321 int pj = permutation[j]; +322 lmDir[pj] = -lmDir[pj]; +323 point[pj] = oldX[pj] + lmDir[pj]; +324 double s = diag[pj] * lmDir[pj]; +325 lmNorm += s * s; +326 } +327 lmNorm = Math.sqrt(lmNorm); +328 +329 // on the first iteration, adjust the initial step bound. +330 if (firstIteration) { +331 delta = Math.min(delta, lmNorm); +332 } +333 +334 // evaluate the function at x + p and calculate its norm +335 updateResidualsAndCost(); +336 +337 // compute the scaled actual reduction +338 double actRed = -1.0; +339 if (0.1 * cost < previousCost) { +340 double r = cost / previousCost; +341 actRed = 1.0 - r * r; +342 } +343 +344 // compute the scaled predicted reduction +345 // and the scaled directional derivative +346 for (int j = 0; j < solvedCols; ++j) { +347 int pj = permutation[j]; +348 double dirJ = lmDir[pj]; +349 work1[j] = 0; +350 for (int i = 0; i <= j; ++i) { +351 work1[i] += jacobian[i][pj] * dirJ; +352 } +353 } +354 double coeff1 = 0; +355 for (int j = 0; j < solvedCols; ++j) { +356 coeff1 += work1[j] * work1[j]; +357 } +358 double pc2 = previousCost * previousCost; +359 coeff1 = coeff1 / pc2; +360 double coeff2 = lmPar * lmNorm * lmNorm / pc2; +361 double preRed = coeff1 + 2 * coeff2; +362 double dirDer = -(coeff1 + coeff2); +363 +364 // ratio of the actual to the predicted reduction +365 ratio = (preRed == 0) ? 0 : (actRed / preRed); +366 +367 // update the step bound +368 if (ratio <= 0.25) { +369 double tmp = +370 (actRed < 0) ? (0.5 * dirDer / (dirDer + 0.5 * actRed)) : 0.5; +371 if ((0.1 * cost >= previousCost) || (tmp < 0.1)) { +372 tmp = 0.1; +373 } +374 delta = tmp * Math.min(delta, 10.0 * lmNorm); +375 lmPar /= tmp; +376 } else if ((lmPar == 0) || (ratio >= 0.75)) { +377 delta = 2 * lmNorm; +378 lmPar *= 0.5; +379 } +380 +381 // test for successful iteration. +382 if (ratio >= 1.0e-4) { +383 // successful iteration, update the norm +384 firstIteration = false; +385 xNorm = 0; +386 for (int k = 0; k < cols; ++k) { +387 double xK = diag[k] * point[k]; +388 xNorm += xK * xK; +389 } +390 xNorm = Math.sqrt(xNorm); +391 } else { +392 // failed iteration, reset the previous values +393 cost = previousCost; +394 for (int j = 0; j < solvedCols; ++j) { +395 int pj = permutation[j]; +396 point[pj] = oldX[pj]; +397 } +398 tmpVec = residuals; +399 residuals = oldRes; +400 oldRes = tmpVec; +401 } +402 +403 // tests for convergence. +404 if (((Math.abs(actRed) <= costRelativeTolerance) && +405 (preRed <= costRelativeTolerance) && +406 (ratio <= 2.0)) || +407 (delta <= parRelativeTolerance * xNorm)) { +408 return new VectorialPointValuePair(point, objective); +409 } +410 +411 // tests for termination and stringent tolerances +412 // (2.2204e-16 is the machine epsilon for IEEE754) +413 if ((Math.abs(actRed) <= 2.2204e-16) && (preRed <= 2.2204e-16) && (ratio <= 2.0)) { +414 throw new OptimizationException("cost relative tolerance is too small ({0})," + +415 " no further reduction in the" + +416 " sum of squares is possible", +417 costRelativeTolerance); +418 } else if (delta <= 2.2204e-16 * xNorm) { +419 throw new OptimizationException("parameters relative tolerance is too small" + +420 " ({0}), no further improvement in" + +421 " the approximate solution is possible", +422 parRelativeTolerance); +423 } else if (maxCosine <= 2.2204e-16) { +424 throw new OptimizationException("orthogonality tolerance is too small ({0})," + +425 " solution is orthogonal to the jacobian", +426 orthoTolerance); +427 } +428 +429 } +430 +431 } +432 +433 } +434 +435 /** +436 * Determine the Levenberg-Marquardt parameter. +437 * <p>This implementation is a translation in Java of the MINPACK +438 * <a href="http://www.netlib.org/minpack/lmpar.f">lmpar</a> +439 * routine.</p> +440 * <p>This method sets the lmPar and lmDir attributes.</p> +441 * <p>The authors of the original fortran function are:</p> +442 * <ul> +443 * <li>Argonne National Laboratory. MINPACK project. March 1980</li> +444 * <li>Burton S. Garbow</li> +445 * <li>Kenneth E. Hillstrom</li> +446 * <li>Jorge J. More</li> +447 * </ul> +448 * <p>Luc Maisonobe did the Java translation.</p> +449 * +450 * @param qy array containing qTy +451 * @param delta upper bound on the euclidean norm of diagR * lmDir +452 * @param diag diagonal matrix +453 * @param work1 work array +454 * @param work2 work array +455 * @param work3 work array +456 */ +457 private void determineLMParameter(double[] qy, double delta, double[] diag, +458 double[] work1, double[] work2, double[] work3) { +459 +460 // compute and store in x the gauss-newton direction, if the +461 // jacobian is rank-deficient, obtain a least squares solution +462 for (int j = 0; j < rank; ++j) { +463 lmDir[permutation[j]] = qy[j]; +464 } +465 for (int j = rank; j < cols; ++j) { +466 lmDir[permutation[j]] = 0; +467 } +468 for (int k = rank - 1; k >= 0; --k) { +469 int pk = permutation[k]; +470 double ypk = lmDir[pk] / diagR[pk]; +471 for (int i = 0; i < k; ++i) { +472 lmDir[permutation[i]] -= ypk * jacobian[i][pk]; +473 } +474 lmDir[pk] = ypk; +475 } +476 +477 // evaluate the function at the origin, and test +478 // for acceptance of the Gauss-Newton direction +479 double dxNorm = 0; +480 for (int j = 0; j < solvedCols; ++j) { +481 int pj = permutation[j]; +482 double s = diag[pj] * lmDir[pj]; +483 work1[pj] = s; +484 dxNorm += s * s; +485 } +486 dxNorm = Math.sqrt(dxNorm); +487 double fp = dxNorm - delta; +488 if (fp <= 0.1 * delta) { +489 lmPar = 0; +490 return; +491 } +492 +493 // if the jacobian is not rank deficient, the Newton step provides +494 // a lower bound, parl, for the zero of the function, +495 // otherwise set this bound to zero +496 double sum2; +497 double parl = 0; +498 if (rank == solvedCols) { +499 for (int j = 0; j < solvedCols; ++j) { +500 int pj = permutation[j]; +501 work1[pj] *= diag[pj] / dxNorm; +502 } +503 sum2 = 0; +504 for (int j = 0; j < solvedCols; ++j) { +505 int pj = permutation[j]; +506 double sum = 0; +507 for (int i = 0; i < j; ++i) { +508 sum += jacobian[i][pj] * work1[permutation[i]]; +509 } +510 double s = (work1[pj] - sum) / diagR[pj]; +511 work1[pj] = s; +512 sum2 += s * s; +513 } +514 parl = fp / (delta * sum2); +515 } +516 +517 // calculate an upper bound, paru, for the zero of the function +518 sum2 = 0; +519 for (int j = 0; j < solvedCols; ++j) { +520 int pj = permutation[j]; +521 double sum = 0; +522 for (int i = 0; i <= j; ++i) { +523 sum += jacobian[i][pj] * qy[i]; +524 } +525 sum /= diag[pj]; +526 sum2 += sum * sum; +527 } +528 double gNorm = Math.sqrt(sum2); +529 double paru = gNorm / delta; +530 if (paru == 0) { +531 // 2.2251e-308 is the smallest positive real for IEE754 +532 paru = 2.2251e-308 / Math.min(delta, 0.1); +533 } +534 +535 // if the input par lies outside of the interval (parl,paru), +536 // set par to the closer endpoint +537 lmPar = Math.min(paru, Math.max(lmPar, parl)); +538 if (lmPar == 0) { +539 lmPar = gNorm / dxNorm; +540 } +541 +542 for (int countdown = 10; countdown >= 0; --countdown) { +543 +544 // evaluate the function at the current value of lmPar +545 if (lmPar == 0) { +546 lmPar = Math.max(2.2251e-308, 0.001 * paru); +547 } +548 double sPar = Math.sqrt(lmPar); +549 for (int j = 0; j < solvedCols; ++j) { +550 int pj = permutation[j]; +551 work1[pj] = sPar * diag[pj]; +552 } +553 determineLMDirection(qy, work1, work2, work3); +554 +555 dxNorm = 0; +556 for (int j = 0; j < solvedCols; ++j) { +557 int pj = permutation[j]; +558 double s = diag[pj] * lmDir[pj]; +559 work3[pj] = s; +560 dxNorm += s * s; +561 } +562 dxNorm = Math.sqrt(dxNorm); +563 double previousFP = fp; +564 fp = dxNorm - delta; +565 +566 // if the function is small enough, accept the current value +567 // of lmPar, also test for the exceptional cases where parl is zero +568 if ((Math.abs(fp) <= 0.1 * delta) || +569 ((parl == 0) && (fp <= previousFP) && (previousFP < 0))) { +570 return; +571 } +572 +573 // compute the Newton correction +574 for (int j = 0; j < solvedCols; ++j) { +575 int pj = permutation[j]; +576 work1[pj] = work3[pj] * diag[pj] / dxNorm; +577 } +578 for (int j = 0; j < solvedCols; ++j) { +579 int pj = permutation[j]; +580 work1[pj] /= work2[j]; +581 double tmp = work1[pj]; +582 for (int i = j + 1; i < solvedCols; ++i) { +583 work1[permutation[i]] -= jacobian[i][pj] * tmp; +584 } +585 } +586 sum2 = 0; +587 for (int j = 0; j < solvedCols; ++j) { +588 double s = work1[permutation[j]]; +589 sum2 += s * s; +590 } +591 double correction = fp / (delta * sum2); +592 +593 // depending on the sign of the function, update parl or paru. +594 if (fp > 0) { +595 parl = Math.max(parl, lmPar); +596 } else if (fp < 0) { +597 paru = Math.min(paru, lmPar); +598 } +599 +600 // compute an improved estimate for lmPar +601 lmPar = Math.max(parl, lmPar + correction); +602 +603 } +604 } +605 +606 /** +607 * Solve a*x = b and d*x = 0 in the least squares sense. +608 * <p>This implementation is a translation in Java of the MINPACK +609 * <a href="http://www.netlib.org/minpack/qrsolv.f">qrsolv</a> +610 * routine.</p> +611 * <p>This method sets the lmDir and lmDiag attributes.</p> +612 * <p>The authors of the original fortran function are:</p> +613 * <ul> +614 * <li>Argonne National Laboratory. MINPACK project. March 1980</li> +615 * <li>Burton S. Garbow</li> +616 * <li>Kenneth E. Hillstrom</li> +617 * <li>Jorge J. More</li> +618 * </ul> +619 * <p>Luc Maisonobe did the Java translation.</p> +620 * +621 * @param qy array containing qTy +622 * @param diag diagonal matrix +623 * @param lmDiag diagonal elements associated with lmDir +624 * @param work work array +625 */ +626 private void determineLMDirection(double[] qy, double[] diag, +627 double[] lmDiag, double[] work) { +628 +629 // copy R and Qty to preserve input and initialize s +630 // in particular, save the diagonal elements of R in lmDir +631 for (int j = 0; j < solvedCols; ++j) { +632 int pj = permutation[j]; +633 for (int i = j + 1; i < solvedCols; ++i) { +634 jacobian[i][pj] = jacobian[j][permutation[i]]; +635 } +636 lmDir[j] = diagR[pj]; +637 work[j] = qy[j]; +638 } +639 +640 // eliminate the diagonal matrix d using a Givens rotation +641 for (int j = 0; j < solvedCols; ++j) { +642 +643 // prepare the row of d to be eliminated, locating the +644 // diagonal element using p from the Q.R. factorization +645 int pj = permutation[j]; +646 double dpj = diag[pj]; +647 if (dpj != 0) { +648 Arrays.fill(lmDiag, j + 1, lmDiag.length, 0); +649 } +650 lmDiag[j] = dpj; +651 +652 // the transformations to eliminate the row of d +653 // modify only a single element of Qty +654 // beyond the first n, which is initially zero. +655 double qtbpj = 0; +656 for (int k = j; k < solvedCols; ++k) { +657 int pk = permutation[k]; +658 +659 // determine a Givens rotation which eliminates the +660 // appropriate element in the current row of d +661 if (lmDiag[k] != 0) { +662 +663 final double sin; +664 final double cos; +665 double rkk = jacobian[k][pk]; +666 if (Math.abs(rkk) < Math.abs(lmDiag[k])) { +667 final double cotan = rkk / lmDiag[k]; +668 sin = 1.0 / Math.sqrt(1.0 + cotan * cotan); +669 cos = sin * cotan; +670 } else { +671 final double tan = lmDiag[k] / rkk; +672 cos = 1.0 / Math.sqrt(1.0 + tan * tan); +673 sin = cos * tan; +674 } +675 +676 // compute the modified diagonal element of R and +677 // the modified element of (Qty,0) +678 jacobian[k][pk] = cos * rkk + sin * lmDiag[k]; +679 final double temp = cos * work[k] + sin * qtbpj; +680 qtbpj = -sin * work[k] + cos * qtbpj; +681 work[k] = temp; +682 +683 // accumulate the tranformation in the row of s +684 for (int i = k + 1; i < solvedCols; ++i) { +685 double rik = jacobian[i][pk]; +686 final double temp2 = cos * rik + sin * lmDiag[i]; +687 lmDiag[i] = -sin * rik + cos * lmDiag[i]; +688 jacobian[i][pk] = temp2; +689 } +690 +691 } +692 } +693 +694 // store the diagonal element of s and restore +695 // the corresponding diagonal element of R +696 lmDiag[j] = jacobian[j][permutation[j]]; +697 jacobian[j][permutation[j]] = lmDir[j]; +698 +699 } +700 +701 // solve the triangular system for z, if the system is +702 // singular, then obtain a least squares solution +703 int nSing = solvedCols; +704 for (int j = 0; j < solvedCols; ++j) { +705 if ((lmDiag[j] == 0) && (nSing == solvedCols)) { +706 nSing = j; +707 } +708 if (nSing < solvedCols) { +709 work[j] = 0; +710 } +711 } +712 if (nSing > 0) { +713 for (int j = nSing - 1; j >= 0; --j) { +714 int pj = permutation[j]; +715 double sum = 0; +716 for (int i = j + 1; i < nSing; ++i) { +717 sum += jacobian[i][pj] * work[i]; +718 } +719 work[j] = (work[j] - sum) / lmDiag[j]; +720 } +721 } +722 +723 // permute the components of z back to components of lmDir +724 for (int j = 0; j < lmDir.length; ++j) { +725 lmDir[permutation[j]] = work[j]; +726 } +727 +728 } +729 +730 /** +731 * Decompose a matrix A as A.P = Q.R using Householder transforms. +732 * <p>As suggested in the P. Lascaux and R. Theodor book +733 * <i>Analyse numérique matricielle appliquée à +734 * l'art de l'ingénieur</i> (Masson, 1986), instead of representing +735 * the Householder transforms with u<sub>k</sub> unit vectors such that: +736 * <pre> +737 * H<sub>k</sub> = I - 2u<sub>k</sub>.u<sub>k</sub><sup>t</sup> +738 * </pre> +739 * we use <sub>k</sub> non-unit vectors such that: +740 * <pre> +741 * H<sub>k</sub> = I - beta<sub>k</sub>v<sub>k</sub>.v<sub>k</sub><sup>t</sup> +742 * </pre> +743 * where v<sub>k</sub> = a<sub>k</sub> - alpha<sub>k</sub> e<sub>k</sub>. +744 * The beta<sub>k</sub> coefficients are provided upon exit as recomputing +745 * them from the v<sub>k</sub> vectors would be costly.</p> +746 * <p>This decomposition handles rank deficient cases since the tranformations +747 * are performed in non-increasing columns norms order thanks to columns +748 * pivoting. The diagonal elements of the R matrix are therefore also in +749 * non-increasing absolute values order.</p> +750 * @exception OptimizationException if the decomposition cannot be performed +751 */ +752 private void qrDecomposition() throws OptimizationException { +753 +754 // initializations +755 for (int k = 0; k < cols; ++k) { +756 permutation[k] = k; +757 double norm2 = 0; +758 for (int i = 0; i < jacobian.length; ++i) { +759 double akk = jacobian[i][k]; +760 norm2 += akk * akk; +761 } +762 jacNorm[k] = Math.sqrt(norm2); +763 } +764 +765 // transform the matrix column after column +766 for (int k = 0; k < cols; ++k) { +767 +768 // select the column with the greatest norm on active components +769 int nextColumn = -1; +770 double ak2 = Double.NEGATIVE_INFINITY; +771 for (int i = k; i < cols; ++i) { +772 double norm2 = 0; +773 for (int j = k; j < jacobian.length; ++j) { +774 double aki = jacobian[j][permutation[i]]; +775 norm2 += aki * aki; +776 } +777 if (Double.isInfinite(norm2) || Double.isNaN(norm2)) { +778 throw new OptimizationException( +779 "unable to perform Q.R decomposition on the {0}x{1} jacobian matrix", +780 rows, cols); +781 } +782 if (norm2 > ak2) { +783 nextColumn = i; +784 ak2 = norm2; +785 } +786 } +787 if (ak2 == 0) { +788 rank = k; +789 return; +790 } +791 int pk = permutation[nextColumn]; +792 permutation[nextColumn] = permutation[k]; +793 permutation[k] = pk; +794 +795 // choose alpha such that Hk.u = alpha ek +796 double akk = jacobian[k][pk]; +797 double alpha = (akk > 0) ? -Math.sqrt(ak2) : Math.sqrt(ak2); +798 double betak = 1.0 / (ak2 - akk * alpha); +799 beta[pk] = betak; +800 +801 // transform the current column +802 diagR[pk] = alpha; +803 jacobian[k][pk] -= alpha; +804 +805 // transform the remaining columns +806 for (int dk = cols - 1 - k; dk > 0; --dk) { +807 double gamma = 0; +808 for (int j = k; j < jacobian.length; ++j) { +809 gamma += jacobian[j][pk] * jacobian[j][permutation[k + dk]]; +810 } +811 gamma *= betak; +812 for (int j = k; j < jacobian.length; ++j) { +813 jacobian[j][permutation[k + dk]] -= gamma * jacobian[j][pk]; +814 } +815 } +816 +817 } +818 +819 rank = solvedCols; +820 +821 } +822 +823 /** +824 * Compute the product Qt.y for some Q.R. decomposition. +825 * +826 * @param y vector to multiply (will be overwritten with the result) +827 */ +828 private void qTy(double[] y) { +829 for (int k = 0; k < cols; ++k) { +830 int pk = permutation[k]; +831 double gamma = 0; +832 for (int i = k; i < rows; ++i) { +833 gamma += jacobian[i][pk] * y[i]; +834 } +835 gamma *= beta[pk]; +836 for (int i = k; i < rows; ++i) { +837 y[i] -= gamma * jacobian[i][pk]; +838 } +839 } +840 } +841 +842 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/general/NonLinearConjugateGradientOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/general/NonLinearConjugateGradientOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,359 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.general; +019 +020 import org.apache.commons.math.ConvergenceException; +021 import org.apache.commons.math.FunctionEvaluationException; +022 import org.apache.commons.math.analysis.UnivariateRealFunction; +023 import org.apache.commons.math.analysis.solvers.BrentSolver; +024 import org.apache.commons.math.analysis.solvers.UnivariateRealSolver; +025 import org.apache.commons.math.optimization.GoalType; +026 import org.apache.commons.math.optimization.OptimizationException; +027 import org.apache.commons.math.optimization.DifferentiableMultivariateRealOptimizer; +028 import org.apache.commons.math.optimization.RealPointValuePair; +029 +030 /** +031 * Non-linear conjugate gradient optimizer. +032 * <p> +033 * This class supports both the Fletcher-Reeves and the Polak-Ribière +034 * update formulas for the conjugate search directions. It also supports +035 * optional preconditioning. +036 * </p> +037 * +038 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +039 * @since 2.0 +040 * +041 */ +042 +043 public class NonLinearConjugateGradientOptimizer +044 extends AbstractScalarDifferentiableOptimizer +045 implements DifferentiableMultivariateRealOptimizer { +046 +047 /** Update formula for the beta parameter. */ +048 private final ConjugateGradientFormula updateFormula; +049 +050 /** Preconditioner (may be null). */ +051 private Preconditioner preconditioner; +052 +053 /** solver to use in the line search (may be null). */ +054 private UnivariateRealSolver solver; +055 +056 /** Initial step used to bracket the optimum in line search. */ +057 private double initialStep; +058 +059 /** Simple constructor with default settings. +060 * <p>The convergence check is set to a {@link +061 * org.apache.commons.math.optimization.SimpleVectorialValueChecker} +062 * and the maximal number of iterations is set to +063 * {@link AbstractScalarDifferentiableOptimizer#DEFAULT_MAX_ITERATIONS}. +064 * @param updateFormula formula to use for updating the β parameter, +065 * must be one of {@link ConjugateGradientFormula#FLETCHER_REEVES} or {@link +066 * ConjugateGradientFormula#POLAK_RIBIERE} +067 */ +068 public NonLinearConjugateGradientOptimizer(final ConjugateGradientFormula updateFormula) { +069 this.updateFormula = updateFormula; +070 preconditioner = null; +071 solver = null; +072 initialStep = 1.0; +073 } +074 +075 /** +076 * Set the preconditioner. +077 * @param preconditioner preconditioner to use for next optimization, +078 * may be null to remove an already registered preconditioner +079 */ +080 public void setPreconditioner(final Preconditioner preconditioner) { +081 this.preconditioner = preconditioner; +082 } +083 +084 /** +085 * Set the solver to use during line search. +086 * @param lineSearchSolver solver to use during line search, may be null +087 * to remove an already registered solver and fall back to the +088 * default {@link BrentSolver Brent solver}. +089 */ +090 public void setLineSearchSolver(final UnivariateRealSolver lineSearchSolver) { +091 this.solver = lineSearchSolver; +092 } +093 +094 /** +095 * Set the initial step used to bracket the optimum in line search. +096 * <p> +097 * The initial step is a factor with respect to the search direction, +098 * which itself is roughly related to the gradient of the function +099 * </p> +100 * @param initialStep initial step used to bracket the optimum in line search, +101 * if a non-positive value is used, the initial step is reset to its +102 * default value of 1.0 +103 */ +104 public void setInitialStep(final double initialStep) { +105 if (initialStep <= 0) { +106 this.initialStep = 1.0; +107 } else { +108 this.initialStep = initialStep; +109 } +110 } +111 +112 /** {@inheritDoc} */ +113 @Override +114 protected RealPointValuePair doOptimize() +115 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException { +116 try { +117 +118 // initialization +119 if (preconditioner == null) { +120 preconditioner = new IdentityPreconditioner(); +121 } +122 if (solver == null) { +123 solver = new BrentSolver(); +124 } +125 final int n = point.length; +126 double[] r = computeObjectiveGradient(point); +127 if (goal == GoalType.MINIMIZE) { +128 for (int i = 0; i < n; ++i) { +129 r[i] = -r[i]; +130 } +131 } +132 +133 // initial search direction +134 double[] steepestDescent = preconditioner.precondition(point, r); +135 double[] searchDirection = steepestDescent.clone(); +136 +137 double delta = 0; +138 for (int i = 0; i < n; ++i) { +139 delta += r[i] * searchDirection[i]; +140 } +141 +142 RealPointValuePair current = null; +143 while (true) { +144 +145 final double objective = computeObjectiveValue(point); +146 RealPointValuePair previous = current; +147 current = new RealPointValuePair(point, objective); +148 if (previous != null) { +149 if (checker.converged(getIterations(), previous, current)) { +150 // we have found an optimum +151 return current; +152 } +153 } +154 +155 incrementIterationsCounter(); +156 +157 double dTd = 0; +158 for (final double di : searchDirection) { +159 dTd += di * di; +160 } +161 +162 // find the optimal step in the search direction +163 final UnivariateRealFunction lsf = new LineSearchFunction(searchDirection); +164 final double step = solver.solve(lsf, 0, findUpperBound(lsf, 0, initialStep)); +165 +166 // validate new point +167 for (int i = 0; i < point.length; ++i) { +168 point[i] += step * searchDirection[i]; +169 } +170 r = computeObjectiveGradient(point); +171 if (goal == GoalType.MINIMIZE) { +172 for (int i = 0; i < n; ++i) { +173 r[i] = -r[i]; +174 } +175 } +176 +177 // compute beta +178 final double deltaOld = delta; +179 final double[] newSteepestDescent = preconditioner.precondition(point, r); +180 delta = 0; +181 for (int i = 0; i < n; ++i) { +182 delta += r[i] * newSteepestDescent[i]; +183 } +184 +185 final double beta; +186 if (updateFormula == ConjugateGradientFormula.FLETCHER_REEVES) { +187 beta = delta / deltaOld; +188 } else { +189 double deltaMid = 0; +190 for (int i = 0; i < r.length; ++i) { +191 deltaMid += r[i] * steepestDescent[i]; +192 } +193 beta = (delta - deltaMid) / deltaOld; +194 } +195 steepestDescent = newSteepestDescent; +196 +197 // compute conjugate search direction +198 if ((getIterations() % n == 0) || (beta < 0)) { +199 // break conjugation: reset search direction +200 searchDirection = steepestDescent.clone(); +201 } else { +202 // compute new conjugate search direction +203 for (int i = 0; i < n; ++i) { +204 searchDirection[i] = steepestDescent[i] + beta * searchDirection[i]; +205 } +206 } +207 +208 } +209 +210 } catch (ConvergenceException ce) { +211 throw new OptimizationException(ce); +212 } +213 } +214 +215 /** +216 * Find the upper bound b ensuring bracketing of a root between a and b +217 * @param f function whose root must be bracketed +218 * @param a lower bound of the interval +219 * @param h initial step to try +220 * @return b such that f(a) and f(b) have opposite signs +221 * @exception FunctionEvaluationException if the function cannot be computed +222 * @exception OptimizationException if no bracket can be found +223 */ +224 private double findUpperBound(final UnivariateRealFunction f, +225 final double a, final double h) +226 throws FunctionEvaluationException, OptimizationException { +227 final double yA = f.value(a); +228 double yB = yA; +229 for (double step = h; step < Double.MAX_VALUE; step *= Math.max(2, yA / yB)) { +230 final double b = a + step; +231 yB = f.value(b); +232 if (yA * yB <= 0) { +233 return b; +234 } +235 } +236 throw new OptimizationException("unable to bracket optimum in line search"); +237 } +238 +239 /** Default identity preconditioner. */ +240 private static class IdentityPreconditioner implements Preconditioner { +241 +242 /** {@inheritDoc} */ +243 public double[] precondition(double[] variables, double[] r) { +244 return r.clone(); +245 } +246 +247 } +248 +249 /** Internal class for line search. +250 * <p> +251 * The function represented by this class is the dot product of +252 * the objective function gradient and the search direction. Its +253 * value is zero when the gradient is orthogonal to the search +254 * direction, i.e. when the objective function value is a local +255 * extremum along the search direction. +256 * </p> +257 */ +258 private class LineSearchFunction implements UnivariateRealFunction { +259 /** Search direction. */ +260 private final double[] searchDirection; +261 +262 /** Simple constructor. +263 * @param searchDirection search direction +264 */ +265 public LineSearchFunction(final double[] searchDirection) { +266 this.searchDirection = searchDirection; +267 } +268 +269 /** {@inheritDoc} */ +270 public double value(double x) throws FunctionEvaluationException { +271 +272 // current point in the search direction +273 final double[] shiftedPoint = point.clone(); +274 for (int i = 0; i < shiftedPoint.length; ++i) { +275 shiftedPoint[i] += x * searchDirection[i]; +276 } +277 +278 // gradient of the objective function +279 final double[] gradient = computeObjectiveGradient(shiftedPoint); +280 +281 // dot product with the search direction +282 double dotProduct = 0; +283 for (int i = 0; i < gradient.length; ++i) { +284 dotProduct += gradient[i] * searchDirection[i]; +285 } +286 +287 return dotProduct; +288 +289 } +290 +291 } +292 +293 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/general/Preconditioner.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/general/Preconditioner.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,118 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.general; +019 +020 import org.apache.commons.math.FunctionEvaluationException; +021 +022 /** +023 * This interface represents a preconditioner for differentiable scalar +024 * objective function optimizers. +025 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +026 * @since 2.0 +027 */ +028 public interface Preconditioner { +029 +030 /** +031 * Precondition a search direction. +032 * <p> +033 * The returned preconditioned search direction must be computed fast or +034 * the algorithm performances will drop drastically. A classical approach +035 * is to compute only the diagonal elements of the hessian and to divide +036 * the raw search direction by these elements if they are all positive. +037 * If at least one of them is negative, it is safer to return a clone of +038 * the raw search direction as if the hessian was the identity matrix. The +039 * rationale for this simplified choice is that a negative diagonal element +040 * means the current point is far from the optimum and preconditioning will +041 * not be efficient anyway in this case. +042 * </p> +043 * @param point current point at which the search direction was computed +044 * @param r raw search direction (i.e. opposite of the gradient) +045 * @return approximation of H<sup>-1</sup>r where H is the objective function hessian +046 * @exception FunctionEvaluationException if no cost can be computed for the parameters +047 * @exception IllegalArgumentException if point dimension is wrong +048 */ +049 double[] precondition(double[] point, double[] r) +050 throws FunctionEvaluationException, IllegalArgumentException; +051 +052 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/AbstractLinearOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/AbstractLinearOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,196 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.linear; +019 +020 import java.util.Collection; +021 +022 import org.apache.commons.math.MaxIterationsExceededException; +023 import org.apache.commons.math.optimization.GoalType; +024 import org.apache.commons.math.optimization.OptimizationException; +025 import org.apache.commons.math.optimization.RealPointValuePair; +026 +027 /** +028 * Base class for implementing linear optimizers. +029 * <p>This base class handles the boilerplate methods associated to thresholds +030 * settings and iterations counters.</p> +031 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +032 * @since 2.0 +033 * +034 */ +035 public abstract class AbstractLinearOptimizer implements LinearOptimizer { +036 +037 /** Default maximal number of iterations allowed. */ +038 public static final int DEFAULT_MAX_ITERATIONS = 100; +039 +040 /** +041 * Linear objective function. +042 * @since 2.1 +043 */ +044 protected LinearObjectiveFunction function; +045 +046 /** +047 * Linear constraints. +048 * @since 2.1 +049 */ +050 protected Collection<LinearConstraint> linearConstraints; +051 +052 /** +053 * Type of optimization goal: either {@link GoalType#MAXIMIZE} or {@link GoalType#MINIMIZE}. +054 * @since 2.1 +055 */ +056 protected GoalType goal; +057 +058 /** +059 * Whether to restrict the variables to non-negative values. +060 * @since 2.1 +061 */ +062 protected boolean nonNegative; +063 +064 /** Maximal number of iterations allowed. */ +065 private int maxIterations; +066 +067 /** Number of iterations already performed. */ +068 private int iterations; +069 +070 /** Simple constructor with default settings. +071 * <p>The maximal number of evaluation is set to its default value.</p> +072 */ +073 protected AbstractLinearOptimizer() { +074 setMaxIterations(DEFAULT_MAX_ITERATIONS); +075 } +076 +077 /** {@inheritDoc} */ +078 public void setMaxIterations(int maxIterations) { +079 this.maxIterations = maxIterations; +080 } +081 +082 /** {@inheritDoc} */ +083 public int getMaxIterations() { +084 return maxIterations; +085 } +086 +087 /** {@inheritDoc} */ +088 public int getIterations() { +089 return iterations; +090 } +091 +092 /** Increment the iterations counter by 1. +093 * @exception OptimizationException if the maximal number +094 * of iterations is exceeded +095 */ +096 protected void incrementIterationsCounter() +097 throws OptimizationException { +098 if (++iterations > maxIterations) { +099 throw new OptimizationException(new MaxIterationsExceededException(maxIterations)); +100 } +101 } +102 +103 /** {@inheritDoc} */ +104 public RealPointValuePair optimize(final LinearObjectiveFunction f, +105 final Collection<LinearConstraint> constraints, +106 final GoalType goalType, final boolean restrictToNonNegative) +107 throws OptimizationException { +108 +109 // store linear problem characteristics +110 this.function = f; +111 this.linearConstraints = constraints; +112 this.goal = goalType; +113 this.nonNegative = restrictToNonNegative; +114 +115 iterations = 0; +116 +117 // solve the problem +118 return doOptimize(); +119 +120 } +121 +122 /** Perform the bulk of optimization algorithm. +123 * @return the point/value pair giving the optimal value for objective function +124 * @exception OptimizationException if no solution fulfilling the constraints +125 * can be found in the allowed number of iterations +126 */ +127 protected abstract RealPointValuePair doOptimize() +128 throws OptimizationException; +129 +130 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/LinearConstraint.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/LinearConstraint.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,299 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.linear; +019 +020 import java.io.IOException; +021 import java.io.ObjectInputStream; +022 import java.io.ObjectOutputStream; +023 import java.io.Serializable; +024 +025 import org.apache.commons.math.linear.MatrixUtils; +026 import org.apache.commons.math.linear.RealVector; +027 import org.apache.commons.math.linear.ArrayRealVector; +028 +029 +030 /** +031 * A linear constraint for a linear optimization problem. +032 * <p> +033 * A linear constraint has one of the forms: +034 * <ul> +035 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li> +036 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li> +037 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li> +038 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> = +039 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> +040 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <= +041 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> +042 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >= +043 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> +044 * </ul> +045 * 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> +046 * are the coordinates of the current point and v is the value of the constraint. +047 * </p> +048 * @version $Revision: 922713 $ $Date: 2010-03-13 20:26:13 -0500 (Sat, 13 Mar 2010) $ +049 * @since 2.0 +050 */ +051 public class LinearConstraint implements Serializable { +052 +053 /** Serializable version identifier. */ +054 private static final long serialVersionUID = -764632794033034092L; +055 +056 /** Coefficients of the constraint (left hand side). */ +057 private final transient RealVector coefficients; +058 +059 /** Relationship between left and right hand sides (=, <=, >=). */ +060 private final Relationship relationship; +061 +062 /** Value of the constraint (right hand side). */ +063 private final double value; +064 +065 /** +066 * Build a constraint involving a single linear equation. +067 * <p> +068 * A linear constraint with a single linear equation has one of the forms: +069 * <ul> +070 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li> +071 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li> +072 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li> +073 * </ul> +074 * </p> +075 * @param coefficients The coefficients of the constraint (left hand side) +076 * @param relationship The type of (in)equality used in the constraint +077 * @param value The value of the constraint (right hand side) +078 */ +079 public LinearConstraint(final double[] coefficients, final Relationship relationship, +080 final double value) { +081 this(new ArrayRealVector(coefficients), relationship, value); +082 } +083 +084 /** +085 * Build a constraint involving a single linear equation. +086 * <p> +087 * A linear constraint with a single linear equation has one of the forms: +088 * <ul> +089 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li> +090 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li> +091 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li> +092 * </ul> +093 * </p> +094 * @param coefficients The coefficients of the constraint (left hand side) +095 * @param relationship The type of (in)equality used in the constraint +096 * @param value The value of the constraint (right hand side) +097 */ +098 public LinearConstraint(final RealVector coefficients, final Relationship relationship, +099 final double value) { +100 this.coefficients = coefficients; +101 this.relationship = relationship; +102 this.value = value; +103 } +104 +105 /** +106 * Build a constraint involving two linear equations. +107 * <p> +108 * A linear constraint with two linear equation has one of the forms: +109 * <ul> +110 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> = +111 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> +112 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <= +113 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> +114 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >= +115 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> +116 * </ul> +117 * </p> +118 * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint +119 * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint +120 * @param relationship The type of (in)equality used in the constraint +121 * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint +122 * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint +123 */ +124 public LinearConstraint(final double[] lhsCoefficients, final double lhsConstant, +125 final Relationship relationship, +126 final double[] rhsCoefficients, final double rhsConstant) { +127 double[] sub = new double[lhsCoefficients.length]; +128 for (int i = 0; i < sub.length; ++i) { +129 sub[i] = lhsCoefficients[i] - rhsCoefficients[i]; +130 } +131 this.coefficients = new ArrayRealVector(sub, false); +132 this.relationship = relationship; +133 this.value = rhsConstant - lhsConstant; +134 } +135 +136 /** +137 * Build a constraint involving two linear equations. +138 * <p> +139 * A linear constraint with two linear equation has one of the forms: +140 * <ul> +141 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> = +142 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> +143 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <= +144 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> +145 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >= +146 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> +147 * </ul> +148 * </p> +149 * @param lhsCoefficients The coefficients of the linear expression on the left hand side of the constraint +150 * @param lhsConstant The constant term of the linear expression on the left hand side of the constraint +151 * @param relationship The type of (in)equality used in the constraint +152 * @param rhsCoefficients The coefficients of the linear expression on the right hand side of the constraint +153 * @param rhsConstant The constant term of the linear expression on the right hand side of the constraint +154 */ +155 public LinearConstraint(final RealVector lhsCoefficients, final double lhsConstant, +156 final Relationship relationship, +157 final RealVector rhsCoefficients, final double rhsConstant) { +158 this.coefficients = lhsCoefficients.subtract(rhsCoefficients); +159 this.relationship = relationship; +160 this.value = rhsConstant - lhsConstant; +161 } +162 +163 /** +164 * Get the coefficients of the constraint (left hand side). +165 * @return coefficients of the constraint (left hand side) +166 */ +167 public RealVector getCoefficients() { +168 return coefficients; +169 } +170 +171 /** +172 * Get the relationship between left and right hand sides. +173 * @return relationship between left and right hand sides +174 */ +175 public Relationship getRelationship() { +176 return relationship; +177 } +178 +179 /** +180 * Get the value of the constraint (right hand side). +181 * @return value of the constraint (right hand side) +182 */ +183 public double getValue() { +184 return value; +185 } +186 +187 /** {@inheritDoc} */ +188 @Override +189 public boolean equals(Object other) { +190 +191 if (this == other) { +192 return true; +193 } +194 +195 if (other instanceof LinearConstraint) { +196 LinearConstraint rhs = (LinearConstraint) other; +197 return (relationship == rhs.relationship) && +198 (value == rhs.value) && +199 coefficients.equals(rhs.coefficients); +200 } +201 return false; +202 } +203 +204 /** {@inheritDoc} */ +205 @Override +206 public int hashCode() { +207 return relationship.hashCode() ^ +208 Double.valueOf(value).hashCode() ^ +209 coefficients.hashCode(); +210 } +211 +212 /** Serialize the instance. +213 * @param oos stream where object should be written +214 * @throws IOException if object cannot be written to stream +215 */ +216 private void writeObject(ObjectOutputStream oos) +217 throws IOException { +218 oos.defaultWriteObject(); +219 MatrixUtils.serializeRealVector(coefficients, oos); +220 } +221 +222 /** Deserialize the instance. +223 * @param ois stream from which the object should be read +224 * @throws ClassNotFoundException if a class in the stream cannot be found +225 * @throws IOException if object cannot be read from the stream +226 */ +227 private void readObject(ObjectInputStream ois) +228 throws ClassNotFoundException, IOException { +229 ois.defaultReadObject(); +230 MatrixUtils.deserializeRealVector(this, "coefficients", ois); +231 } +232 +233 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/LinearObjectiveFunction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/LinearObjectiveFunction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,213 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.linear; +019 +020 import java.io.IOException; +021 import java.io.ObjectInputStream; +022 import java.io.ObjectOutputStream; +023 import java.io.Serializable; +024 +025 import org.apache.commons.math.linear.MatrixUtils; +026 import org.apache.commons.math.linear.RealVector; +027 import org.apache.commons.math.linear.ArrayRealVector; +028 +029 /** +030 * An objective function for a linear optimization problem. +031 * <p> +032 * A linear objective function has one the form: +033 * <pre> +034 * c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> + d +035 * </pre> +036 * The c<sub>i</sub> and d are the coefficients of the equation, +037 * the x<sub>i</sub> are the coordinates of the current point. +038 * </p> +039 * @version $Revision: 922713 $ $Date: 2010-03-13 20:26:13 -0500 (Sat, 13 Mar 2010) $ +040 * @since 2.0 +041 */ +042 public class LinearObjectiveFunction implements Serializable { +043 +044 /** Serializable version identifier. */ +045 private static final long serialVersionUID = -4531815507568396090L; +046 +047 /** Coefficients of the constraint (c<sub>i</sub>). */ +048 private final transient RealVector coefficients; +049 +050 /** Constant term of the linear equation. */ +051 private final double constantTerm; +052 +053 /** +054 * @param coefficients The coefficients for the linear equation being optimized +055 * @param constantTerm The constant term of the linear equation +056 */ +057 public LinearObjectiveFunction(double[] coefficients, double constantTerm) { +058 this(new ArrayRealVector(coefficients), constantTerm); +059 } +060 +061 /** +062 * @param coefficients The coefficients for the linear equation being optimized +063 * @param constantTerm The constant term of the linear equation +064 */ +065 public LinearObjectiveFunction(RealVector coefficients, double constantTerm) { +066 this.coefficients = coefficients; +067 this.constantTerm = constantTerm; +068 } +069 +070 /** +071 * Get the coefficients of the linear equation being optimized. +072 * @return coefficients of the linear equation being optimized +073 */ +074 public RealVector getCoefficients() { +075 return coefficients; +076 } +077 +078 /** +079 * Get the constant of the linear equation being optimized. +080 * @return constant of the linear equation being optimized +081 */ +082 public double getConstantTerm() { +083 return constantTerm; +084 } +085 +086 /** +087 * Compute the value of the linear equation at the current point +088 * @param point point at which linear equation must be evaluated +089 * @return value of the linear equation at the current point +090 */ +091 public double getValue(final double[] point) { +092 return coefficients.dotProduct(point) + constantTerm; +093 } +094 +095 /** +096 * Compute the value of the linear equation at the current point +097 * @param point point at which linear equation must be evaluated +098 * @return value of the linear equation at the current point +099 */ +100 public double getValue(final RealVector point) { +101 return coefficients.dotProduct(point) + constantTerm; +102 } +103 +104 /** {@inheritDoc} */ +105 @Override +106 public boolean equals(Object other) { +107 +108 if (this == other) { +109 return true; +110 } +111 +112 if (other instanceof LinearObjectiveFunction) { +113 LinearObjectiveFunction rhs = (LinearObjectiveFunction) other; +114 return (constantTerm == rhs.constantTerm) && coefficients.equals(rhs.coefficients); +115 } +116 +117 return false; +118 } +119 +120 /** {@inheritDoc} */ +121 @Override +122 public int hashCode() { +123 return Double.valueOf(constantTerm).hashCode() ^ coefficients.hashCode(); +124 } +125 +126 /** Serialize the instance. +127 * @param oos stream where object should be written +128 * @throws IOException if object cannot be written to stream +129 */ +130 private void writeObject(ObjectOutputStream oos) +131 throws IOException { +132 oos.defaultWriteObject(); +133 MatrixUtils.serializeRealVector(coefficients, oos); +134 } +135 +136 /** Deserialize the instance. +137 * @param ois stream from which the object should be read +138 * @throws ClassNotFoundException if a class in the stream cannot be found +139 * @throws IOException if object cannot be read from the stream +140 */ +141 private void readObject(ObjectInputStream ois) +142 throws ClassNotFoundException, IOException { +143 ois.defaultReadObject(); +144 MatrixUtils.deserializeRealVector(this, "coefficients", ois); +145 } +146 +147 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/LinearOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/LinearOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,155 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.linear; +019 +020 import java.util.Collection; +021 +022 import org.apache.commons.math.optimization.GoalType; +023 import org.apache.commons.math.optimization.OptimizationException; +024 import org.apache.commons.math.optimization.RealPointValuePair; +025 +026 /** +027 * This interface represents an optimization algorithm for linear problems. +028 * <p>Optimization algorithms find the input point set that either {@link GoalType +029 * maximize or minimize} an objective function. In the linear case the form of +030 * the function is restricted to +031 * <pre> +032 * c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v +033 * </pre> +034 * and there may be linear constraints too, of one of the forms: +035 * <ul> +036 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> = v</li> +037 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> <= v</li> +038 * <li>c<sub>1</sub>x<sub>1</sub> + ... c<sub>n</sub>x<sub>n</sub> >= v</li> +039 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> = +040 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> +041 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> <= +042 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> +043 * <li>l<sub>1</sub>x<sub>1</sub> + ... l<sub>n</sub>x<sub>n</sub> + l<sub>cst</sub> >= +044 * r<sub>1</sub>x<sub>1</sub> + ... r<sub>n</sub>x<sub>n</sub> + r<sub>cst</sub></li> +045 * </ul> +046 * where the c<sub>i</sub>, l<sub>i</sub> or r<sub>i</sub> are the coefficients of +047 * the constraints, the x<sub>i</sub> are the coordinates of the current point and +048 * v is the value of the constraint. +049 * </p> +050 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +051 * @since 2.0 +052 */ +053 public interface LinearOptimizer { +054 +055 /** Set the maximal number of iterations of the algorithm. +056 * @param maxIterations maximal number of function calls +057 */ +058 void setMaxIterations(int maxIterations); +059 +060 /** Get the maximal number of iterations of the algorithm. +061 * @return maximal number of iterations +062 */ +063 int getMaxIterations(); +064 +065 /** Get the number of iterations realized by the algorithm. +066 * <p> +067 * The number of evaluations corresponds to the last call to the +068 * {@link #optimize(LinearObjectiveFunction, Collection, GoalType, boolean) optimize} +069 * method. It is 0 if the method has not been called yet. +070 * </p> +071 * @return number of iterations +072 */ +073 int getIterations(); +074 +075 /** Optimizes an objective function. +076 * @param f linear objective function +077 * @param constraints linear constraints +078 * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE} +079 * or {@link GoalType#MINIMIZE} +080 * @param restrictToNonNegative whether to restrict the variables to non-negative values +081 * @return point/value pair giving the optimal value for objective function +082 * @exception OptimizationException if no solution fulfilling the constraints +083 * can be found in the allowed number of iterations +084 */ +085 RealPointValuePair optimize(LinearObjectiveFunction f, Collection<LinearConstraint> constraints, +086 GoalType goalType, boolean restrictToNonNegative) +087 throws OptimizationException; +088 +089 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/NoFeasibleSolutionException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/NoFeasibleSolutionException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,106 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.linear; +019 +020 import org.apache.commons.math.optimization.OptimizationException; +021 +022 /** +023 * This class represents exceptions thrown by optimizers when no solution +024 * fulfills the constraints. +025 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +026 * @since 2.0 +027 */ +028 public class NoFeasibleSolutionException extends OptimizationException { +029 +030 /** Serializable version identifier. */ +031 private static final long serialVersionUID = -3044253632189082760L; +032 +033 /** +034 * Simple constructor using a default message. +035 */ +036 public NoFeasibleSolutionException() { +037 super("no feasible solution"); +038 } +039 +040 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/Relationship.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/Relationship.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,133 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.linear; +019 +020 /** +021 * Types of relationships between two cells in a Solver {@link LinearConstraint}. +022 * @version $Revision: 758920 $ $Date: 2009-03-26 19:25:30 -0400 (Thu, 26 Mar 2009) $ +023 * @since 2.0 +024 */ +025 public enum Relationship { +026 +027 /** Equality relationship. */ +028 EQ("="), +029 +030 /** Lesser than or equal relationship. */ +031 LEQ("<="), +032 +033 /** Greater than or equal relationship. */ +034 GEQ(">="); +035 +036 /** Display string for the relationship. */ +037 private String stringValue; +038 +039 /** Simple constructor. +040 * @param stringValue display string for the relationship +041 */ +042 private Relationship(String stringValue) { +043 this.stringValue = stringValue; +044 } +045 +046 /** {@inheritDoc} */ +047 @Override +048 public String toString() { +049 return stringValue; +050 } +051 +052 /** +053 * Get the relationship obtained when multiplying all coefficients by -1. +054 * @return relationship obtained when multiplying all coefficients by -1 +055 */ +056 public Relationship oppositeRelationship() { +057 switch (this) { +058 case LEQ : +059 return GEQ; +060 case GEQ : +061 return LEQ; +062 default : +063 return EQ; +064 } +065 } +066 +067 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/SimplexSolver.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/SimplexSolver.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,251 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.linear; +019 +020 import java.util.ArrayList; +021 import java.util.List; +022 +023 import org.apache.commons.math.optimization.OptimizationException; +024 import org.apache.commons.math.optimization.RealPointValuePair; +025 import org.apache.commons.math.util.MathUtils; +026 +027 +028 /** +029 * Solves a linear problem using the Two-Phase Simplex Method. +030 * @version $Revision: 812831 $ $Date: 2009-09-09 04:48:03 -0400 (Wed, 09 Sep 2009) $ +031 * @since 2.0 +032 */ +033 public class SimplexSolver extends AbstractLinearOptimizer { +034 +035 /** Default amount of error to accept in floating point comparisons. */ +036 private static final double DEFAULT_EPSILON = 1.0e-6; +037 +038 /** Amount of error to accept in floating point comparisons. */ +039 protected final double epsilon; +040 +041 /** +042 * Build a simplex solver with default settings. +043 */ +044 public SimplexSolver() { +045 this(DEFAULT_EPSILON); +046 } +047 +048 /** +049 * Build a simplex solver with a specified accepted amount of error +050 * @param epsilon the amount of error to accept in floating point comparisons +051 */ +052 public SimplexSolver(final double epsilon) { +053 this.epsilon = epsilon; +054 } +055 +056 /** +057 * Returns the column with the most negative coefficient in the objective function row. +058 * @param tableau simple tableau for the problem +059 * @return column with the most negative coefficient +060 */ +061 private Integer getPivotColumn(SimplexTableau tableau) { +062 double minValue = 0; +063 Integer minPos = null; +064 for (int i = tableau.getNumObjectiveFunctions(); i < tableau.getWidth() - 1; i++) { +065 if (MathUtils.compareTo(tableau.getEntry(0, i), minValue, epsilon) < 0) { +066 minValue = tableau.getEntry(0, i); +067 minPos = i; +068 } +069 } +070 return minPos; +071 } +072 +073 /** +074 * Returns the row with the minimum ratio as given by the minimum ratio test (MRT). +075 * @param tableau simple tableau for the problem +076 * @param col the column to test the ratio of. See {@link #getPivotColumn(SimplexTableau)} +077 * @return row with the minimum ratio +078 */ +079 private Integer getPivotRow(SimplexTableau tableau, final int col) { +080 // create a list of all the rows that tie for the lowest score in the minimum ratio test +081 List<Integer> minRatioPositions = new ArrayList<Integer>(); +082 double minRatio = Double.MAX_VALUE; +083 for (int i = tableau.getNumObjectiveFunctions(); i < tableau.getHeight(); i++) { +084 final double rhs = tableau.getEntry(i, tableau.getWidth() - 1); +085 final double entry = tableau.getEntry(i, col); +086 if (MathUtils.compareTo(entry, 0, epsilon) > 0) { +087 final double ratio = rhs / entry; +088 if (MathUtils.equals(ratio, minRatio, epsilon)) { +089 minRatioPositions.add(i); +090 } else if (ratio < minRatio) { +091 minRatio = ratio; +092 minRatioPositions = new ArrayList<Integer>(); +093 minRatioPositions.add(i); +094 } +095 } +096 } +097 +098 if (minRatioPositions.size() == 0) { +099 return null; +100 } else if (minRatioPositions.size() > 1) { +101 // there's a degeneracy as indicated by a tie in the minimum ratio test +102 // check if there's an artificial variable that can be forced out of the basis +103 for (Integer row : minRatioPositions) { +104 for (int i = 0; i < tableau.getNumArtificialVariables(); i++) { +105 int column = i + tableau.getArtificialVariableOffset(); +106 if (MathUtils.equals(tableau.getEntry(row, column), 1, epsilon) && +107 row.equals(tableau.getBasicRow(column))) { +108 return row; +109 } +110 } +111 } +112 } +113 return minRatioPositions.get(0); +114 } +115 +116 /** +117 * Runs one iteration of the Simplex method on the given model. +118 * @param tableau simple tableau for the problem +119 * @throws OptimizationException if the maximal iteration count has been +120 * exceeded or if the model is found not to have a bounded solution +121 */ +122 protected void doIteration(final SimplexTableau tableau) +123 throws OptimizationException { +124 +125 incrementIterationsCounter(); +126 +127 Integer pivotCol = getPivotColumn(tableau); +128 Integer pivotRow = getPivotRow(tableau, pivotCol); +129 if (pivotRow == null) { +130 throw new UnboundedSolutionException(); +131 } +132 +133 // set the pivot element to 1 +134 double pivotVal = tableau.getEntry(pivotRow, pivotCol); +135 tableau.divideRow(pivotRow, pivotVal); +136 +137 // set the rest of the pivot column to 0 +138 for (int i = 0; i < tableau.getHeight(); i++) { +139 if (i != pivotRow) { +140 double multiplier = tableau.getEntry(i, pivotCol); +141 tableau.subtractRow(i, pivotRow, multiplier); +142 } +143 } +144 } +145 +146 /** +147 * Solves Phase 1 of the Simplex method. +148 * @param tableau simple tableau for the problem +149 * @exception OptimizationException if the maximal number of iterations is +150 * exceeded, or if the problem is found not to have a bounded solution, or +151 * if there is no feasible solution +152 */ +153 protected void solvePhase1(final SimplexTableau tableau) throws OptimizationException { +154 +155 // make sure we're in Phase 1 +156 if (tableau.getNumArtificialVariables() == 0) { +157 return; +158 } +159 +160 while (!tableau.isOptimal()) { +161 doIteration(tableau); +162 } +163 +164 // if W is not zero then we have no feasible solution +165 if (!MathUtils.equals(tableau.getEntry(0, tableau.getRhsOffset()), 0, epsilon)) { +166 throw new NoFeasibleSolutionException(); +167 } +168 } +169 +170 /** {@inheritDoc} */ +171 @Override +172 public RealPointValuePair doOptimize() throws OptimizationException { +173 final SimplexTableau tableau = +174 new SimplexTableau(function, linearConstraints, goal, nonNegative, epsilon); +175 +176 solvePhase1(tableau); +177 tableau.dropPhase1Objective(); +178 +179 while (!tableau.isOptimal()) { +180 doIteration(tableau); +181 } +182 return tableau.getSolution(); +183 } +184 +185 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/UnboundedSolutionException.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/linear/UnboundedSolutionException.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,106 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.linear; +019 +020 import org.apache.commons.math.optimization.OptimizationException; +021 +022 /** +023 * This class represents exceptions thrown by optimizers when a solution +024 * escapes to infinity. +025 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +026 * @since 2.0 +027 */ +028 public class UnboundedSolutionException extends OptimizationException { +029 +030 /** Serializable version identifier. */ +031 private static final long serialVersionUID = 940539497277290619L; +032 +033 /** +034 * Simple constructor using a default message. +035 */ +036 public UnboundedSolutionException() { +037 super("unbounded solution"); +038 } +039 +040 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/univariate/AbstractUnivariateRealOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/univariate/AbstractUnivariateRealOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,209 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.optimization.univariate; +019 +020 import org.apache.commons.math.ConvergingAlgorithmImpl; +021 import org.apache.commons.math.FunctionEvaluationException; +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.MaxEvaluationsExceededException; +024 import org.apache.commons.math.analysis.UnivariateRealFunction; +025 import org.apache.commons.math.optimization.UnivariateRealOptimizer; +026 +027 /** +028 * Provide a default implementation for several functions useful to generic +029 * optimizers. +030 * +031 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +032 * @since 2.0 +033 */ +034 public abstract class AbstractUnivariateRealOptimizer +035 extends ConvergingAlgorithmImpl implements UnivariateRealOptimizer { +036 +037 /** Indicates where a root has been computed. */ +038 protected boolean resultComputed; +039 +040 /** The last computed root. */ +041 protected double result; +042 +043 /** Value of the function at the last computed result. */ +044 protected double functionValue; +045 +046 /** Maximal number of evaluations allowed. */ +047 private int maxEvaluations; +048 +049 /** Number of evaluations already performed. */ +050 private int evaluations; +051 +052 /** +053 * Construct a solver with given iteration count and accuracy. +054 * FunctionEvaluationExceptionFunctionEvaluationException +055 * @param defaultAbsoluteAccuracy maximum absolute error +056 * @param defaultMaximalIterationCount maximum number of iterations +057 * @throws IllegalArgumentException if f is null or the +058 * defaultAbsoluteAccuracy is not valid +059 */ +060 protected AbstractUnivariateRealOptimizer(final int defaultMaximalIterationCount, +061 final double defaultAbsoluteAccuracy) { +062 super(defaultMaximalIterationCount, defaultAbsoluteAccuracy); +063 resultComputed = false; +064 setMaxEvaluations(Integer.MAX_VALUE); +065 } +066 +067 /** Check if a result has been computed. +068 * @exception IllegalStateException if no result has been computed +069 */ +070 protected void checkResultComputed() throws IllegalStateException { +071 if (!resultComputed) { +072 throw MathRuntimeException.createIllegalStateException("no result available"); +073 } +074 } +075 +076 /** {@inheritDoc} */ +077 public double getResult() { +078 checkResultComputed(); +079 return result; +080 } +081 +082 /** {@inheritDoc} */ +083 public double getFunctionValue() { +084 checkResultComputed(); +085 return functionValue; +086 } +087 +088 /** +089 * Convenience function for implementations. +090 * +091 * @param x the result to set +092 * @param fx the result to set +093 * @param iterationCount the iteration count to set +094 */ +095 protected final void setResult(final double x, final double fx, +096 final int iterationCount) { +097 this.result = x; +098 this.functionValue = fx; +099 this.iterationCount = iterationCount; +100 this.resultComputed = true; +101 } +102 +103 /** +104 * Convenience function for implementations. +105 */ +106 protected final void clearResult() { +107 this.resultComputed = false; +108 } +109 +110 /** {@inheritDoc} */ +111 public void setMaxEvaluations(int maxEvaluations) { +112 this.maxEvaluations = maxEvaluations; +113 } +114 +115 /** {@inheritDoc} */ +116 public int getMaxEvaluations() { +117 return maxEvaluations; +118 } +119 +120 /** {@inheritDoc} */ +121 public int getEvaluations() { +122 return evaluations; +123 } +124 +125 /** +126 * Compute the objective function value. +127 * @param f objective function +128 * @param point point at which the objective function must be evaluated +129 * @return objective function value at specified point +130 * @exception FunctionEvaluationException if the function cannot be evaluated +131 * or the maximal number of iterations is exceeded +132 */ +133 protected double computeObjectiveValue(final UnivariateRealFunction f, +134 final double point) +135 throws FunctionEvaluationException { +136 if (++evaluations > maxEvaluations) { +137 throw new FunctionEvaluationException(new MaxEvaluationsExceededException(maxEvaluations), +138 point); +139 } +140 return f.value(point); +141 } +142 +143 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/univariate/BrentOptimizer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/univariate/BrentOptimizer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,257 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.optimization.univariate; +018 +019 import org.apache.commons.math.FunctionEvaluationException; +020 import org.apache.commons.math.MaxIterationsExceededException; +021 import org.apache.commons.math.analysis.UnivariateRealFunction; +022 import org.apache.commons.math.optimization.GoalType; +023 +024 /** +025 * Implements Richard Brent's algorithm (from his book "Algorithms for +026 * Minimization without Derivatives", p. 79) for finding minima of real +027 * univariate functions. +028 * +029 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +030 * @since 2.0 +031 */ +032 public class BrentOptimizer extends AbstractUnivariateRealOptimizer { +033 +034 /** +035 * Golden section. +036 */ +037 private static final double GOLDEN_SECTION = 0.5 * (3 - Math.sqrt(5)); +038 +039 /** +040 * Construct a solver. +041 */ +042 public BrentOptimizer() { +043 super(100, 1E-10); +044 } +045 +046 /** {@inheritDoc} */ +047 public double optimize(final UnivariateRealFunction f, final GoalType goalType, +048 final double min, final double max, final double startValue) +049 throws MaxIterationsExceededException, FunctionEvaluationException { +050 return optimize(f, goalType, min, max); +051 } +052 +053 /** {@inheritDoc} */ +054 public double optimize(final UnivariateRealFunction f, final GoalType goalType, +055 final double min, final double max) +056 throws MaxIterationsExceededException, FunctionEvaluationException { +057 clearResult(); +058 return localMin(f, goalType, min, max, relativeAccuracy, absoluteAccuracy); +059 } +060 +061 /** +062 * Find the minimum of the function {@code f} within the interval {@code (a, b)}. +063 * +064 * If the function {@code f} is defined on the interval {@code (a, b)}, then +065 * this method finds an approximation {@code x} to the point at which {@code f} +066 * attains its minimum.<br/> +067 * {@code t} and {@code eps} define a tolerance {@code tol = eps |x| + t} and +068 * {@code f} is never evaluated at two points closer together than {@code tol}. +069 * {@code eps} should be no smaller than <em>2 macheps</em> and preferable not +070 * much less than <em>sqrt(macheps)</em>, where <em>macheps</em> is the relative +071 * machine precision. {@code t} should be positive. +072 * @param f the function to solve +073 * @param goalType type of optimization goal: either {@link GoalType#MAXIMIZE} +074 * or {@link GoalType#MINIMIZE} +075 * @param a Lower bound of the interval +076 * @param b Higher bound of the interval +077 * @param eps Relative accuracy +078 * @param t Absolute accuracy +079 * @return the point at which the function is minimal. +080 * @throws MaxIterationsExceededException if the maximum iteration count +081 * is exceeded. +082 * @throws FunctionEvaluationException if an error occurs evaluating +083 * the function. +084 */ +085 private double localMin(final UnivariateRealFunction f, final GoalType goalType, +086 double a, double b, final double eps, final double t) +087 throws MaxIterationsExceededException, FunctionEvaluationException { +088 double x = a + GOLDEN_SECTION * (b - a); +089 double v = x; +090 double w = x; +091 double e = 0; +092 double fx = computeObjectiveValue(f, x); +093 if (goalType == GoalType.MAXIMIZE) { +094 fx = -fx; +095 } +096 double fv = fx; +097 double fw = fx; +098 +099 int count = 0; +100 while (count < maximalIterationCount) { +101 double m = 0.5 * (a + b); +102 double tol = eps * Math.abs(x) + t; +103 double t2 = 2 * tol; +104 +105 // Check stopping criterion. +106 if (Math.abs(x - m) > t2 - 0.5 * (b - a)) { +107 double p = 0; +108 double q = 0; +109 double r = 0; +110 double d = 0; +111 double u = 0; +112 +113 if (Math.abs(e) > tol) { // Fit parabola. +114 r = (x - w) * (fx - fv); +115 q = (x - v) * (fx - fw); +116 p = (x - v) * q - (x - w) * r; +117 q = 2 * (q - r); +118 +119 if (q > 0) { +120 p = -p; +121 } else { +122 q = -q; +123 } +124 +125 r = e; +126 e = d; +127 } +128 +129 if (Math.abs(p) < Math.abs(0.5 * q * r) && +130 (p < q * (a - x)) && (p < q * (b - x))) { // Parabolic interpolation step. +131 d = p / q; +132 u = x + d; +133 +134 // f must not be evaluated too close to a or b. +135 if (((u - a) < t2) || ((b - u) < t2)) { +136 d = (x < m) ? tol : -tol; +137 } +138 } else { // Golden section step. +139 e = ((x < m) ? b : a) - x; +140 d = GOLDEN_SECTION * e; +141 } +142 +143 // f must not be evaluated too close to a or b. +144 u = x + ((Math.abs(d) > tol) ? d : ((d > 0) ? tol : -tol)); +145 double fu = computeObjectiveValue(f, u); +146 if (goalType == GoalType.MAXIMIZE) { +147 fu = -fu; +148 } +149 +150 // Update a, b, v, w and x. +151 if (fu <= fx) { +152 if (u < x) { +153 b = x; +154 } else { +155 a = x; +156 } +157 v = w; +158 fv = fw; +159 w = x; +160 fw = fx; +161 x = u; +162 fx = fu; +163 } else { +164 if (u < x) { +165 a = u; +166 } else { +167 b = u; +168 } +169 if ((fu <= fw) || (w == x)) { +170 v = w; +171 fv = fw; +172 w = u; +173 fw = fu; +174 } else if ((fu <= fv) || (v == x) || (v == w)) { +175 v = u; +176 fv = fu; +177 } +178 } +179 } else { // termination +180 setResult(x, (goalType == GoalType.MAXIMIZE) ? -fx : fx, count); +181 return x; +182 } +183 +184 ++count; +185 } +186 +187 throw new MaxIterationsExceededException(maximalIterationCount); +188 +189 } +190 +191 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/AbstractRandomGenerator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/AbstractRandomGenerator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,338 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.random; +018 +019 import org.apache.commons.math.MathRuntimeException; +020 +021 /** +022 * Abstract class implementing the {@link RandomGenerator} interface. +023 * Default implementations for all methods other than {@link #nextDouble()} and +024 * {@link #setSeed(long)} are provided. +025 * <p> +026 * All data generation methods are based on <code>nextDouble().</code> +027 * Concrete implementations <strong>must</strong> override +028 * this method and <strong>should</strong> provide better / more +029 * performant implementations of the other methods if the underlying PRNG +030 * supplies them.</p> +031 * +032 * @since 1.1 +033 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +034 */ +035 public abstract class AbstractRandomGenerator implements RandomGenerator { +036 +037 /** +038 * Cached random normal value. The default implementation for +039 * {@link #nextGaussian} generates pairs of values and this field caches the +040 * second value so that the full algorithm is not executed for every +041 * activation. The value <code>Double.NaN</code> signals that there is +042 * no cached value. Use {@link #clear} to clear the cached value. +043 */ +044 private double cachedNormalDeviate = Double.NaN; +045 +046 /** +047 * Construct a RandomGenerator. +048 */ +049 public AbstractRandomGenerator() { +050 super(); +051 +052 } +053 +054 /** +055 * Clears the cache used by the default implementation of +056 * {@link #nextGaussian}. Implemementations that do not override the +057 * default implementation of <code>nextGaussian</code> should call this +058 * method in the implementation of {@link #setSeed(long)} +059 */ +060 public void clear() { +061 cachedNormalDeviate = Double.NaN; +062 } +063 +064 /** {@inheritDoc} */ +065 public void setSeed(int seed) { +066 setSeed((long) seed); +067 } +068 +069 /** {@inheritDoc} */ +070 public void setSeed(int[] seed) { +071 // the following number is the largest prime that fits in 32 bits (it is 2^32 - 5) +072 final long prime = 4294967291l; +073 +074 long combined = 0l; +075 for (int s : seed) { +076 combined = combined * prime + s; +077 } +078 setSeed(combined); +079 } +080 +081 /** +082 * Sets the seed of the underyling random number generator using a +083 * <code>long</code> seed. Sequences of values generated starting with the +084 * same seeds should be identical. +085 * <p> +086 * Implementations that do not override the default implementation of +087 * <code>nextGaussian</code> should include a call to {@link #clear} in the +088 * implementation of this method.</p> +089 * +090 * @param seed the seed value +091 */ +092 public abstract void setSeed(long seed); +093 +094 /** +095 * Generates random bytes and places them into a user-supplied +096 * byte array. The number of random bytes produced is equal to +097 * the length of the byte array. +098 * <p> +099 * The default implementation fills the array with bytes extracted from +100 * random integers generated using {@link #nextInt}.</p> +101 * +102 * @param bytes the non-null byte array in which to put the +103 * random bytes +104 */ +105 public void nextBytes(byte[] bytes) { +106 int bytesOut = 0; +107 while (bytesOut < bytes.length) { +108 int randInt = nextInt(); +109 for (int i = 0; i < 3; i++) { +110 if ( i > 0) { +111 randInt = randInt >> 8; +112 } +113 bytes[bytesOut++] = (byte) randInt; +114 if (bytesOut == bytes.length) { +115 return; +116 } +117 } +118 } +119 } +120 +121 /** +122 * Returns the next pseudorandom, uniformly distributed <code>int</code> +123 * value from this random number generator's sequence. +124 * All 2<font size="-1"><sup>32</sup></font> possible <tt>int</tt> values +125 * should be produced with (approximately) equal probability. +126 * <p> +127 * The default implementation provided here returns +128 * <pre> +129 * <code>(int) (nextDouble() * Integer.MAX_VALUE)</code> +130 * </pre></p> +131 * +132 * @return the next pseudorandom, uniformly distributed <code>int</code> +133 * value from this random number generator's sequence +134 */ +135 public int nextInt() { +136 return (int) (nextDouble() * Integer.MAX_VALUE); +137 } +138 +139 /** +140 * Returns a pseudorandom, uniformly distributed <tt>int</tt> value +141 * between 0 (inclusive) and the specified value (exclusive), drawn from +142 * this random number generator's sequence. +143 * <p> +144 * The default implementation returns +145 * <pre> +146 * <code>(int) (nextDouble() * n</code> +147 * </pre></p> +148 * +149 * @param n the bound on the random number to be returned. Must be +150 * positive. +151 * @return a pseudorandom, uniformly distributed <tt>int</tt> +152 * value between 0 (inclusive) and n (exclusive). +153 * @throws IllegalArgumentException if n is not positive. +154 */ +155 public int nextInt(int n) { +156 if (n <= 0 ) { +157 throw MathRuntimeException.createIllegalArgumentException( +158 "upper bound must be positive ({0})", n); +159 } +160 int result = (int) (nextDouble() * n); +161 return result < n ? result : n - 1; +162 } +163 +164 /** +165 * Returns the next pseudorandom, uniformly distributed <code>long</code> +166 * value from this random number generator's sequence. All +167 * 2<font size="-1"><sup>64</sup></font> possible <tt>long</tt> values +168 * should be produced with (approximately) equal probability. +169 * <p> +170 * The default implementation returns +171 * <pre> +172 * <code>(long) (nextDouble() * Long.MAX_VALUE)</code> +173 * </pre></p> +174 * +175 * @return the next pseudorandom, uniformly distributed <code>long</code> +176 *value from this random number generator's sequence +177 */ +178 public long nextLong() { +179 return (long) (nextDouble() * Long.MAX_VALUE); +180 } +181 +182 /** +183 * Returns the next pseudorandom, uniformly distributed +184 * <code>boolean</code> value from this random number generator's +185 * sequence. +186 * <p> +187 * The default implementation returns +188 * <pre> +189 * <code>nextDouble() <= 0.5</code> +190 * </pre></p> +191 * +192 * @return the next pseudorandom, uniformly distributed +193 * <code>boolean</code> value from this random number generator's +194 * sequence +195 */ +196 public boolean nextBoolean() { +197 return nextDouble() <= 0.5; +198 } +199 +200 /** +201 * Returns the next pseudorandom, uniformly distributed <code>float</code> +202 * value between <code>0.0</code> and <code>1.0</code> from this random +203 * number generator's sequence. +204 * <p> +205 * The default implementation returns +206 * <pre> +207 * <code>(float) nextDouble() </code> +208 * </pre></p> +209 * +210 * @return the next pseudorandom, uniformly distributed <code>float</code> +211 * value between <code>0.0</code> and <code>1.0</code> from this +212 * random number generator's sequence +213 */ +214 public float nextFloat() { +215 return (float) nextDouble(); +216 } +217 +218 /** +219 * Returns the next pseudorandom, uniformly distributed +220 * <code>double</code> value between <code>0.0</code> and +221 * <code>1.0</code> from this random number generator's sequence. +222 * <p> +223 * This method provides the underlying source of random data used by the +224 * other methods.</p> +225 * +226 * @return the next pseudorandom, uniformly distributed +227 * <code>double</code> value between <code>0.0</code> and +228 * <code>1.0</code> from this random number generator's sequence +229 */ +230 public abstract double nextDouble(); +231 +232 /** +233 * Returns the next pseudorandom, Gaussian ("normally") distributed +234 * <code>double</code> value with mean <code>0.0</code> and standard +235 * deviation <code>1.0</code> from this random number generator's sequence. +236 * <p> +237 * The default implementation uses the <em>Polar Method</em> +238 * due to G.E.P. Box, M.E. Muller and G. Marsaglia, as described in +239 * D. Knuth, <u>The Art of Computer Programming</u>, 3.4.1C.</p> +240 * <p> +241 * The algorithm generates a pair of independent random values. One of +242 * these is cached for reuse, so the full algorithm is not executed on each +243 * activation. Implementations that do not override this method should +244 * make sure to call {@link #clear} to clear the cached value in the +245 * implementation of {@link #setSeed(long)}.</p> +246 * +247 * @return the next pseudorandom, Gaussian ("normally") distributed +248 * <code>double</code> value with mean <code>0.0</code> and +249 * standard deviation <code>1.0</code> from this random number +250 * generator's sequence +251 */ +252 public double nextGaussian() { +253 if (!Double.isNaN(cachedNormalDeviate)) { +254 double dev = cachedNormalDeviate; +255 cachedNormalDeviate = Double.NaN; +256 return dev; +257 } +258 double v1 = 0; +259 double v2 = 0; +260 double s = 1; +261 while (s >=1 ) { +262 v1 = 2 * nextDouble() - 1; +263 v2 = 2 * nextDouble() - 1; +264 s = v1 * v1 + v2 * v2; +265 } +266 if (s != 0) { +267 s = Math.sqrt(-2 * Math.log(s) / s); +268 } +269 cachedNormalDeviate = v2 * s; +270 return v1 * s; +271 } +272 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/BitsStreamGenerator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/BitsStreamGenerator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,219 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.random; +018 +019 import org.apache.commons.math.MathRuntimeException; +020 +021 /** Base class for random number generators that generates bits streams. +022 +023 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +024 * @since 2.0 +025 +026 */ +027 public abstract class BitsStreamGenerator implements RandomGenerator { +028 +029 /** Next gaussian. */ +030 private double nextGaussian; +031 +032 /** Creates a new random number generator. +033 */ +034 public BitsStreamGenerator() { +035 nextGaussian = Double.NaN; +036 } +037 +038 /** {@inheritDoc} */ +039 public abstract void setSeed(int seed); +040 +041 /** {@inheritDoc} */ +042 public abstract void setSeed(int[] seed); +043 +044 /** {@inheritDoc} */ +045 public abstract void setSeed(long seed); +046 +047 /** Generate next pseudorandom number. +048 * <p>This method is the core generation algorithm. It is used by all the +049 * public generation methods for the various primitive types {@link +050 * #nextBoolean()}, {@link #nextBytes(byte[])}, {@link #nextDouble()}, +051 * {@link #nextFloat()}, {@link #nextGaussian()}, {@link #nextInt()}, +052 * {@link #next(int)} and {@link #nextLong()}.</p> +053 * @param bits number of random bits to produce +054 * @return random bits generated +055 */ +056 protected abstract int next(int bits); +057 +058 /** {@inheritDoc} */ +059 public boolean nextBoolean() { +060 return next(1) != 0; +061 } +062 +063 /** {@inheritDoc} */ +064 public void nextBytes(byte[] bytes) { +065 int i = 0; +066 final int iEnd = bytes.length - 3; +067 while (i < iEnd) { +068 final int random = next(32); +069 bytes[i] = (byte) (random & 0xff); +070 bytes[i + 1] = (byte) ((random >> 8) & 0xff); +071 bytes[i + 2] = (byte) ((random >> 16) & 0xff); +072 bytes[i + 3] = (byte) ((random >> 24) & 0xff); +073 i += 4; +074 } +075 int random = next(32); +076 while (i < bytes.length) { +077 bytes[i++] = (byte) (random & 0xff); +078 random = random >> 8; +079 } +080 } +081 +082 /** {@inheritDoc} */ +083 public double nextDouble() { +084 final long high = ((long) next(26)) << 26; +085 final int low = next(26); +086 return (high | low) * 0x1.0p-52d; +087 } +088 +089 /** {@inheritDoc} */ +090 public float nextFloat() { +091 return next(23) * 0x1.0p-23f; +092 } +093 +094 /** {@inheritDoc} */ +095 public double nextGaussian() { +096 +097 final double random; +098 if (Double.isNaN(nextGaussian)) { +099 // generate a new pair of gaussian numbers +100 final double x = nextDouble(); +101 final double y = nextDouble(); +102 final double alpha = 2 * Math.PI * x; +103 final double r = Math.sqrt(-2 * Math.log(y)); +104 random = r * Math.cos(alpha); +105 nextGaussian = r * Math.sin(alpha); +106 } else { +107 // use the second element of the pair already generated +108 random = nextGaussian; +109 nextGaussian = Double.NaN; +110 } +111 +112 return random; +113 +114 } +115 +116 /** {@inheritDoc} */ +117 public int nextInt() { +118 return next(32); +119 } +120 +121 /** {@inheritDoc} */ +122 public int nextInt(int n) throws IllegalArgumentException { +123 +124 if (n < 1) { +125 throw MathRuntimeException.createIllegalArgumentException( +126 "upper bound must be positive ({0})", n); +127 } +128 +129 // find bit mask for n +130 int mask = n; +131 mask |= mask >> 1; +132 mask |= mask >> 2; +133 mask |= mask >> 4; +134 mask |= mask >> 8; +135 mask |= mask >> 16; +136 +137 while (true) { +138 final int random = next(32) & mask; +139 if (random < n) { +140 return random; +141 } +142 } +143 +144 } +145 +146 /** {@inheritDoc} */ +147 public long nextLong() { +148 final long high = ((long) next(32)) << 32; +149 final long low = ((long) next(32)) & 0xffffffffL; +150 return high | low; +151 } +152 +153 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/CorrelatedRandomVectorGenerator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/CorrelatedRandomVectorGenerator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,369 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.random; +019 +020 import org.apache.commons.math.DimensionMismatchException; +021 import org.apache.commons.math.linear.MatrixUtils; +022 import org.apache.commons.math.linear.NotPositiveDefiniteMatrixException; +023 import org.apache.commons.math.linear.RealMatrix; +024 +025 /** +026 * A {@link RandomVectorGenerator} that generates vectors with with +027 * correlated components. +028 * <p>Random vectors with correlated components are built by combining +029 * the uncorrelated components of another random vector in such a way that +030 * the resulting correlations are the ones specified by a positive +031 * definite covariance matrix.</p> +032 * <p>The main use for correlated random vector generation is for Monte-Carlo +033 * simulation of physical problems with several variables, for example to +034 * generate error vectors to be added to a nominal vector. A particularly +035 * interesting case is when the generated vector should be drawn from a <a +036 * href="http://en.wikipedia.org/wiki/Multivariate_normal_distribution"> +037 * Multivariate Normal Distribution</a>. The approach using a Cholesky +038 * decomposition is quite usual in this case. However, it cas be extended +039 * to other cases as long as the underlying random generator provides +040 * {@link NormalizedRandomGenerator normalized values} like {@link +041 * GaussianRandomGenerator} or {@link UniformRandomGenerator}.</p> +042 * <p>Sometimes, the covariance matrix for a given simulation is not +043 * strictly positive definite. This means that the correlations are +044 * not all independent from each other. In this case, however, the non +045 * strictly positive elements found during the Cholesky decomposition +046 * of the covariance matrix should not be negative either, they +047 * should be null. Another non-conventional extension handling this case +048 * is used here. Rather than computing <code>C = U<sup>T</sup>.U</code> +049 * where <code>C</code> is the covariance matrix and <code>U</code> +050 * is an uppertriangular matrix, we compute <code>C = B.B<sup>T</sup></code> +051 * where <code>B</code> is a rectangular matrix having +052 * more rows than columns. The number of columns of <code>B</code> is +053 * the rank of the covariance matrix, and it is the dimension of the +054 * uncorrelated random vector that is needed to compute the component +055 * of the correlated vector. This class handles this situation +056 * automatically.</p> +057 * +058 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +059 * @since 1.2 +060 */ +061 +062 public class CorrelatedRandomVectorGenerator +063 implements RandomVectorGenerator { +064 +065 /** Mean vector. */ +066 private final double[] mean; +067 +068 /** Underlying generator. */ +069 private final NormalizedRandomGenerator generator; +070 +071 /** Storage for the normalized vector. */ +072 private final double[] normalized; +073 +074 /** Permutated Cholesky root of the covariance matrix. */ +075 private RealMatrix root; +076 +077 /** Rank of the covariance matrix. */ +078 private int rank; +079 +080 /** Simple constructor. +081 * <p>Build a correlated random vector generator from its mean +082 * vector and covariance matrix.</p> +083 * @param mean expected mean values for all components +084 * @param covariance covariance matrix +085 * @param small diagonal elements threshold under which column are +086 * considered to be dependent on previous ones and are discarded +087 * @param generator underlying generator for uncorrelated normalized +088 * components +089 * @exception IllegalArgumentException if there is a dimension +090 * mismatch between the mean vector and the covariance matrix +091 * @exception NotPositiveDefiniteMatrixException if the +092 * covariance matrix is not strictly positive definite +093 * @exception DimensionMismatchException if the mean and covariance +094 * arrays dimensions don't match +095 */ +096 public CorrelatedRandomVectorGenerator(double[] mean, +097 RealMatrix covariance, double small, +098 NormalizedRandomGenerator generator) +099 throws NotPositiveDefiniteMatrixException, DimensionMismatchException { +100 +101 int order = covariance.getRowDimension(); +102 if (mean.length != order) { +103 throw new DimensionMismatchException(mean.length, order); +104 } +105 this.mean = mean.clone(); +106 +107 decompose(covariance, small); +108 +109 this.generator = generator; +110 normalized = new double[rank]; +111 +112 } +113 +114 /** Simple constructor. +115 * <p>Build a null mean random correlated vector generator from its +116 * covariance matrix.</p> +117 * @param covariance covariance matrix +118 * @param small diagonal elements threshold under which column are +119 * considered to be dependent on previous ones and are discarded +120 * @param generator underlying generator for uncorrelated normalized +121 * components +122 * @exception NotPositiveDefiniteMatrixException if the +123 * covariance matrix is not strictly positive definite +124 */ +125 public CorrelatedRandomVectorGenerator(RealMatrix covariance, double small, +126 NormalizedRandomGenerator generator) +127 throws NotPositiveDefiniteMatrixException { +128 +129 int order = covariance.getRowDimension(); +130 mean = new double[order]; +131 for (int i = 0; i < order; ++i) { +132 mean[i] = 0; +133 } +134 +135 decompose(covariance, small); +136 +137 this.generator = generator; +138 normalized = new double[rank]; +139 +140 } +141 +142 /** Get the underlying normalized components generator. +143 * @return underlying uncorrelated components generator +144 */ +145 public NormalizedRandomGenerator getGenerator() { +146 return generator; +147 } +148 +149 /** Get the root of the covariance matrix. +150 * The root is the rectangular matrix <code>B</code> such that +151 * the covariance matrix is equal to <code>B.B<sup>T</sup></code> +152 * @return root of the square matrix +153 * @see #getRank() +154 */ +155 public RealMatrix getRootMatrix() { +156 return root; +157 } +158 +159 /** Get the rank of the covariance matrix. +160 * The rank is the number of independent rows in the covariance +161 * matrix, it is also the number of columns of the rectangular +162 * matrix of the decomposition. +163 * @return rank of the square matrix. +164 * @see #getRootMatrix() +165 */ +166 public int getRank() { +167 return rank; +168 } +169 +170 /** Decompose the original square matrix. +171 * <p>The decomposition is based on a Choleski decomposition +172 * where additional transforms are performed: +173 * <ul> +174 * <li>the rows of the decomposed matrix are permuted</li> +175 * <li>columns with the too small diagonal element are discarded</li> +176 * <li>the matrix is permuted</li> +177 * </ul> +178 * This means that rather than computing M = U<sup>T</sup>.U where U +179 * is an upper triangular matrix, this method computed M=B.B<sup>T</sup> +180 * where B is a rectangular matrix. +181 * @param covariance covariance matrix +182 * @param small diagonal elements threshold under which column are +183 * considered to be dependent on previous ones and are discarded +184 * @exception NotPositiveDefiniteMatrixException if the +185 * covariance matrix is not strictly positive definite +186 */ +187 private void decompose(RealMatrix covariance, double small) +188 throws NotPositiveDefiniteMatrixException { +189 +190 int order = covariance.getRowDimension(); +191 double[][] c = covariance.getData(); +192 double[][] b = new double[order][order]; +193 +194 int[] swap = new int[order]; +195 int[] index = new int[order]; +196 for (int i = 0; i < order; ++i) { +197 index[i] = i; +198 } +199 +200 rank = 0; +201 for (boolean loop = true; loop;) { +202 +203 // find maximal diagonal element +204 swap[rank] = rank; +205 for (int i = rank + 1; i < order; ++i) { +206 int ii = index[i]; +207 int isi = index[swap[i]]; +208 if (c[ii][ii] > c[isi][isi]) { +209 swap[rank] = i; +210 } +211 } +212 +213 +214 // swap elements +215 if (swap[rank] != rank) { +216 int tmp = index[rank]; +217 index[rank] = index[swap[rank]]; +218 index[swap[rank]] = tmp; +219 } +220 +221 // check diagonal element +222 int ir = index[rank]; +223 if (c[ir][ir] < small) { +224 +225 if (rank == 0) { +226 throw new NotPositiveDefiniteMatrixException(); +227 } +228 +229 // check remaining diagonal elements +230 for (int i = rank; i < order; ++i) { +231 if (c[index[i]][index[i]] < -small) { +232 // there is at least one sufficiently negative diagonal element, +233 // the covariance matrix is wrong +234 throw new NotPositiveDefiniteMatrixException(); +235 } +236 } +237 +238 // all remaining diagonal elements are close to zero, +239 // we consider we have found the rank of the covariance matrix +240 ++rank; +241 loop = false; +242 +243 } else { +244 +245 // transform the matrix +246 double sqrt = Math.sqrt(c[ir][ir]); +247 b[rank][rank] = sqrt; +248 double inverse = 1 / sqrt; +249 for (int i = rank + 1; i < order; ++i) { +250 int ii = index[i]; +251 double e = inverse * c[ii][ir]; +252 b[i][rank] = e; +253 c[ii][ii] -= e * e; +254 for (int j = rank + 1; j < i; ++j) { +255 int ij = index[j]; +256 double f = c[ii][ij] - e * b[j][rank]; +257 c[ii][ij] = f; +258 c[ij][ii] = f; +259 } +260 } +261 +262 // prepare next iteration +263 loop = ++rank < order; +264 +265 } +266 +267 } +268 +269 // build the root matrix +270 root = MatrixUtils.createRealMatrix(order, rank); +271 for (int i = 0; i < order; ++i) { +272 for (int j = 0; j < rank; ++j) { +273 root.setEntry(index[i], j, b[i][j]); +274 } +275 } +276 +277 } +278 +279 /** Generate a correlated random vector. +280 * @return a random vector as an array of double. The returned array +281 * is created at each call, the caller can do what it wants with it. +282 */ +283 public double[] nextVector() { +284 +285 // generate uncorrelated vector +286 for (int i = 0; i < rank; ++i) { +287 normalized[i] = generator.nextNormalizedDouble(); +288 } +289 +290 // compute correlated vector +291 double[] correlated = new double[mean.length]; +292 for (int i = 0; i < correlated.length; ++i) { +293 correlated[i] = mean[i]; +294 for (int j = 0; j < rank; ++j) { +295 correlated[i] += root.getEntry(i, j) * normalized[j]; +296 } +297 } +298 +299 return correlated; +300 +301 } +302 +303 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/EmpiricalDistribution.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/EmpiricalDistribution.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,199 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.random; +019 +020 import java.io.IOException; +021 import java.io.File; +022 import java.net.URL; +023 import java.util.List; +024 +025 import org.apache.commons.math.stat.descriptive.StatisticalSummary; +026 import org.apache.commons.math.stat.descriptive.SummaryStatistics; +027 +028 /** +029 * Represents an <a href="http://random.mat.sbg.ac.at/~ste/dipl/node11.html"> +030 * empirical probability distribution</a> -- a probability distribution derived +031 * from observed data without making any assumptions about the functional form +032 * of the population distribution that the data come from.<p> +033 * Implementations of this interface maintain data structures, called +034 * <i>distribution digests</i>, that describe empirical distributions and +035 * support the following operations: <ul> +036 * <li>loading the distribution from a file of observed data values</li> +037 * <li>dividing the input data into "bin ranges" and reporting bin frequency +038 * counts (data for histogram)</li> +039 * <li>reporting univariate statistics describing the full set of data values +040 * as well as the observations within each bin</li> +041 * <li>generating random values from the distribution</li> +042 * </ul> +043 * Applications can use <code>EmpiricalDistribution</code> implementations to +044 * build grouped frequency histograms representing the input data or to +045 * generate random values "like" those in the input file -- i.e., the values +046 * generated will follow the distribution of the values in the file.</p> +047 * +048 * @version $Revision: 817128 $ $Date: 2009-09-20 21:30:53 -0400 (Sun, 20 Sep 2009) $ +049 */ +050 public interface EmpiricalDistribution { +051 +052 /** +053 * Computes the empirical distribution from the provided +054 * array of numbers. +055 * +056 * @param dataArray the data array +057 */ +058 void load(double[] dataArray); +059 +060 /** +061 * Computes the empirical distribution from the input file. +062 * +063 * @param file the input file +064 * @throws IOException if an IO error occurs +065 */ +066 void load(File file) throws IOException; +067 +068 /** +069 * Computes the empirical distribution using data read from a URL. +070 * +071 * @param url url of the input file +072 * @throws IOException if an IO error occurs +073 */ +074 void load(URL url) throws IOException; +075 +076 /** +077 * Generates a random value from this distribution. +078 * <strong>Preconditions:</strong><ul> +079 * <li>the distribution must be loaded before invoking this method</li></ul> +080 * @return the random value. +081 * +082 * @throws IllegalStateException if the distribution has not been loaded +083 */ +084 double getNextValue() throws IllegalStateException; +085 +086 +087 /** +088 * Returns a +089 * {@link org.apache.commons.math.stat.descriptive.StatisticalSummary} +090 * describing this distribution. +091 * <strong>Preconditions:</strong><ul> +092 * <li>the distribution must be loaded before invoking this method</li> +093 * </ul> +094 * +095 * @return the sample statistics +096 * @throws IllegalStateException if the distribution has not been loaded +097 */ +098 StatisticalSummary getSampleStats() throws IllegalStateException; +099 +100 /** +101 * Property indicating whether or not the distribution has been loaded. +102 * +103 * @return true if the distribution has been loaded +104 */ +105 boolean isLoaded(); +106 +107 /** +108 * Returns the number of bins. +109 * +110 * @return the number of bins +111 */ +112 int getBinCount(); +113 +114 /** +115 * Returns a list of +116 * {@link org.apache.commons.math.stat.descriptive.SummaryStatistics} +117 * containing statistics describing the values in each of the bins. The +118 * List is indexed on the bin number. +119 * +120 * @return List of bin statistics +121 */ +122 List<SummaryStatistics> getBinStats(); +123 +124 /** +125 * Returns the array of upper bounds for the bins. Bins are: <br/> +126 * [min,upperBounds[0]],(upperBounds[0],upperBounds[1]],..., +127 * (upperBounds[binCount-2], upperBounds[binCount-1] = max]. +128 * +129 * @return array of bin upper bounds +130 */ +131 double[] getUpperBounds(); +132 +133 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/EmpiricalDistributionImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/EmpiricalDistributionImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,543 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.random; +019 +020 import java.io.BufferedReader; +021 import java.io.File; +022 import java.io.FileReader; +023 import java.io.IOException; +024 import java.io.InputStreamReader; +025 import java.io.Serializable; +026 import java.net.URL; +027 import java.util.ArrayList; +028 import java.util.List; +029 +030 import org.apache.commons.math.MathRuntimeException; +031 import org.apache.commons.math.stat.descriptive.StatisticalSummary; +032 import org.apache.commons.math.stat.descriptive.SummaryStatistics; +033 +034 /** +035 * Implements <code>EmpiricalDistribution</code> interface. This implementation +036 * uses what amounts to the +037 * <a href="http://nedwww.ipac.caltech.edu/level5/March02/Silverman/Silver2_6.html"> +038 * Variable Kernel Method</a> with Gaussian smoothing:<p> +039 * <strong>Digesting the input file</strong> +040 * <ol><li>Pass the file once to compute min and max.</li> +041 * <li>Divide the range from min-max into <code>binCount</code> "bins."</li> +042 * <li>Pass the data file again, computing bin counts and univariate +043 * statistics (mean, std dev.) for each of the bins </li> +044 * <li>Divide the interval (0,1) into subintervals associated with the bins, +045 * with the length of a bin's subinterval proportional to its count.</li></ol> +046 * <strong>Generating random values from the distribution</strong><ol> +047 * <li>Generate a uniformly distributed value in (0,1) </li> +048 * <li>Select the subinterval to which the value belongs. +049 * <li>Generate a random Gaussian value with mean = mean of the associated +050 * bin and std dev = std dev of associated bin.</li></ol></p><p> +051 *<strong>USAGE NOTES:</strong><ul> +052 *<li>The <code>binCount</code> is set by default to 1000. A good rule of thumb +053 * is to set the bin count to approximately the length of the input file divided +054 * by 10. </li> +055 *<li>The input file <i>must</i> be a plain text file containing one valid numeric +056 * entry per line.</li> +057 * </ul></p> +058 * +059 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +060 */ +061 public class EmpiricalDistributionImpl implements Serializable, EmpiricalDistribution { +062 +063 /** Serializable version identifier */ +064 private static final long serialVersionUID = 5729073523949762654L; +065 +066 /** List of SummaryStatistics objects characterizing the bins */ +067 private List<SummaryStatistics> binStats = null; +068 +069 /** Sample statistics */ +070 private SummaryStatistics sampleStats = null; +071 +072 /** Max loaded value */ +073 private double max = Double.NEGATIVE_INFINITY; +074 +075 /** Min loaded value */ +076 private double min = Double.POSITIVE_INFINITY; +077 +078 /** Grid size */ +079 private double delta = 0d; +080 +081 /** number of bins */ +082 private int binCount = 1000; +083 +084 /** is the distribution loaded? */ +085 private boolean loaded = false; +086 +087 /** upper bounds of subintervals in (0,1) "belonging" to the bins */ +088 private double[] upperBounds = null; +089 +090 /** RandomData instance to use in repeated calls to getNext() */ +091 private RandomData randomData = new RandomDataImpl(); +092 +093 /** +094 * Creates a new EmpiricalDistribution with the default bin count. +095 */ +096 public EmpiricalDistributionImpl() { +097 binStats = new ArrayList<SummaryStatistics>(); +098 } +099 +100 /** +101 * Creates a new EmpiricalDistribution with the specified bin count. +102 * +103 * @param binCount number of bins +104 */ +105 public EmpiricalDistributionImpl(int binCount) { +106 this.binCount = binCount; +107 binStats = new ArrayList<SummaryStatistics>(); +108 } +109 +110 /** +111 * Computes the empirical distribution from the provided +112 * array of numbers. +113 * +114 * @param in the input data array +115 */ +116 public void load(double[] in) { +117 DataAdapter da = new ArrayDataAdapter(in); +118 try { +119 da.computeStats(); +120 fillBinStats(in); +121 } catch (IOException e) { +122 throw new MathRuntimeException(e); +123 } +124 loaded = true; +125 +126 } +127 +128 /** +129 * Computes the empirical distribution using data read from a URL. +130 * @param url url of the input file +131 * +132 * @throws IOException if an IO error occurs +133 */ +134 public void load(URL url) throws IOException { +135 BufferedReader in = +136 new BufferedReader(new InputStreamReader(url.openStream())); +137 try { +138 DataAdapter da = new StreamDataAdapter(in); +139 da.computeStats(); +140 if (sampleStats.getN() == 0) { +141 throw MathRuntimeException.createEOFException("URL {0} contains no data", +142 url); +143 } +144 in = new BufferedReader(new InputStreamReader(url.openStream())); +145 fillBinStats(in); +146 loaded = true; +147 } finally { +148 try { +149 in.close(); +150 } catch (IOException ex) { +151 // ignore +152 } +153 } +154 } +155 +156 /** +157 * Computes the empirical distribution from the input file. +158 * +159 * @param file the input file +160 * @throws IOException if an IO error occurs +161 */ +162 public void load(File file) throws IOException { +163 BufferedReader in = new BufferedReader(new FileReader(file)); +164 try { +165 DataAdapter da = new StreamDataAdapter(in); +166 da.computeStats(); +167 in = new BufferedReader(new FileReader(file)); +168 fillBinStats(in); +169 loaded = true; +170 } finally { +171 try { +172 in.close(); +173 } catch (IOException ex) { +174 // ignore +175 } +176 } +177 } +178 +179 /** +180 * Provides methods for computing <code>sampleStats</code> and +181 * <code>beanStats</code> abstracting the source of data. +182 */ +183 private abstract class DataAdapter{ +184 +185 /** +186 * Compute bin stats. +187 * +188 * @throws IOException if an error occurs computing bin stats +189 */ +190 public abstract void computeBinStats() throws IOException; +191 +192 /** +193 * Compute sample statistics. +194 * +195 * @throws IOException if an error occurs computing sample stats +196 */ +197 public abstract void computeStats() throws IOException; +198 +199 } +200 +201 /** +202 * Factory of <code>DataAdapter</code> objects. For every supported source +203 * of data (array of doubles, file, etc.) an instance of the proper object +204 * is returned. +205 */ +206 private class DataAdapterFactory{ +207 /** +208 * Creates a DataAdapter from a data object +209 * +210 * @param in object providing access to the data +211 * @return DataAdapter instance +212 */ +213 public DataAdapter getAdapter(Object in) { +214 if (in instanceof BufferedReader) { +215 BufferedReader inputStream = (BufferedReader) in; +216 return new StreamDataAdapter(inputStream); +217 } else if (in instanceof double[]) { +218 double[] inputArray = (double[]) in; +219 return new ArrayDataAdapter(inputArray); +220 } else { +221 throw MathRuntimeException.createIllegalArgumentException( +222 "input data comes from unsupported datasource: {0}, " + +223 "supported sources: {1}, {2}", +224 in.getClass().getName(), +225 BufferedReader.class.getName(), double[].class.getName()); +226 } +227 } +228 } +229 /** +230 * <code>DataAdapter</code> for data provided through some input stream +231 */ +232 private class StreamDataAdapter extends DataAdapter{ +233 +234 /** Input stream providing access to the data */ +235 private BufferedReader inputStream; +236 +237 /** +238 * Create a StreamDataAdapter from a BufferedReader +239 * +240 * @param in BufferedReader input stream +241 */ +242 public StreamDataAdapter(BufferedReader in){ +243 super(); +244 inputStream = in; +245 } +246 +247 /** {@inheritDoc} */ +248 @Override +249 public void computeBinStats() throws IOException { +250 String str = null; +251 double val = 0.0d; +252 while ((str = inputStream.readLine()) != null) { +253 val = Double.parseDouble(str); +254 SummaryStatistics stats = binStats.get(findBin(val)); +255 stats.addValue(val); +256 } +257 +258 inputStream.close(); +259 inputStream = null; +260 } +261 +262 /** {@inheritDoc} */ +263 @Override +264 public void computeStats() throws IOException { +265 String str = null; +266 double val = 0.0; +267 sampleStats = new SummaryStatistics(); +268 while ((str = inputStream.readLine()) != null) { +269 val = Double.valueOf(str).doubleValue(); +270 sampleStats.addValue(val); +271 } +272 inputStream.close(); +273 inputStream = null; +274 } +275 } +276 +277 /** +278 * <code>DataAdapter</code> for data provided as array of doubles. +279 */ +280 private class ArrayDataAdapter extends DataAdapter { +281 +282 /** Array of input data values */ +283 private double[] inputArray; +284 +285 /** +286 * Construct an ArrayDataAdapter from a double[] array +287 * +288 * @param in double[] array holding the data +289 */ +290 public ArrayDataAdapter(double[] in){ +291 super(); +292 inputArray = in; +293 } +294 +295 /** {@inheritDoc} */ +296 @Override +297 public void computeStats() throws IOException { +298 sampleStats = new SummaryStatistics(); +299 for (int i = 0; i < inputArray.length; i++) { +300 sampleStats.addValue(inputArray[i]); +301 } +302 } +303 +304 /** {@inheritDoc} */ +305 @Override +306 public void computeBinStats() throws IOException { +307 for (int i = 0; i < inputArray.length; i++) { +308 SummaryStatistics stats = +309 binStats.get(findBin(inputArray[i])); +310 stats.addValue(inputArray[i]); +311 } +312 } +313 } +314 +315 /** +316 * Fills binStats array (second pass through data file). +317 * +318 * @param in object providing access to the data +319 * @throws IOException if an IO error occurs +320 */ +321 private void fillBinStats(Object in) throws IOException { +322 // Set up grid +323 min = sampleStats.getMin(); +324 max = sampleStats.getMax(); +325 delta = (max - min)/(Double.valueOf(binCount)).doubleValue(); +326 +327 // Initialize binStats ArrayList +328 if (!binStats.isEmpty()) { +329 binStats.clear(); +330 } +331 for (int i = 0; i < binCount; i++) { +332 SummaryStatistics stats = new SummaryStatistics(); +333 binStats.add(i,stats); +334 } +335 +336 // Filling data in binStats Array +337 DataAdapterFactory aFactory = new DataAdapterFactory(); +338 DataAdapter da = aFactory.getAdapter(in); +339 da.computeBinStats(); +340 +341 // Assign upperBounds based on bin counts +342 upperBounds = new double[binCount]; +343 upperBounds[0] = +344 ((double) binStats.get(0).getN()) / (double) sampleStats.getN(); +345 for (int i = 1; i < binCount-1; i++) { +346 upperBounds[i] = upperBounds[i-1] + +347 ((double) binStats.get(i).getN()) / (double) sampleStats.getN(); +348 } +349 upperBounds[binCount-1] = 1.0d; +350 } +351 +352 /** +353 * Returns the index of the bin to which the given value belongs +354 * +355 * @param value the value whose bin we are trying to find +356 * @return the index of the bin containing the value +357 */ +358 private int findBin(double value) { +359 return Math.min( +360 Math.max((int) Math.ceil((value- min) / delta) - 1, 0), +361 binCount - 1); +362 } +363 +364 /** +365 * Generates a random value from this distribution. +366 * +367 * @return the random value. +368 * @throws IllegalStateException if the distribution has not been loaded +369 */ +370 public double getNextValue() throws IllegalStateException { +371 +372 if (!loaded) { +373 throw MathRuntimeException.createIllegalStateException("distribution not loaded"); +374 } +375 +376 // Start with a uniformly distributed random number in (0,1) +377 double x = Math.random(); +378 +379 // Use this to select the bin and generate a Gaussian within the bin +380 for (int i = 0; i < binCount; i++) { +381 if (x <= upperBounds[i]) { +382 SummaryStatistics stats = binStats.get(i); +383 if (stats.getN() > 0) { +384 if (stats.getStandardDeviation() > 0) { // more than one obs +385 return randomData.nextGaussian +386 (stats.getMean(),stats.getStandardDeviation()); +387 } else { +388 return stats.getMean(); // only one obs in bin +389 } +390 } +391 } +392 } +393 throw new MathRuntimeException("no bin selected"); +394 } +395 +396 /** +397 * Returns a {@link StatisticalSummary} describing this distribution. +398 * <strong>Preconditions:</strong><ul> +399 * <li>the distribution must be loaded before invoking this method</li></ul> +400 * +401 * @return the sample statistics +402 * @throws IllegalStateException if the distribution has not been loaded +403 */ +404 public StatisticalSummary getSampleStats() { +405 return sampleStats; +406 } +407 +408 /** +409 * Returns the number of bins. +410 * +411 * @return the number of bins. +412 */ +413 public int getBinCount() { +414 return binCount; +415 } +416 +417 /** +418 * Returns a List of {@link SummaryStatistics} instances containing +419 * statistics describing the values in each of the bins. The list is +420 * indexed on the bin number. +421 * +422 * @return List of bin statistics. +423 */ +424 public List<SummaryStatistics> getBinStats() { +425 return binStats; +426 } +427 +428 /** +429 * <p>Returns a fresh copy of the array of upper bounds for the bins. +430 * Bins are: <br/> +431 * [min,upperBounds[0]],(upperBounds[0],upperBounds[1]],..., +432 * (upperBounds[binCount-2], upperBounds[binCount-1] = max].</p> +433 * +434 * <p>Note: In versions 1.0-2.0 of commons-math, this method +435 * incorrectly returned the array of probability generator upper +436 * bounds now returned by {@link #getGeneratorUpperBounds()}.</p> +437 * +438 * @return array of bin upper bounds +439 * @since 2.1 +440 */ +441 public double[] getUpperBounds() { +442 double[] binUpperBounds = new double[binCount]; +443 binUpperBounds[0] = min + delta; +444 for (int i = 1; i < binCount - 1; i++) { +445 binUpperBounds[i] = binUpperBounds[i-1] + delta; +446 } +447 binUpperBounds[binCount - 1] = max; +448 return binUpperBounds; +449 } +450 +451 /** +452 * <p>Returns a fresh copy of the array of upper bounds of the subintervals +453 * of [0,1] used in generating data from the empirical distribution. +454 * Subintervals correspond to bins with lengths proportional to bin counts.</p> +455 * +456 * <p>In versions 1.0-2.0 of commons-math, this array was (incorrectly) returned +457 * by {@link #getUpperBounds()}.</p> +458 * +459 * @since 2.1 +460 * @return array of upper bounds of subintervals used in data generation +461 */ +462 public double[] getGeneratorUpperBounds() { +463 int len = upperBounds.length; +464 double[] out = new double[len]; +465 System.arraycopy(upperBounds, 0, out, 0, len); +466 return out; +467 } +468 +469 /** +470 * Property indicating whether or not the distribution has been loaded. +471 * +472 * @return true if the distribution has been loaded +473 */ +474 public boolean isLoaded() { +475 return loaded; +476 } +477 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/GaussianRandomGenerator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/GaussianRandomGenerator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,113 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.random; +019 +020 /** +021 * This class is a gaussian normalized random generator for scalars. +022 * <p>This class is a simple wrapper around the {@link +023 * RandomGenerator#nextGaussian} method.</p> +024 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +025 * @since 1.2 +026 */ +027 +028 public class GaussianRandomGenerator implements NormalizedRandomGenerator { +029 +030 /** Underlying generator. */ +031 private final RandomGenerator generator; +032 +033 /** Create a new generator. +034 * @param generator underlying random generator to use +035 */ +036 public GaussianRandomGenerator(final RandomGenerator generator) { +037 this.generator = generator; +038 } +039 +040 /** Generate a random scalar with null mean and unit standard deviation. +041 * @return a random scalar with null mean and unit standard deviation +042 */ +043 public double nextNormalizedDouble() { +044 return generator.nextGaussian(); +045 } +046 +047 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/JDKRandomGenerator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/JDKRandomGenerator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,116 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.random; +018 +019 import java.util.Random; +020 +021 /** +022 * Extension of <code>java.util.Random</code> to implement +023 * {@link RandomGenerator}. +024 * +025 * @since 1.1 +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 */ +028 public class JDKRandomGenerator extends Random implements RandomGenerator { +029 +030 /** Serializable version identifier. */ +031 private static final long serialVersionUID = -7745277476784028798L; +032 +033 /** {@inheritDoc} */ +034 public void setSeed(int seed) { +035 setSeed((long) seed); +036 } +037 +038 /** {@inheritDoc} */ +039 public void setSeed(int[] seed) { +040 // the following number is the largest prime that fits in 32 bits (it is 2^32 - 5) +041 final long prime = 4294967291l; +042 +043 long combined = 0l; +044 for (int s : seed) { +045 combined = combined * prime + s; +046 } +047 setSeed(combined); +048 } +049 +050 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/MersenneTwister.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/MersenneTwister.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,323 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.random; +018 +019 import java.io.Serializable; +020 +021 +022 /** This class implements a powerful pseudo-random number generator +023 * developed by Makoto Matsumoto and Takuji Nishimura during +024 * 1996-1997. +025 +026 * <p>This generator features an extremely long period +027 * (2<sup>19937</sup>-1) and 623-dimensional equidistribution up to 32 +028 * bits accuracy. The home page for this generator is located at <a +029 * href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html"> +030 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html</a>.</p> +031 +032 * <p>This generator is described in a paper by Makoto Matsumoto and +033 * Takuji Nishimura in 1998: <a +034 * href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/ARTICLES/mt.pdf">Mersenne +035 * Twister: A 623-Dimensionally Equidistributed Uniform Pseudo-Random +036 * Number Generator</a>, ACM Transactions on Modeling and Computer +037 * Simulation, Vol. 8, No. 1, January 1998, pp 3--30</p> +038 +039 * <p>This class is mainly a Java port of the 2002-01-26 version of +040 * the generator written in C by Makoto Matsumoto and Takuji +041 * Nishimura. Here is their original copyright:</p> +042 +043 * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0"> +044 * <tr><td>Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, +045 * All rights reserved.</td></tr> +046 +047 * <tr><td>Redistribution and use in source and binary forms, with or without +048 * modification, are permitted provided that the following conditions +049 * are met: +050 * <ol> +051 * <li>Redistributions of source code must retain the above copyright +052 * notice, this list of conditions and the following disclaimer.</li> +053 * <li>Redistributions in binary form must reproduce the above copyright +054 * notice, this list of conditions and the following disclaimer in the +055 * documentation and/or other materials provided with the distribution.</li> +056 * <li>The names of its contributors may not be used to endorse or promote +057 * products derived from this software without specific prior written +058 * permission.</li> +059 * </ol></td></tr> +060 +061 * <tr><td><strong>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +062 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +063 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +064 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +065 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +066 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +067 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +068 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +069 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +070 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +071 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +072 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +073 * DAMAGE.</strong></td></tr> +074 * </table> +075 +076 * @version $Revision: 902203 $ $Date: 2010-01-22 13:27:41 -0500 (Fri, 22 Jan 2010) $ +077 * @since 2.0 +078 +079 */ +080 public class MersenneTwister extends BitsStreamGenerator implements Serializable { +081 +082 /** Serializable version identifier. */ +083 private static final long serialVersionUID = 8661194735290153518L; +084 +085 /** Size of the bytes pool. */ +086 private static final int N = 624; +087 +088 /** Period second parameter. */ +089 private static final int M = 397; +090 +091 /** X * MATRIX_A for X = {0, 1}. */ +092 private static final int[] MAG01 = { 0x0, 0x9908b0df }; +093 +094 /** Bytes pool. */ +095 private int[] mt; +096 +097 /** Current index in the bytes pool. */ +098 private int mti; +099 +100 /** Creates a new random number generator. +101 * <p>The instance is initialized using the current time as the +102 * seed.</p> +103 */ +104 public MersenneTwister() { +105 mt = new int[N]; +106 setSeed(System.currentTimeMillis()); +107 } +108 +109 /** Creates a new random number generator using a single int seed. +110 * @param seed the initial seed (32 bits integer) +111 */ +112 public MersenneTwister(int seed) { +113 mt = new int[N]; +114 setSeed(seed); +115 } +116 +117 /** Creates a new random number generator using an int array seed. +118 * @param seed the initial seed (32 bits integers array), if null +119 * the seed of the generator will be related to the current time +120 */ +121 public MersenneTwister(int[] seed) { +122 mt = new int[N]; +123 setSeed(seed); +124 } +125 +126 /** Creates a new random number generator using a single long seed. +127 * @param seed the initial seed (64 bits integer) +128 */ +129 public MersenneTwister(long seed) { +130 mt = new int[N]; +131 setSeed(seed); +132 } +133 +134 /** Reinitialize the generator as if just built with the given int seed. +135 * <p>The state of the generator is exactly the same as a new +136 * generator built with the same seed.</p> +137 * @param seed the initial seed (32 bits integer) +138 */ +139 @Override +140 public void setSeed(int seed) { +141 // we use a long masked by 0xffffffffL as a poor man unsigned int +142 long longMT = seed; +143 mt[0]= (int) longMT; +144 for (mti = 1; mti < N; ++mti) { +145 // See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. +146 // initializer from the 2002-01-09 C version by Makoto Matsumoto +147 longMT = (1812433253l * (longMT ^ (longMT >> 30)) + mti) & 0xffffffffL; +148 mt[mti]= (int) longMT; +149 } +150 } +151 +152 /** Reinitialize the generator as if just built with the given int array seed. +153 * <p>The state of the generator is exactly the same as a new +154 * generator built with the same seed.</p> +155 * @param seed the initial seed (32 bits integers array), if null +156 * the seed of the generator will be related to the current time +157 */ +158 @Override +159 public void setSeed(int[] seed) { +160 +161 if (seed == null) { +162 setSeed(System.currentTimeMillis()); +163 return; +164 } +165 +166 setSeed(19650218); +167 int i = 1; +168 int j = 0; +169 +170 for (int k = Math.max(N, seed.length); k != 0; k--) { +171 long l0 = (mt[i] & 0x7fffffffl) | ((mt[i] < 0) ? 0x80000000l : 0x0l); +172 long l1 = (mt[i-1] & 0x7fffffffl) | ((mt[i-1] < 0) ? 0x80000000l : 0x0l); +173 long l = (l0 ^ ((l1 ^ (l1 >> 30)) * 1664525l)) + seed[j] + j; // non linear +174 mt[i] = (int) (l & 0xffffffffl); +175 i++; j++; +176 if (i >= N) { +177 mt[0] = mt[N - 1]; +178 i = 1; +179 } +180 if (j >= seed.length) { +181 j = 0; +182 } +183 } +184 +185 for (int k = N - 1; k != 0; k--) { +186 long l0 = (mt[i] & 0x7fffffffl) | ((mt[i] < 0) ? 0x80000000l : 0x0l); +187 long l1 = (mt[i-1] & 0x7fffffffl) | ((mt[i-1] < 0) ? 0x80000000l : 0x0l); +188 long l = (l0 ^ ((l1 ^ (l1 >> 30)) * 1566083941l)) - i; // non linear +189 mt[i] = (int) (l & 0xffffffffL); +190 i++; +191 if (i >= N) { +192 mt[0] = mt[N - 1]; +193 i = 1; +194 } +195 } +196 +197 mt[0] = 0x80000000; // MSB is 1; assuring non-zero initial array +198 +199 } +200 +201 /** Reinitialize the generator as if just built with the given long seed. +202 * <p>The state of the generator is exactly the same as a new +203 * generator built with the same seed.</p> +204 * @param seed the initial seed (64 bits integer) +205 */ +206 @Override +207 public void setSeed(long seed) { +208 setSeed(new int[] { (int) (seed >>> 32), (int) (seed & 0xffffffffl) }); +209 } +210 +211 /** Generate next pseudorandom number. +212 * <p>This method is the core generation algorithm. It is used by all the +213 * public generation methods for the various primitive types {@link +214 * #nextBoolean()}, {@link #nextBytes(byte[])}, {@link #nextDouble()}, +215 * {@link #nextFloat()}, {@link #nextGaussian()}, {@link #nextInt()}, +216 * {@link #next(int)} and {@link #nextLong()}.</p> +217 * @param bits number of random bits to produce +218 * @return random bits generated +219 */ +220 @Override +221 protected int next(int bits) { +222 +223 int y; +224 +225 if (mti >= N) { // generate N words at one time +226 int mtNext = mt[0]; +227 for (int k = 0; k < N - M; ++k) { +228 int mtCurr = mtNext; +229 mtNext = mt[k + 1]; +230 y = (mtCurr & 0x80000000) | (mtNext & 0x7fffffff); +231 mt[k] = mt[k + M] ^ (y >>> 1) ^ MAG01[y & 0x1]; +232 } +233 for (int k = N - M; k < N - 1; ++k) { +234 int mtCurr = mtNext; +235 mtNext = mt[k + 1]; +236 y = (mtCurr & 0x80000000) | (mtNext & 0x7fffffff); +237 mt[k] = mt[k + (M - N)] ^ (y >>> 1) ^ MAG01[y & 0x1]; +238 } +239 y = (mtNext & 0x80000000) | (mt[0] & 0x7fffffff); +240 mt[N - 1] = mt[M - 1] ^ (y >>> 1) ^ MAG01[y & 0x1]; +241 +242 mti = 0; +243 } +244 +245 y = mt[mti++]; +246 +247 // tempering +248 y ^= y >>> 11; +249 y ^= (y << 7) & 0x9d2c5680; +250 y ^= (y << 15) & 0xefc60000; +251 y ^= y >>> 18; +252 +253 return y >>> (32 - bits); +254 +255 } +256 +257 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/NormalizedRandomGenerator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/NormalizedRandomGenerator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,104 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.random; +019 +020 /** +021 * This interface represent a normalized random generator for +022 * scalars. +023 * Normalized generator provide null mean and unit standard deviation scalars. +024 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +025 * @since 1.2 +026 */ +027 public interface NormalizedRandomGenerator { +028 +029 /** Generate a random scalar with null mean and unit standard deviation. +030 * <p>This method does <strong>not</strong> specify the shape of the +031 * distribution, it is the implementing class that provides it. The +032 * only contract here is to generate numbers with null mean and unit +033 * standard deviation.</p> +034 * @return a random scalar with null mean and unit standard deviation +035 */ +036 double nextNormalizedDouble(); +037 +038 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/RandomAdaptor.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/RandomAdaptor.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,264 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.random; +018 +019 import java.util.Random; +020 +021 /** +022 * Extension of <code>java.util.Random</code> wrapping a +023 * {@link RandomGenerator}. +024 * +025 * @since 1.1 +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 */ +028 public class RandomAdaptor extends Random implements RandomGenerator { +029 +030 /** Serializable version identifier. */ +031 private static final long serialVersionUID = 2306581345647615033L; +032 +033 /** Wrapped randomGenerator instance */ +034 private RandomGenerator randomGenerator = null; +035 +036 /** +037 * Prevent instantiation without a generator argument +038 */ +039 @SuppressWarnings("unused") +040 private RandomAdaptor() { } +041 +042 /** +043 * Construct a RandomAdaptor wrapping the supplied RandomGenerator. +044 * +045 * @param randomGenerator the wrapped generator +046 */ +047 public RandomAdaptor(RandomGenerator randomGenerator) { +048 this.randomGenerator = randomGenerator; +049 } +050 +051 /** +052 * Factory method to create a <code>Random</code> using the supplied +053 * <code>RandomGenerator</code>. +054 * +055 * @param randomGenerator wrapped RandomGenerator instance +056 * @return a Random instance wrapping the RandomGenerator +057 */ +058 public static Random createAdaptor(RandomGenerator randomGenerator) { +059 return new RandomAdaptor(randomGenerator); +060 } +061 +062 /** +063 * Returns the next pseudorandom, uniformly distributed +064 * <code>boolean</code> value from this random number generator's +065 * sequence. +066 * +067 * @return the next pseudorandom, uniformly distributed +068 * <code>boolean</code> value from this random number generator's +069 * sequence +070 */ +071 @Override +072 public boolean nextBoolean() { +073 return randomGenerator.nextBoolean(); +074 } +075 +076 /** +077 * Generates random bytes and places them into a user-supplied +078 * byte array. The number of random bytes produced is equal to +079 * the length of the byte array. +080 * +081 * @param bytes the non-null byte array in which to put the +082 * random bytes +083 */ +084 @Override +085 public void nextBytes(byte[] bytes) { +086 randomGenerator.nextBytes(bytes); +087 } +088 +089 /** +090 * Returns the next pseudorandom, uniformly distributed +091 * <code>double</code> value between <code>0.0</code> and +092 * <code>1.0</code> from this random number generator's sequence. +093 * +094 * @return the next pseudorandom, uniformly distributed +095 * <code>double</code> value between <code>0.0</code> and +096 * <code>1.0</code> from this random number generator's sequence +097 */ +098 @Override +099 public double nextDouble() { +100 return randomGenerator.nextDouble(); +101 } +102 +103 /** +104 * Returns the next pseudorandom, uniformly distributed <code>float</code> +105 * value between <code>0.0</code> and <code>1.0</code> from this random +106 * number generator's sequence. +107 * +108 * @return the next pseudorandom, uniformly distributed <code>float</code> +109 * value between <code>0.0</code> and <code>1.0</code> from this +110 * random number generator's sequence +111 */ +112 @Override +113 public float nextFloat() { +114 return randomGenerator.nextFloat(); +115 } +116 +117 /** +118 * Returns the next pseudorandom, Gaussian ("normally") distributed +119 * <code>double</code> value with mean <code>0.0</code> and standard +120 * deviation <code>1.0</code> from this random number generator's sequence. +121 * +122 * @return the next pseudorandom, Gaussian ("normally") distributed +123 * <code>double</code> value with mean <code>0.0</code> and +124 * standard deviation <code>1.0</code> from this random number +125 * generator's sequence +126 */ +127 @Override +128 public double nextGaussian() { +129 return randomGenerator.nextGaussian(); +130 } +131 +132 /** +133 * Returns the next pseudorandom, uniformly distributed <code>int</code> +134 * value from this random number generator's sequence. +135 * All 2<font size="-1"><sup>32</sup></font> possible <tt>int</tt> values +136 * should be produced with (approximately) equal probability. +137 * +138 * @return the next pseudorandom, uniformly distributed <code>int</code> +139 * value from this random number generator's sequence +140 */ +141 @Override +142 public int nextInt() { +143 return randomGenerator.nextInt(); +144 } +145 +146 /** +147 * Returns a pseudorandom, uniformly distributed <tt>int</tt> value +148 * between 0 (inclusive) and the specified value (exclusive), drawn from +149 * this random number generator's sequence. +150 * +151 * @param n the bound on the random number to be returned. Must be +152 * positive. +153 * @return a pseudorandom, uniformly distributed <tt>int</tt> +154 * value between 0 (inclusive) and n (exclusive). +155 * @throws IllegalArgumentException if n is not positive. +156 */ +157 @Override +158 public int nextInt(int n) { +159 return randomGenerator.nextInt(n); +160 } +161 +162 /** +163 * Returns the next pseudorandom, uniformly distributed <code>long</code> +164 * value from this random number generator's sequence. All +165 * 2<font size="-1"><sup>64</sup></font> possible <tt>long</tt> values +166 * should be produced with (approximately) equal probability. +167 * +168 * @return the next pseudorandom, uniformly distributed <code>long</code> +169 *value from this random number generator's sequence +170 */ +171 @Override +172 public long nextLong() { +173 return randomGenerator.nextLong(); +174 } +175 +176 /** {@inheritDoc} */ +177 public void setSeed(int seed) { +178 if (randomGenerator != null) { // required to avoid NPE in constructor +179 randomGenerator.setSeed(seed); +180 } +181 } +182 +183 /** {@inheritDoc} */ +184 public void setSeed(int[] seed) { +185 if (randomGenerator != null) { // required to avoid NPE in constructor +186 randomGenerator.setSeed(seed); +187 } +188 } +189 +190 /** {@inheritDoc} */ +191 @Override +192 public void setSeed(long seed) { +193 if (randomGenerator != null) { // required to avoid NPE in constructor +194 randomGenerator.setSeed(seed); +195 } +196 } +197 +198 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/RandomData.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/RandomData.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,338 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.random; +019 import java.util.Collection; +020 +021 /** +022 * Random data generation utilities. +023 * @version $Revision: 780975 $ $Date: 2009-06-02 05:05:37 -0400 (Tue, 02 Jun 2009) $ +024 */ +025 public interface RandomData { +026 /** +027 * Generates a random string of hex characters of length +028 * <code>len</code>. +029 * <p> +030 * The generated string will be random, but not cryptographically +031 * secure. To generate cryptographically secure strings, use +032 * <code>nextSecureHexString</code></p> +033 * <p> +034 * <strong>Preconditions</strong>:<ul> +035 * <li><code>len > 0</code> (otherwise an IllegalArgumentException +036 * is thrown.)</li> +037 * </ul></p> +038 * +039 * @param len the length of the string to be generated +040 * @return random string of hex characters of length <code>len</code> +041 */ +042 String nextHexString(int len); +043 +044 /** +045 * Generates a uniformly distributed random integer between +046 * <code>lower</code> and <code>upper</code> (endpoints included). +047 * <p> +048 * The generated integer will be random, but not cryptographically secure. +049 * To generate cryptographically secure integer sequences, use +050 * <code>nextSecureInt</code>.</p> +051 * <p> +052 * <strong>Preconditions</strong>:<ul> +053 * <li><code>lower < upper</code> (otherwise an IllegalArgumentException +054 * is thrown.)</li> +055 * </ul></p> +056 * +057 * @param lower lower bound for generated integer +058 * @param upper upper bound for generated integer +059 * @return a random integer greater than or equal to <code>lower</code> +060 * and less than or equal to <code>upper</code>. +061 */ +062 int nextInt(int lower, int upper); +063 +064 /** +065 * Generates a uniformly distributed random long integer between +066 * <code>lower</code> and <code>upper</code> (endpoints included). +067 * <p> +068 * The generated long integer values will be random, but not +069 * cryptographically secure. +070 * To generate cryptographically secure sequences of longs, use +071 * <code>nextSecureLong</code></p> +072 * <p> +073 * <strong>Preconditions</strong>:<ul> +074 * <li><code>lower < upper</code> (otherwise an IllegalArgumentException +075 * is thrown.)</li> +076 * </ul></p> +077 * +078 * @param lower lower bound for generated integer +079 * @param upper upper bound for generated integer +080 * @return a random integer greater than or equal to <code>lower</code> +081 * and less than or equal to <code>upper</code>. +082 */ +083 long nextLong(long lower, long upper); +084 +085 /** +086 * Generates a random string of hex characters from a secure random +087 * sequence. +088 * <p> +089 * If cryptographic security is not required, +090 * use <code>nextHexString()</code>.</p> +091 * <p> +092 * <strong>Preconditions</strong>:<ul> +093 * <li><code>len > 0</code> (otherwise an IllegalArgumentException +094 * is thrown.)</li> +095 * </ul></p> +096 * @param len length of return string +097 * @return the random hex string +098 */ +099 String nextSecureHexString(int len); +100 +101 /** +102 * Generates a uniformly distributed random integer between +103 * <code>lower</code> and <code>upper</code> (endpoints included) +104 * from a secure random sequence. +105 * <p> +106 * Sequences of integers generated using this method will be +107 * cryptographically secure. If cryptographic security is not required, +108 * <code>nextInt</code> should be used instead of this method.</p> +109 * <p> +110 * <strong>Definition</strong>: +111 * <a href="http://en.wikipedia.org/wiki/Cryptographically_secure_pseudo-random_number_generator"> +112 * Secure Random Sequence</a></p> +113 * <p> +114 * <strong>Preconditions</strong>:<ul> +115 * <li><code>lower < upper</code> (otherwise an IllegalArgumentException +116 * is thrown.)</li> +117 * </ul></p> +118 * +119 * @param lower lower bound for generated integer +120 * @param upper upper bound for generated integer +121 * @return a random integer greater than or equal to <code>lower</code> +122 * and less than or equal to <code>upper</code>. +123 */ +124 int nextSecureInt(int lower, int upper); +125 +126 /** +127 * Generates a random long integer between <code>lower</code> +128 * and <code>upper</code> (endpoints included). +129 * <p> +130 * Sequences of long values generated using this method will be +131 * cryptographically secure. If cryptographic security is not required, +132 * <code>nextLong</code> should be used instead of this method.</p> +133 * <p> +134 * <strong>Definition</strong>: +135 * <a href="http://en.wikipedia.org/wiki/Cryptographically_secure_pseudo-random_number_generator"> +136 * Secure Random Sequence</a></p> +137 * <p> +138 * <strong>Preconditions</strong>:<ul> +139 * <li><code>lower < upper</code> (otherwise an IllegalArgumentException +140 * is thrown.)</li> +141 * </ul></p> +142 * +143 * @param lower lower bound for generated integer +144 * @param upper upper bound for generated integer +145 * @return a long integer greater than or equal to <code>lower</code> +146 * and less than or equal to <code>upper</code>. +147 */ +148 long nextSecureLong(long lower, long upper); +149 +150 /** +151 * Generates a random value from the Poisson distribution with +152 * the given mean. +153 * <p> +154 * <strong>Definition</strong>: +155 * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda366j.htm"> +156 * Poisson Distribution</a></p> +157 * <p> +158 * <strong>Preconditions</strong>: <ul> +159 * <li>The specified mean <i>must</i> be positive (otherwise an +160 * IllegalArgumentException is thrown.)</li> +161 * </ul></p> +162 * @param mean Mean of the distribution +163 * @return poisson deviate with the specified mean +164 */ +165 long nextPoisson(double mean); +166 +167 /** +168 * Generates a random value from the +169 * Normal (or Gaussian) distribution with the given mean +170 * and standard deviation. +171 * <p> +172 * <strong>Definition</strong>: +173 * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3661.htm"> +174 * Normal Distribution</a></p> +175 * <p> +176 * <strong>Preconditions</strong>: <ul> +177 * <li><code>sigma > 0</code> (otherwise an IllegalArgumentException +178 * is thrown.)</li> +179 * </ul></p> +180 * @param mu Mean of the distribution +181 * @param sigma Standard deviation of the distribution +182 * @return random value from Gaussian distribution with mean = mu, +183 * standard deviation = sigma +184 */ +185 double nextGaussian(double mu, double sigma); +186 +187 /** +188 * Generates a random value from the exponential distribution +189 * with expected value = <code>mean</code>. +190 * <p> +191 * <strong>Definition</strong>: +192 * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3667.htm"> +193 * Exponential Distribution</a></p> +194 * <p> +195 * <strong>Preconditions</strong>: <ul> +196 * <li><code>mu >= 0</code> (otherwise an IllegalArgumentException +197 * is thrown.)</li> +198 * </ul></p> +199 * @param mean Mean of the distribution +200 * @return random value from exponential distribution +201 */ +202 double nextExponential(double mean); +203 +204 /** +205 * Generates a uniformly distributed random value from the open interval +206 * (<code>lower</code>,<code>upper</code>) (i.e., endpoints excluded). +207 * <p> +208 * <strong>Definition</strong>: +209 * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3662.htm"> +210 * Uniform Distribution</a> <code>lower</code> and +211 * <code>upper - lower</code> are the +212 * <a href = "http://www.itl.nist.gov/div898/handbook/eda/section3/eda364.htm"> +213 * location and scale parameters</a>, respectively.</p> +214 * <p> +215 * <strong>Preconditions</strong>:<ul> +216 * <li><code>lower < upper</code> (otherwise an IllegalArgumentException +217 * is thrown.)</li> +218 * </ul></p> +219 * +220 * @param lower lower endpoint of the interval of support +221 * @param upper upper endpoint of the interval of support +222 * @return uniformly distributed random value between lower +223 * and upper (exclusive) +224 */ +225 double nextUniform(double lower, double upper); +226 +227 /** +228 * Generates an integer array of length <code>k</code> whose entries +229 * are selected randomly, without repetition, from the integers <code> +230 * 0 through n-1</code> (inclusive). +231 * <p> +232 * Generated arrays represent permutations +233 * of <code>n</code> taken <code>k</code> at a time.</p> +234 * <p> +235 * <strong>Preconditions:</strong><ul> +236 * <li> <code>k <= n</code></li> +237 * <li> <code>n > 0</code> </li> +238 * </ul> +239 * If the preconditions are not met, an IllegalArgumentException is +240 * thrown.</p> +241 * +242 * @param n domain of the permutation +243 * @param k size of the permutation +244 * @return random k-permutation of n +245 */ +246 int[] nextPermutation(int n, int k); +247 +248 /** +249 * Returns an array of <code>k</code> objects selected randomly +250 * from the Collection <code>c</code>. +251 * <p> +252 * Sampling from <code>c</code> +253 * is without replacement; but if <code>c</code> contains identical +254 * objects, the sample may include repeats. If all elements of <code> +255 * c</code> are distinct, the resulting object array represents a +256 * <a href="http://rkb.home.cern.ch/rkb/AN16pp/node250.html#SECTION0002500000000000000000"> +257 * Simple Random Sample</a> of size +258 * <code>k</code> from the elements of <code>c</code>.</p> +259 * <p> +260 * <strong>Preconditions:</strong><ul> +261 * <li> k must be less than or equal to the size of c </li> +262 * <li> c must not be empty </li> +263 * </ul> +264 * If the preconditions are not met, an IllegalArgumentException is +265 * thrown.</p> +266 * +267 * @param c collection to be sampled +268 * @param k size of the sample +269 * @return random sample of k elements from c +270 */ +271 Object[] nextSample(Collection<?> c, int k); +272 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/RandomDataImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/RandomDataImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,814 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.random; +019 +020 import java.io.Serializable; +021 import java.security.MessageDigest; +022 import java.security.SecureRandom; +023 import java.security.NoSuchAlgorithmException; +024 import java.security.NoSuchProviderException; +025 import java.util.Collection; +026 +027 import org.apache.commons.math.MathRuntimeException; +028 import org.apache.commons.math.util.MathUtils; +029 +030 /** +031 * Implements the {@link RandomData} interface using a {@link RandomGenerator} +032 * instance to generate non-secure data and a {@link java.security.SecureRandom} +033 * instance to provide data for the <code>nextSecureXxx</code> methods. If no +034 * <code>RandomGenerator</code> is provided in the constructor, the default is +035 * to use a generator based on {@link java.util.Random}. To plug in a different +036 * implementation, either implement <code>RandomGenerator</code> directly or +037 * extend {@link AbstractRandomGenerator}. +038 * <p> +039 * Supports reseeding the underlying pseudo-random number generator (PRNG). The +040 * <code>SecurityProvider</code> and <code>Algorithm</code> used by the +041 * <code>SecureRandom</code> instance can also be reset. +042 * </p> +043 * <p> +044 * For details on the default PRNGs, see {@link java.util.Random} and +045 * {@link java.security.SecureRandom}. +046 * </p> +047 * <p> +048 * <strong>Usage Notes</strong>: +049 * <ul> +050 * <li> +051 * Instance variables are used to maintain <code>RandomGenerator</code> and +052 * <code>SecureRandom</code> instances used in data generation. Therefore, to +053 * generate a random sequence of values or strings, you should use just +054 * <strong>one</strong> <code>RandomDataImpl</code> instance repeatedly.</li> +055 * <li> +056 * The "secure" methods are *much* slower. These should be used only when a +057 * cryptographically secure random sequence is required. A secure random +058 * sequence is a sequence of pseudo-random values which, in addition to being +059 * well-dispersed (so no subsequence of values is an any more likely than other +060 * subsequence of the the same length), also has the additional property that +061 * knowledge of values generated up to any point in the sequence does not make +062 * it any easier to predict subsequent values.</li> +063 * <li> +064 * When a new <code>RandomDataImpl</code> is created, the underlying random +065 * number generators are <strong>not</strong> intialized. If you do not +066 * explicitly seed the default non-secure generator, it is seeded with the +067 * current time in milliseconds on first use. The same holds for the secure +068 * generator. If you provide a <code>RandomGenerator</code> to the constructor, +069 * however, this generator is not reseeded by the constructor nor is it reseeded +070 * on first use.</li> +071 * <li> +072 * The <code>reSeed</code> and <code>reSeedSecure</code> methods delegate to the +073 * corresponding methods on the underlying <code>RandomGenerator</code> and +074 * <code>SecureRandom</code> instances. Therefore, <code>reSeed(long)</code> +075 * fully resets the initial state of the non-secure random number generator (so +076 * that reseeding with a specific value always results in the same subsequent +077 * random sequence); whereas reSeedSecure(long) does <strong>not</strong> +078 * reinitialize the secure random number generator (so secure sequences started +079 * with calls to reseedSecure(long) won't be identical).</li> +080 * <li> +081 * This implementation is not synchronized. +082 * </ul> +083 * </p> +084 * +085 * @version $Revision: 831510 $ $Date: 2009-10-30 22:30:18 -0400 (Fri, 30 Oct 2009) $ +086 */ +087 public class RandomDataImpl implements RandomData, Serializable { +088 +089 /** Serializable version identifier */ +090 private static final long serialVersionUID = -626730818244969716L; +091 +092 /** underlying random number generator */ +093 private RandomGenerator rand = null; +094 +095 /** underlying secure random number generator */ +096 private SecureRandom secRand = null; +097 +098 /** +099 * Construct a RandomDataImpl. +100 */ +101 public RandomDataImpl() { +102 } +103 +104 /** +105 * Construct a RandomDataImpl using the supplied {@link RandomGenerator} as +106 * the source of (non-secure) random data. +107 * +108 * @param rand +109 * the source of (non-secure) random data +110 * @since 1.1 +111 */ +112 public RandomDataImpl(RandomGenerator rand) { +113 super(); +114 this.rand = rand; +115 } +116 +117 /** +118 * {@inheritDoc} +119 * <p> +120 * <strong>Algorithm Description:</strong> hex strings are generated using a +121 * 2-step process. +122 * <ol> +123 * <li> +124 * len/2+1 binary bytes are generated using the underlying Random</li> +125 * <li> +126 * Each binary byte is translated into 2 hex digits</li> +127 * </ol> +128 * </p> +129 * +130 * @param len +131 * the desired string length. +132 * @return the random string. +133 */ +134 public String nextHexString(int len) { +135 if (len <= 0) { +136 throw MathRuntimeException.createIllegalArgumentException( +137 "length must be positive ({0})", len); +138 } +139 +140 // Get a random number generator +141 RandomGenerator ran = getRan(); +142 +143 // Initialize output buffer +144 StringBuffer outBuffer = new StringBuffer(); +145 +146 // Get int(len/2)+1 random bytes +147 byte[] randomBytes = new byte[(len / 2) + 1]; +148 ran.nextBytes(randomBytes); +149 +150 // Convert each byte to 2 hex digits +151 for (int i = 0; i < randomBytes.length; i++) { +152 Integer c = Integer.valueOf(randomBytes[i]); +153 +154 /* +155 * Add 128 to byte value to make interval 0-255 before doing hex +156 * conversion. This guarantees <= 2 hex digits from toHexString() +157 * toHexString would otherwise add 2^32 to negative arguments. +158 */ +159 String hex = Integer.toHexString(c.intValue() + 128); +160 +161 // Make sure we add 2 hex digits for each byte +162 if (hex.length() == 1) { +163 hex = "0" + hex; +164 } +165 outBuffer.append(hex); +166 } +167 return outBuffer.toString().substring(0, len); +168 } +169 +170 /** +171 * Generate a random int value uniformly distributed between +172 * <code>lower</code> and <code>upper</code>, inclusive. +173 * +174 * @param lower +175 * the lower bound. +176 * @param upper +177 * the upper bound. +178 * @return the random integer. +179 */ +180 public int nextInt(int lower, int upper) { +181 if (lower >= upper) { +182 throw MathRuntimeException.createIllegalArgumentException( +183 "upper bound ({0}) must be greater than lower bound ({1})", +184 upper, lower); +185 } +186 double r = getRan().nextDouble(); +187 return (int) ((r * upper) + ((1.0 - r) * lower) + r); +188 } +189 +190 /** +191 * Generate a random long value uniformly distributed between +192 * <code>lower</code> and <code>upper</code>, inclusive. +193 * +194 * @param lower +195 * the lower bound. +196 * @param upper +197 * the upper bound. +198 * @return the random integer. +199 */ +200 public long nextLong(long lower, long upper) { +201 if (lower >= upper) { +202 throw MathRuntimeException.createIllegalArgumentException( +203 "upper bound ({0}) must be greater than lower bound ({1})", +204 upper, lower); +205 } +206 double r = getRan().nextDouble(); +207 return (long) ((r * upper) + ((1.0 - r) * lower) + r); +208 } +209 +210 /** +211 * {@inheritDoc} +212 * <p> +213 * <strong>Algorithm Description:</strong> hex strings are generated in +214 * 40-byte segments using a 3-step process. +215 * <ol> +216 * <li> +217 * 20 random bytes are generated using the underlying +218 * <code>SecureRandom</code>.</li> +219 * <li> +220 * SHA-1 hash is applied to yield a 20-byte binary digest.</li> +221 * <li> +222 * Each byte of the binary digest is converted to 2 hex digits.</li> +223 * </ol> +224 * </p> +225 * +226 * @param len +227 * the length of the generated string +228 * @return the random string +229 */ +230 public String nextSecureHexString(int len) { +231 if (len <= 0) { +232 throw MathRuntimeException.createIllegalArgumentException( +233 "length must be positive ({0})", len); +234 } +235 +236 // Get SecureRandom and setup Digest provider +237 SecureRandom secRan = getSecRan(); +238 MessageDigest alg = null; +239 try { +240 alg = MessageDigest.getInstance("SHA-1"); +241 } catch (NoSuchAlgorithmException ex) { +242 // this should never happen +243 throw MathRuntimeException.createInternalError(ex); +244 } +245 alg.reset(); +246 +247 // Compute number of iterations required (40 bytes each) +248 int numIter = (len / 40) + 1; +249 +250 StringBuffer outBuffer = new StringBuffer(); +251 for (int iter = 1; iter < numIter + 1; iter++) { +252 byte[] randomBytes = new byte[40]; +253 secRan.nextBytes(randomBytes); +254 alg.update(randomBytes); +255 +256 // Compute hash -- will create 20-byte binary hash +257 byte hash[] = alg.digest(); +258 +259 // Loop over the hash, converting each byte to 2 hex digits +260 for (int i = 0; i < hash.length; i++) { +261 Integer c = Integer.valueOf(hash[i]); +262 +263 /* +264 * Add 128 to byte value to make interval 0-255 This guarantees +265 * <= 2 hex digits from toHexString() toHexString would +266 * otherwise add 2^32 to negative arguments +267 */ +268 String hex = Integer.toHexString(c.intValue() + 128); +269 +270 // Keep strings uniform length -- guarantees 40 bytes +271 if (hex.length() == 1) { +272 hex = "0" + hex; +273 } +274 outBuffer.append(hex); +275 } +276 } +277 return outBuffer.toString().substring(0, len); +278 } +279 +280 /** +281 * Generate a random int value uniformly distributed between +282 * <code>lower</code> and <code>upper</code>, inclusive. This algorithm uses +283 * a secure random number generator. +284 * +285 * @param lower +286 * the lower bound. +287 * @param upper +288 * the upper bound. +289 * @return the random integer. +290 */ +291 public int nextSecureInt(int lower, int upper) { +292 if (lower >= upper) { +293 throw MathRuntimeException.createIllegalArgumentException( +294 "upper bound ({0}) must be greater than lower bound ({1})", +295 upper, lower); +296 } +297 SecureRandom sec = getSecRan(); +298 return lower + (int) (sec.nextDouble() * (upper - lower + 1)); +299 } +300 +301 /** +302 * Generate a random long value uniformly distributed between +303 * <code>lower</code> and <code>upper</code>, inclusive. This algorithm uses +304 * a secure random number generator. +305 * +306 * @param lower +307 * the lower bound. +308 * @param upper +309 * the upper bound. +310 * @return the random integer. +311 */ +312 public long nextSecureLong(long lower, long upper) { +313 if (lower >= upper) { +314 throw MathRuntimeException.createIllegalArgumentException( +315 "upper bound ({0}) must be greater than lower bound ({1})", +316 upper, lower); +317 } +318 SecureRandom sec = getSecRan(); +319 return lower + (long) (sec.nextDouble() * (upper - lower + 1)); +320 } +321 +322 /** +323 * {@inheritDoc} +324 * <p> +325 * <strong>Algorithm Description</strong>: +326 * <ul><li> For small means, uses simulation of a Poisson process +327 * using Uniform deviates, as described +328 * <a href="http://irmi.epfl.ch/cmos/Pmmi/interactive/rng7.htm"> here.</a> +329 * The Poisson process (and hence value returned) is bounded by 1000 * mean.</li> +330 * +331 * <li> For large means, uses the rejection algorithm described in <br/> +332 * Devroye, Luc. (1981).<i>The Computer Generation of Poisson Random Variables</i> +333 * <strong>Computing</strong> vol. 26 pp. 197-207.</li></ul></p> +334 * +335 * @param mean mean of the Poisson distribution. +336 * @return the random Poisson value. +337 */ +338 public long nextPoisson(double mean) { +339 if (mean <= 0) { +340 throw MathRuntimeException.createIllegalArgumentException( +341 "the Poisson mean must be positive ({0})", mean); +342 } +343 +344 final RandomGenerator generator = getRan(); +345 +346 final double pivot = 40.0d; +347 if (mean < pivot) { +348 double p = Math.exp(-mean); +349 long n = 0; +350 double r = 1.0d; +351 double rnd = 1.0d; +352 +353 while (n < 1000 * mean) { +354 rnd = generator.nextDouble(); +355 r = r * rnd; +356 if (r >= p) { +357 n++; +358 } else { +359 return n; +360 } +361 } +362 return n; +363 } else { +364 final double lambda = Math.floor(mean); +365 final double lambdaFractional = mean - lambda; +366 final double logLambda = Math.log(lambda); +367 final double logLambdaFactorial = MathUtils.factorialLog((int) lambda); +368 final long y2 = lambdaFractional < Double.MIN_VALUE ? 0 : nextPoisson(lambdaFractional); +369 final double delta = Math.sqrt(lambda * Math.log(32 * lambda / Math.PI + 1)); +370 final double halfDelta = delta / 2; +371 final double twolpd = 2 * lambda + delta; +372 final double a1 = Math.sqrt(Math.PI * twolpd) * Math.exp(1 / 8 * lambda); +373 final double a2 = (twolpd / delta) * Math.exp(-delta * (1 + delta) / twolpd); +374 final double aSum = a1 + a2 + 1; +375 final double p1 = a1 / aSum; +376 final double p2 = a2 / aSum; +377 final double c1 = 1 / (8 * lambda); +378 +379 double x = 0; +380 double y = 0; +381 double v = 0; +382 int a = 0; +383 double t = 0; +384 double qr = 0; +385 double qa = 0; +386 for (;;) { +387 final double u = nextUniform(0.0, 1); +388 if (u <= p1) { +389 final double n = nextGaussian(0d, 1d); +390 x = n * Math.sqrt(lambda + halfDelta) - 0.5d; +391 if (x > delta || x < -lambda) { +392 continue; +393 } +394 y = x < 0 ? Math.floor(x) : Math.ceil(x); +395 final double e = nextExponential(1d); +396 v = -e - (n * n / 2) + c1; +397 } else { +398 if (u > p1 + p2) { +399 y = lambda; +400 break; +401 } else { +402 x = delta + (twolpd / delta) * nextExponential(1d); +403 y = Math.ceil(x); +404 v = -nextExponential(1d) - delta * (x + 1) / twolpd; +405 } +406 } +407 a = x < 0 ? 1 : 0; +408 t = y * (y + 1) / (2 * lambda); +409 if (v < -t && a == 0) { +410 y = lambda + y; +411 break; +412 } +413 qr = t * ((2 * y + 1) / (6 * lambda) - 1); +414 qa = qr - (t * t) / (3 * (lambda + a * (y + 1))); +415 if (v < qa) { +416 y = lambda + y; +417 break; +418 } +419 if (v > qr) { +420 continue; +421 } +422 if (v < y * logLambda - MathUtils.factorialLog((int) (y + lambda)) + logLambdaFactorial) { +423 y = lambda + y; +424 break; +425 } +426 } +427 return y2 + (long) y; +428 } +429 } +430 +431 /** +432 * Generate a random value from a Normal (a.k.a. Gaussian) distribution with +433 * the given mean, <code>mu</code> and the given standard deviation, +434 * <code>sigma</code>. +435 * +436 * @param mu +437 * the mean of the distribution +438 * @param sigma +439 * the standard deviation of the distribution +440 * @return the random Normal value +441 */ +442 public double nextGaussian(double mu, double sigma) { +443 if (sigma <= 0) { +444 throw MathRuntimeException.createIllegalArgumentException( +445 "standard deviation must be positive ({0})", sigma); +446 } +447 return sigma * getRan().nextGaussian() + mu; +448 } +449 +450 /** +451 * Returns a random value from an Exponential distribution with the given +452 * mean. +453 * <p> +454 * <strong>Algorithm Description</strong>: Uses the <a +455 * href="http://www.jesus.ox.ac.uk/~clifford/a5/chap1/node5.html"> Inversion +456 * Method</a> to generate exponentially distributed random values from +457 * uniform deviates. +458 * </p> +459 * +460 * @param mean the mean of the distribution +461 * @return the random Exponential value +462 */ +463 public double nextExponential(double mean) { +464 if (mean <= 0.0) { +465 throw MathRuntimeException.createIllegalArgumentException( +466 "mean must be positive ({0})", mean); +467 } +468 final RandomGenerator generator = getRan(); +469 double unif = generator.nextDouble(); +470 while (unif == 0.0d) { +471 unif = generator.nextDouble(); +472 } +473 return -mean * Math.log(unif); +474 } +475 +476 /** +477 * {@inheritDoc} +478 * <p> +479 * <strong>Algorithm Description</strong>: scales the output of +480 * Random.nextDouble(), but rejects 0 values (i.e., will generate another +481 * random double if Random.nextDouble() returns 0). This is necessary to +482 * provide a symmetric output interval (both endpoints excluded). +483 * </p> +484 * +485 * @param lower +486 * the lower bound. +487 * @param upper +488 * the upper bound. +489 * @return a uniformly distributed random value from the interval (lower, +490 * upper) +491 */ +492 public double nextUniform(double lower, double upper) { +493 if (lower >= upper) { +494 throw MathRuntimeException.createIllegalArgumentException( +495 "upper bound ({0}) must be greater than lower bound ({1})", +496 upper, lower); +497 } +498 final RandomGenerator generator = getRan(); +499 +500 // ensure nextDouble() isn't 0.0 +501 double u = generator.nextDouble(); +502 while (u <= 0.0) { +503 u = generator.nextDouble(); +504 } +505 +506 return lower + u * (upper - lower); +507 } +508 +509 /** +510 * Returns the RandomGenerator used to generate non-secure random data. +511 * <p> +512 * Creates and initializes a default generator if null. +513 * </p> +514 * +515 * @return the Random used to generate random data +516 * @since 1.1 +517 */ +518 private RandomGenerator getRan() { +519 if (rand == null) { +520 rand = new JDKRandomGenerator(); +521 rand.setSeed(System.currentTimeMillis()); +522 } +523 return rand; +524 } +525 +526 /** +527 * Returns the SecureRandom used to generate secure random data. +528 * <p> +529 * Creates and initializes if null. +530 * </p> +531 * +532 * @return the SecureRandom used to generate secure random data +533 */ +534 private SecureRandom getSecRan() { +535 if (secRand == null) { +536 secRand = new SecureRandom(); +537 secRand.setSeed(System.currentTimeMillis()); +538 } +539 return secRand; +540 } +541 +542 /** +543 * Reseeds the random number generator with the supplied seed. +544 * <p> +545 * Will create and initialize if null. +546 * </p> +547 * +548 * @param seed +549 * the seed value to use +550 */ +551 public void reSeed(long seed) { +552 if (rand == null) { +553 rand = new JDKRandomGenerator(); +554 } +555 rand.setSeed(seed); +556 } +557 +558 /** +559 * Reseeds the secure random number generator with the current time in +560 * milliseconds. +561 * <p> +562 * Will create and initialize if null. +563 * </p> +564 */ +565 public void reSeedSecure() { +566 if (secRand == null) { +567 secRand = new SecureRandom(); +568 } +569 secRand.setSeed(System.currentTimeMillis()); +570 } +571 +572 /** +573 * Reseeds the secure random number generator with the supplied seed. +574 * <p> +575 * Will create and initialize if null. +576 * </p> +577 * +578 * @param seed +579 * the seed value to use +580 */ +581 public void reSeedSecure(long seed) { +582 if (secRand == null) { +583 secRand = new SecureRandom(); +584 } +585 secRand.setSeed(seed); +586 } +587 +588 /** +589 * Reseeds the random number generator with the current time in +590 * milliseconds. +591 */ +592 public void reSeed() { +593 if (rand == null) { +594 rand = new JDKRandomGenerator(); +595 } +596 rand.setSeed(System.currentTimeMillis()); +597 } +598 +599 /** +600 * Sets the PRNG algorithm for the underlying SecureRandom instance using +601 * the Security Provider API. The Security Provider API is defined in <a +602 * href = +603 * "http://java.sun.com/j2se/1.3/docs/guide/security/CryptoSpec.html#AppA"> +604 * Java Cryptography Architecture API Specification & Reference.</a> +605 * <p> +606 * <strong>USAGE NOTE:</strong> This method carries <i>significant</i> +607 * overhead and may take several seconds to execute. +608 * </p> +609 * +610 * @param algorithm +611 * the name of the PRNG algorithm +612 * @param provider +613 * the name of the provider +614 * @throws NoSuchAlgorithmException +615 * if the specified algorithm is not available +616 * @throws NoSuchProviderException +617 * if the specified provider is not installed +618 */ +619 public void setSecureAlgorithm(String algorithm, String provider) +620 throws NoSuchAlgorithmException, NoSuchProviderException { +621 secRand = SecureRandom.getInstance(algorithm, provider); +622 } +623 +624 /** +625 * Generates an integer array of length <code>k</code> whose entries are +626 * selected randomly, without repetition, from the integers +627 * <code>0 through n-1</code> (inclusive). +628 * <p> +629 * Generated arrays represent permutations of <code>n</code> taken +630 * <code>k</code> at a time. +631 * </p> +632 * <p> +633 * <strong>Preconditions:</strong> +634 * <ul> +635 * <li> <code>k <= n</code></li> +636 * <li> <code>n > 0</code></li> +637 * </ul> +638 * If the preconditions are not met, an IllegalArgumentException is thrown. +639 * </p> +640 * <p> +641 * Uses a 2-cycle permutation shuffle. The shuffling process is described <a +642 * href="http://www.maths.abdn.ac.uk/~igc/tch/mx4002/notes/node83.html"> +643 * here</a>. +644 * </p> +645 * +646 * @param n +647 * domain of the permutation (must be positive) +648 * @param k +649 * size of the permutation (must satisfy 0 < k <= n). +650 * @return the random permutation as an int array +651 */ +652 public int[] nextPermutation(int n, int k) { +653 if (k > n) { +654 throw MathRuntimeException.createIllegalArgumentException( +655 "permutation k ({0}) exceeds n ({1})", k, n); +656 } +657 if (k == 0) { +658 throw MathRuntimeException.createIllegalArgumentException( +659 "permutation k ({0}) must be positive", k); +660 } +661 +662 int[] index = getNatural(n); +663 shuffle(index, n - k); +664 int[] result = new int[k]; +665 for (int i = 0; i < k; i++) { +666 result[i] = index[n - i - 1]; +667 } +668 +669 return result; +670 } +671 +672 /** +673 * Uses a 2-cycle permutation shuffle to generate a random permutation. +674 * <strong>Algorithm Description</strong>: Uses a 2-cycle permutation +675 * shuffle to generate a random permutation of <code>c.size()</code> and +676 * then returns the elements whose indexes correspond to the elements of the +677 * generated permutation. This technique is described, and proven to +678 * generate random samples, <a +679 * href="http://www.maths.abdn.ac.uk/~igc/tch/mx4002/notes/node83.html"> +680 * here</a> +681 * +682 * @param c +683 * Collection to sample from. +684 * @param k +685 * sample size. +686 * @return the random sample. +687 */ +688 public Object[] nextSample(Collection<?> c, int k) { +689 int len = c.size(); +690 if (k > len) { +691 throw MathRuntimeException.createIllegalArgumentException( +692 "sample size ({0}) exceeds collection size ({1})"); +693 } +694 if (k <= 0) { +695 throw MathRuntimeException.createIllegalArgumentException( +696 "sample size must be positive ({0})", k); +697 } +698 +699 Object[] objects = c.toArray(); +700 int[] index = nextPermutation(len, k); +701 Object[] result = new Object[k]; +702 for (int i = 0; i < k; i++) { +703 result[i] = objects[index[i]]; +704 } +705 return result; +706 } +707 +708 // ------------------------Private methods---------------------------------- +709 +710 /** +711 * Uses a 2-cycle permutation shuffle to randomly re-order the last elements +712 * of list. +713 * +714 * @param list +715 * list to be shuffled +716 * @param end +717 * element past which shuffling begins +718 */ +719 private void shuffle(int[] list, int end) { +720 int target = 0; +721 for (int i = list.length - 1; i >= end; i--) { +722 if (i == 0) { +723 target = 0; +724 } else { +725 target = nextInt(0, i); +726 } +727 int temp = list[target]; +728 list[target] = list[i]; +729 list[i] = temp; +730 } +731 } +732 +733 /** +734 * Returns an array representing n. +735 * +736 * @param n +737 * the natural number to represent +738 * @return array with entries = elements of n +739 */ +740 private int[] getNatural(int n) { +741 int[] natural = new int[n]; +742 for (int i = 0; i < n; i++) { +743 natural[i] = i; +744 } +745 return natural; +746 } +747 +748 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/RandomGenerator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/RandomGenerator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,214 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.random; +018 +019 +020 /** +021 * Interface extracted from <code>java.util.Random</code>. This interface is +022 * implemented by {@link AbstractRandomGenerator}. +023 * +024 * @since 1.1 +025 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +026 */ +027 public interface RandomGenerator { +028 +029 /** +030 * Sets the seed of the underyling random number generator using an +031 * <code>int</code> seed. +032 * <p>Sequences of values generated starting with the same seeds +033 * should be identical. +034 * </p> +035 * @param seed the seed value +036 */ +037 void setSeed(int seed); +038 +039 /** +040 * Sets the seed of the underyling random number generator using an +041 * <code>int</code> array seed. +042 * <p>Sequences of values generated starting with the same seeds +043 * should be identical. +044 * </p> +045 * @param seed the seed value +046 */ +047 void setSeed(int[] seed); +048 +049 /** +050 * Sets the seed of the underyling random number generator using a +051 * <code>long</code> seed. +052 * <p>Sequences of values generated starting with the same seeds +053 * should be identical. +054 * </p> +055 * @param seed the seed value +056 */ +057 void setSeed(long seed); +058 +059 /** +060 * Generates random bytes and places them into a user-supplied +061 * byte array. The number of random bytes produced is equal to +062 * the length of the byte array. +063 * +064 * @param bytes the non-null byte array in which to put the +065 * random bytes +066 */ +067 void nextBytes(byte[] bytes); +068 +069 /** +070 * Returns the next pseudorandom, uniformly distributed <code>int</code> +071 * value from this random number generator's sequence. +072 * All 2<font size="-1"><sup>32</sup></font> possible <tt>int</tt> values +073 * should be produced with (approximately) equal probability. +074 * +075 * @return the next pseudorandom, uniformly distributed <code>int</code> +076 * value from this random number generator's sequence +077 */ +078 int nextInt(); +079 +080 /** +081 * Returns a pseudorandom, uniformly distributed <tt>int</tt> value +082 * between 0 (inclusive) and the specified value (exclusive), drawn from +083 * this random number generator's sequence. +084 * +085 * @param n the bound on the random number to be returned. Must be +086 * positive. +087 * @return a pseudorandom, uniformly distributed <tt>int</tt> +088 * value between 0 (inclusive) and n (exclusive). +089 * @throws IllegalArgumentException if n is not positive. +090 */ +091 int nextInt(int n); +092 +093 /** +094 * Returns the next pseudorandom, uniformly distributed <code>long</code> +095 * value from this random number generator's sequence. All +096 * 2<font size="-1"><sup>64</sup></font> possible <tt>long</tt> values +097 * should be produced with (approximately) equal probability. +098 * +099 * @return the next pseudorandom, uniformly distributed <code>long</code> +100 *value from this random number generator's sequence +101 */ +102 long nextLong(); +103 +104 /** +105 * Returns the next pseudorandom, uniformly distributed +106 * <code>boolean</code> value from this random number generator's +107 * sequence. +108 * +109 * @return the next pseudorandom, uniformly distributed +110 * <code>boolean</code> value from this random number generator's +111 * sequence +112 */ +113 boolean nextBoolean(); +114 +115 /** +116 * Returns the next pseudorandom, uniformly distributed <code>float</code> +117 * value between <code>0.0</code> and <code>1.0</code> from this random +118 * number generator's sequence. +119 * +120 * @return the next pseudorandom, uniformly distributed <code>float</code> +121 * value between <code>0.0</code> and <code>1.0</code> from this +122 * random number generator's sequence +123 */ +124 float nextFloat(); +125 +126 /** +127 * Returns the next pseudorandom, uniformly distributed +128 * <code>double</code> value between <code>0.0</code> and +129 * <code>1.0</code> from this random number generator's sequence. +130 * +131 * @return the next pseudorandom, uniformly distributed +132 * <code>double</code> value between <code>0.0</code> and +133 * <code>1.0</code> from this random number generator's sequence +134 */ +135 double nextDouble(); +136 +137 /** +138 * Returns the next pseudorandom, Gaussian ("normally") distributed +139 * <code>double</code> value with mean <code>0.0</code> and standard +140 * deviation <code>1.0</code> from this random number generator's sequence. +141 * +142 * @return the next pseudorandom, Gaussian ("normally") distributed +143 * <code>double</code> value with mean <code>0.0</code> and +144 * standard deviation <code>1.0</code> from this random number +145 * generator's sequence +146 */ +147 double nextGaussian(); +148 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/RandomVectorGenerator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/RandomVectorGenerator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,101 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.random; +019 +020 +021 /** This interface represents a random generator for whole vectors. +022 * +023 * @since 1.2 +024 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +025 * +026 */ +027 +028 public interface RandomVectorGenerator { +029 +030 /** Generate a random vector. +031 * @return a random vector as an array of double. +032 */ +033 double[] nextVector(); +034 +035 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/UncorrelatedRandomVectorGenerator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/UncorrelatedRandomVectorGenerator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,161 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.random; +019 +020 import java.util.Arrays; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 +024 /** +025 * A {@link RandomVectorGenerator} that generates vectors with uncorrelated +026 * components. Components of generated vectors follow (independent) Gaussian +027 * distributions, with parameters supplied in the constructor. +028 * +029 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +030 * @since 1.2 +031 */ +032 +033 public class UncorrelatedRandomVectorGenerator +034 implements RandomVectorGenerator { +035 +036 /** Underlying scalar generator. */ +037 private final NormalizedRandomGenerator generator; +038 +039 /** Mean vector. */ +040 private final double[] mean; +041 +042 /** Standard deviation vector. */ +043 private final double[] standardDeviation; +044 +045 /** Simple constructor. +046 * <p>Build an uncorrelated random vector generator from +047 * its mean and standard deviation vectors.</p> +048 * @param mean expected mean values for each component +049 * @param standardDeviation standard deviation for each component +050 * @param generator underlying generator for uncorrelated normalized +051 * components +052 */ +053 public UncorrelatedRandomVectorGenerator(double[] mean, +054 double[] standardDeviation, +055 NormalizedRandomGenerator generator) { +056 if (mean.length != standardDeviation.length) { +057 throw MathRuntimeException.createIllegalArgumentException( +058 "dimension mismatch {0} != {1}", +059 mean.length, standardDeviation.length); +060 } +061 this.mean = mean.clone(); +062 this.standardDeviation = standardDeviation.clone(); +063 this.generator = generator; +064 } +065 +066 /** Simple constructor. +067 * <p>Build a null mean random and unit standard deviation +068 * uncorrelated vector generator</p> +069 * @param dimension dimension of the vectors to generate +070 * @param generator underlying generator for uncorrelated normalized +071 * components +072 */ +073 public UncorrelatedRandomVectorGenerator(int dimension, +074 NormalizedRandomGenerator generator) { +075 mean = new double[dimension]; +076 standardDeviation = new double[dimension]; +077 Arrays.fill(standardDeviation, 1.0); +078 this.generator = generator; +079 } +080 +081 /** Generate an uncorrelated random vector. +082 * @return a random vector as a newly built array of double +083 */ +084 public double[] nextVector() { +085 +086 double[] random = new double[mean.length]; +087 for (int i = 0; i < random.length; ++i) { +088 random[i] = mean[i] + standardDeviation[i] * generator.nextNormalizedDouble(); +089 } +090 +091 return random; +092 +093 } +094 +095 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/UniformRandomGenerator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/UniformRandomGenerator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,125 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.random; +019 +020 /** +021 * This class implements a normalized uniform random generator. +022 * <p>Since it is a normalized random generator, it generates values +023 * from a uniform distribution with mean equal to 0 and standard +024 * deviation equal to 1. Generated values fall in the range +025 * [-√3, +√3].</p> +026 * +027 * @since 1.2 +028 * +029 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +030 */ +031 +032 public class UniformRandomGenerator implements NormalizedRandomGenerator { +033 +034 /** Serializable version identifier. */ +035 private static final long serialVersionUID = 1569292426375546027L; +036 +037 /** Square root of three. */ +038 private static final double SQRT3 = Math.sqrt(3.0); +039 +040 /** Underlying generator. */ +041 private final RandomGenerator generator; +042 +043 /** Create a new generator. +044 * @param generator underlying random generator to use +045 */ +046 public UniformRandomGenerator(RandomGenerator generator) { +047 this.generator = generator; +048 } +049 +050 /** Generate a random scalar with null mean and unit standard deviation. +051 * <p>The number generated is uniformly distributed between -&sqrt;(3) +052 * and +&sqrt;(3).</p> +053 * @return a random scalar with null mean and unit standard deviation +054 */ +055 public double nextNormalizedDouble() { +056 return SQRT3 * (2 * generator.nextDouble() - 1.0); +057 } +058 +059 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/UnitSphereRandomVectorGenerator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/UnitSphereRandomVectorGenerator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,148 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.random; +019 +020 +021 /** +022 * Generate random vectors isotropically located on the surface of a sphere. +023 * +024 * @since 2.1 +025 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +026 */ +027 +028 public class UnitSphereRandomVectorGenerator +029 implements RandomVectorGenerator { +030 /** +031 * RNG used for generating the individual components of the vectors. +032 */ +033 private final RandomGenerator rand; +034 /** +035 * Space dimension. +036 */ +037 private final int dimension; +038 +039 /** +040 * @param dimension Space dimension. +041 * @param rand RNG for the individual components of the vectors. +042 */ +043 public UnitSphereRandomVectorGenerator(final int dimension, +044 final RandomGenerator rand) { +045 this.dimension = dimension; +046 this.rand = rand; +047 } +048 /** +049 * Create an object that will use a default RNG ({@link MersenneTwister}), +050 * in order to generate the individual components. +051 * +052 * @param dimension Space dimension. +053 */ +054 public UnitSphereRandomVectorGenerator(final int dimension) { +055 this(dimension, new MersenneTwister()); +056 } +057 +058 /** {@inheritDoc} */ +059 public double[] nextVector() { +060 +061 final double[] v = new double[dimension]; +062 +063 double normSq; +064 do { +065 normSq = 0; +066 for (int i = 0; i < dimension; i++) { +067 final double comp = 2 * rand.nextDouble() - 1; +068 v[i] = comp; +069 normSq += comp * comp; +070 } +071 } while (normSq > 1); +072 +073 final double f = 1 / Math.sqrt(normSq); +074 for (int i = 0; i < dimension; i++) { +075 v[i] *= f; +076 } +077 +078 return v; +079 +080 } +081 +082 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/ValueServer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/random/ValueServer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,450 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.random; +019 import java.io.BufferedReader; +020 import java.io.IOException; +021 import java.io.InputStreamReader; +022 import java.net.MalformedURLException; +023 import java.net.URL; +024 +025 import org.apache.commons.math.MathRuntimeException; +026 +027 /** +028 * Generates values for use in simulation applications. +029 * <p> +030 * How values are generated is determined by the <code>mode</code> +031 * property.</p> +032 * <p> +033 * Supported <code>mode</code> values are: <ul> +034 * <li> DIGEST_MODE -- uses an empirical distribution </li> +035 * <li> REPLAY_MODE -- replays data from <code>valuesFileURL</code></li> +036 * <li> UNIFORM_MODE -- generates uniformly distributed random values with +037 * mean = <code>mu</code> </li> +038 * <li> EXPONENTIAL_MODE -- generates exponentially distributed random values +039 * with mean = <code>mu</code></li> +040 * <li> GAUSSIAN_MODE -- generates Gaussian distributed random values with +041 * mean = <code>mu</code> and +042 * standard deviation = <code>sigma</code></li> +043 * <li> CONSTANT_MODE -- returns <code>mu</code> every time.</li></ul></p> +044 * +045 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +046 * +047 */ +048 public class ValueServer { +049 +050 /** Use empirical distribution. */ +051 public static final int DIGEST_MODE = 0; +052 +053 /** Replay data from valuesFilePath. */ +054 public static final int REPLAY_MODE = 1; +055 +056 /** Uniform random deviates with mean = μ. */ +057 public static final int UNIFORM_MODE = 2; +058 +059 /** Exponential random deviates with mean = μ. */ +060 public static final int EXPONENTIAL_MODE = 3; +061 +062 /** Gaussian random deviates with mean = μ, std dev = σ. */ +063 public static final int GAUSSIAN_MODE = 4; +064 +065 /** Always return mu */ +066 public static final int CONSTANT_MODE = 5; +067 +068 /** mode determines how values are generated. */ +069 private int mode = 5; +070 +071 /** URI to raw data values. */ +072 private URL valuesFileURL = null; +073 +074 /** Mean for use with non-data-driven modes. */ +075 private double mu = 0.0; +076 +077 /** Standard deviation for use with GAUSSIAN_MODE. */ +078 private double sigma = 0.0; +079 +080 /** Empirical probability distribution for use with DIGEST_MODE. */ +081 private EmpiricalDistribution empiricalDistribution = null; +082 +083 /** File pointer for REPLAY_MODE. */ +084 private BufferedReader filePointer = null; +085 +086 /** RandomDataImpl to use for random data generation. */ +087 private RandomData randomData = new RandomDataImpl(); +088 +089 // Data generation modes ====================================== +090 +091 /** Creates new ValueServer */ +092 public ValueServer() { +093 } +094 +095 /** +096 * Construct a ValueServer instance using a RandomData as its source +097 * of random data. +098 * +099 * @param randomData the RandomData instance used to source random data +100 * @since 1.1 +101 */ +102 public ValueServer(RandomData randomData) { +103 this.randomData = randomData; +104 } +105 +106 /** +107 * Returns the next generated value, generated according +108 * to the mode value (see MODE constants). +109 * +110 * @return generated value +111 * @throws IOException in REPLAY_MODE if a file I/O error occurs +112 */ +113 public double getNext() throws IOException { +114 switch (mode) { +115 case DIGEST_MODE: return getNextDigest(); +116 case REPLAY_MODE: return getNextReplay(); +117 case UNIFORM_MODE: return getNextUniform(); +118 case EXPONENTIAL_MODE: return getNextExponential(); +119 case GAUSSIAN_MODE: return getNextGaussian(); +120 case CONSTANT_MODE: return mu; +121 default: throw MathRuntimeException.createIllegalStateException( +122 "unknown mode {0}, known modes: " + +123 "{1} ({2}), {3} ({4}), {5} ({6}), {7} ({8}), {9} ({10}) and {11} ({12})", +124 mode, +125 "DIGEST_MODE", DIGEST_MODE, "REPLAY_MODE", REPLAY_MODE, +126 "UNIFORM_MODE", UNIFORM_MODE, "EXPONENTIAL_MODE", EXPONENTIAL_MODE, +127 "GAUSSIAN_MODE", GAUSSIAN_MODE, "CONSTANT_MODE", CONSTANT_MODE); +128 } +129 } +130 +131 /** +132 * Fills the input array with values generated using getNext() repeatedly. +133 * +134 * @param values array to be filled +135 * @throws IOException in REPLAY_MODE if a file I/O error occurs +136 */ +137 public void fill(double[] values) throws IOException { +138 for (int i = 0; i < values.length; i++) { +139 values[i] = getNext(); +140 } +141 } +142 +143 /** +144 * Returns an array of length <code>length</code> with values generated +145 * using getNext() repeatedly. +146 * +147 * @param length length of output array +148 * @return array of generated values +149 * @throws IOException in REPLAY_MODE if a file I/O error occurs +150 */ +151 public double[] fill(int length) throws IOException { +152 double[] out = new double[length]; +153 for (int i = 0; i < length; i++) { +154 out[i] = getNext(); +155 } +156 return out; +157 } +158 +159 /** +160 * Computes the empirical distribution using values from the file +161 * in <code>valuesFileURL</code>, using the default number of bins. +162 * <p> +163 * <code>valuesFileURL</code> must exist and be +164 * readable by *this at runtime.</p> +165 * <p> +166 * This method must be called before using <code>getNext()</code> +167 * with <code>mode = DIGEST_MODE</code></p> +168 * +169 * @throws IOException if an I/O error occurs reading the input file +170 */ +171 public void computeDistribution() throws IOException { +172 empiricalDistribution = new EmpiricalDistributionImpl(); +173 empiricalDistribution.load(valuesFileURL); +174 } +175 +176 /** +177 * Computes the empirical distribution using values from the file +178 * in <code>valuesFileURL</code> and <code>binCount</code> bins. +179 * <p> +180 * <code>valuesFileURL</code> must exist and be readable by this process +181 * at runtime.</p> +182 * <p> +183 * This method must be called before using <code>getNext()</code> +184 * with <code>mode = DIGEST_MODE</code></p> +185 * +186 * @param binCount the number of bins used in computing the empirical +187 * distribution +188 * @throws IOException if an error occurs reading the input file +189 */ +190 public void computeDistribution(int binCount) +191 throws IOException { +192 empiricalDistribution = new EmpiricalDistributionImpl(binCount); +193 empiricalDistribution.load(valuesFileURL); +194 mu = empiricalDistribution.getSampleStats().getMean(); +195 sigma = empiricalDistribution.getSampleStats().getStandardDeviation(); +196 } +197 +198 /** Getter for property mode. +199 * @return Value of property mode. +200 */ +201 public int getMode() { +202 return mode; +203 } +204 +205 /** Setter for property mode. +206 * @param mode New value of property mode. +207 */ +208 public void setMode(int mode) { +209 this.mode = mode; +210 } +211 +212 /** +213 * Getter for <code>valuesFileURL<code> +214 * @return Value of property valuesFileURL. +215 */ +216 public URL getValuesFileURL() { +217 return valuesFileURL; +218 } +219 +220 /** +221 * Sets the <code>valuesFileURL</code> using a string URL representation +222 * @param url String representation for new valuesFileURL. +223 * @throws MalformedURLException if url is not well formed +224 */ +225 public void setValuesFileURL(String url) throws MalformedURLException { +226 this.valuesFileURL = new URL(url); +227 } +228 +229 /** +230 * Sets the <code>valuesFileURL</code> +231 * @param url New value of property valuesFileURL. +232 */ +233 public void setValuesFileURL(URL url) { +234 this.valuesFileURL = url; +235 } +236 +237 /** Getter for property empiricalDistribution. +238 * @return Value of property empiricalDistribution. +239 */ +240 public EmpiricalDistribution getEmpiricalDistribution() { +241 return empiricalDistribution; +242 } +243 +244 /** +245 * Resets REPLAY_MODE file pointer to the beginning of the <code>valuesFileURL</code>. +246 * +247 * @throws IOException if an error occurs opening the file +248 */ +249 public void resetReplayFile() throws IOException { +250 if (filePointer != null) { +251 try { +252 filePointer.close(); +253 filePointer = null; +254 } catch (IOException ex) { +255 // ignore +256 } +257 } +258 filePointer = new BufferedReader(new InputStreamReader(valuesFileURL.openStream())); +259 } +260 +261 /** +262 * Closes <code>valuesFileURL</code> after use in REPLAY_MODE. +263 * +264 * @throws IOException if an error occurs closing the file +265 */ +266 public void closeReplayFile() throws IOException { +267 if (filePointer != null) { +268 filePointer.close(); +269 filePointer = null; +270 } +271 } +272 +273 /** Getter for property mu. +274 * @return Value of property mu. +275 */ +276 public double getMu() { +277 return mu; +278 } +279 +280 /** Setter for property mu. +281 * @param mu New value of property mu. +282 */ +283 public void setMu(double mu) { +284 this.mu = mu; +285 } +286 +287 /** Getter for property sigma. +288 * @return Value of property sigma. +289 */ +290 public double getSigma() { +291 return sigma; +292 } +293 +294 /** Setter for property sigma. +295 * @param sigma New value of property sigma. +296 */ +297 public void setSigma(double sigma) { +298 this.sigma = sigma; +299 } +300 +301 //------------- private methods --------------------------------- +302 +303 /** +304 * Gets a random value in DIGEST_MODE. +305 * <p> +306 * <strong>Preconditions</strong>: <ul> +307 * <li>Before this method is called, <code>computeDistribution()</code> +308 * must have completed successfully; otherwise an +309 * <code>IllegalStateException</code> will be thrown</li></ul></p> +310 * +311 * @return next random value from the empirical distribution digest +312 */ +313 private double getNextDigest() { +314 if ((empiricalDistribution == null) || +315 (empiricalDistribution.getBinStats().size() == 0)) { +316 throw MathRuntimeException.createIllegalStateException("digest not initialized"); +317 } +318 return empiricalDistribution.getNextValue(); +319 } +320 +321 /** +322 * Gets next sequential value from the <code>valuesFileURL</code>. +323 * <p> +324 * Throws an IOException if the read fails.</p> +325 * <p> +326 * This method will open the <code>valuesFileURL</code> if there is no +327 * replay file open.</p> +328 * <p> +329 * The <code>valuesFileURL</code> will be closed and reopened to wrap around +330 * from EOF to BOF if EOF is encountered. EOFException (which is a kind of +331 * IOException) may still be thrown if the <code>valuesFileURL</code> is +332 * empty.</p> +333 * +334 * @return next value from the replay file +335 * @throws IOException if there is a problem reading from the file +336 * @throws NumberFormatException if an invalid numeric string is +337 * encountered in the file +338 */ +339 private double getNextReplay() throws IOException { +340 String str = null; +341 if (filePointer == null) { +342 resetReplayFile(); +343 } +344 if ((str = filePointer.readLine()) == null) { +345 // we have probably reached end of file, wrap around from EOF to BOF +346 closeReplayFile(); +347 resetReplayFile(); +348 if ((str = filePointer.readLine()) == null) { +349 throw MathRuntimeException.createEOFException("URL {0} contains no data", +350 valuesFileURL); +351 } +352 } +353 return Double.valueOf(str).doubleValue(); +354 } +355 +356 /** +357 * Gets a uniformly distributed random value with mean = mu. +358 * +359 * @return random uniform value +360 */ +361 private double getNextUniform() { +362 return randomData.nextUniform(0, 2 * mu); +363 } +364 +365 /** +366 * Gets an exponentially distributed random value with mean = mu. +367 * +368 * @return random exponential value +369 */ +370 private double getNextExponential() { +371 return randomData.nextExponential(mu); +372 } +373 +374 /** +375 * Gets a Gaussian distributed random value with mean = mu +376 * and standard deviation = sigma. +377 * +378 * @return random Gaussian value +379 */ +380 private double getNextGaussian() { +381 return randomData.nextGaussian(mu, sigma); +382 } +383 +384 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/special/Beta.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/special/Beta.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,267 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.special; +018 +019 import org.apache.commons.math.MathException; +020 import org.apache.commons.math.util.ContinuedFraction; +021 +022 /** +023 * This is a utility class that provides computation methods related to the +024 * Beta family of functions. +025 * +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 */ +028 public class Beta { +029 +030 /** Maximum allowed numerical error. */ +031 private static final double DEFAULT_EPSILON = 10e-15; +032 +033 /** +034 * Default constructor. Prohibit instantiation. +035 */ +036 private Beta() { +037 super(); +038 } +039 +040 /** +041 * Returns the +042 * <a href="http://mathworld.wolfram.com/RegularizedBetaFunction.html"> +043 * regularized beta function</a> I(x, a, b). +044 * +045 * @param x the value. +046 * @param a the a parameter. +047 * @param b the b parameter. +048 * @return the regularized beta function I(x, a, b) +049 * @throws MathException if the algorithm fails to converge. +050 */ +051 public static double regularizedBeta(double x, double a, double b) +052 throws MathException +053 { +054 return regularizedBeta(x, a, b, DEFAULT_EPSILON, Integer.MAX_VALUE); +055 } +056 +057 /** +058 * Returns the +059 * <a href="http://mathworld.wolfram.com/RegularizedBetaFunction.html"> +060 * regularized beta function</a> I(x, a, b). +061 * +062 * @param x the value. +063 * @param a the a parameter. +064 * @param b the b parameter. +065 * @param epsilon When the absolute value of the nth item in the +066 * series is less than epsilon the approximation ceases +067 * to calculate further elements in the series. +068 * @return the regularized beta function I(x, a, b) +069 * @throws MathException if the algorithm fails to converge. +070 */ +071 public static double regularizedBeta(double x, double a, double b, +072 double epsilon) throws MathException +073 { +074 return regularizedBeta(x, a, b, epsilon, Integer.MAX_VALUE); +075 } +076 +077 /** +078 * Returns the regularized beta function I(x, a, b). +079 * +080 * @param x the value. +081 * @param a the a parameter. +082 * @param b the b parameter. +083 * @param maxIterations Maximum number of "iterations" to complete. +084 * @return the regularized beta function I(x, a, b) +085 * @throws MathException if the algorithm fails to converge. +086 */ +087 public static double regularizedBeta(double x, double a, double b, +088 int maxIterations) throws MathException +089 { +090 return regularizedBeta(x, a, b, DEFAULT_EPSILON, maxIterations); +091 } +092 +093 /** +094 * Returns the regularized beta function I(x, a, b). +095 * +096 * The implementation of this method is based on: +097 * <ul> +098 * <li> +099 * <a href="http://mathworld.wolfram.com/RegularizedBetaFunction.html"> +100 * Regularized Beta Function</a>.</li> +101 * <li> +102 * <a href="http://functions.wolfram.com/06.21.10.0001.01"> +103 * Regularized Beta Function</a>.</li> +104 * </ul> +105 * +106 * @param x the value. +107 * @param a the a parameter. +108 * @param b the b parameter. +109 * @param epsilon When the absolute value of the nth item in the +110 * series is less than epsilon the approximation ceases +111 * to calculate further elements in the series. +112 * @param maxIterations Maximum number of "iterations" to complete. +113 * @return the regularized beta function I(x, a, b) +114 * @throws MathException if the algorithm fails to converge. +115 */ +116 public static double regularizedBeta(double x, final double a, +117 final double b, double epsilon, int maxIterations) throws MathException +118 { +119 double ret; +120 +121 if (Double.isNaN(x) || Double.isNaN(a) || Double.isNaN(b) || (x < 0) || +122 (x > 1) || (a <= 0.0) || (b <= 0.0)) +123 { +124 ret = Double.NaN; +125 } else if (x > (a + 1.0) / (a + b + 2.0)) { +126 ret = 1.0 - regularizedBeta(1.0 - x, b, a, epsilon, maxIterations); +127 } else { +128 ContinuedFraction fraction = new ContinuedFraction() { +129 +130 @Override +131 protected double getB(int n, double x) { +132 double ret; +133 double m; +134 if (n % 2 == 0) { // even +135 m = n / 2.0; +136 ret = (m * (b - m) * x) / +137 ((a + (2 * m) - 1) * (a + (2 * m))); +138 } else { +139 m = (n - 1.0) / 2.0; +140 ret = -((a + m) * (a + b + m) * x) / +141 ((a + (2 * m)) * (a + (2 * m) + 1.0)); +142 } +143 return ret; +144 } +145 +146 @Override +147 protected double getA(int n, double x) { +148 return 1.0; +149 } +150 }; +151 ret = Math.exp((a * Math.log(x)) + (b * Math.log(1.0 - x)) - +152 Math.log(a) - logBeta(a, b, epsilon, maxIterations)) * +153 1.0 / fraction.evaluate(x, epsilon, maxIterations); +154 } +155 +156 return ret; +157 } +158 +159 /** +160 * Returns the natural logarithm of the beta function B(a, b). +161 * +162 * @param a the a parameter. +163 * @param b the b parameter. +164 * @return log(B(a, b)) +165 */ +166 public static double logBeta(double a, double b) { +167 return logBeta(a, b, DEFAULT_EPSILON, Integer.MAX_VALUE); +168 } +169 +170 /** +171 * Returns the natural logarithm of the beta function B(a, b). +172 * +173 * The implementation of this method is based on: +174 * <ul> +175 * <li><a href="http://mathworld.wolfram.com/BetaFunction.html"> +176 * Beta Function</a>, equation (1).</li> +177 * </ul> +178 * +179 * @param a the a parameter. +180 * @param b the b parameter. +181 * @param epsilon When the absolute value of the nth item in the +182 * series is less than epsilon the approximation ceases +183 * to calculate further elements in the series. +184 * @param maxIterations Maximum number of "iterations" to complete. +185 * @return log(B(a, b)) +186 */ +187 public static double logBeta(double a, double b, double epsilon, +188 int maxIterations) { +189 +190 double ret; +191 +192 if (Double.isNaN(a) || Double.isNaN(b) || (a <= 0.0) || (b <= 0.0)) { +193 ret = Double.NaN; +194 } else { +195 ret = Gamma.logGamma(a) + Gamma.logGamma(b) - +196 Gamma.logGamma(a + b); +197 } +198 +199 return ret; +200 } +201 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/special/Erf.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/special/Erf.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,123 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.special; +018 +019 import org.apache.commons.math.MathException; +020 +021 /** +022 * This is a utility class that provides computation methods related to the +023 * error functions. +024 * +025 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +026 */ +027 public class Erf { +028 +029 /** +030 * Default constructor. Prohibit instantiation. +031 */ +032 private Erf() { +033 super(); +034 } +035 +036 /** +037 * Returns the error function erf(x). +038 * +039 * The implementation of this method is based on: +040 * <ul> +041 * <li> +042 * <a href="http://mathworld.wolfram.com/Erf.html"> +043 * Erf</a>, equation (3).</li> +044 * </ul> +045 * +046 * @param x the value. +047 * @return the error function erf(x) +048 * @throws MathException if the algorithm fails to converge. +049 */ +050 public static double erf(double x) throws MathException { +051 double ret = Gamma.regularizedGammaP(0.5, x * x, 1.0e-15, 10000); +052 if (x < 0) { +053 ret = -ret; +054 } +055 return ret; +056 } +057 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/special/Gamma.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/special/Gamma.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,404 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.special; +018 +019 import org.apache.commons.math.MathException; +020 import org.apache.commons.math.MaxIterationsExceededException; +021 import org.apache.commons.math.util.ContinuedFraction; +022 +023 /** +024 * This is a utility class that provides computation methods related to the +025 * Gamma family of functions. +026 * +027 * @version $Revision: 920558 $ $Date: 2010-03-08 17:57:32 -0500 (Mon, 08 Mar 2010) $ +028 */ +029 public class Gamma { +030 +031 /** +032 * <a href="http://en.wikipedia.org/wiki/Euler-Mascheroni_constant">Euler-Mascheroni constant</a> +033 * @since 2.0 +034 */ +035 public static final double GAMMA = 0.577215664901532860606512090082; +036 +037 /** Maximum allowed numerical error. */ +038 private static final double DEFAULT_EPSILON = 10e-15; +039 +040 /** Lanczos coefficients */ +041 private static final double[] LANCZOS = +042 { +043 0.99999999999999709182, +044 57.156235665862923517, +045 -59.597960355475491248, +046 14.136097974741747174, +047 -0.49191381609762019978, +048 .33994649984811888699e-4, +049 .46523628927048575665e-4, +050 -.98374475304879564677e-4, +051 .15808870322491248884e-3, +052 -.21026444172410488319e-3, +053 .21743961811521264320e-3, +054 -.16431810653676389022e-3, +055 .84418223983852743293e-4, +056 -.26190838401581408670e-4, +057 .36899182659531622704e-5, +058 }; +059 +060 /** Avoid repeated computation of log of 2 PI in logGamma */ +061 private static final double HALF_LOG_2_PI = 0.5 * Math.log(2.0 * Math.PI); +062 +063 // limits for switching algorithm in digamma +064 /** C limit. */ +065 private static final double C_LIMIT = 49; +066 +067 /** S limit. */ +068 private static final double S_LIMIT = 1e-5; +069 +070 /** +071 * Default constructor. Prohibit instantiation. +072 */ +073 private Gamma() { +074 super(); +075 } +076 +077 /** +078 * Returns the natural logarithm of the gamma function Γ(x). +079 * +080 * The implementation of this method is based on: +081 * <ul> +082 * <li><a href="http://mathworld.wolfram.com/GammaFunction.html"> +083 * Gamma Function</a>, equation (28).</li> +084 * <li><a href="http://mathworld.wolfram.com/LanczosApproximation.html"> +085 * Lanczos Approximation</a>, equations (1) through (5).</li> +086 * <li><a href="http://my.fit.edu/~gabdo/gamma.txt">Paul Godfrey, A note on +087 * the computation of the convergent Lanczos complex Gamma approximation +088 * </a></li> +089 * </ul> +090 * +091 * @param x the value. +092 * @return log(Γ(x)) +093 */ +094 public static double logGamma(double x) { +095 double ret; +096 +097 if (Double.isNaN(x) || (x <= 0.0)) { +098 ret = Double.NaN; +099 } else { +100 double g = 607.0 / 128.0; +101 +102 double sum = 0.0; +103 for (int i = LANCZOS.length - 1; i > 0; --i) { +104 sum = sum + (LANCZOS[i] / (x + i)); +105 } +106 sum = sum + LANCZOS[0]; +107 +108 double tmp = x + g + .5; +109 ret = ((x + .5) * Math.log(tmp)) - tmp + +110 HALF_LOG_2_PI + Math.log(sum / x); +111 } +112 +113 return ret; +114 } +115 +116 /** +117 * Returns the regularized gamma function P(a, x). +118 * +119 * @param a the a parameter. +120 * @param x the value. +121 * @return the regularized gamma function P(a, x) +122 * @throws MathException if the algorithm fails to converge. +123 */ +124 public static double regularizedGammaP(double a, double x) +125 throws MathException +126 { +127 return regularizedGammaP(a, x, DEFAULT_EPSILON, Integer.MAX_VALUE); +128 } +129 +130 +131 /** +132 * Returns the regularized gamma function P(a, x). +133 * +134 * The implementation of this method is based on: +135 * <ul> +136 * <li> +137 * <a href="http://mathworld.wolfram.com/RegularizedGammaFunction.html"> +138 * Regularized Gamma Function</a>, equation (1).</li> +139 * <li> +140 * <a href="http://mathworld.wolfram.com/IncompleteGammaFunction.html"> +141 * Incomplete Gamma Function</a>, equation (4).</li> +142 * <li> +143 * <a href="http://mathworld.wolfram.com/ConfluentHypergeometricFunctionoftheFirstKind.html"> +144 * Confluent Hypergeometric Function of the First Kind</a>, equation (1). +145 * </li> +146 * </ul> +147 * +148 * @param a the a parameter. +149 * @param x the value. +150 * @param epsilon When the absolute value of the nth item in the +151 * series is less than epsilon the approximation ceases +152 * to calculate further elements in the series. +153 * @param maxIterations Maximum number of "iterations" to complete. +154 * @return the regularized gamma function P(a, x) +155 * @throws MathException if the algorithm fails to converge. +156 */ +157 public static double regularizedGammaP(double a, +158 double x, +159 double epsilon, +160 int maxIterations) +161 throws MathException +162 { +163 double ret; +164 +165 if (Double.isNaN(a) || Double.isNaN(x) || (a <= 0.0) || (x < 0.0)) { +166 ret = Double.NaN; +167 } else if (x == 0.0) { +168 ret = 0.0; +169 } else if (x >= a + 1) { +170 // use regularizedGammaQ because it should converge faster in this +171 // case. +172 ret = 1.0 - regularizedGammaQ(a, x, epsilon, maxIterations); +173 } else { +174 // calculate series +175 double n = 0.0; // current element index +176 double an = 1.0 / a; // n-th element in the series +177 double sum = an; // partial sum +178 while (Math.abs(an/sum) > epsilon && n < maxIterations && sum < Double.POSITIVE_INFINITY) { +179 // compute next element in the series +180 n = n + 1.0; +181 an = an * (x / (a + n)); +182 +183 // update partial sum +184 sum = sum + an; +185 } +186 if (n >= maxIterations) { +187 throw new MaxIterationsExceededException(maxIterations); +188 } else if (Double.isInfinite(sum)) { +189 ret = 1.0; +190 } else { +191 ret = Math.exp(-x + (a * Math.log(x)) - logGamma(a)) * sum; +192 } +193 } +194 +195 return ret; +196 } +197 +198 /** +199 * Returns the regularized gamma function Q(a, x) = 1 - P(a, x). +200 * +201 * @param a the a parameter. +202 * @param x the value. +203 * @return the regularized gamma function Q(a, x) +204 * @throws MathException if the algorithm fails to converge. +205 */ +206 public static double regularizedGammaQ(double a, double x) +207 throws MathException +208 { +209 return regularizedGammaQ(a, x, DEFAULT_EPSILON, Integer.MAX_VALUE); +210 } +211 +212 /** +213 * Returns the regularized gamma function Q(a, x) = 1 - P(a, x). +214 * +215 * The implementation of this method is based on: +216 * <ul> +217 * <li> +218 * <a href="http://mathworld.wolfram.com/RegularizedGammaFunction.html"> +219 * Regularized Gamma Function</a>, equation (1).</li> +220 * <li> +221 * <a href="http://functions.wolfram.com/GammaBetaErf/GammaRegularized/10/0003/"> +222 * Regularized incomplete gamma function: Continued fraction representations (formula 06.08.10.0003)</a></li> +223 * </ul> +224 * +225 * @param a the a parameter. +226 * @param x the value. +227 * @param epsilon When the absolute value of the nth item in the +228 * series is less than epsilon the approximation ceases +229 * to calculate further elements in the series. +230 * @param maxIterations Maximum number of "iterations" to complete. +231 * @return the regularized gamma function P(a, x) +232 * @throws MathException if the algorithm fails to converge. +233 */ +234 public static double regularizedGammaQ(final double a, +235 double x, +236 double epsilon, +237 int maxIterations) +238 throws MathException +239 { +240 double ret; +241 +242 if (Double.isNaN(a) || Double.isNaN(x) || (a <= 0.0) || (x < 0.0)) { +243 ret = Double.NaN; +244 } else if (x == 0.0) { +245 ret = 1.0; +246 } else if (x < a + 1.0) { +247 // use regularizedGammaP because it should converge faster in this +248 // case. +249 ret = 1.0 - regularizedGammaP(a, x, epsilon, maxIterations); +250 } else { +251 // create continued fraction +252 ContinuedFraction cf = new ContinuedFraction() { +253 +254 @Override +255 protected double getA(int n, double x) { +256 return ((2.0 * n) + 1.0) - a + x; +257 } +258 +259 @Override +260 protected double getB(int n, double x) { +261 return n * (a - n); +262 } +263 }; +264 +265 ret = 1.0 / cf.evaluate(x, epsilon, maxIterations); +266 ret = Math.exp(-x + (a * Math.log(x)) - logGamma(a)) * ret; +267 } +268 +269 return ret; +270 } +271 +272 +273 /** +274 * <p>Computes the digamma function of x.</p> +275 * +276 * <p>This is an independently written implementation of the algorithm described in +277 * Jose Bernardo, Algorithm AS 103: Psi (Digamma) Function, Applied Statistics, 1976.</p> +278 * +279 * <p>Some of the constants have been changed to increase accuracy at the moderate expense +280 * of run-time. The result should be accurate to within 10^-8 absolute tolerance for +281 * x >= 10^-5 and within 10^-8 relative tolerance for x > 0.</p> +282 * +283 * <p>Performance for large negative values of x will be quite expensive (proportional to +284 * |x|). Accuracy for negative values of x should be about 10^-8 absolute for results +285 * less than 10^5 and 10^-8 relative for results larger than that.</p> +286 * +287 * @param x the argument +288 * @return digamma(x) to within 10-8 relative or absolute error whichever is smaller +289 * @see <a href="http://en.wikipedia.org/wiki/Digamma_function"> Digamma at wikipedia </a> +290 * @see <a href="http://www.uv.es/~bernardo/1976AppStatist.pdf"> Bernardo's original article </a> +291 * @since 2.0 +292 */ +293 public static double digamma(double x) { +294 if (x > 0 && x <= S_LIMIT) { +295 // use method 5 from Bernardo AS103 +296 // accurate to O(x) +297 return -GAMMA - 1 / x; +298 } +299 +300 if (x >= C_LIMIT) { +301 // use method 4 (accurate to O(1/x^8) +302 double inv = 1 / (x * x); +303 // 1 1 1 1 +304 // log(x) - --- - ------ + ------- - ------- +305 // 2 x 12 x^2 120 x^4 252 x^6 +306 return Math.log(x) - 0.5 / x - inv * ((1.0 / 12) + inv * (1.0 / 120 - inv / 252)); +307 } +308 +309 return digamma(x + 1) - 1 / x; +310 } +311 +312 /** +313 * <p>Computes the trigamma function of x. This function is derived by taking the derivative of +314 * the implementation of digamma.</p> +315 * +316 * @param x the argument +317 * @return trigamma(x) to within 10-8 relative or absolute error whichever is smaller +318 * @see <a href="http://en.wikipedia.org/wiki/Trigamma_function"> Trigamma at wikipedia </a> +319 * @see Gamma#digamma(double) +320 * @since 2.0 +321 */ +322 public static double trigamma(double x) { +323 if (x > 0 && x <= S_LIMIT) { +324 return 1 / (x * x); +325 } +326 +327 if (x >= C_LIMIT) { +328 double inv = 1 / (x * x); +329 // 1 1 1 1 1 +330 // - + ---- + ---- - ----- + ----- +331 // x 2 3 5 7 +332 // 2 x 6 x 30 x 42 x +333 return 1 / x + inv / 2 + inv / x * (1.0 / 6 - inv * (1.0 / 30 + inv / 42)); +334 } +335 +336 return trigamma(x + 1) + 1 / (x * x); +337 } +338 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/Frequency.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/Frequency.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,658 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat; +018 +019 import java.io.Serializable; +020 import java.text.NumberFormat; +021 import java.util.Iterator; +022 import java.util.Comparator; +023 import java.util.TreeMap; +024 +025 import org.apache.commons.math.MathRuntimeException; +026 +027 /** +028 * Maintains a frequency distribution. +029 * <p> +030 * Accepts int, long, char or Comparable values. New values added must be +031 * comparable to those that have been added, otherwise the add method will +032 * throw an IllegalArgumentException.</p> +033 * <p> +034 * Integer values (int, long, Integer, Long) are not distinguished by type -- +035 * i.e. <code>addValue(Long.valueOf(2)), addValue(2), addValue(2l)</code> all have +036 * the same effect (similarly for arguments to <code>getCount,</code> etc.).</p> +037 * <p> +038 * char values are converted by <code>addValue</code> to Character instances. +039 * As such, these values are not comparable to integral values, so attempts +040 * to combine integral types with chars in a frequency distribution will fail. +041 * </p> +042 * <p> +043 * The values are ordered using the default (natural order), unless a +044 * <code>Comparator</code> is supplied in the constructor.</p> +045 * +046 * @version $Revision: 922722 $ $Date: 2010-03-13 21:15:01 -0500 (Sat, 13 Mar 2010) $ +047 */ +048 public class Frequency implements Serializable { +049 +050 /** Serializable version identifier */ +051 private static final long serialVersionUID = -3845586908418844111L; +052 +053 /** underlying collection */ +054 private final TreeMap<Comparable<?>, Long> freqTable; +055 +056 /** +057 * Default constructor. +058 */ +059 public Frequency() { +060 freqTable = new TreeMap<Comparable<?>, Long>(); +061 } +062 +063 /** +064 * Constructor allowing values Comparator to be specified. +065 * +066 * @param comparator Comparator used to order values +067 */ +068 @SuppressWarnings("unchecked") // TODO is the cast OK? +069 public Frequency(Comparator<?> comparator) { +070 freqTable = new TreeMap<Comparable<?>, Long>((Comparator<? super Comparable<?>>) comparator); +071 } +072 +073 /** +074 * Return a string representation of this frequency +075 * distribution. +076 * +077 * @return a string representation. +078 */ +079 @Override +080 public String toString() { +081 NumberFormat nf = NumberFormat.getPercentInstance(); +082 StringBuffer outBuffer = new StringBuffer(); +083 outBuffer.append("Value \t Freq. \t Pct. \t Cum Pct. \n"); +084 Iterator<Comparable<?>> iter = freqTable.keySet().iterator(); +085 while (iter.hasNext()) { +086 Comparable<?> value = iter.next(); +087 outBuffer.append(value); +088 outBuffer.append('\t'); +089 outBuffer.append(getCount(value)); +090 outBuffer.append('\t'); +091 outBuffer.append(nf.format(getPct(value))); +092 outBuffer.append('\t'); +093 outBuffer.append(nf.format(getCumPct(value))); +094 outBuffer.append('\n'); +095 } +096 return outBuffer.toString(); +097 } +098 +099 /** +100 * Adds 1 to the frequency count for v. +101 * <p> +102 * If other objects have already been added to this Frequency, v must +103 * be comparable to those that have already been added. +104 * </p> +105 * +106 * @param v the value to add. +107 * @throws IllegalArgumentException if <code>v</code> is not Comparable, +108 * or is not comparable with previous entries +109 * @deprecated use {@link #addValue(Comparable)} instead +110 */ +111 @Deprecated +112 public void addValue(Object v) { +113 if (v instanceof Comparable<?>){ +114 addValue((Comparable<?>) v); +115 } else { +116 throw MathRuntimeException.createIllegalArgumentException( +117 "class ({0}) does not implement Comparable", +118 v.getClass().getName()); +119 } +120 } +121 +122 /** +123 * Adds 1 to the frequency count for v. +124 * <p> +125 * If other objects have already been added to this Frequency, v must +126 * be comparable to those that have already been added. +127 * </p> +128 * +129 * @param v the value to add. +130 * @throws IllegalArgumentException if <code>v</code> is not comparable with previous entries +131 */ +132 public void addValue(Comparable<?> v){ +133 Comparable<?> obj = v; +134 if (v instanceof Integer) { +135 obj = Long.valueOf(((Integer) v).longValue()); +136 } +137 try { +138 Long count = freqTable.get(obj); +139 if (count == null) { +140 freqTable.put(obj, Long.valueOf(1)); +141 } else { +142 freqTable.put(obj, Long.valueOf(count.longValue() + 1)); +143 } +144 } catch (ClassCastException ex) { +145 //TreeMap will throw ClassCastException if v is not comparable +146 throw MathRuntimeException.createIllegalArgumentException( +147 "instance of class {0} not comparable to existing values", +148 v.getClass().getName()); +149 } +150 } +151 +152 /** +153 * Adds 1 to the frequency count for v. +154 * +155 * @param v the value to add. +156 */ +157 public void addValue(int v) { +158 addValue(Long.valueOf(v)); +159 } +160 +161 /** +162 * Adds 1 to the frequency count for v. +163 * +164 * @param v the value to add. +165 * @deprecated to be removed in math 3.0 +166 */ +167 @Deprecated +168 public void addValue(Integer v) { +169 addValue(Long.valueOf(v.longValue())); +170 } +171 +172 /** +173 * Adds 1 to the frequency count for v. +174 * +175 * @param v the value to add. +176 */ +177 public void addValue(long v) { +178 addValue(Long.valueOf(v)); +179 } +180 +181 /** +182 * Adds 1 to the frequency count for v. +183 * +184 * @param v the value to add. +185 */ +186 public void addValue(char v) { +187 addValue(Character.valueOf(v)); +188 } +189 +190 /** Clears the frequency table */ +191 public void clear() { +192 freqTable.clear(); +193 } +194 +195 /** +196 * Returns an Iterator over the set of values that have been added. +197 * <p> +198 * If added values are integral (i.e., integers, longs, Integers, or Longs), +199 * they are converted to Longs when they are added, so the objects returned +200 * by the Iterator will in this case be Longs.</p> +201 * +202 * @return values Iterator +203 */ +204 public Iterator<Comparable<?>> valuesIterator() { +205 return freqTable.keySet().iterator(); +206 } +207 +208 //------------------------------------------------------------------------- +209 +210 /** +211 * Returns the sum of all frequencies. +212 * +213 * @return the total frequency count. +214 */ +215 public long getSumFreq() { +216 long result = 0; +217 Iterator<Long> iterator = freqTable.values().iterator(); +218 while (iterator.hasNext()) { +219 result += iterator.next().longValue(); +220 } +221 return result; +222 } +223 +224 /** +225 * Returns the number of values = v. +226 * Returns 0 if the value is not comparable. +227 * +228 * @param v the value to lookup. +229 * @return the frequency of v. +230 * @deprecated replaced by {@link #getCount(Comparable)} as of 2.0 +231 */ +232 @Deprecated +233 public long getCount(Object v) { +234 return getCount((Comparable<?>) v); +235 } +236 +237 /** +238 * Returns the number of values = v. +239 * Returns 0 if the value is not comparable. +240 * +241 * @param v the value to lookup. +242 * @return the frequency of v. +243 */ +244 public long getCount(Comparable<?> v) { +245 if (v instanceof Integer) { +246 return getCount(((Integer) v).longValue()); +247 } +248 long result = 0; +249 try { +250 Long count = freqTable.get(v); +251 if (count != null) { +252 result = count.longValue(); +253 } +254 } catch (ClassCastException ex) { +255 // ignore and return 0 -- ClassCastException will be thrown if value is not comparable +256 } +257 return result; +258 } +259 +260 /** +261 * Returns the number of values = v. +262 * +263 * @param v the value to lookup. +264 * @return the frequency of v. +265 */ +266 public long getCount(int v) { +267 return getCount(Long.valueOf(v)); +268 } +269 +270 /** +271 * Returns the number of values = v. +272 * +273 * @param v the value to lookup. +274 * @return the frequency of v. +275 */ +276 public long getCount(long v) { +277 return getCount(Long.valueOf(v)); +278 } +279 +280 /** +281 * Returns the number of values = v. +282 * +283 * @param v the value to lookup. +284 * @return the frequency of v. +285 */ +286 public long getCount(char v) { +287 return getCount(Character.valueOf(v)); +288 } +289 +290 //------------------------------------------------------------- +291 +292 /** +293 * Returns the percentage of values that are equal to v +294 * (as a proportion between 0 and 1). +295 * <p> +296 * Returns <code>Double.NaN</code> if no values have been added.</p> +297 * +298 * @param v the value to lookup +299 * @return the proportion of values equal to v +300 * @deprecated replaced by {@link #getPct(Comparable)} as of 2.0 +301 */ +302 @Deprecated +303 public double getPct(Object v) { +304 return getPct((Comparable<?>) v); +305 } +306 +307 /** +308 * Returns the percentage of values that are equal to v +309 * (as a proportion between 0 and 1). +310 * <p> +311 * Returns <code>Double.NaN</code> if no values have been added.</p> +312 * +313 * @param v the value to lookup +314 * @return the proportion of values equal to v +315 */ +316 public double getPct(Comparable<?> v) { +317 final long sumFreq = getSumFreq(); +318 if (sumFreq == 0) { +319 return Double.NaN; +320 } +321 return (double) getCount(v) / (double) sumFreq; +322 } +323 +324 /** +325 * Returns the percentage of values that are equal to v +326 * (as a proportion between 0 and 1). +327 * +328 * @param v the value to lookup +329 * @return the proportion of values equal to v +330 */ +331 public double getPct(int v) { +332 return getPct(Long.valueOf(v)); +333 } +334 +335 /** +336 * Returns the percentage of values that are equal to v +337 * (as a proportion between 0 and 1). +338 * +339 * @param v the value to lookup +340 * @return the proportion of values equal to v +341 */ +342 public double getPct(long v) { +343 return getPct(Long.valueOf(v)); +344 } +345 +346 /** +347 * Returns the percentage of values that are equal to v +348 * (as a proportion between 0 and 1). +349 * +350 * @param v the value to lookup +351 * @return the proportion of values equal to v +352 */ +353 public double getPct(char v) { +354 return getPct(Character.valueOf(v)); +355 } +356 +357 //----------------------------------------------------------------------------------------- +358 +359 /** +360 * Returns the cumulative frequency of values less than or equal to v. +361 * <p> +362 * Returns 0 if v is not comparable to the values set.</p> +363 * +364 * @param v the value to lookup. +365 * @return the proportion of values equal to v +366 * @deprecated replaced by {@link #getCumFreq(Comparable)} as of 2.0 +367 */ +368 @Deprecated +369 public long getCumFreq(Object v) { +370 return getCumFreq((Comparable<?>) v); +371 } +372 +373 /** +374 * Returns the cumulative frequency of values less than or equal to v. +375 * <p> +376 * Returns 0 if v is not comparable to the values set.</p> +377 * +378 * @param v the value to lookup. +379 * @return the proportion of values equal to v +380 */ +381 public long getCumFreq(Comparable<?> v) { +382 if (getSumFreq() == 0) { +383 return 0; +384 } +385 if (v instanceof Integer) { +386 return getCumFreq(((Integer) v).longValue()); +387 } +388 @SuppressWarnings("unchecked") // OK, freqTable is Comparable<?> +389 Comparator<Comparable<?>> c = (Comparator<Comparable<?>>) freqTable.comparator(); +390 if (c == null) { +391 c = new NaturalComparator(); +392 } +393 long result = 0; +394 +395 try { +396 Long value = freqTable.get(v); +397 if (value != null) { +398 result = value.longValue(); +399 } +400 } catch (ClassCastException ex) { +401 return result; // v is not comparable +402 } +403 +404 if (c.compare(v, freqTable.firstKey()) < 0) { +405 return 0; // v is comparable, but less than first value +406 } +407 +408 if (c.compare(v, freqTable.lastKey()) >= 0) { +409 return getSumFreq(); // v is comparable, but greater than the last value +410 } +411 +412 Iterator<Comparable<?>> values = valuesIterator(); +413 while (values.hasNext()) { +414 Comparable<?> nextValue = values.next(); +415 if (c.compare(v, nextValue) > 0) { +416 result += getCount(nextValue); +417 } else { +418 return result; +419 } +420 } +421 return result; +422 } +423 +424 /** +425 * Returns the cumulative frequency of values less than or equal to v. +426 * <p> +427 * Returns 0 if v is not comparable to the values set.</p> +428 * +429 * @param v the value to lookup +430 * @return the proportion of values equal to v +431 */ +432 public long getCumFreq(int v) { +433 return getCumFreq(Long.valueOf(v)); +434 } +435 +436 /** +437 * Returns the cumulative frequency of values less than or equal to v. +438 * <p> +439 * Returns 0 if v is not comparable to the values set.</p> +440 * +441 * @param v the value to lookup +442 * @return the proportion of values equal to v +443 */ +444 public long getCumFreq(long v) { +445 return getCumFreq(Long.valueOf(v)); +446 } +447 +448 /** +449 * Returns the cumulative frequency of values less than or equal to v. +450 * <p> +451 * Returns 0 if v is not comparable to the values set.</p> +452 * +453 * @param v the value to lookup +454 * @return the proportion of values equal to v +455 */ +456 public long getCumFreq(char v) { +457 return getCumFreq(Character.valueOf(v)); +458 } +459 +460 //---------------------------------------------------------------------------------------------- +461 +462 /** +463 * Returns the cumulative percentage of values less than or equal to v +464 * (as a proportion between 0 and 1). +465 * <p> +466 * Returns <code>Double.NaN</code> if no values have been added. +467 * Returns 0 if at least one value has been added, but v is not comparable +468 * to the values set.</p> +469 * +470 * @param v the value to lookup +471 * @return the proportion of values less than or equal to v +472 * @deprecated replaced by {@link #getCumPct(Comparable)} as of 2.0 +473 */ +474 @Deprecated +475 public double getCumPct(Object v) { +476 return getCumPct((Comparable<?>) v); +477 +478 } +479 +480 /** +481 * Returns the cumulative percentage of values less than or equal to v +482 * (as a proportion between 0 and 1). +483 * <p> +484 * Returns <code>Double.NaN</code> if no values have been added. +485 * Returns 0 if at least one value has been added, but v is not comparable +486 * to the values set.</p> +487 * +488 * @param v the value to lookup +489 * @return the proportion of values less than or equal to v +490 */ +491 public double getCumPct(Comparable<?> v) { +492 final long sumFreq = getSumFreq(); +493 if (sumFreq == 0) { +494 return Double.NaN; +495 } +496 return (double) getCumFreq(v) / (double) sumFreq; +497 } +498 +499 /** +500 * Returns the cumulative percentage of values less than or equal to v +501 * (as a proportion between 0 and 1). +502 * <p> +503 * Returns 0 if v is not comparable to the values set.</p> +504 * +505 * @param v the value to lookup +506 * @return the proportion of values less than or equal to v +507 */ +508 public double getCumPct(int v) { +509 return getCumPct(Long.valueOf(v)); +510 } +511 +512 /** +513 * Returns the cumulative percentage of values less than or equal to v +514 * (as a proportion between 0 and 1). +515 * <p> +516 * Returns 0 if v is not comparable to the values set.</p> +517 * +518 * @param v the value to lookup +519 * @return the proportion of values less than or equal to v +520 */ +521 public double getCumPct(long v) { +522 return getCumPct(Long.valueOf(v)); +523 } +524 +525 /** +526 * Returns the cumulative percentage of values less than or equal to v +527 * (as a proportion between 0 and 1). +528 * <p> +529 * Returns 0 if v is not comparable to the values set.</p> +530 * +531 * @param v the value to lookup +532 * @return the proportion of values less than or equal to v +533 */ +534 public double getCumPct(char v) { +535 return getCumPct(Character.valueOf(v)); +536 } +537 +538 /** +539 * A Comparator that compares comparable objects using the +540 * natural order. Copied from Commons Collections ComparableComparator. +541 */ +542 private static class NaturalComparator<T extends Comparable<T>> implements Comparator<Comparable<T>>, Serializable { +543 +544 /** Serializable version identifier */ +545 private static final long serialVersionUID = -3852193713161395148L; +546 +547 /** +548 * Compare the two {@link Comparable Comparable} arguments. +549 * This method is equivalent to: +550 * <pre>(({@link Comparable Comparable})o1).{@link Comparable#compareTo compareTo}(o2)</pre> +551 * +552 * @param o1 the first object +553 * @param o2 the second object +554 * @return result of comparison +555 * @throws NullPointerException when <i>o1</i> is <code>null</code>, +556 * or when <code>((Comparable)o1).compareTo(o2)</code> does +557 * @throws ClassCastException when <i>o1</i> is not a {@link Comparable Comparable}, +558 * or when <code>((Comparable)o1).compareTo(o2)</code> does +559 */ +560 @SuppressWarnings("unchecked") // cast to (T) may throw ClassCastException, see Javadoc +561 public int compare(Comparable<T> o1, Comparable<T> o2) { +562 return o1.compareTo((T) o2); +563 } +564 } +565 +566 /** {@inheritDoc} */ +567 @Override +568 public int hashCode() { +569 final int prime = 31; +570 int result = 1; +571 result = prime * result + +572 ((freqTable == null) ? 0 : freqTable.hashCode()); +573 return result; +574 } +575 +576 /** {@inheritDoc} */ +577 @Override +578 public boolean equals(Object obj) { +579 if (this == obj) +580 return true; +581 if (!(obj instanceof Frequency)) +582 return false; +583 Frequency other = (Frequency) obj; +584 if (freqTable == null) { +585 if (other.freqTable != null) +586 return false; +587 } else if (!freqTable.equals(other.freqTable)) +588 return false; +589 return true; +590 } +591 +592 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/StatUtils.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/StatUtils.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,691 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat; +018 +019 import org.apache.commons.math.MathRuntimeException; +020 import org.apache.commons.math.stat.descriptive.UnivariateStatistic; +021 import org.apache.commons.math.stat.descriptive.moment.GeometricMean; +022 import org.apache.commons.math.stat.descriptive.moment.Mean; +023 import org.apache.commons.math.stat.descriptive.moment.Variance; +024 import org.apache.commons.math.stat.descriptive.rank.Max; +025 import org.apache.commons.math.stat.descriptive.rank.Min; +026 import org.apache.commons.math.stat.descriptive.rank.Percentile; +027 import org.apache.commons.math.stat.descriptive.summary.Product; +028 import org.apache.commons.math.stat.descriptive.summary.Sum; +029 import org.apache.commons.math.stat.descriptive.summary.SumOfLogs; +030 import org.apache.commons.math.stat.descriptive.summary.SumOfSquares; +031 +032 /** +033 * StatUtils provides static methods for computing statistics based on data +034 * stored in double[] arrays. +035 * +036 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +037 */ +038 public final class StatUtils { +039 +040 /** sum */ +041 private static final UnivariateStatistic SUM = new Sum(); +042 +043 /** sumSq */ +044 private static final UnivariateStatistic SUM_OF_SQUARES = new SumOfSquares(); +045 +046 /** prod */ +047 private static final UnivariateStatistic PRODUCT = new Product(); +048 +049 /** sumLog */ +050 private static final UnivariateStatistic SUM_OF_LOGS = new SumOfLogs(); +051 +052 /** min */ +053 private static final UnivariateStatistic MIN = new Min(); +054 +055 /** max */ +056 private static final UnivariateStatistic MAX = new Max(); +057 +058 /** mean */ +059 private static final UnivariateStatistic MEAN = new Mean(); +060 +061 /** variance */ +062 private static final Variance VARIANCE = new Variance(); +063 +064 /** percentile */ +065 private static final Percentile PERCENTILE = new Percentile(); +066 +067 /** geometric mean */ +068 private static final GeometricMean GEOMETRIC_MEAN = new GeometricMean(); +069 +070 /** +071 * Private Constructor +072 */ +073 private StatUtils() { +074 } +075 +076 /** +077 * Returns the sum of the values in the input array, or +078 * <code>Double.NaN</code> if the array is empty. +079 * <p> +080 * Throws <code>IllegalArgumentException</code> if the input array +081 * is null.</p> +082 * +083 * @param values array of values to sum +084 * @return the sum of the values or <code>Double.NaN</code> if the array +085 * is empty +086 * @throws IllegalArgumentException if the array is null +087 */ +088 public static double sum(final double[] values) { +089 return SUM.evaluate(values); +090 } +091 +092 /** +093 * Returns the sum of the entries in the specified portion of +094 * the input array, or <code>Double.NaN</code> if the designated subarray +095 * is empty. +096 * <p> +097 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +098 * +099 * @param values the input array +100 * @param begin index of the first array element to include +101 * @param length the number of elements to include +102 * @return the sum of the values or Double.NaN if length = 0 +103 * @throws IllegalArgumentException if the array is null or the array index +104 * parameters are not valid +105 */ +106 public static double sum(final double[] values, final int begin, +107 final int length) { +108 return SUM.evaluate(values, begin, length); +109 } +110 +111 /** +112 * Returns the sum of the squares of the entries in the input array, or +113 * <code>Double.NaN</code> if the array is empty. +114 * <p> +115 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +116 * +117 * @param values input array +118 * @return the sum of the squared values or <code>Double.NaN</code> if the +119 * array is empty +120 * @throws IllegalArgumentException if the array is null +121 */ +122 public static double sumSq(final double[] values) { +123 return SUM_OF_SQUARES.evaluate(values); +124 } +125 +126 /** +127 * Returns the sum of the squares of the entries in the specified portion of +128 * the input array, or <code>Double.NaN</code> if the designated subarray +129 * is empty. +130 * <p> +131 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +132 * +133 * @param values the input array +134 * @param begin index of the first array element to include +135 * @param length the number of elements to include +136 * @return the sum of the squares of the values or Double.NaN if length = 0 +137 * @throws IllegalArgumentException if the array is null or the array index +138 * parameters are not valid +139 */ +140 public static double sumSq(final double[] values, final int begin, +141 final int length) { +142 return SUM_OF_SQUARES.evaluate(values, begin, length); +143 } +144 +145 /** +146 * Returns the product of the entries in the input array, or +147 * <code>Double.NaN</code> if the array is empty. +148 * <p> +149 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +150 * +151 * @param values the input array +152 * @return the product of the values or Double.NaN if the array is empty +153 * @throws IllegalArgumentException if the array is null +154 */ +155 public static double product(final double[] values) { +156 return PRODUCT.evaluate(values); +157 } +158 +159 /** +160 * Returns the product of the entries in the specified portion of +161 * the input array, or <code>Double.NaN</code> if the designated subarray +162 * is empty. +163 * <p> +164 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +165 * +166 * @param values the input array +167 * @param begin index of the first array element to include +168 * @param length the number of elements to include +169 * @return the product of the values or Double.NaN if length = 0 +170 * @throws IllegalArgumentException if the array is null or the array index +171 * parameters are not valid +172 */ +173 public static double product(final double[] values, final int begin, +174 final int length) { +175 return PRODUCT.evaluate(values, begin, length); +176 } +177 +178 /** +179 * Returns the sum of the natural logs of the entries in the input array, or +180 * <code>Double.NaN</code> if the array is empty. +181 * <p> +182 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +183 * <p> +184 * See {@link org.apache.commons.math.stat.descriptive.summary.SumOfLogs}. +185 * </p> +186 * +187 * @param values the input array +188 * @return the sum of the natural logs of the values or Double.NaN if +189 * the array is empty +190 * @throws IllegalArgumentException if the array is null +191 */ +192 public static double sumLog(final double[] values) { +193 return SUM_OF_LOGS.evaluate(values); +194 } +195 +196 /** +197 * Returns the sum of the natural logs of the entries in the specified portion of +198 * the input array, or <code>Double.NaN</code> if the designated subarray +199 * is empty. +200 * <p> +201 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +202 * <p> +203 * See {@link org.apache.commons.math.stat.descriptive.summary.SumOfLogs}. +204 * </p> +205 * +206 * @param values the input array +207 * @param begin index of the first array element to include +208 * @param length the number of elements to include +209 * @return the sum of the natural logs of the values or Double.NaN if +210 * length = 0 +211 * @throws IllegalArgumentException if the array is null or the array index +212 * parameters are not valid +213 */ +214 public static double sumLog(final double[] values, final int begin, +215 final int length) { +216 return SUM_OF_LOGS.evaluate(values, begin, length); +217 } +218 +219 /** +220 * Returns the arithmetic mean of the entries in the input array, or +221 * <code>Double.NaN</code> if the array is empty. +222 * <p> +223 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +224 * <p> +225 * See {@link org.apache.commons.math.stat.descriptive.moment.Mean} for +226 * details on the computing algorithm.</p> +227 * +228 * @param values the input array +229 * @return the mean of the values or Double.NaN if the array is empty +230 * @throws IllegalArgumentException if the array is null +231 */ +232 public static double mean(final double[] values) { +233 return MEAN.evaluate(values); +234 } +235 +236 /** +237 * Returns the arithmetic mean of the entries in the specified portion of +238 * the input array, or <code>Double.NaN</code> if the designated subarray +239 * is empty. +240 * <p> +241 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +242 * <p> +243 * See {@link org.apache.commons.math.stat.descriptive.moment.Mean} for +244 * details on the computing algorithm.</p> +245 * +246 * @param values the input array +247 * @param begin index of the first array element to include +248 * @param length the number of elements to include +249 * @return the mean of the values or Double.NaN if length = 0 +250 * @throws IllegalArgumentException if the array is null or the array index +251 * parameters are not valid +252 */ +253 public static double mean(final double[] values, final int begin, +254 final int length) { +255 return MEAN.evaluate(values, begin, length); +256 } +257 +258 /** +259 * Returns the geometric mean of the entries in the input array, or +260 * <code>Double.NaN</code> if the array is empty. +261 * <p> +262 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +263 * <p> +264 * See {@link org.apache.commons.math.stat.descriptive.moment.GeometricMean} +265 * for details on the computing algorithm.</p> +266 * +267 * @param values the input array +268 * @return the geometric mean of the values or Double.NaN if the array is empty +269 * @throws IllegalArgumentException if the array is null +270 */ +271 public static double geometricMean(final double[] values) { +272 return GEOMETRIC_MEAN.evaluate(values); +273 } +274 +275 /** +276 * Returns the geometric mean of the entries in the specified portion of +277 * the input array, or <code>Double.NaN</code> if the designated subarray +278 * is empty. +279 * <p> +280 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +281 * <p> +282 * See {@link org.apache.commons.math.stat.descriptive.moment.GeometricMean} +283 * for details on the computing algorithm.</p> +284 * +285 * @param values the input array +286 * @param begin index of the first array element to include +287 * @param length the number of elements to include +288 * @return the geometric mean of the values or Double.NaN if length = 0 +289 * @throws IllegalArgumentException if the array is null or the array index +290 * parameters are not valid +291 */ +292 public static double geometricMean(final double[] values, final int begin, +293 final int length) { +294 return GEOMETRIC_MEAN.evaluate(values, begin, length); +295 } +296 +297 +298 /** +299 * Returns the variance of the entries in the input array, or +300 * <code>Double.NaN</code> if the array is empty. +301 * <p> +302 * See {@link org.apache.commons.math.stat.descriptive.moment.Variance} for +303 * details on the computing algorithm.</p> +304 * <p> +305 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +306 * <p> +307 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +308 * +309 * @param values the input array +310 * @return the variance of the values or Double.NaN if the array is empty +311 * @throws IllegalArgumentException if the array is null +312 */ +313 public static double variance(final double[] values) { +314 return VARIANCE.evaluate(values); +315 } +316 +317 /** +318 * Returns the variance of the entries in the specified portion of +319 * the input array, or <code>Double.NaN</code> if the designated subarray +320 * is empty. +321 * <p> +322 * See {@link org.apache.commons.math.stat.descriptive.moment.Variance} for +323 * details on the computing algorithm.</p> +324 * <p> +325 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +326 * <p> +327 * Throws <code>IllegalArgumentException</code> if the array is null or the +328 * array index parameters are not valid.</p> +329 * +330 * @param values the input array +331 * @param begin index of the first array element to include +332 * @param length the number of elements to include +333 * @return the variance of the values or Double.NaN if length = 0 +334 * @throws IllegalArgumentException if the array is null or the array index +335 * parameters are not valid +336 */ +337 public static double variance(final double[] values, final int begin, +338 final int length) { +339 return VARIANCE.evaluate(values, begin, length); +340 } +341 +342 /** +343 * Returns the variance of the entries in the specified portion of +344 * the input array, using the precomputed mean value. Returns +345 * <code>Double.NaN</code> if the designated subarray is empty. +346 * <p> +347 * See {@link org.apache.commons.math.stat.descriptive.moment.Variance} for +348 * details on the computing algorithm.</p> +349 * <p> +350 * The formula used assumes that the supplied mean value is the arithmetic +351 * mean of the sample data, not a known population parameter. This method +352 * is supplied only to save computation when the mean has already been +353 * computed.</p> +354 * <p> +355 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +356 * <p> +357 * Throws <code>IllegalArgumentException</code> if the array is null or the +358 * array index parameters are not valid.</p> +359 * +360 * @param values the input array +361 * @param mean the precomputed mean value +362 * @param begin index of the first array element to include +363 * @param length the number of elements to include +364 * @return the variance of the values or Double.NaN if length = 0 +365 * @throws IllegalArgumentException if the array is null or the array index +366 * parameters are not valid +367 */ +368 public static double variance(final double[] values, final double mean, +369 final int begin, final int length) { +370 return VARIANCE.evaluate(values, mean, begin, length); +371 } +372 +373 /** +374 * Returns the variance of the entries in the input array, using the +375 * precomputed mean value. Returns <code>Double.NaN</code> if the array +376 * is empty. +377 * <p> +378 * See {@link org.apache.commons.math.stat.descriptive.moment.Variance} for +379 * details on the computing algorithm.</p> +380 * <p> +381 * The formula used assumes that the supplied mean value is the arithmetic +382 * mean of the sample data, not a known population parameter. This method +383 * is supplied only to save computation when the mean has already been +384 * computed.</p> +385 * <p> +386 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +387 * <p> +388 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +389 * +390 * @param values the input array +391 * @param mean the precomputed mean value +392 * @return the variance of the values or Double.NaN if the array is empty +393 * @throws IllegalArgumentException if the array is null +394 */ +395 public static double variance(final double[] values, final double mean) { +396 return VARIANCE.evaluate(values, mean); +397 } +398 +399 /** +400 * Returns the maximum of the entries in the input array, or +401 * <code>Double.NaN</code> if the array is empty. +402 * <p> +403 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +404 * <p> +405 * <ul> +406 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code> +407 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li> +408 * <li>If any of the values equals <code>Double.POSITIVE_INFINITY</code>, +409 * the result is <code>Double.POSITIVE_INFINITY.</code></li> +410 * </ul></p> +411 * +412 * @param values the input array +413 * @return the maximum of the values or Double.NaN if the array is empty +414 * @throws IllegalArgumentException if the array is null +415 */ +416 public static double max(final double[] values) { +417 return MAX.evaluate(values); +418 } +419 +420 /** +421 * Returns the maximum of the entries in the specified portion of +422 * the input array, or <code>Double.NaN</code> if the designated subarray +423 * is empty. +424 * <p> +425 * Throws <code>IllegalArgumentException</code> if the array is null or +426 * the array index parameters are not valid.</p> +427 * <p> +428 * <ul> +429 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code> +430 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li> +431 * <li>If any of the values equals <code>Double.POSITIVE_INFINITY</code>, +432 * the result is <code>Double.POSITIVE_INFINITY.</code></li> +433 * </ul></p> +434 * +435 * @param values the input array +436 * @param begin index of the first array element to include +437 * @param length the number of elements to include +438 * @return the maximum of the values or Double.NaN if length = 0 +439 * @throws IllegalArgumentException if the array is null or the array index +440 * parameters are not valid +441 */ +442 public static double max(final double[] values, final int begin, +443 final int length) { +444 return MAX.evaluate(values, begin, length); +445 } +446 +447 /** +448 * Returns the minimum of the entries in the input array, or +449 * <code>Double.NaN</code> if the array is empty. +450 * <p> +451 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +452 * <p> +453 * <ul> +454 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code> +455 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li> +456 * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>, +457 * the result is <code>Double.NEGATIVE_INFINITY.</code></li> +458 * </ul> </p> +459 * +460 * @param values the input array +461 * @return the minimum of the values or Double.NaN if the array is empty +462 * @throws IllegalArgumentException if the array is null +463 */ +464 public static double min(final double[] values) { +465 return MIN.evaluate(values); +466 } +467 +468 /** +469 * Returns the minimum of the entries in the specified portion of +470 * the input array, or <code>Double.NaN</code> if the designated subarray +471 * is empty. +472 * <p> +473 * Throws <code>IllegalArgumentException</code> if the array is null or +474 * the array index parameters are not valid.</p> +475 * <p> +476 * <ul> +477 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code> +478 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li> +479 * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>, +480 * the result is <code>Double.NEGATIVE_INFINITY.</code></li> +481 * </ul></p> +482 * +483 * @param values the input array +484 * @param begin index of the first array element to include +485 * @param length the number of elements to include +486 * @return the minimum of the values or Double.NaN if length = 0 +487 * @throws IllegalArgumentException if the array is null or the array index +488 * parameters are not valid +489 */ +490 public static double min(final double[] values, final int begin, +491 final int length) { +492 return MIN.evaluate(values, begin, length); +493 } +494 +495 /** +496 * Returns an estimate of the <code>p</code>th percentile of the values +497 * in the <code>values</code> array. +498 * <p> +499 * <ul> +500 * <li>Returns <code>Double.NaN</code> if <code>values</code> has length +501 * <code>0</code></li></p> +502 * <li>Returns (for any value of <code>p</code>) <code>values[0]</code> +503 * if <code>values</code> has length <code>1</code></li> +504 * <li>Throws <code>IllegalArgumentException</code> if <code>values</code> +505 * is null or p is not a valid quantile value (p must be greater than 0 +506 * and less than or equal to 100)</li> +507 * </ul></p> +508 * <p> +509 * See {@link org.apache.commons.math.stat.descriptive.rank.Percentile} for +510 * a description of the percentile estimation algorithm used.</p> +511 * +512 * @param values input array of values +513 * @param p the percentile value to compute +514 * @return the percentile value or Double.NaN if the array is empty +515 * @throws IllegalArgumentException if <code>values</code> is null +516 * or p is invalid +517 */ +518 public static double percentile(final double[] values, final double p) { +519 return PERCENTILE.evaluate(values,p); +520 } +521 +522 /** +523 * Returns an estimate of the <code>p</code>th percentile of the values +524 * in the <code>values</code> array, starting with the element in (0-based) +525 * position <code>begin</code> in the array and including <code>length</code> +526 * values. +527 * <p> +528 * <ul> +529 * <li>Returns <code>Double.NaN</code> if <code>length = 0</code></li> +530 * <li>Returns (for any value of <code>p</code>) <code>values[begin]</code> +531 * if <code>length = 1 </code></li> +532 * <li>Throws <code>IllegalArgumentException</code> if <code>values</code> +533 * is null , <code>begin</code> or <code>length</code> is invalid, or +534 * <code>p</code> is not a valid quantile value (p must be greater than 0 +535 * and less than or equal to 100)</li> +536 * </ul></p> +537 * <p> +538 * See {@link org.apache.commons.math.stat.descriptive.rank.Percentile} for +539 * a description of the percentile estimation algorithm used.</p> +540 * +541 * @param values array of input values +542 * @param p the percentile to compute +543 * @param begin the first (0-based) element to include in the computation +544 * @param length the number of array elements to include +545 * @return the percentile value +546 * @throws IllegalArgumentException if the parameters are not valid or the +547 * input array is null +548 */ +549 public static double percentile(final double[] values, final int begin, +550 final int length, final double p) { +551 return PERCENTILE.evaluate(values, begin, length, p); +552 } +553 +554 /** +555 * Returns the sum of the (signed) differences between corresponding elements of the +556 * input arrays -- i.e., sum(sample1[i] - sample2[i]). +557 * +558 * @param sample1 the first array +559 * @param sample2 the second array +560 * @return sum of paired differences +561 * @throws IllegalArgumentException if the arrays do not have the same +562 * (positive) length +563 */ +564 public static double sumDifference(final double[] sample1, final double[] sample2) +565 throws IllegalArgumentException { +566 int n = sample1.length; +567 if ((n != sample2.length) || (n < 1)) { +568 throw MathRuntimeException.createIllegalArgumentException( +569 "input arrays must have the same positive length ({0} and {1})", +570 n, sample2.length); +571 } +572 double result = 0; +573 for (int i = 0; i < n; i++) { +574 result += sample1[i] - sample2[i]; +575 } +576 return result; +577 } +578 +579 /** +580 * Returns the mean of the (signed) differences between corresponding elements of the +581 * input arrays -- i.e., sum(sample1[i] - sample2[i]) / sample1.length. +582 * +583 * @param sample1 the first array +584 * @param sample2 the second array +585 * @return mean of paired differences +586 * @throws IllegalArgumentException if the arrays do not have the same +587 * (positive) length +588 */ +589 public static double meanDifference(final double[] sample1, final double[] sample2) +590 throws IllegalArgumentException { +591 return sumDifference(sample1, sample2) / sample1.length; +592 } +593 +594 /** +595 * Returns the variance of the (signed) differences between corresponding elements of the +596 * input arrays -- i.e., var(sample1[i] - sample2[i]). +597 * +598 * @param sample1 the first array +599 * @param sample2 the second array +600 * @param meanDifference the mean difference between corresponding entries +601 * @see #meanDifference(double[],double[]) +602 * @return variance of paired differences +603 * @throws IllegalArgumentException if the arrays do not have the same +604 * length or their common length is less than 2. +605 */ +606 public static double varianceDifference(final double[] sample1, final double[] sample2, +607 double meanDifference) throws IllegalArgumentException { +608 double sum1 = 0d; +609 double sum2 = 0d; +610 double diff = 0d; +611 int n = sample1.length; +612 if (n < 2 || n != sample2.length) { +613 throw MathRuntimeException.createIllegalArgumentException( +614 "input arrays must have the same length and at least two elements ({0} and {1})", +615 n, sample2.length); +616 } +617 for (int i = 0; i < n; i++) { +618 diff = sample1[i] - sample2[i]; +619 sum1 += (diff - meanDifference) *(diff - meanDifference); +620 sum2 += diff - meanDifference; +621 } +622 return (sum1 - (sum2 * sum2 / n)) / (n - 1); +623 } +624 +625 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/clustering/Cluster.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/clustering/Cluster.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,140 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.stat.clustering; +019 +020 import java.io.Serializable; +021 import java.util.ArrayList; +022 import java.util.List; +023 +024 /** +025 * Cluster holding a set of {@link Clusterable} points. +026 * @param <T> the type of points that can be clustered +027 * @version $Revision: 771076 $ $Date: 2009-05-03 12:28:48 -0400 (Sun, 03 May 2009) $ +028 * @since 2.0 +029 */ +030 public class Cluster<T extends Clusterable<T>> implements Serializable { +031 +032 /** Serializable version identifier. */ +033 private static final long serialVersionUID = -3442297081515880464L; +034 +035 /** The points contained in this cluster. */ +036 private final List<T> points; +037 +038 /** Center of the cluster. */ +039 private final T center; +040 +041 /** +042 * Build a cluster centered at a specified point. +043 * @param center the point which is to be the center of this cluster +044 */ +045 public Cluster(final T center) { +046 this.center = center; +047 points = new ArrayList<T>(); +048 } +049 +050 /** +051 * Add a point to this cluster. +052 * @param point point to add +053 */ +054 public void addPoint(final T point) { +055 points.add(point); +056 } +057 +058 /** +059 * Get the points contained in the cluster. +060 * @return points contained in the cluster +061 */ +062 public List<T> getPoints() { +063 return points; +064 } +065 +066 /** +067 * Get the point chosen to be the center of this cluster. +068 * @return chosen cluster center +069 */ +070 public T getCenter() { +071 return center; +072 } +073 +074 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/clustering/Clusterable.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/clustering/Clusterable.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,112 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.stat.clustering; +019 +020 import java.util.Collection; +021 +022 /** +023 * Interface for points that can be clustered together. +024 * @param <T> the type of point that can be clustered +025 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +026 * @since 2.0 +027 */ +028 public interface Clusterable<T> { +029 +030 /** +031 * Returns the distance from the given point. +032 * +033 * @param p the point to compute the distance from +034 * @return the distance from the given point +035 */ +036 double distanceFrom(T p); +037 +038 /** +039 * Returns the centroid of the given Collection of points. +040 * +041 * @param p the Collection of points to compute the centroid of +042 * @return the centroid of the given Collection of Points +043 */ +044 T centroidOf(Collection<T> p); +045 +046 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/clustering/EuclideanIntegerPoint.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/clustering/EuclideanIntegerPoint.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,186 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.stat.clustering; +019 +020 import java.io.Serializable; +021 import java.util.Collection; +022 +023 import org.apache.commons.math.util.MathUtils; +024 +025 /** +026 * A simple implementation of {@link Clusterable} for points with integer coordinates. +027 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +028 * @since 2.0 +029 */ +030 public class EuclideanIntegerPoint implements Clusterable<EuclideanIntegerPoint>, Serializable { +031 +032 /** Serializable version identifier. */ +033 private static final long serialVersionUID = 3946024775784901369L; +034 +035 /** Point coordinates. */ +036 private final int[] point; +037 +038 /** +039 * Build an instance wrapping an integer array. +040 * <p>The wrapped array is referenced, it is <em>not</em> copied.</p> +041 * @param point the n-dimensional point in integer space +042 */ +043 public EuclideanIntegerPoint(final int[] point) { +044 this.point = point; +045 } +046 +047 /** +048 * Get the n-dimensional point in integer space. +049 * @return a reference (not a copy!) to the wrapped array +050 */ +051 public int[] getPoint() { +052 return point; +053 } +054 +055 /** {@inheritDoc} */ +056 public double distanceFrom(final EuclideanIntegerPoint p) { +057 return MathUtils.distance(point, p.getPoint()); +058 } +059 +060 /** {@inheritDoc} */ +061 public EuclideanIntegerPoint centroidOf(final Collection<EuclideanIntegerPoint> points) { +062 int[] centroid = new int[getPoint().length]; +063 for (EuclideanIntegerPoint p : points) { +064 for (int i = 0; i < centroid.length; i++) { +065 centroid[i] += p.getPoint()[i]; +066 } +067 } +068 for (int i = 0; i < centroid.length; i++) { +069 centroid[i] /= points.size(); +070 } +071 return new EuclideanIntegerPoint(centroid); +072 } +073 +074 /** {@inheritDoc} */ +075 @Override +076 public boolean equals(final Object other) { +077 if (!(other instanceof EuclideanIntegerPoint)) { +078 return false; +079 } +080 final int[] otherPoint = ((EuclideanIntegerPoint) other).getPoint(); +081 if (point.length != otherPoint.length) { +082 return false; +083 } +084 for (int i = 0; i < point.length; i++) { +085 if (point[i] != otherPoint[i]) { +086 return false; +087 } +088 } +089 return true; +090 } +091 +092 /** {@inheritDoc} */ +093 @Override +094 public int hashCode() { +095 int hashCode = 0; +096 for (Integer i : point) { +097 hashCode += i.hashCode() * 13 + 7; +098 } +099 return hashCode; +100 } +101 +102 /** +103 * {@inheritDoc} +104 * @since 2.1 +105 */ +106 @Override +107 public String toString() { +108 final StringBuffer buff = new StringBuffer("("); +109 final int[] coordinates = getPoint(); +110 for (int i = 0; i < coordinates.length; i++) { +111 buff.append(coordinates[i]); +112 if (i < coordinates.length - 1) { +113 buff.append(","); +114 } +115 } +116 buff.append(")"); +117 return buff.toString(); +118 } +119 +120 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/clustering/KMeansPlusPlusClusterer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/clustering/KMeansPlusPlusClusterer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,231 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.stat.clustering; +019 +020 import java.util.ArrayList; +021 import java.util.Collection; +022 import java.util.List; +023 import java.util.Random; +024 +025 /** +026 * Clustering algorithm based on David Arthur and Sergei Vassilvitski k-means++ algorithm. +027 * @param <T> type of the points to cluster +028 * @see <a href="http://en.wikipedia.org/wiki/K-means%2B%2B">K-means++ (wikipedia)</a> +029 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +030 * @since 2.0 +031 */ +032 public class KMeansPlusPlusClusterer<T extends Clusterable<T>> { +033 +034 /** Random generator for choosing initial centers. */ +035 private final Random random; +036 +037 /** Build a clusterer. +038 * @param random random generator to use for choosing initial centers +039 */ +040 public KMeansPlusPlusClusterer(final Random random) { +041 this.random = random; +042 } +043 +044 /** +045 * Runs the K-means++ clustering algorithm. +046 * +047 * @param points the points to cluster +048 * @param k the number of clusters to split the data into +049 * @param maxIterations the maximum number of iterations to run the algorithm +050 * for. If negative, no maximum will be used +051 * @return a list of clusters containing the points +052 */ +053 public List<Cluster<T>> cluster(final Collection<T> points, +054 final int k, final int maxIterations) { +055 // create the initial clusters +056 List<Cluster<T>> clusters = chooseInitialCenters(points, k, random); +057 assignPointsToClusters(clusters, points); +058 +059 // iterate through updating the centers until we're done +060 final int max = (maxIterations < 0) ? Integer.MAX_VALUE : maxIterations; +061 for (int count = 0; count < max; count++) { +062 boolean clusteringChanged = false; +063 List<Cluster<T>> newClusters = new ArrayList<Cluster<T>>(); +064 for (final Cluster<T> cluster : clusters) { +065 final T newCenter = cluster.getCenter().centroidOf(cluster.getPoints()); +066 if (!newCenter.equals(cluster.getCenter())) { +067 clusteringChanged = true; +068 } +069 newClusters.add(new Cluster<T>(newCenter)); +070 } +071 if (!clusteringChanged) { +072 return clusters; +073 } +074 assignPointsToClusters(newClusters, points); +075 clusters = newClusters; +076 } +077 return clusters; +078 } +079 +080 /** +081 * Adds the given points to the closest {@link Cluster}. +082 * +083 * @param <T> type of the points to cluster +084 * @param clusters the {@link Cluster}s to add the points to +085 * @param points the points to add to the given {@link Cluster}s +086 */ +087 private static <T extends Clusterable<T>> void +088 assignPointsToClusters(final Collection<Cluster<T>> clusters, final Collection<T> points) { +089 for (final T p : points) { +090 Cluster<T> cluster = getNearestCluster(clusters, p); +091 cluster.addPoint(p); +092 } +093 } +094 +095 /** +096 * Use K-means++ to choose the initial centers. +097 * +098 * @param <T> type of the points to cluster +099 * @param points the points to choose the initial centers from +100 * @param k the number of centers to choose +101 * @param random random generator to use +102 * @return the initial centers +103 */ +104 private static <T extends Clusterable<T>> List<Cluster<T>> +105 chooseInitialCenters(final Collection<T> points, final int k, final Random random) { +106 +107 final List<T> pointSet = new ArrayList<T>(points); +108 final List<Cluster<T>> resultSet = new ArrayList<Cluster<T>>(); +109 +110 // Choose one center uniformly at random from among the data points. +111 final T firstPoint = pointSet.remove(random.nextInt(pointSet.size())); +112 resultSet.add(new Cluster<T>(firstPoint)); +113 +114 final double[] dx2 = new double[pointSet.size()]; +115 while (resultSet.size() < k) { +116 // For each data point x, compute D(x), the distance between x and +117 // the nearest center that has already been chosen. +118 int sum = 0; +119 for (int i = 0; i < pointSet.size(); i++) { +120 final T p = pointSet.get(i); +121 final Cluster<T> nearest = getNearestCluster(resultSet, p); +122 final double d = p.distanceFrom(nearest.getCenter()); +123 sum += d * d; +124 dx2[i] = sum; +125 } +126 +127 // Add one new data point as a center. Each point x is chosen with +128 // probability proportional to D(x)2 +129 final double r = random.nextDouble() * sum; +130 for (int i = 0 ; i < dx2.length; i++) { +131 if (dx2[i] >= r) { +132 final T p = pointSet.remove(i); +133 resultSet.add(new Cluster<T>(p)); +134 break; +135 } +136 } +137 } +138 +139 return resultSet; +140 +141 } +142 +143 /** +144 * Returns the nearest {@link Cluster} to the given point +145 * +146 * @param <T> type of the points to cluster +147 * @param clusters the {@link Cluster}s to search +148 * @param point the point to find the nearest {@link Cluster} for +149 * @return the nearest {@link Cluster} to the given point +150 */ +151 private static <T extends Clusterable<T>> Cluster<T> +152 getNearestCluster(final Collection<Cluster<T>> clusters, final T point) { +153 double minDistance = Double.MAX_VALUE; +154 Cluster<T> minCluster = null; +155 for (final Cluster<T> c : clusters) { +156 final double distance = point.distanceFrom(c.getCenter()); +157 if (distance < minDistance) { +158 minDistance = distance; +159 minCluster = c; +160 } +161 } +162 return minCluster; +163 } +164 +165 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/correlation/Covariance.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/correlation/Covariance.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,339 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.correlation; +018 +019 import org.apache.commons.math.MathRuntimeException; +020 import org.apache.commons.math.linear.RealMatrix; +021 import org.apache.commons.math.linear.BlockRealMatrix; +022 import org.apache.commons.math.stat.descriptive.moment.Mean; +023 import org.apache.commons.math.stat.descriptive.moment.Variance; +024 +025 /** +026 * Computes covariances for pairs of arrays or columns of a matrix. +027 * +028 * <p>The constructors that take <code>RealMatrix</code> or +029 * <code>double[][]</code> arguments generate covariance matrices. The +030 * columns of the input matrices are assumed to represent variable values.</p> +031 * +032 * <p>The constructor argument <code>biasCorrected</code> determines whether or +033 * not computed covariances are bias-corrected.</p> +034 * +035 * <p>Unbiased covariances are given by the formula</p> +036 * <code>cov(X, Y) = Σ[(x<sub>i</sub> - E(X))(y<sub>i</sub> - E(Y))] / (n - 1)</code> +037 * where <code>E(X)</code> is the mean of <code>X</code> and <code>E(Y)</code> +038 * is the mean of the <code>Y</code> values. +039 * +040 * <p>Non-bias-corrected estimates use <code>n</code> in place of <code>n - 1</code> +041 * +042 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +043 * @since 2.0 +044 */ +045 public class Covariance { +046 +047 /** covariance matrix */ +048 private final RealMatrix covarianceMatrix; +049 +050 /** +051 * Create an empty covariance matrix. +052 */ +053 /** Number of observations (length of covariate vectors) */ +054 private final int n; +055 +056 /** +057 * Create a Covariance with no data +058 */ +059 public Covariance() { +060 super(); +061 covarianceMatrix = null; +062 n = 0; +063 } +064 +065 /** +066 * Create a Covariance matrix from a rectangular array +067 * whose columns represent covariates. +068 * +069 * <p>The <code>biasCorrected</code> parameter determines whether or not +070 * covariance estimates are bias-corrected.</p> +071 * +072 * <p>The input array must be rectangular with at least two columns +073 * and two rows.</p> +074 * +075 * @param data rectangular array with columns representing covariates +076 * @param biasCorrected true means covariances are bias-corrected +077 * @throws IllegalArgumentException if the input data array is not +078 * rectangular with at least two rows and two columns. +079 */ +080 public Covariance(double[][] data, boolean biasCorrected) { +081 this(new BlockRealMatrix(data), biasCorrected); +082 } +083 +084 /** +085 * Create a Covariance matrix from a rectangular array +086 * whose columns represent covariates. +087 * +088 * <p>The input array must be rectangular with at least two columns +089 * and two rows</p> +090 * +091 * @param data rectangular array with columns representing covariates +092 * @throws IllegalArgumentException if the input data array is not +093 * rectangular with at least two rows and two columns. +094 */ +095 public Covariance(double[][] data) { +096 this(data, true); +097 } +098 +099 /** +100 * Create a covariance matrix from a matrix whose columns +101 * represent covariates. +102 * +103 * <p>The <code>biasCorrected</code> parameter determines whether or not +104 * covariance estimates are bias-corrected.</p> +105 * +106 * <p>The matrix must have at least two columns and two rows</p> +107 * +108 * @param matrix matrix with columns representing covariates +109 * @param biasCorrected true means covariances are bias-corrected +110 * @throws IllegalArgumentException if the input matrix does not have +111 * at least two rows and two columns +112 */ +113 public Covariance(RealMatrix matrix, boolean biasCorrected) { +114 checkSufficientData(matrix); +115 n = matrix.getRowDimension(); +116 covarianceMatrix = computeCovarianceMatrix(matrix, biasCorrected); +117 } +118 +119 /** +120 * Create a covariance matrix from a matrix whose columns +121 * represent covariates. +122 * +123 * <p>The matrix must have at least two columns and two rows</p> +124 * +125 * @param matrix matrix with columns representing covariates +126 * @throws IllegalArgumentException if the input matrix does not have +127 * at least two rows and two columns +128 */ +129 public Covariance(RealMatrix matrix) { +130 this(matrix, true); +131 } +132 +133 /** +134 * Returns the covariance matrix +135 * +136 * @return covariance matrix +137 */ +138 public RealMatrix getCovarianceMatrix() { +139 return covarianceMatrix; +140 } +141 +142 /** +143 * Returns the number of observations (length of covariate vectors) +144 * +145 * @return number of observations +146 */ +147 +148 public int getN() { +149 return n; +150 } +151 +152 /** +153 * Compute a covariance matrix from a matrix whose columns represent +154 * covariates. +155 * @param matrix input matrix (must have at least two columns and two rows) +156 * @param biasCorrected determines whether or not covariance estimates are bias-corrected +157 * @return covariance matrix +158 */ +159 protected RealMatrix computeCovarianceMatrix(RealMatrix matrix, boolean biasCorrected) { +160 int dimension = matrix.getColumnDimension(); +161 Variance variance = new Variance(biasCorrected); +162 RealMatrix outMatrix = new BlockRealMatrix(dimension, dimension); +163 for (int i = 0; i < dimension; i++) { +164 for (int j = 0; j < i; j++) { +165 double cov = covariance(matrix.getColumn(i), matrix.getColumn(j), biasCorrected); +166 outMatrix.setEntry(i, j, cov); +167 outMatrix.setEntry(j, i, cov); +168 } +169 outMatrix.setEntry(i, i, variance.evaluate(matrix.getColumn(i))); +170 } +171 return outMatrix; +172 } +173 +174 /** +175 * Create a covariance matrix from a matrix whose columns represent +176 * covariates. Covariances are computed using the bias-corrected formula. +177 * @param matrix input matrix (must have at least two columns and two rows) +178 * @return covariance matrix +179 * @see #Covariance +180 */ +181 protected RealMatrix computeCovarianceMatrix(RealMatrix matrix) { +182 return computeCovarianceMatrix(matrix, true); +183 } +184 +185 /** +186 * Compute a covariance matrix from a rectangular array whose columns represent +187 * covariates. +188 * @param data input array (must have at least two columns and two rows) +189 * @param biasCorrected determines whether or not covariance estimates are bias-corrected +190 * @return covariance matrix +191 */ +192 protected RealMatrix computeCovarianceMatrix(double[][] data, boolean biasCorrected) { +193 return computeCovarianceMatrix(new BlockRealMatrix(data), biasCorrected); +194 } +195 +196 /** +197 * Create a covariance matrix from a rectangual array whose columns represent +198 * covariates. Covariances are computed using the bias-corrected formula. +199 * @param data input array (must have at least two columns and two rows) +200 * @return covariance matrix +201 * @see #Covariance +202 */ +203 protected RealMatrix computeCovarianceMatrix(double[][] data) { +204 return computeCovarianceMatrix(data, true); +205 } +206 +207 /** +208 * Computes the covariance between the two arrays. +209 * +210 * <p>Array lengths must match and the common length must be at least 2.</p> +211 * +212 * @param xArray first data array +213 * @param yArray second data array +214 * @param biasCorrected if true, returned value will be bias-corrected +215 * @return returns the covariance for the two arrays +216 * @throws IllegalArgumentException if the arrays lengths do not match or +217 * there is insufficient data +218 */ +219 public double covariance(final double[] xArray, final double[] yArray, boolean biasCorrected) +220 throws IllegalArgumentException { +221 Mean mean = new Mean(); +222 double result = 0d; +223 int length = xArray.length; +224 if(length == yArray.length && length > 1) { +225 double xMean = mean.evaluate(xArray); +226 double yMean = mean.evaluate(yArray); +227 for (int i = 0; i < length; i++) { +228 double xDev = xArray[i] - xMean; +229 double yDev = yArray[i] - yMean; +230 result += (xDev * yDev - result) / (i + 1); +231 } +232 } +233 else { +234 throw MathRuntimeException.createIllegalArgumentException( +235 "arrays must have the same length and both must have at " + +236 "least two elements. xArray has size {0}, yArray has {1} elements", +237 length, yArray.length); +238 } +239 return biasCorrected ? result * ((double) length / (double)(length - 1)) : result; +240 } +241 +242 /** +243 * Computes the covariance between the two arrays, using the bias-corrected +244 * formula. +245 * +246 * <p>Array lengths must match and the common length must be at least 2.</p> +247 * +248 * @param xArray first data array +249 * @param yArray second data array +250 * @return returns the covariance for the two arrays +251 * @throws IllegalArgumentException if the arrays lengths do not match or +252 * there is insufficient data +253 */ +254 public double covariance(final double[] xArray, final double[] yArray) +255 throws IllegalArgumentException { +256 return covariance(xArray, yArray, true); +257 } +258 +259 /** +260 * Throws IllegalArgumentException of the matrix does not have at least +261 * two columns and two rows +262 * @param matrix matrix to check +263 */ +264 private void checkSufficientData(final RealMatrix matrix) { +265 int nRows = matrix.getRowDimension(); +266 int nCols = matrix.getColumnDimension(); +267 if (nRows < 2 || nCols < 2) { +268 throw MathRuntimeException.createIllegalArgumentException( +269 "insufficient data: only {0} rows and {1} columns.", +270 nRows, nCols); +271 } +272 } +273 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/correlation/PearsonsCorrelation.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/correlation/PearsonsCorrelation.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,347 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.correlation; +018 +019 import org.apache.commons.math.MathException; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.distribution.TDistribution; +022 import org.apache.commons.math.distribution.TDistributionImpl; +023 import org.apache.commons.math.linear.RealMatrix; +024 import org.apache.commons.math.linear.BlockRealMatrix; +025 import org.apache.commons.math.stat.regression.SimpleRegression; +026 +027 /** +028 * Computes Pearson's product-moment correlation coefficients for pairs of arrays +029 * or columns of a matrix. +030 * +031 * <p>The constructors that take <code>RealMatrix</code> or +032 * <code>double[][]</code> arguments generate correlation matrices. The +033 * columns of the input matrices are assumed to represent variable values. +034 * Correlations are given by the formula</p> +035 * <code>cor(X, Y) = Σ[(x<sub>i</sub> - E(X))(y<sub>i</sub> - E(Y))] / [(n - 1)s(X)s(Y)]</code> +036 * where <code>E(X)</code> is the mean of <code>X</code>, <code>E(Y)</code> +037 * is the mean of the <code>Y</code> values and s(X), s(Y) are standard deviations. +038 * +039 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +040 * @since 2.0 +041 */ +042 public class PearsonsCorrelation { +043 +044 /** correlation matrix */ +045 private final RealMatrix correlationMatrix; +046 +047 /** number of observations */ +048 private final int nObs; +049 +050 /** +051 * Create a PearsonsCorrelation instance without data +052 */ +053 public PearsonsCorrelation() { +054 super(); +055 correlationMatrix = null; +056 nObs = 0; +057 } +058 +059 /** +060 * Create a PearsonsCorrelation from a rectangular array +061 * whose columns represent values of variables to be correlated. +062 * +063 * @param data rectangular array with columns representing variables +064 * @throws IllegalArgumentException if the input data array is not +065 * rectangular with at least two rows and two columns. +066 */ +067 public PearsonsCorrelation(double[][] data) { +068 this(new BlockRealMatrix(data)); +069 } +070 +071 /** +072 * Create a PearsonsCorrelation from a RealMatrix whose columns +073 * represent variables to be correlated. +074 * +075 * @param matrix matrix with columns representing variables to correlate +076 */ +077 public PearsonsCorrelation(RealMatrix matrix) { +078 checkSufficientData(matrix); +079 nObs = matrix.getRowDimension(); +080 correlationMatrix = computeCorrelationMatrix(matrix); +081 } +082 +083 /** +084 * Create a PearsonsCorrelation from a {@link Covariance}. The correlation +085 * matrix is computed by scaling the Covariance's covariance matrix. +086 * The Covariance instance must have been created from a data matrix with +087 * columns representing variable values. +088 * +089 * @param covariance Covariance instance +090 */ +091 public PearsonsCorrelation(Covariance covariance) { +092 RealMatrix covarianceMatrix = covariance.getCovarianceMatrix(); +093 if (covarianceMatrix == null) { +094 throw MathRuntimeException.createIllegalArgumentException("covariance matrix is null"); +095 } +096 nObs = covariance.getN(); +097 correlationMatrix = covarianceToCorrelation(covarianceMatrix); +098 } +099 +100 /** +101 * Create a PearsonsCorrelation from a covariance matrix. The correlation +102 * matrix is computed by scaling the covariance matrix. +103 * +104 * @param covarianceMatrix covariance matrix +105 * @param numberOfObservations the number of observations in the dataset used to compute +106 * the covariance matrix +107 */ +108 public PearsonsCorrelation(RealMatrix covarianceMatrix, int numberOfObservations) { +109 nObs = numberOfObservations; +110 correlationMatrix = covarianceToCorrelation(covarianceMatrix); +111 +112 } +113 +114 /** +115 * Returns the correlation matrix +116 * +117 * @return correlation matrix +118 */ +119 public RealMatrix getCorrelationMatrix() { +120 return correlationMatrix; +121 } +122 +123 /** +124 * Returns a matrix of standard errors associated with the estimates +125 * in the correlation matrix.<br/> +126 * <code>getCorrelationStandardErrors().getEntry(i,j)</code> is the standard +127 * error associated with <code>getCorrelationMatrix.getEntry(i,j)</code> +128 * <p>The formula used to compute the standard error is <br/> +129 * <code>SE<sub>r</sub> = ((1 - r<sup>2</sup>) / (n - 2))<sup>1/2</sup></code> +130 * where <code>r</code> is the estimated correlation coefficient and +131 * <code>n</code> is the number of observations in the source dataset.</p> +132 * +133 * @return matrix of correlation standard errors +134 */ +135 public RealMatrix getCorrelationStandardErrors() { +136 int nVars = correlationMatrix.getColumnDimension(); +137 double[][] out = new double[nVars][nVars]; +138 for (int i = 0; i < nVars; i++) { +139 for (int j = 0; j < nVars; j++) { +140 double r = correlationMatrix.getEntry(i, j); +141 out[i][j] = Math.sqrt((1 - r * r) /(nObs - 2)); +142 } +143 } +144 return new BlockRealMatrix(out); +145 } +146 +147 /** +148 * Returns a matrix of p-values associated with the (two-sided) null +149 * hypothesis that the corresponding correlation coefficient is zero. +150 * <p><code>getCorrelationPValues().getEntry(i,j)</code> is the probability +151 * that a random variable distributed as <code>t<sub>n-2</sub></code> takes +152 * a value with absolute value greater than or equal to <br> +153 * <code>|r|((n - 2) / (1 - r<sup>2</sup>))<sup>1/2</sup></code></p> +154 * <p>The values in the matrix are sometimes referred to as the +155 * <i>significance</i> of the corresponding correlation coefficients.</p> +156 * +157 * @return matrix of p-values +158 * @throws MathException if an error occurs estimating probabilities +159 */ +160 public RealMatrix getCorrelationPValues() throws MathException { +161 TDistribution tDistribution = new TDistributionImpl(nObs - 2); +162 int nVars = correlationMatrix.getColumnDimension(); +163 double[][] out = new double[nVars][nVars]; +164 for (int i = 0; i < nVars; i++) { +165 for (int j = 0; j < nVars; j++) { +166 if (i == j) { +167 out[i][j] = 0d; +168 } else { +169 double r = correlationMatrix.getEntry(i, j); +170 double t = Math.abs(r * Math.sqrt((nObs - 2)/(1 - r * r))); +171 out[i][j] = 2 * (1 - tDistribution.cumulativeProbability(t)); +172 } +173 } +174 } +175 return new BlockRealMatrix(out); +176 } +177 +178 +179 /** +180 * Computes the correlation matrix for the columns of the +181 * input matrix. +182 * +183 * @param matrix matrix with columns representing variables to correlate +184 * @return correlation matrix +185 */ +186 public RealMatrix computeCorrelationMatrix(RealMatrix matrix) { +187 int nVars = matrix.getColumnDimension(); +188 RealMatrix outMatrix = new BlockRealMatrix(nVars, nVars); +189 for (int i = 0; i < nVars; i++) { +190 for (int j = 0; j < i; j++) { +191 double corr = correlation(matrix.getColumn(i), matrix.getColumn(j)); +192 outMatrix.setEntry(i, j, corr); +193 outMatrix.setEntry(j, i, corr); +194 } +195 outMatrix.setEntry(i, i, 1d); +196 } +197 return outMatrix; +198 } +199 +200 /** +201 * Computes the correlation matrix for the columns of the +202 * input rectangular array. The colums of the array represent values +203 * of variables to be correlated. +204 * +205 * @param data matrix with columns representing variables to correlate +206 * @return correlation matrix +207 */ +208 public RealMatrix computeCorrelationMatrix(double[][] data) { +209 return computeCorrelationMatrix(new BlockRealMatrix(data)); +210 } +211 +212 /** +213 * Computes the Pearson's product-moment correlation coefficient between the two arrays. +214 * +215 * </p>Throws IllegalArgumentException if the arrays do not have the same length +216 * or their common length is less than 2</p> +217 * +218 * @param xArray first data array +219 * @param yArray second data array +220 * @return Returns Pearson's correlation coefficient for the two arrays +221 * @throws IllegalArgumentException if the arrays lengths do not match or +222 * there is insufficient data +223 */ +224 public double correlation(final double[] xArray, final double[] yArray) throws IllegalArgumentException { +225 SimpleRegression regression = new SimpleRegression(); +226 if(xArray.length == yArray.length && xArray.length > 1) { +227 for(int i=0; i<xArray.length; i++) { +228 regression.addData(xArray[i], yArray[i]); +229 } +230 return regression.getR(); +231 } +232 else { +233 throw MathRuntimeException.createIllegalArgumentException( +234 "invalid array dimensions. xArray has size {0}; yArray has {1} elements", +235 xArray.length, yArray.length); +236 } +237 } +238 +239 /** +240 * Derives a correlation matrix from a covariance matrix. +241 * +242 * <p>Uses the formula <br/> +243 * <code>r(X,Y) = cov(X,Y)/s(X)s(Y)</code> where +244 * <code>r(·,·)</code> is the correlation coefficient and +245 * <code>s(·)</code> means standard deviation.</p> +246 * +247 * @param covarianceMatrix the covariance matrix +248 * @return correlation matrix +249 */ +250 public RealMatrix covarianceToCorrelation(RealMatrix covarianceMatrix) { +251 int nVars = covarianceMatrix.getColumnDimension(); +252 RealMatrix outMatrix = new BlockRealMatrix(nVars, nVars); +253 for (int i = 0; i < nVars; i++) { +254 double sigma = Math.sqrt(covarianceMatrix.getEntry(i, i)); +255 outMatrix.setEntry(i, i, 1d); +256 for (int j = 0; j < i; j++) { +257 double entry = covarianceMatrix.getEntry(i, j) / +258 (sigma * Math.sqrt(covarianceMatrix.getEntry(j, j))); +259 outMatrix.setEntry(i, j, entry); +260 outMatrix.setEntry(j, i, entry); +261 } +262 } +263 return outMatrix; +264 } +265 +266 /** +267 * Throws IllegalArgumentException of the matrix does not have at least +268 * two columns and two rows +269 * +270 * @param matrix matrix to check for sufficiency +271 */ +272 private void checkSufficientData(final RealMatrix matrix) { +273 int nRows = matrix.getRowDimension(); +274 int nCols = matrix.getColumnDimension(); +275 if (nRows < 2 || nCols < 2) { +276 throw MathRuntimeException.createIllegalArgumentException( +277 "insufficient data: only {0} rows and {1} columns.", +278 nRows, nCols); +279 } +280 } +281 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/correlation/SpearmansCorrelation.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/correlation/SpearmansCorrelation.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,236 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.stat.correlation; +019 +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.linear.BlockRealMatrix; +022 import org.apache.commons.math.linear.RealMatrix; +023 import org.apache.commons.math.stat.ranking.NaturalRanking; +024 import org.apache.commons.math.stat.ranking.RankingAlgorithm; +025 +026 /** +027 * <p>Spearman's rank correlation. This implementation performs a rank +028 * transformation on the input data and then computes {@link PearsonsCorrelation} +029 * on the ranked data.</p> +030 * +031 * <p>By default, ranks are computed using {@link NaturalRanking} with default +032 * strategies for handling NaNs and ties in the data (NaNs maximal, ties averaged). +033 * The ranking algorithm can be set using a constructor argument.</p> +034 * +035 * @since 2.0 +036 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +037 */ +038 +039 public class SpearmansCorrelation { +040 +041 /** Input data */ +042 private final RealMatrix data; +043 +044 /** Ranking algorithm */ +045 private final RankingAlgorithm rankingAlgorithm; +046 +047 /** Rank correlation */ +048 private final PearsonsCorrelation rankCorrelation; +049 +050 /** +051 * Create a SpearmansCorrelation with the given input data matrix +052 * and ranking algorithm. +053 * +054 * @param dataMatrix matrix of data with columns representing +055 * variables to correlate +056 * @param rankingAlgorithm ranking algorithm +057 */ +058 public SpearmansCorrelation(final RealMatrix dataMatrix, final RankingAlgorithm rankingAlgorithm) { +059 this.data = dataMatrix.copy(); +060 this.rankingAlgorithm = rankingAlgorithm; +061 rankTransform(data); +062 rankCorrelation = new PearsonsCorrelation(data); +063 } +064 +065 /** +066 * Create a SpearmansCorrelation from the given data matrix. +067 * +068 * @param dataMatrix matrix of data with columns representing +069 * variables to correlate +070 */ +071 public SpearmansCorrelation(final RealMatrix dataMatrix) { +072 this(dataMatrix, new NaturalRanking()); +073 } +074 +075 /** +076 * Create a SpearmansCorrelation without data. +077 */ +078 public SpearmansCorrelation() { +079 data = null; +080 this.rankingAlgorithm = new NaturalRanking(); +081 rankCorrelation = null; +082 } +083 +084 /** +085 * Calculate the Spearman Rank Correlation Matrix. +086 * +087 * @return Spearman Rank Correlation Matrix +088 */ +089 public RealMatrix getCorrelationMatrix() { +090 return rankCorrelation.getCorrelationMatrix(); +091 } +092 +093 /** +094 * Returns a {@link PearsonsCorrelation} instance constructed from the +095 * ranked input data. That is, +096 * <code>new SpearmansCorrelation(matrix).getRankCorrelation()</code> +097 * is equivalent to +098 * <code>new PearsonsCorrelation(rankTransform(matrix))</code> where +099 * <code>rankTransform(matrix)</code> is the result of applying the +100 * configured <code>RankingAlgorithm</code> to each of the columns of +101 * <code>matrix.</code> +102 * +103 * @return PearsonsCorrelation among ranked column data +104 */ +105 public PearsonsCorrelation getRankCorrelation() { +106 return rankCorrelation; +107 } +108 +109 /** +110 * Computes the Spearman's rank correlation matrix for the columns of the +111 * input matrix. +112 * +113 * @param matrix matrix with columns representing variables to correlate +114 * @return correlation matrix +115 */ +116 public RealMatrix computeCorrelationMatrix(RealMatrix matrix) { +117 RealMatrix matrixCopy = matrix.copy(); +118 rankTransform(matrixCopy); +119 return new PearsonsCorrelation().computeCorrelationMatrix(matrixCopy); +120 } +121 +122 /** +123 * Computes the Spearman's rank correlation matrix for the columns of the +124 * input rectangular array. The columns of the array represent values +125 * of variables to be correlated. +126 * +127 * @param matrix matrix with columns representing variables to correlate +128 * @return correlation matrix +129 */ +130 public RealMatrix computeCorrelationMatrix(double[][] matrix) { +131 return computeCorrelationMatrix(new BlockRealMatrix(matrix)); +132 } +133 +134 /** +135 * Computes the Spearman's rank correlation coefficient between the two arrays. +136 * +137 * </p>Throws IllegalArgumentException if the arrays do not have the same length +138 * or their common length is less than 2</p> +139 * +140 * @param xArray first data array +141 * @param yArray second data array +142 * @return Returns Spearman's rank correlation coefficient for the two arrays +143 * @throws IllegalArgumentException if the arrays lengths do not match or +144 * there is insufficient data +145 */ +146 public double correlation(final double[] xArray, final double[] yArray) +147 throws IllegalArgumentException { +148 if (xArray.length == yArray.length && xArray.length > 1) { +149 return new PearsonsCorrelation().correlation(rankingAlgorithm.rank(xArray), +150 rankingAlgorithm.rank(yArray)); +151 } +152 else { +153 throw MathRuntimeException.createIllegalArgumentException( +154 "invalid array dimensions. xArray has size {0}; yArray has {1} elements", +155 xArray.length, yArray.length); +156 } +157 } +158 +159 /** +160 * Applies rank transform to each of the columns of <code>matrix</code> +161 * using the current <code>rankingAlgorithm</code> +162 * +163 * @param matrix matrix to transform +164 */ +165 private void rankTransform(RealMatrix matrix) { +166 for (int i = 0; i < matrix.getColumnDimension(); i++) { +167 matrix.setColumn(i, rankingAlgorithm.rank(matrix.getColumn(i))); +168 } +169 } +170 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/AbstractStorelessUnivariateStatistic.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/AbstractStorelessUnivariateStatistic.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,248 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive; +018 +019 import org.apache.commons.math.MathRuntimeException; +020 import org.apache.commons.math.util.MathUtils; +021 +022 /** +023 * +024 * Abstract implementation of the {@link StorelessUnivariateStatistic} interface. +025 * <p> +026 * Provides default <code>evaluate()</code> and <code>incrementAll(double[])<code> +027 * implementations.</p> +028 * <p> +029 * <strong>Note that these implementations are not synchronized.</strong></p> +030 * +031 * @version $Revision: 811833 $ $Date: 2009-09-06 12:27:50 -0400 (Sun, 06 Sep 2009) $ +032 */ +033 public abstract class AbstractStorelessUnivariateStatistic +034 extends AbstractUnivariateStatistic +035 implements StorelessUnivariateStatistic { +036 +037 /** +038 * This default implementation calls {@link #clear}, then invokes +039 * {@link #increment} in a loop over the the input array, and then uses +040 * {@link #getResult} to compute the return value. +041 * <p> +042 * Note that this implementation changes the internal state of the +043 * statistic. Its side effects are the same as invoking {@link #clear} and +044 * then {@link #incrementAll(double[])}.</p> +045 * <p> +046 * Implementations may override this method with a more efficient and +047 * possibly more accurate implementation that works directly with the +048 * input array.</p> +049 * <p> +050 * If the array is null, an IllegalArgumentException is thrown.</p> +051 * @param values input array +052 * @return the value of the statistic applied to the input array +053 * @see org.apache.commons.math.stat.descriptive.UnivariateStatistic#evaluate(double[]) +054 */ +055 @Override +056 public double evaluate(final double[] values) { +057 if (values == null) { +058 throw MathRuntimeException.createIllegalArgumentException("input values array is null"); +059 } +060 return evaluate(values, 0, values.length); +061 } +062 +063 /** +064 * This default implementation calls {@link #clear}, then invokes +065 * {@link #increment} in a loop over the specified portion of the input +066 * array, and then uses {@link #getResult} to compute the return value. +067 * <p> +068 * Note that this implementation changes the internal state of the +069 * statistic. Its side effects are the same as invoking {@link #clear} and +070 * then {@link #incrementAll(double[], int, int)}.</p> +071 * <p> +072 * Implementations may override this method with a more efficient and +073 * possibly more accurate implementation that works directly with the +074 * input array.</p> +075 * <p> +076 * If the array is null or the index parameters are not valid, an +077 * IllegalArgumentException is thrown.</p> +078 * @param values the input array +079 * @param begin the index of the first element to include +080 * @param length the number of elements to include +081 * @return the value of the statistic applied to the included array entries +082 * @see org.apache.commons.math.stat.descriptive.UnivariateStatistic#evaluate(double[], int, int) +083 */ +084 @Override +085 public double evaluate(final double[] values, final int begin, final int length) { +086 if (test(values, begin, length)) { +087 clear(); +088 incrementAll(values, begin, length); +089 } +090 return getResult(); +091 } +092 +093 /** +094 * {@inheritDoc} +095 */ +096 @Override +097 public abstract StorelessUnivariateStatistic copy(); +098 +099 /** +100 * {@inheritDoc} +101 */ +102 public abstract void clear(); +103 +104 /** +105 * {@inheritDoc} +106 */ +107 public abstract double getResult(); +108 +109 /** +110 * {@inheritDoc} +111 */ +112 public abstract void increment(final double d); +113 +114 /** +115 * This default implementation just calls {@link #increment} in a loop over +116 * the input array. +117 * <p> +118 * Throws IllegalArgumentException if the input values array is null.</p> +119 * +120 * @param values values to add +121 * @throws IllegalArgumentException if values is null +122 * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#incrementAll(double[]) +123 */ +124 public void incrementAll(double[] values) { +125 if (values == null) { +126 throw MathRuntimeException.createIllegalArgumentException("input values array is null"); +127 } +128 incrementAll(values, 0, values.length); +129 } +130 +131 /** +132 * This default implementation just calls {@link #increment} in a loop over +133 * the specified portion of the input array. +134 * <p> +135 * Throws IllegalArgumentException if the input values array is null.</p> +136 * +137 * @param values array holding values to add +138 * @param begin index of the first array element to add +139 * @param length number of array elements to add +140 * @throws IllegalArgumentException if values is null +141 * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#incrementAll(double[], int, int) +142 */ +143 public void incrementAll(double[] values, int begin, int length) { +144 if (test(values, begin, length)) { +145 int k = begin + length; +146 for (int i = begin; i < k; i++) { +147 increment(values[i]); +148 } +149 } +150 } +151 +152 /** +153 * Returns true iff <code>object</code> is an +154 * <code>AbstractStorelessUnivariateStatistic</code> returning the same +155 * values as this for <code>getResult()</code> and <code>getN()</code> +156 * @param object object to test equality against. +157 * @return true if object returns the same value as this +158 */ +159 @Override +160 public boolean equals(Object object) { +161 if (object == this ) { +162 return true; +163 } +164 if (object instanceof AbstractStorelessUnivariateStatistic == false) { +165 return false; +166 } +167 AbstractStorelessUnivariateStatistic stat = (AbstractStorelessUnivariateStatistic) object; +168 return MathUtils.equals(stat.getResult(), this.getResult()) && +169 MathUtils.equals(stat.getN(), this.getN()); +170 } +171 +172 /** +173 * Returns hash code based on getResult() and getN() +174 * +175 * @return hash code +176 */ +177 @Override +178 public int hashCode() { +179 return 31* (31 + MathUtils.hash(getResult())) + MathUtils.hash(getN()); +180 } +181 +182 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatistic.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/AbstractUnivariateStatistic.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,243 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive; +018 +019 import org.apache.commons.math.MathRuntimeException; +020 +021 /** +022 * Abstract base class for all implementations of the +023 * {@link UnivariateStatistic} interface. +024 * <p> +025 * Provides a default implementation of <code>evaluate(double[]),</code> +026 * delegating to <code>evaluate(double[], int, int)</code> in the natural way. +027 * </p> +028 * <p> +029 * Also includes a <code>test</code> method that performs generic parameter +030 * validation for the <code>evaluate</code> methods.</p> +031 * +032 * @version $Revision: 894705 $ $Date: 2009-12-30 15:24:54 -0500 (Wed, 30 Dec 2009) $ +033 */ +034 public abstract class AbstractUnivariateStatistic +035 implements UnivariateStatistic { +036 +037 /** +038 * {@inheritDoc} +039 */ +040 public double evaluate(final double[] values) { +041 test(values, 0, 0); +042 return evaluate(values, 0, values.length); +043 } +044 +045 /** +046 * {@inheritDoc} +047 */ +048 public abstract double evaluate(final double[] values, final int begin, final int length); +049 +050 /** +051 * {@inheritDoc} +052 */ +053 public abstract UnivariateStatistic copy(); +054 +055 /** +056 * This method is used by <code>evaluate(double[], int, int)</code> methods +057 * to verify that the input parameters designate a subarray of positive length. +058 * <p> +059 * <ul> +060 * <li>returns <code>true</code> iff the parameters designate a subarray of +061 * positive length</li> +062 * <li>throws <code>IllegalArgumentException</code> if the array is null or +063 * or the indices are invalid</li> +064 * <li>returns <code>false</li> if the array is non-null, but +065 * <code>length</code> is 0. +066 * </ul></p> +067 * +068 * @param values the input array +069 * @param begin index of the first array element to include +070 * @param length the number of elements to include +071 * @return true if the parameters are valid and designate a subarray of positive length +072 * @throws IllegalArgumentException if the indices are invalid or the array is null +073 */ +074 protected boolean test( +075 final double[] values, +076 final int begin, +077 final int length) { +078 +079 if (values == null) { +080 throw MathRuntimeException.createIllegalArgumentException("input values array is null"); +081 } +082 +083 if (begin < 0) { +084 throw MathRuntimeException.createIllegalArgumentException( +085 "start position cannot be negative ({0})", begin); +086 } +087 +088 if (length < 0) { +089 throw MathRuntimeException.createIllegalArgumentException( +090 "length cannot be negative ({0})", length); +091 } +092 +093 if (begin + length > values.length) { +094 throw MathRuntimeException.createIllegalArgumentException( +095 "subarray ends after array end"); +096 } +097 +098 if (length == 0) { +099 return false; +100 } +101 +102 return true; +103 +104 } +105 +106 /** +107 * This method is used by <code>evaluate(double[], double[], int, int)</code> methods +108 * to verify that the begin and length parameters designate a subarray of positive length +109 * and the weights are all non-negative, non-NaN, finite, and not all zero. +110 * <p> +111 * <ul> +112 * <li>returns <code>true</code> iff the parameters designate a subarray of +113 * positive length and the weights array contains legitimate values.</li> +114 * <li>throws <code>IllegalArgumentException</code> if any of the following are true: +115 * <ul><li>the values array is null</li> +116 * <li>the weights array is null</li> +117 * <li>the weights array does not have the same length as the values array</li> +118 * <li>the weights array contains one or more infinite values</li> +119 * <li>the weights array contains one or more NaN values</li> +120 * <li>the weights array contains negative values</li> +121 * <li>the start and length arguments do not determine a valid array</li></ul> +122 * </li> +123 * <li>returns <code>false</li> if the array is non-null, but +124 * <code>length</code> is 0. +125 * </ul></p> +126 * +127 * @param values the input array +128 * @param weights the weights array +129 * @param begin index of the first array element to include +130 * @param length the number of elements to include +131 * @return true if the parameters are valid and designate a subarray of positive length +132 * @throws IllegalArgumentException if the indices are invalid or the array is null +133 * @since 2.1 +134 */ +135 protected boolean test( +136 final double[] values, +137 final double[] weights, +138 final int begin, +139 final int length) { +140 +141 if (weights == null) { +142 throw MathRuntimeException.createIllegalArgumentException("input weights array is null"); +143 } +144 +145 if (weights.length != values.length) { +146 throw MathRuntimeException.createIllegalArgumentException( +147 "Different number of weights and values"); +148 } +149 +150 boolean containsPositiveWeight = false; +151 for (int i = begin; i < begin + length; i++) { +152 if (Double.isNaN(weights[i])) { +153 throw MathRuntimeException.createIllegalArgumentException( +154 "NaN weight at index {0}", i); +155 } +156 if (Double.isInfinite(weights[i])) { +157 throw MathRuntimeException.createIllegalArgumentException( +158 "Infinite weight at index {0}", i); +159 } +160 if (weights[i] < 0) { +161 throw MathRuntimeException.createIllegalArgumentException( +162 "negative weight {0} at index {1} ", weights[i], i); +163 } +164 if (!containsPositiveWeight && weights[i] > 0.0) { +165 containsPositiveWeight = true; +166 } +167 } +168 +169 if (!containsPositiveWeight) { +170 throw MathRuntimeException.createIllegalArgumentException( +171 "weight array must contain at least one non-zero value"); +172 } +173 +174 return test(values, begin, length); +175 } +176 } +177 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/AggregateSummaryStatistics.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/AggregateSummaryStatistics.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,482 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.stat.descriptive; +019 +020 import java.io.Serializable; +021 import java.util.Collection; +022 import java.util.Iterator; +023 +024 /** +025 * <p> +026 * An aggregator for {@code SummaryStatistics} from several data sets or +027 * data set partitions. In its simplest usage mode, the client creates an +028 * instance via the zero-argument constructor, then uses +029 * {@link #createContributingStatistics()} to obtain a {@code SummaryStatistics} +030 * for each individual data set / partition. The per-set statistics objects +031 * are used as normal, and at any time the aggregate statistics for all the +032 * contributors can be obtained from this object. +033 * </p><p> +034 * Clients with specialized requirements can use alternative constructors to +035 * control the statistics implementations and initial values used by the +036 * contributing and the internal aggregate {@code SummaryStatistics} objects. +037 * </p><p> +038 * A static {@link #aggregate(Collection)} method is also included that computes +039 * aggregate statistics directly from a Collection of SummaryStatistics instances. +040 * </p><p> +041 * When {@link #createContributingStatistics()} is used to create SummaryStatistics +042 * instances to be aggregated concurrently, the created instances' +043 * {@link SummaryStatistics#addValue(double)} methods must synchronize on the aggregating +044 * instance maintained by this class. In multithreaded environments, if the functionality +045 * provided by {@link #aggregate(Collection)} is adequate, that method should be used +046 * to avoid unecessary computation and synchronization delays.</p> +047 * +048 * @since 2.0 +049 * @version $Revision: 811833 $ $Date: 2009-09-06 12:27:50 -0400 (Sun, 06 Sep 2009) $ +050 * +051 */ +052 public class AggregateSummaryStatistics implements StatisticalSummary, +053 Serializable { +054 +055 +056 /** Serializable version identifier */ +057 private static final long serialVersionUID = -8207112444016386906L; +058 +059 /** +060 * A SummaryStatistics serving as a prototype for creating SummaryStatistics +061 * contributing to this aggregate +062 */ +063 private final SummaryStatistics statisticsPrototype; +064 +065 /** +066 * The SummaryStatistics in which aggregate statistics are accumulated. +067 */ +068 private final SummaryStatistics statistics; +069 +070 /** +071 * Initializes a new AggregateSummaryStatistics with default statistics +072 * implementations. +073 * +074 */ +075 public AggregateSummaryStatistics() { +076 this(new SummaryStatistics()); +077 } +078 +079 /** +080 * Initializes a new AggregateSummaryStatistics with the specified statistics +081 * object as a prototype for contributing statistics and for the internal +082 * aggregate statistics. This provides for customized statistics implementations +083 * to be used by contributing and aggregate statistics. +084 * +085 * @param prototypeStatistics a {@code SummaryStatistics} serving as a +086 * prototype both for the internal aggregate statistics and for +087 * contributing statistics obtained via the +088 * {@code createContributingStatistics()} method. Being a prototype +089 * means that other objects are initialized by copying this object's state. +090 * If {@code null}, a new, default statistics object is used. Any statistic +091 * values in the prototype are propagated to contributing statistics +092 * objects and (once) into these aggregate statistics. +093 * @see #createContributingStatistics() +094 */ +095 public AggregateSummaryStatistics(SummaryStatistics prototypeStatistics) { +096 this(prototypeStatistics, +097 prototypeStatistics == null ? null : new SummaryStatistics(prototypeStatistics)); +098 } +099 +100 /** +101 * Initializes a new AggregateSummaryStatistics with the specified statistics +102 * object as a prototype for contributing statistics and for the internal +103 * aggregate statistics. This provides for different statistics implementations +104 * to be used by contributing and aggregate statistics and for an initial +105 * state to be supplied for the aggregate statistics. +106 * +107 * @param prototypeStatistics a {@code SummaryStatistics} serving as a +108 * prototype both for the internal aggregate statistics and for +109 * contributing statistics obtained via the +110 * {@code createContributingStatistics()} method. Being a prototype +111 * means that other objects are initialized by copying this object's state. +112 * If {@code null}, a new, default statistics object is used. Any statistic +113 * values in the prototype are propagated to contributing statistics +114 * objects, but not into these aggregate statistics. +115 * @param initialStatistics a {@code SummaryStatistics} to serve as the +116 * internal aggregate statistics object. If {@code null}, a new, default +117 * statistics object is used. +118 * @see #createContributingStatistics() +119 */ +120 public AggregateSummaryStatistics(SummaryStatistics prototypeStatistics, +121 SummaryStatistics initialStatistics) { +122 this.statisticsPrototype = +123 (prototypeStatistics == null) ? new SummaryStatistics() : prototypeStatistics; +124 this.statistics = +125 (initialStatistics == null) ? new SummaryStatistics() : initialStatistics; +126 } +127 +128 /** +129 * {@inheritDoc}. This version returns the maximum over all the aggregated +130 * data. +131 * +132 * @see StatisticalSummary#getMax() +133 */ +134 public double getMax() { +135 synchronized (statistics) { +136 return statistics.getMax(); +137 } +138 } +139 +140 /** +141 * {@inheritDoc}. This version returns the mean of all the aggregated data. +142 * +143 * @see StatisticalSummary#getMean() +144 */ +145 public double getMean() { +146 synchronized (statistics) { +147 return statistics.getMean(); +148 } +149 } +150 +151 /** +152 * {@inheritDoc}. This version returns the minimum over all the aggregated +153 * data. +154 * +155 * @see StatisticalSummary#getMin() +156 */ +157 public double getMin() { +158 synchronized (statistics) { +159 return statistics.getMin(); +160 } +161 } +162 +163 /** +164 * {@inheritDoc}. This version returns a count of all the aggregated data. +165 * +166 * @see StatisticalSummary#getN() +167 */ +168 public long getN() { +169 synchronized (statistics) { +170 return statistics.getN(); +171 } +172 } +173 +174 /** +175 * {@inheritDoc}. This version returns the standard deviation of all the +176 * aggregated data. +177 * +178 * @see StatisticalSummary#getStandardDeviation() +179 */ +180 public double getStandardDeviation() { +181 synchronized (statistics) { +182 return statistics.getStandardDeviation(); +183 } +184 } +185 +186 /** +187 * {@inheritDoc}. This version returns a sum of all the aggregated data. +188 * +189 * @see StatisticalSummary#getSum() +190 */ +191 public double getSum() { +192 synchronized (statistics) { +193 return statistics.getSum(); +194 } +195 } +196 +197 /** +198 * {@inheritDoc}. This version returns the variance of all the aggregated +199 * data. +200 * +201 * @see StatisticalSummary#getVariance() +202 */ +203 public double getVariance() { +204 synchronized (statistics) { +205 return statistics.getVariance(); +206 } +207 } +208 +209 /** +210 * Returns the sum of the logs of all the aggregated data. +211 * +212 * @return the sum of logs +213 * @see SummaryStatistics#getSumOfLogs() +214 */ +215 public double getSumOfLogs() { +216 synchronized (statistics) { +217 return statistics.getSumOfLogs(); +218 } +219 } +220 +221 /** +222 * Returns the geometric mean of all the aggregated data. +223 * +224 * @return the geometric mean +225 * @see SummaryStatistics#getGeometricMean() +226 */ +227 public double getGeometricMean() { +228 synchronized (statistics) { +229 return statistics.getGeometricMean(); +230 } +231 } +232 +233 /** +234 * Returns the sum of the squares of all the aggregated data. +235 * +236 * @return The sum of squares +237 * @see SummaryStatistics#getSumsq() +238 */ +239 public double getSumsq() { +240 synchronized (statistics) { +241 return statistics.getSumsq(); +242 } +243 } +244 +245 /** +246 * Returns a statistic related to the Second Central Moment. Specifically, +247 * what is returned is the sum of squared deviations from the sample mean +248 * among the all of the aggregated data. +249 * +250 * @return second central moment statistic +251 * @see SummaryStatistics#getSecondMoment() +252 */ +253 public double getSecondMoment() { +254 synchronized (statistics) { +255 return statistics.getSecondMoment(); +256 } +257 } +258 +259 /** +260 * Return a {@link StatisticalSummaryValues} instance reporting current +261 * aggregate statistics. +262 * +263 * @return Current values of aggregate statistics +264 */ +265 public StatisticalSummary getSummary() { +266 synchronized (statistics) { +267 return new StatisticalSummaryValues(getMean(), getVariance(), getN(), +268 getMax(), getMin(), getSum()); +269 } +270 } +271 +272 /** +273 * Creates and returns a {@code SummaryStatistics} whose data will be +274 * aggregated with those of this {@code AggregateSummaryStatistics}. +275 * +276 * @return a {@code SummaryStatistics} whose data will be aggregated with +277 * those of this {@code AggregateSummaryStatistics}. The initial state +278 * is a copy of the configured prototype statistics. +279 */ +280 public SummaryStatistics createContributingStatistics() { +281 SummaryStatistics contributingStatistics +282 = new AggregatingSummaryStatistics(statistics); +283 +284 SummaryStatistics.copy(statisticsPrototype, contributingStatistics); +285 +286 return contributingStatistics; +287 } +288 +289 /** +290 * Computes aggregate summary statistics. This method can be used to combine statistics +291 * computed over partitions or subsamples - i.e., the StatisticalSummaryValues returned +292 * should contain the same values that would have been obtained by computing a single +293 * StatisticalSummary over the combined dataset. +294 * <p> +295 * Returns null if the collection is empty or null. +296 * </p> +297 * +298 * @param statistics collection of SummaryStatistics to aggregate +299 * @return summary statistics for the combined dataset +300 */ +301 public static StatisticalSummaryValues aggregate(Collection<SummaryStatistics> statistics) { +302 if (statistics == null) { +303 return null; +304 } +305 Iterator<SummaryStatistics> iterator = statistics.iterator(); +306 if (!iterator.hasNext()) { +307 return null; +308 } +309 SummaryStatistics current = iterator.next(); +310 long n = current.getN(); +311 double min = current.getMin(); +312 double sum = current.getSum(); +313 double max = current.getMax(); +314 double m2 = current.getSecondMoment(); +315 double mean = current.getMean(); +316 while (iterator.hasNext()) { +317 current = iterator.next(); +318 if (current.getMin() < min || Double.isNaN(min)) { +319 min = current.getMin(); +320 } +321 if (current.getMax() > max || Double.isNaN(max)) { +322 max = current.getMax(); +323 } +324 sum += current.getSum(); +325 final double oldN = n; +326 final double curN = current.getN(); +327 n += curN; +328 final double meanDiff = current.getMean() - mean; +329 mean = sum / n; +330 m2 = m2 + current.getSecondMoment() + meanDiff * meanDiff * oldN * curN / n; +331 } +332 final double variance; +333 if (n == 0) { +334 variance = Double.NaN; +335 } else if (n == 1) { +336 variance = 0d; +337 } else { +338 variance = m2 / (n - 1); +339 } +340 return new StatisticalSummaryValues(mean, variance, n, max, min, sum); +341 } +342 +343 /** +344 * A SummaryStatistics that also forwards all values added to it to a second +345 * {@code SummaryStatistics} for aggregation. +346 * +347 * @since 2.0 +348 */ +349 private static class AggregatingSummaryStatistics extends SummaryStatistics { +350 +351 /** +352 * The serialization version of this class +353 */ +354 private static final long serialVersionUID = 1L; +355 +356 /** +357 * An additional SummaryStatistics into which values added to these +358 * statistics (and possibly others) are aggregated +359 */ +360 private final SummaryStatistics aggregateStatistics; +361 +362 /** +363 * Initializes a new AggregatingSummaryStatistics with the specified +364 * aggregate statistics object +365 * +366 * @param aggregateStatistics a {@code SummaryStatistics} into which +367 * values added to this statistics object should be aggregated +368 */ +369 public AggregatingSummaryStatistics(SummaryStatistics aggregateStatistics) { +370 this.aggregateStatistics = aggregateStatistics; +371 } +372 +373 /** +374 * {@inheritDoc}. This version adds the provided value to the configured +375 * aggregate after adding it to these statistics. +376 * +377 * @see SummaryStatistics#addValue(double) +378 */ +379 @Override +380 public void addValue(double value) { +381 super.addValue(value); +382 synchronized (aggregateStatistics) { +383 aggregateStatistics.addValue(value); +384 } +385 } +386 +387 /** +388 * Returns true iff <code>object</code> is a +389 * <code>SummaryStatistics</code> instance and all statistics have the +390 * same values as this. +391 * @param object the object to test equality against. +392 * @return true if object equals this +393 */ +394 @Override +395 public boolean equals(Object object) { +396 if (object == this) { +397 return true; +398 } +399 if (object instanceof AggregatingSummaryStatistics == false) { +400 return false; +401 } +402 AggregatingSummaryStatistics stat = (AggregatingSummaryStatistics)object; +403 return super.equals(stat) && +404 aggregateStatistics.equals(stat.aggregateStatistics); +405 } +406 +407 /** +408 * Returns hash code based on values of statistics +409 * @return hash code +410 */ +411 @Override +412 public int hashCode() { +413 return 123 + super.hashCode() + aggregateStatistics.hashCode(); +414 } +415 } +416 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/DescriptiveStatistics.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/DescriptiveStatistics.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,779 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive; +018 +019 import java.io.Serializable; +020 import java.lang.reflect.InvocationTargetException; +021 import java.util.Arrays; +022 +023 import org.apache.commons.math.MathRuntimeException; +024 import org.apache.commons.math.stat.descriptive.moment.GeometricMean; +025 import org.apache.commons.math.stat.descriptive.moment.Kurtosis; +026 import org.apache.commons.math.stat.descriptive.moment.Mean; +027 import org.apache.commons.math.stat.descriptive.moment.Skewness; +028 import org.apache.commons.math.stat.descriptive.moment.Variance; +029 import org.apache.commons.math.stat.descriptive.rank.Max; +030 import org.apache.commons.math.stat.descriptive.rank.Min; +031 import org.apache.commons.math.stat.descriptive.rank.Percentile; +032 import org.apache.commons.math.stat.descriptive.summary.Sum; +033 import org.apache.commons.math.stat.descriptive.summary.SumOfSquares; +034 import org.apache.commons.math.util.ResizableDoubleArray; +035 +036 +037 /** +038 * Maintains a dataset of values of a single variable and computes descriptive +039 * statistics based on stored data. The {@link #getWindowSize() windowSize} +040 * property sets a limit on the number of values that can be stored in the +041 * dataset. The default value, INFINITE_WINDOW, puts no limit on the size of +042 * the dataset. This value should be used with caution, as the backing store +043 * will grow without bound in this case. For very large datasets, +044 * {@link SummaryStatistics}, which does not store the dataset, should be used +045 * instead of this class. If <code>windowSize</code> is not INFINITE_WINDOW and +046 * more values are added than can be stored in the dataset, new values are +047 * added in a "rolling" manner, with new values replacing the "oldest" values +048 * in the dataset. +049 * +050 * <p>Note: this class is not threadsafe. Use +051 * {@link SynchronizedDescriptiveStatistics} if concurrent access from multiple +052 * threads is required.</p> +053 * +054 * @version $Revision: 885278 $ $Date: 2009-11-29 16:47:51 -0500 (Sun, 29 Nov 2009) $ +055 */ +056 public class DescriptiveStatistics implements StatisticalSummary, Serializable { +057 +058 /** +059 * Represents an infinite window size. When the {@link #getWindowSize()} +060 * returns this value, there is no limit to the number of data values +061 * that can be stored in the dataset. +062 */ +063 public static final int INFINITE_WINDOW = -1; +064 +065 /** Serialization UID */ +066 private static final long serialVersionUID = 4133067267405273064L; +067 +068 /** Name of the setQuantile method. */ +069 private static final String SET_QUANTILE_METHOD_NAME = "setQuantile"; +070 +071 /** Message for unsupported setQuantile. */ +072 private static final String UNSUPPORTED_METHOD_MESSAGE = +073 "percentile implementation {0} does not support {1}"; +074 +075 /** Message for illegal accesson setquantile. */ +076 private static final String ILLEGAL_ACCESS_MESSAGE = +077 "cannot access {0} method in percentile implementation {1}"; +078 +079 /** hold the window size **/ +080 protected int windowSize = INFINITE_WINDOW; +081 +082 /** +083 * Stored data values +084 */ +085 protected ResizableDoubleArray eDA = new ResizableDoubleArray(); +086 +087 /** Mean statistic implementation - can be reset by setter. */ +088 private UnivariateStatistic meanImpl = new Mean(); +089 +090 /** Geometric mean statistic implementation - can be reset by setter. */ +091 private UnivariateStatistic geometricMeanImpl = new GeometricMean(); +092 +093 /** Kurtosis statistic implementation - can be reset by setter. */ +094 private UnivariateStatistic kurtosisImpl = new Kurtosis(); +095 +096 /** Maximum statistic implementation - can be reset by setter. */ +097 private UnivariateStatistic maxImpl = new Max(); +098 +099 /** Minimum statistic implementation - can be reset by setter. */ +100 private UnivariateStatistic minImpl = new Min(); +101 +102 /** Percentile statistic implementation - can be reset by setter. */ +103 private UnivariateStatistic percentileImpl = new Percentile(); +104 +105 /** Skewness statistic implementation - can be reset by setter. */ +106 private UnivariateStatistic skewnessImpl = new Skewness(); +107 +108 /** Variance statistic implementation - can be reset by setter. */ +109 private UnivariateStatistic varianceImpl = new Variance(); +110 +111 /** Sum of squares statistic implementation - can be reset by setter. */ +112 private UnivariateStatistic sumsqImpl = new SumOfSquares(); +113 +114 /** Sum statistic implementation - can be reset by setter. */ +115 private UnivariateStatistic sumImpl = new Sum(); +116 +117 /** +118 * Construct a DescriptiveStatistics instance with an infinite window +119 */ +120 public DescriptiveStatistics() { +121 } +122 +123 /** +124 * Construct a DescriptiveStatistics instance with the specified window +125 * +126 * @param window the window size. +127 */ +128 public DescriptiveStatistics(int window) { +129 setWindowSize(window); +130 } +131 +132 /** +133 * Copy constructor. Construct a new DescriptiveStatistics instance that +134 * is a copy of original. +135 * +136 * @param original DescriptiveStatistics instance to copy +137 */ +138 public DescriptiveStatistics(DescriptiveStatistics original) { +139 copy(original, this); +140 } +141 +142 /** +143 * Adds the value to the dataset. If the dataset is at the maximum size +144 * (i.e., the number of stored elements equals the currently configured +145 * windowSize), the first (oldest) element in the dataset is discarded +146 * to make room for the new value. +147 * +148 * @param v the value to be added +149 */ +150 public void addValue(double v) { +151 if (windowSize != INFINITE_WINDOW) { +152 if (getN() == windowSize) { +153 eDA.addElementRolling(v); +154 } else if (getN() < windowSize) { +155 eDA.addElement(v); +156 } +157 } else { +158 eDA.addElement(v); +159 } +160 } +161 +162 /** +163 * Removes the most recent value from the dataset. +164 */ +165 public void removeMostRecentValue() { +166 eDA.discardMostRecentElements(1); +167 } +168 +169 /** +170 * Replaces the most recently stored value with the given value. +171 * There must be at least one element stored to call this method. +172 * +173 * @param v the value to replace the most recent stored value +174 * @return replaced value +175 */ +176 public double replaceMostRecentValue(double v) { +177 return eDA.substituteMostRecentElement(v); +178 } +179 +180 /** +181 * Returns the <a href="http://www.xycoon.com/arithmetic_mean.htm"> +182 * arithmetic mean </a> of the available values +183 * @return The mean or Double.NaN if no values have been added. +184 */ +185 public double getMean() { +186 return apply(meanImpl); +187 } +188 +189 /** +190 * Returns the <a href="http://www.xycoon.com/geometric_mean.htm"> +191 * geometric mean </a> of the available values +192 * @return The geometricMean, Double.NaN if no values have been added, +193 * or if the product of the available values is less than or equal to 0. +194 */ +195 public double getGeometricMean() { +196 return apply(geometricMeanImpl); +197 } +198 +199 /** +200 * Returns the variance of the available values. +201 * @return The variance, Double.NaN if no values have been added +202 * or 0.0 for a single value set. +203 */ +204 public double getVariance() { +205 return apply(varianceImpl); +206 } +207 +208 /** +209 * Returns the standard deviation of the available values. +210 * @return The standard deviation, Double.NaN if no values have been added +211 * or 0.0 for a single value set. +212 */ +213 public double getStandardDeviation() { +214 double stdDev = Double.NaN; +215 if (getN() > 0) { +216 if (getN() > 1) { +217 stdDev = Math.sqrt(getVariance()); +218 } else { +219 stdDev = 0.0; +220 } +221 } +222 return stdDev; +223 } +224 +225 /** +226 * Returns the skewness of the available values. Skewness is a +227 * measure of the asymmetry of a given distribution. +228 * @return The skewness, Double.NaN if no values have been added +229 * or 0.0 for a value set <=2. +230 */ +231 public double getSkewness() { +232 return apply(skewnessImpl); +233 } +234 +235 /** +236 * Returns the Kurtosis of the available values. Kurtosis is a +237 * measure of the "peakedness" of a distribution +238 * @return The kurtosis, Double.NaN if no values have been added, or 0.0 +239 * for a value set <=3. +240 */ +241 public double getKurtosis() { +242 return apply(kurtosisImpl); +243 } +244 +245 /** +246 * Returns the maximum of the available values +247 * @return The max or Double.NaN if no values have been added. +248 */ +249 public double getMax() { +250 return apply(maxImpl); +251 } +252 +253 /** +254 * Returns the minimum of the available values +255 * @return The min or Double.NaN if no values have been added. +256 */ +257 public double getMin() { +258 return apply(minImpl); +259 } +260 +261 /** +262 * Returns the number of available values +263 * @return The number of available values +264 */ +265 public long getN() { +266 return eDA.getNumElements(); +267 } +268 +269 /** +270 * Returns the sum of the values that have been added to Univariate. +271 * @return The sum or Double.NaN if no values have been added +272 */ +273 public double getSum() { +274 return apply(sumImpl); +275 } +276 +277 /** +278 * Returns the sum of the squares of the available values. +279 * @return The sum of the squares or Double.NaN if no +280 * values have been added. +281 */ +282 public double getSumsq() { +283 return apply(sumsqImpl); +284 } +285 +286 /** +287 * Resets all statistics and storage +288 */ +289 public void clear() { +290 eDA.clear(); +291 } +292 +293 +294 /** +295 * Returns the maximum number of values that can be stored in the +296 * dataset, or INFINITE_WINDOW (-1) if there is no limit. +297 * +298 * @return The current window size or -1 if its Infinite. +299 */ +300 public int getWindowSize() { +301 return windowSize; +302 } +303 +304 /** +305 * WindowSize controls the number of values which contribute +306 * to the reported statistics. For example, if +307 * windowSize is set to 3 and the values {1,2,3,4,5} +308 * have been added <strong> in that order</strong> +309 * then the <i>available values</i> are {3,4,5} and all +310 * reported statistics will be based on these values +311 * @param windowSize sets the size of the window. +312 */ +313 public void setWindowSize(int windowSize) { +314 if (windowSize < 1) { +315 if (windowSize != INFINITE_WINDOW) { +316 throw MathRuntimeException.createIllegalArgumentException( +317 "window size must be positive ({0})", windowSize); +318 } +319 } +320 +321 this.windowSize = windowSize; +322 +323 // We need to check to see if we need to discard elements +324 // from the front of the array. If the windowSize is less than +325 // the current number of elements. +326 if (windowSize != INFINITE_WINDOW && windowSize < eDA.getNumElements()) { +327 eDA.discardFrontElements(eDA.getNumElements() - windowSize); +328 } +329 } +330 +331 /** +332 * Returns the current set of values in an array of double primitives. +333 * The order of addition is preserved. The returned array is a fresh +334 * copy of the underlying data -- i.e., it is not a reference to the +335 * stored data. +336 * +337 * @return returns the current set of numbers in the order in which they +338 * were added to this set +339 */ +340 public double[] getValues() { +341 return eDA.getElements(); +342 } +343 +344 /** +345 * Returns the current set of values in an array of double primitives, +346 * sorted in ascending order. The returned array is a fresh +347 * copy of the underlying data -- i.e., it is not a reference to the +348 * stored data. +349 * @return returns the current set of +350 * numbers sorted in ascending order +351 */ +352 public double[] getSortedValues() { +353 double[] sort = getValues(); +354 Arrays.sort(sort); +355 return sort; +356 } +357 +358 /** +359 * Returns the element at the specified index +360 * @param index The Index of the element +361 * @return return the element at the specified index +362 */ +363 public double getElement(int index) { +364 return eDA.getElement(index); +365 } +366 +367 /** +368 * Returns an estimate for the pth percentile of the stored values. +369 * <p> +370 * The implementation provided here follows the first estimation procedure presented +371 * <a href="http://www.itl.nist.gov/div898/handbook/prc/section2/prc252.htm">here.</a> +372 * </p><p> +373 * <strong>Preconditions</strong>:<ul> +374 * <li><code>0 < p ≤ 100</code> (otherwise an +375 * <code>IllegalArgumentException</code> is thrown)</li> +376 * <li>at least one value must be stored (returns <code>Double.NaN +377 * </code> otherwise)</li> +378 * </ul></p> +379 * +380 * @param p the requested percentile (scaled from 0 - 100) +381 * @return An estimate for the pth percentile of the stored data +382 * @throws IllegalStateException if percentile implementation has been +383 * overridden and the supplied implementation does not support setQuantile +384 * values +385 */ +386 public double getPercentile(double p) { +387 if (percentileImpl instanceof Percentile) { +388 ((Percentile) percentileImpl).setQuantile(p); +389 } else { +390 try { +391 percentileImpl.getClass().getMethod(SET_QUANTILE_METHOD_NAME, +392 new Class[] {Double.TYPE}).invoke(percentileImpl, +393 new Object[] {Double.valueOf(p)}); +394 } catch (NoSuchMethodException e1) { // Setter guard should prevent +395 throw MathRuntimeException.createIllegalArgumentException( +396 UNSUPPORTED_METHOD_MESSAGE, +397 percentileImpl.getClass().getName(), SET_QUANTILE_METHOD_NAME); +398 } catch (IllegalAccessException e2) { +399 throw MathRuntimeException.createIllegalArgumentException( +400 ILLEGAL_ACCESS_MESSAGE, +401 SET_QUANTILE_METHOD_NAME, percentileImpl.getClass().getName()); +402 } catch (InvocationTargetException e3) { +403 throw MathRuntimeException.createIllegalArgumentException(e3.getCause()); +404 } +405 } +406 return apply(percentileImpl); +407 } +408 +409 /** +410 * Generates a text report displaying univariate statistics from values +411 * that have been added. Each statistic is displayed on a separate +412 * line. +413 * +414 * @return String with line feeds displaying statistics +415 */ +416 @Override +417 public String toString() { +418 StringBuffer outBuffer = new StringBuffer(); +419 String endl = "\n"; +420 outBuffer.append("DescriptiveStatistics:").append(endl); +421 outBuffer.append("n: ").append(getN()).append(endl); +422 outBuffer.append("min: ").append(getMin()).append(endl); +423 outBuffer.append("max: ").append(getMax()).append(endl); +424 outBuffer.append("mean: ").append(getMean()).append(endl); +425 outBuffer.append("std dev: ").append(getStandardDeviation()) +426 .append(endl); +427 outBuffer.append("median: ").append(getPercentile(50)).append(endl); +428 outBuffer.append("skewness: ").append(getSkewness()).append(endl); +429 outBuffer.append("kurtosis: ").append(getKurtosis()).append(endl); +430 return outBuffer.toString(); +431 } +432 +433 /** +434 * Apply the given statistic to the data associated with this set of statistics. +435 * @param stat the statistic to apply +436 * @return the computed value of the statistic. +437 */ +438 public double apply(UnivariateStatistic stat) { +439 return stat.evaluate(eDA.getInternalValues(), eDA.start(), eDA.getNumElements()); +440 } +441 +442 // Implementation getters and setter +443 +444 /** +445 * Returns the currently configured mean implementation. +446 * +447 * @return the UnivariateStatistic implementing the mean +448 * @since 1.2 +449 */ +450 public synchronized UnivariateStatistic getMeanImpl() { +451 return meanImpl; +452 } +453 +454 /** +455 * <p>Sets the implementation for the mean.</p> +456 * +457 * @param meanImpl the UnivariateStatistic instance to use +458 * for computing the mean +459 * @since 1.2 +460 */ +461 public synchronized void setMeanImpl(UnivariateStatistic meanImpl) { +462 this.meanImpl = meanImpl; +463 } +464 +465 /** +466 * Returns the currently configured geometric mean implementation. +467 * +468 * @return the UnivariateStatistic implementing the geometric mean +469 * @since 1.2 +470 */ +471 public synchronized UnivariateStatistic getGeometricMeanImpl() { +472 return geometricMeanImpl; +473 } +474 +475 /** +476 * <p>Sets the implementation for the gemoetric mean.</p> +477 * +478 * @param geometricMeanImpl the UnivariateStatistic instance to use +479 * for computing the geometric mean +480 * @since 1.2 +481 */ +482 public synchronized void setGeometricMeanImpl( +483 UnivariateStatistic geometricMeanImpl) { +484 this.geometricMeanImpl = geometricMeanImpl; +485 } +486 +487 /** +488 * Returns the currently configured kurtosis implementation. +489 * +490 * @return the UnivariateStatistic implementing the kurtosis +491 * @since 1.2 +492 */ +493 public synchronized UnivariateStatistic getKurtosisImpl() { +494 return kurtosisImpl; +495 } +496 +497 /** +498 * <p>Sets the implementation for the kurtosis.</p> +499 * +500 * @param kurtosisImpl the UnivariateStatistic instance to use +501 * for computing the kurtosis +502 * @since 1.2 +503 */ +504 public synchronized void setKurtosisImpl(UnivariateStatistic kurtosisImpl) { +505 this.kurtosisImpl = kurtosisImpl; +506 } +507 +508 /** +509 * Returns the currently configured maximum implementation. +510 * +511 * @return the UnivariateStatistic implementing the maximum +512 * @since 1.2 +513 */ +514 public synchronized UnivariateStatistic getMaxImpl() { +515 return maxImpl; +516 } +517 +518 /** +519 * <p>Sets the implementation for the maximum.</p> +520 * +521 * @param maxImpl the UnivariateStatistic instance to use +522 * for computing the maximum +523 * @since 1.2 +524 */ +525 public synchronized void setMaxImpl(UnivariateStatistic maxImpl) { +526 this.maxImpl = maxImpl; +527 } +528 +529 /** +530 * Returns the currently configured minimum implementation. +531 * +532 * @return the UnivariateStatistic implementing the minimum +533 * @since 1.2 +534 */ +535 public synchronized UnivariateStatistic getMinImpl() { +536 return minImpl; +537 } +538 +539 /** +540 * <p>Sets the implementation for the minimum.</p> +541 * +542 * @param minImpl the UnivariateStatistic instance to use +543 * for computing the minimum +544 * @since 1.2 +545 */ +546 public synchronized void setMinImpl(UnivariateStatistic minImpl) { +547 this.minImpl = minImpl; +548 } +549 +550 /** +551 * Returns the currently configured percentile implementation. +552 * +553 * @return the UnivariateStatistic implementing the percentile +554 * @since 1.2 +555 */ +556 public synchronized UnivariateStatistic getPercentileImpl() { +557 return percentileImpl; +558 } +559 +560 /** +561 * Sets the implementation to be used by {@link #getPercentile(double)}. +562 * The supplied <code>UnivariateStatistic</code> must provide a +563 * <code>setQuantile(double)</code> method; otherwise +564 * <code>IllegalArgumentException</code> is thrown. +565 * +566 * @param percentileImpl the percentileImpl to set +567 * @throws IllegalArgumentException if the supplied implementation does not +568 * provide a <code>setQuantile</code> method +569 * @since 1.2 +570 */ +571 public synchronized void setPercentileImpl( +572 UnivariateStatistic percentileImpl) { +573 try { +574 percentileImpl.getClass().getMethod(SET_QUANTILE_METHOD_NAME, +575 new Class[] {Double.TYPE}).invoke(percentileImpl, +576 new Object[] {Double.valueOf(50.0d)}); +577 } catch (NoSuchMethodException e1) { +578 throw MathRuntimeException.createIllegalArgumentException( +579 "percentile implementation {0} does not support setQuantile", +580 percentileImpl.getClass().getName()); +581 } catch (IllegalAccessException e2) { +582 throw MathRuntimeException.createIllegalArgumentException( +583 ILLEGAL_ACCESS_MESSAGE, +584 SET_QUANTILE_METHOD_NAME, percentileImpl.getClass().getName()); +585 } catch (InvocationTargetException e3) { +586 throw MathRuntimeException.createIllegalArgumentException(e3.getCause()); +587 } +588 this.percentileImpl = percentileImpl; +589 } +590 +591 /** +592 * Returns the currently configured skewness implementation. +593 * +594 * @return the UnivariateStatistic implementing the skewness +595 * @since 1.2 +596 */ +597 public synchronized UnivariateStatistic getSkewnessImpl() { +598 return skewnessImpl; +599 } +600 +601 /** +602 * <p>Sets the implementation for the skewness.</p> +603 * +604 * @param skewnessImpl the UnivariateStatistic instance to use +605 * for computing the skewness +606 * @since 1.2 +607 */ +608 public synchronized void setSkewnessImpl( +609 UnivariateStatistic skewnessImpl) { +610 this.skewnessImpl = skewnessImpl; +611 } +612 +613 /** +614 * Returns the currently configured variance implementation. +615 * +616 * @return the UnivariateStatistic implementing the variance +617 * @since 1.2 +618 */ +619 public synchronized UnivariateStatistic getVarianceImpl() { +620 return varianceImpl; +621 } +622 +623 /** +624 * <p>Sets the implementation for the variance.</p> +625 * +626 * @param varianceImpl the UnivariateStatistic instance to use +627 * for computing the variance +628 * @since 1.2 +629 */ +630 public synchronized void setVarianceImpl( +631 UnivariateStatistic varianceImpl) { +632 this.varianceImpl = varianceImpl; +633 } +634 +635 /** +636 * Returns the currently configured sum of squares implementation. +637 * +638 * @return the UnivariateStatistic implementing the sum of squares +639 * @since 1.2 +640 */ +641 public synchronized UnivariateStatistic getSumsqImpl() { +642 return sumsqImpl; +643 } +644 +645 /** +646 * <p>Sets the implementation for the sum of squares.</p> +647 * +648 * @param sumsqImpl the UnivariateStatistic instance to use +649 * for computing the sum of squares +650 * @since 1.2 +651 */ +652 public synchronized void setSumsqImpl(UnivariateStatistic sumsqImpl) { +653 this.sumsqImpl = sumsqImpl; +654 } +655 +656 /** +657 * Returns the currently configured sum implementation. +658 * +659 * @return the UnivariateStatistic implementing the sum +660 * @since 1.2 +661 */ +662 public synchronized UnivariateStatistic getSumImpl() { +663 return sumImpl; +664 } +665 +666 /** +667 * <p>Sets the implementation for the sum.</p> +668 * +669 * @param sumImpl the UnivariateStatistic instance to use +670 * for computing the sum +671 * @since 1.2 +672 */ +673 public synchronized void setSumImpl(UnivariateStatistic sumImpl) { +674 this.sumImpl = sumImpl; +675 } +676 +677 /** +678 * Returns a copy of this DescriptiveStatistics instance with the same internal state. +679 * +680 * @return a copy of this +681 */ +682 public DescriptiveStatistics copy() { +683 DescriptiveStatistics result = new DescriptiveStatistics(); +684 copy(this, result); +685 return result; +686 } +687 +688 /** +689 * Copies source to dest. +690 * <p>Neither source nor dest can be null.</p> +691 * +692 * @param source DescriptiveStatistics to copy +693 * @param dest DescriptiveStatistics to copy to +694 * @throws NullPointerException if either source or dest is null +695 */ +696 public static void copy(DescriptiveStatistics source, DescriptiveStatistics dest) { +697 // Copy data and window size +698 dest.eDA = source.eDA.copy(); +699 dest.windowSize = source.windowSize; +700 +701 // Copy implementations +702 dest.maxImpl = source.maxImpl.copy(); +703 dest.meanImpl = source.meanImpl.copy(); +704 dest.minImpl = source.minImpl.copy(); +705 dest.sumImpl = source.sumImpl.copy(); +706 dest.varianceImpl = source.varianceImpl.copy(); +707 dest.sumsqImpl = source.sumsqImpl.copy(); +708 dest.geometricMeanImpl = source.geometricMeanImpl.copy(); +709 dest.kurtosisImpl = source.kurtosisImpl; +710 dest.skewnessImpl = source.skewnessImpl; +711 dest.percentileImpl = source.percentileImpl; +712 } +713 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatistics.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/MultivariateSummaryStatistics.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,699 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive; +018 +019 import java.io.Serializable; +020 import java.util.Arrays; +021 +022 import org.apache.commons.math.DimensionMismatchException; +023 import org.apache.commons.math.MathRuntimeException; +024 import org.apache.commons.math.linear.RealMatrix; +025 import org.apache.commons.math.stat.descriptive.moment.GeometricMean; +026 import org.apache.commons.math.stat.descriptive.moment.Mean; +027 import org.apache.commons.math.stat.descriptive.moment.VectorialCovariance; +028 import org.apache.commons.math.stat.descriptive.rank.Max; +029 import org.apache.commons.math.stat.descriptive.rank.Min; +030 import org.apache.commons.math.stat.descriptive.summary.Sum; +031 import org.apache.commons.math.stat.descriptive.summary.SumOfLogs; +032 import org.apache.commons.math.stat.descriptive.summary.SumOfSquares; +033 import org.apache.commons.math.util.MathUtils; +034 +035 /** +036 * <p>Computes summary statistics for a stream of n-tuples added using the +037 * {@link #addValue(double[]) addValue} method. The data values are not stored +038 * in memory, so this class can be used to compute statistics for very large +039 * n-tuple streams.</p> +040 * +041 * <p>The {@link StorelessUnivariateStatistic} instances used to maintain +042 * summary state and compute statistics are configurable via setters. +043 * For example, the default implementation for the mean can be overridden by +044 * calling {@link #setMeanImpl(StorelessUnivariateStatistic[])}. Actual +045 * parameters to these methods must implement the +046 * {@link StorelessUnivariateStatistic} interface and configuration must be +047 * completed before <code>addValue</code> is called. No configuration is +048 * necessary to use the default, commons-math provided implementations.</p> +049 * +050 * <p>To compute statistics for a stream of n-tuples, construct a +051 * MultivariateStatistics instance with dimension n and then use +052 * {@link #addValue(double[])} to add n-tuples. The <code>getXxx</code> +053 * methods where Xxx is a statistic return an array of <code>double</code> +054 * values, where for <code>i = 0,...,n-1</code> the i<sup>th</sup> array element is the +055 * value of the given statistic for data range consisting of the i<sup>th</sup> element of +056 * each of the input n-tuples. For example, if <code>addValue</code> is called +057 * with actual parameters {0, 1, 2}, then {3, 4, 5} and finally {6, 7, 8}, +058 * <code>getSum</code> will return a three-element array with values +059 * {0+3+6, 1+4+7, 2+5+8}</p> +060 * +061 * <p>Note: This class is not thread-safe. Use +062 * {@link SynchronizedMultivariateSummaryStatistics} if concurrent access from multiple +063 * threads is required.</p> +064 * +065 * @since 1.2 +066 * @version $Revision: 811833 $ $Date: 2009-09-06 12:27:50 -0400 (Sun, 06 Sep 2009) $ +067 */ +068 public class MultivariateSummaryStatistics +069 implements StatisticalMultivariateSummary, Serializable { +070 +071 /** Serialization UID */ +072 private static final long serialVersionUID = 2271900808994826718L; +073 +074 /** Dimension of the data. */ +075 private int k; +076 +077 /** Count of values that have been added */ +078 private long n = 0; +079 +080 /** Sum statistic implementation - can be reset by setter. */ +081 private StorelessUnivariateStatistic[] sumImpl; +082 +083 /** Sum of squares statistic implementation - can be reset by setter. */ +084 private StorelessUnivariateStatistic[] sumSqImpl; +085 +086 /** Minimum statistic implementation - can be reset by setter. */ +087 private StorelessUnivariateStatistic[] minImpl; +088 +089 /** Maximum statistic implementation - can be reset by setter. */ +090 private StorelessUnivariateStatistic[] maxImpl; +091 +092 /** Sum of log statistic implementation - can be reset by setter. */ +093 private StorelessUnivariateStatistic[] sumLogImpl; +094 +095 /** Geometric mean statistic implementation - can be reset by setter. */ +096 private StorelessUnivariateStatistic[] geoMeanImpl; +097 +098 /** Mean statistic implementation - can be reset by setter. */ +099 private StorelessUnivariateStatistic[] meanImpl; +100 +101 /** Covariance statistic implementation - cannot be reset. */ +102 private VectorialCovariance covarianceImpl; +103 +104 /** +105 * Construct a MultivariateSummaryStatistics instance +106 * @param k dimension of the data +107 * @param isCovarianceBiasCorrected if true, the unbiased sample +108 * covariance is computed, otherwise the biased population covariance +109 * is computed +110 */ +111 public MultivariateSummaryStatistics(int k, boolean isCovarianceBiasCorrected) { +112 this.k = k; +113 +114 sumImpl = new StorelessUnivariateStatistic[k]; +115 sumSqImpl = new StorelessUnivariateStatistic[k]; +116 minImpl = new StorelessUnivariateStatistic[k]; +117 maxImpl = new StorelessUnivariateStatistic[k]; +118 sumLogImpl = new StorelessUnivariateStatistic[k]; +119 geoMeanImpl = new StorelessUnivariateStatistic[k]; +120 meanImpl = new StorelessUnivariateStatistic[k]; +121 +122 for (int i = 0; i < k; ++i) { +123 sumImpl[i] = new Sum(); +124 sumSqImpl[i] = new SumOfSquares(); +125 minImpl[i] = new Min(); +126 maxImpl[i] = new Max(); +127 sumLogImpl[i] = new SumOfLogs(); +128 geoMeanImpl[i] = new GeometricMean(); +129 meanImpl[i] = new Mean(); +130 } +131 +132 covarianceImpl = +133 new VectorialCovariance(k, isCovarianceBiasCorrected); +134 +135 } +136 +137 /** +138 * Add an n-tuple to the data +139 * +140 * @param value the n-tuple to add +141 * @throws DimensionMismatchException if the length of the array +142 * does not match the one used at construction +143 */ +144 public void addValue(double[] value) +145 throws DimensionMismatchException { +146 checkDimension(value.length); +147 for (int i = 0; i < k; ++i) { +148 double v = value[i]; +149 sumImpl[i].increment(v); +150 sumSqImpl[i].increment(v); +151 minImpl[i].increment(v); +152 maxImpl[i].increment(v); +153 sumLogImpl[i].increment(v); +154 geoMeanImpl[i].increment(v); +155 meanImpl[i].increment(v); +156 } +157 covarianceImpl.increment(value); +158 n++; +159 } +160 +161 /** +162 * Returns the dimension of the data +163 * @return The dimension of the data +164 */ +165 public int getDimension() { +166 return k; +167 } +168 +169 /** +170 * Returns the number of available values +171 * @return The number of available values +172 */ +173 public long getN() { +174 return n; +175 } +176 +177 /** +178 * Returns an array of the results of a statistic. +179 * @param stats univariate statistic array +180 * @return results array +181 */ +182 private double[] getResults(StorelessUnivariateStatistic[] stats) { +183 double[] results = new double[stats.length]; +184 for (int i = 0; i < results.length; ++i) { +185 results[i] = stats[i].getResult(); +186 } +187 return results; +188 } +189 +190 /** +191 * Returns an array whose i<sup>th</sup> entry is the sum of the +192 * i<sup>th</sup> entries of the arrays that have been added using +193 * {@link #addValue(double[])} +194 * +195 * @return the array of component sums +196 */ +197 public double[] getSum() { +198 return getResults(sumImpl); +199 } +200 +201 /** +202 * Returns an array whose i<sup>th</sup> entry is the sum of squares of the +203 * i<sup>th</sup> entries of the arrays that have been added using +204 * {@link #addValue(double[])} +205 * +206 * @return the array of component sums of squares +207 */ +208 public double[] getSumSq() { +209 return getResults(sumSqImpl); +210 } +211 +212 /** +213 * Returns an array whose i<sup>th</sup> entry is the sum of logs of the +214 * i<sup>th</sup> entries of the arrays that have been added using +215 * {@link #addValue(double[])} +216 * +217 * @return the array of component log sums +218 */ +219 public double[] getSumLog() { +220 return getResults(sumLogImpl); +221 } +222 +223 /** +224 * Returns an array whose i<sup>th</sup> entry is the mean of the +225 * i<sup>th</sup> entries of the arrays that have been added using +226 * {@link #addValue(double[])} +227 * +228 * @return the array of component means +229 */ +230 public double[] getMean() { +231 return getResults(meanImpl); +232 } +233 +234 /** +235 * Returns an array whose i<sup>th</sup> entry is the standard deviation of the +236 * i<sup>th</sup> entries of the arrays that have been added using +237 * {@link #addValue(double[])} +238 * +239 * @return the array of component standard deviations +240 */ +241 public double[] getStandardDeviation() { +242 double[] stdDev = new double[k]; +243 if (getN() < 1) { +244 Arrays.fill(stdDev, Double.NaN); +245 } else if (getN() < 2) { +246 Arrays.fill(stdDev, 0.0); +247 } else { +248 RealMatrix matrix = covarianceImpl.getResult(); +249 for (int i = 0; i < k; ++i) { +250 stdDev[i] = Math.sqrt(matrix.getEntry(i, i)); +251 } +252 } +253 return stdDev; +254 } +255 +256 /** +257 * Returns the covariance matrix of the values that have been added. +258 * +259 * @return the covariance matrix +260 */ +261 public RealMatrix getCovariance() { +262 return covarianceImpl.getResult(); +263 } +264 +265 /** +266 * Returns an array whose i<sup>th</sup> entry is the maximum of the +267 * i<sup>th</sup> entries of the arrays that have been added using +268 * {@link #addValue(double[])} +269 * +270 * @return the array of component maxima +271 */ +272 public double[] getMax() { +273 return getResults(maxImpl); +274 } +275 +276 /** +277 * Returns an array whose i<sup>th</sup> entry is the minimum of the +278 * i<sup>th</sup> entries of the arrays that have been added using +279 * {@link #addValue(double[])} +280 * +281 * @return the array of component minima +282 */ +283 public double[] getMin() { +284 return getResults(minImpl); +285 } +286 +287 /** +288 * Returns an array whose i<sup>th</sup> entry is the geometric mean of the +289 * i<sup>th</sup> entries of the arrays that have been added using +290 * {@link #addValue(double[])} +291 * +292 * @return the array of component geometric means +293 */ +294 public double[] getGeometricMean() { +295 return getResults(geoMeanImpl); +296 } +297 +298 /** +299 * Generates a text report displaying +300 * summary statistics from values that +301 * have been added. +302 * @return String with line feeds displaying statistics +303 */ +304 @Override +305 public String toString() { +306 StringBuffer outBuffer = new StringBuffer(); +307 outBuffer.append("MultivariateSummaryStatistics:\n"); +308 outBuffer.append("n: " + getN() + "\n"); +309 append(outBuffer, getMin(), "min: ", ", ", "\n"); +310 append(outBuffer, getMax(), "max: ", ", ", "\n"); +311 append(outBuffer, getMean(), "mean: ", ", ", "\n"); +312 append(outBuffer, getGeometricMean(), "geometric mean: ", ", ", "\n"); +313 append(outBuffer, getSumSq(), "sum of squares: ", ", ", "\n"); +314 append(outBuffer, getSumLog(), "sum of logarithms: ", ", ", "\n"); +315 append(outBuffer, getStandardDeviation(), "standard deviation: ", ", ", "\n"); +316 outBuffer.append("covariance: " + getCovariance().toString() + "\n"); +317 return outBuffer.toString(); +318 } +319 +320 /** +321 * Append a text representation of an array to a buffer. +322 * @param buffer buffer to fill +323 * @param data data array +324 * @param prefix text prefix +325 * @param separator elements separator +326 * @param suffix text suffix +327 */ +328 private void append(StringBuffer buffer, double[] data, +329 String prefix, String separator, String suffix) { +330 buffer.append(prefix); +331 for (int i = 0; i < data.length; ++i) { +332 if (i > 0) { +333 buffer.append(separator); +334 } +335 buffer.append(data[i]); +336 } +337 buffer.append(suffix); +338 } +339 +340 /** +341 * Resets all statistics and storage +342 */ +343 public void clear() { +344 this.n = 0; +345 for (int i = 0; i < k; ++i) { +346 minImpl[i].clear(); +347 maxImpl[i].clear(); +348 sumImpl[i].clear(); +349 sumLogImpl[i].clear(); +350 sumSqImpl[i].clear(); +351 geoMeanImpl[i].clear(); +352 meanImpl[i].clear(); +353 } +354 covarianceImpl.clear(); +355 } +356 +357 /** +358 * Returns true iff <code>object</code> is a <code>SummaryStatistics</code> +359 * instance and all statistics have the same values as this. +360 * @param object the object to test equality against. +361 * @return true if object equals this +362 */ +363 @Override +364 public boolean equals(Object object) { +365 if (object == this ) { +366 return true; +367 } +368 if (object instanceof MultivariateSummaryStatistics == false) { +369 return false; +370 } +371 MultivariateSummaryStatistics stat = (MultivariateSummaryStatistics) object; +372 return MathUtils.equals(stat.getGeometricMean(), getGeometricMean()) && +373 MathUtils.equals(stat.getMax(), getMax()) && +374 MathUtils.equals(stat.getMean(), getMean()) && +375 MathUtils.equals(stat.getMin(), getMin()) && +376 MathUtils.equals(stat.getN(), getN()) && +377 MathUtils.equals(stat.getSum(), getSum()) && +378 MathUtils.equals(stat.getSumSq(), getSumSq()) && +379 MathUtils.equals(stat.getSumLog(), getSumLog()) && +380 stat.getCovariance().equals( getCovariance()); +381 } +382 +383 /** +384 * Returns hash code based on values of statistics +385 * +386 * @return hash code +387 */ +388 @Override +389 public int hashCode() { +390 int result = 31 + MathUtils.hash(getGeometricMean()); +391 result = result * 31 + MathUtils.hash(getGeometricMean()); +392 result = result * 31 + MathUtils.hash(getMax()); +393 result = result * 31 + MathUtils.hash(getMean()); +394 result = result * 31 + MathUtils.hash(getMin()); +395 result = result * 31 + MathUtils.hash(getN()); +396 result = result * 31 + MathUtils.hash(getSum()); +397 result = result * 31 + MathUtils.hash(getSumSq()); +398 result = result * 31 + MathUtils.hash(getSumLog()); +399 result = result * 31 + getCovariance().hashCode(); +400 return result; +401 } +402 +403 // Getters and setters for statistics implementations +404 /** +405 * Sets statistics implementations. +406 * @param newImpl new implementations for statistics +407 * @param oldImpl old implementations for statistics +408 * @throws DimensionMismatchException if the array dimension +409 * does not match the one used at construction +410 * @throws IllegalStateException if data has already been added +411 * (i.e if n > 0) +412 */ +413 private void setImpl(StorelessUnivariateStatistic[] newImpl, +414 StorelessUnivariateStatistic[] oldImpl) +415 throws DimensionMismatchException, IllegalStateException { +416 checkEmpty(); +417 checkDimension(newImpl.length); +418 System.arraycopy(newImpl, 0, oldImpl, 0, newImpl.length); +419 } +420 +421 /** +422 * Returns the currently configured Sum implementation +423 * +424 * @return the StorelessUnivariateStatistic implementing the sum +425 */ +426 public StorelessUnivariateStatistic[] getSumImpl() { +427 return sumImpl.clone(); +428 } +429 +430 /** +431 * <p>Sets the implementation for the Sum.</p> +432 * <p>This method must be activated before any data has been added - i.e., +433 * before {@link #addValue(double[]) addValue} has been used to add data; +434 * otherwise an IllegalStateException will be thrown.</p> +435 * +436 * @param sumImpl the StorelessUnivariateStatistic instance to use +437 * for computing the Sum +438 * @throws DimensionMismatchException if the array dimension +439 * does not match the one used at construction +440 * @throws IllegalStateException if data has already been added +441 * (i.e if n > 0) +442 */ +443 public void setSumImpl(StorelessUnivariateStatistic[] sumImpl) +444 throws DimensionMismatchException { +445 setImpl(sumImpl, this.sumImpl); +446 } +447 +448 /** +449 * Returns the currently configured sum of squares implementation +450 * +451 * @return the StorelessUnivariateStatistic implementing the sum of squares +452 */ +453 public StorelessUnivariateStatistic[] getSumsqImpl() { +454 return sumSqImpl.clone(); +455 } +456 +457 /** +458 * <p>Sets the implementation for the sum of squares.</p> +459 * <p>This method must be activated before any data has been added - i.e., +460 * before {@link #addValue(double[]) addValue} has been used to add data; +461 * otherwise an IllegalStateException will be thrown.</p> +462 * +463 * @param sumsqImpl the StorelessUnivariateStatistic instance to use +464 * for computing the sum of squares +465 * @throws DimensionMismatchException if the array dimension +466 * does not match the one used at construction +467 * @throws IllegalStateException if data has already been added +468 * (i.e if n > 0) +469 */ +470 public void setSumsqImpl(StorelessUnivariateStatistic[] sumsqImpl) +471 throws DimensionMismatchException { +472 setImpl(sumsqImpl, this.sumSqImpl); +473 } +474 +475 /** +476 * Returns the currently configured minimum implementation +477 * +478 * @return the StorelessUnivariateStatistic implementing the minimum +479 */ +480 public StorelessUnivariateStatistic[] getMinImpl() { +481 return minImpl.clone(); +482 } +483 +484 /** +485 * <p>Sets the implementation for the minimum.</p> +486 * <p>This method must be activated before any data has been added - i.e., +487 * before {@link #addValue(double[]) addValue} has been used to add data; +488 * otherwise an IllegalStateException will be thrown.</p> +489 * +490 * @param minImpl the StorelessUnivariateStatistic instance to use +491 * for computing the minimum +492 * @throws DimensionMismatchException if the array dimension +493 * does not match the one used at construction +494 * @throws IllegalStateException if data has already been added +495 * (i.e if n > 0) +496 */ +497 public void setMinImpl(StorelessUnivariateStatistic[] minImpl) +498 throws DimensionMismatchException { +499 setImpl(minImpl, this.minImpl); +500 } +501 +502 /** +503 * Returns the currently configured maximum implementation +504 * +505 * @return the StorelessUnivariateStatistic implementing the maximum +506 */ +507 public StorelessUnivariateStatistic[] getMaxImpl() { +508 return maxImpl.clone(); +509 } +510 +511 /** +512 * <p>Sets the implementation for the maximum.</p> +513 * <p>This method must be activated before any data has been added - i.e., +514 * before {@link #addValue(double[]) addValue} has been used to add data; +515 * otherwise an IllegalStateException will be thrown.</p> +516 * +517 * @param maxImpl the StorelessUnivariateStatistic instance to use +518 * for computing the maximum +519 * @throws DimensionMismatchException if the array dimension +520 * does not match the one used at construction +521 * @throws IllegalStateException if data has already been added +522 * (i.e if n > 0) +523 */ +524 public void setMaxImpl(StorelessUnivariateStatistic[] maxImpl) +525 throws DimensionMismatchException { +526 setImpl(maxImpl, this.maxImpl); +527 } +528 +529 /** +530 * Returns the currently configured sum of logs implementation +531 * +532 * @return the StorelessUnivariateStatistic implementing the log sum +533 */ +534 public StorelessUnivariateStatistic[] getSumLogImpl() { +535 return sumLogImpl.clone(); +536 } +537 +538 /** +539 * <p>Sets the implementation for the sum of logs.</p> +540 * <p>This method must be activated before any data has been added - i.e., +541 * before {@link #addValue(double[]) addValue} has been used to add data; +542 * otherwise an IllegalStateException will be thrown.</p> +543 * +544 * @param sumLogImpl the StorelessUnivariateStatistic instance to use +545 * for computing the log sum +546 * @throws DimensionMismatchException if the array dimension +547 * does not match the one used at construction +548 * @throws IllegalStateException if data has already been added +549 * (i.e if n > 0) +550 */ +551 public void setSumLogImpl(StorelessUnivariateStatistic[] sumLogImpl) +552 throws DimensionMismatchException { +553 setImpl(sumLogImpl, this.sumLogImpl); +554 } +555 +556 /** +557 * Returns the currently configured geometric mean implementation +558 * +559 * @return the StorelessUnivariateStatistic implementing the geometric mean +560 */ +561 public StorelessUnivariateStatistic[] getGeoMeanImpl() { +562 return geoMeanImpl.clone(); +563 } +564 +565 /** +566 * <p>Sets the implementation for the geometric mean.</p> +567 * <p>This method must be activated before any data has been added - i.e., +568 * before {@link #addValue(double[]) addValue} has been used to add data; +569 * otherwise an IllegalStateException will be thrown.</p> +570 * +571 * @param geoMeanImpl the StorelessUnivariateStatistic instance to use +572 * for computing the geometric mean +573 * @throws DimensionMismatchException if the array dimension +574 * does not match the one used at construction +575 * @throws IllegalStateException if data has already been added +576 * (i.e if n > 0) +577 */ +578 public void setGeoMeanImpl(StorelessUnivariateStatistic[] geoMeanImpl) +579 throws DimensionMismatchException { +580 setImpl(geoMeanImpl, this.geoMeanImpl); +581 } +582 +583 /** +584 * Returns the currently configured mean implementation +585 * +586 * @return the StorelessUnivariateStatistic implementing the mean +587 */ +588 public StorelessUnivariateStatistic[] getMeanImpl() { +589 return meanImpl.clone(); +590 } +591 +592 /** +593 * <p>Sets the implementation for the mean.</p> +594 * <p>This method must be activated before any data has been added - i.e., +595 * before {@link #addValue(double[]) addValue} has been used to add data; +596 * otherwise an IllegalStateException will be thrown.</p> +597 * +598 * @param meanImpl the StorelessUnivariateStatistic instance to use +599 * for computing the mean +600 * @throws DimensionMismatchException if the array dimension +601 * does not match the one used at construction +602 * @throws IllegalStateException if data has already been added +603 * (i.e if n > 0) +604 */ +605 public void setMeanImpl(StorelessUnivariateStatistic[] meanImpl) +606 throws DimensionMismatchException { +607 setImpl(meanImpl, this.meanImpl); +608 } +609 +610 /** +611 * Throws IllegalStateException if n > 0. +612 */ +613 private void checkEmpty() { +614 if (n > 0) { +615 throw MathRuntimeException.createIllegalStateException( +616 "{0} values have been added before statistic is configured", +617 n); +618 } +619 } +620 +621 /** +622 * Throws DimensionMismatchException if dimension != k. +623 * @param dimension dimension to check +624 * @throws DimensionMismatchException if dimension != k +625 */ +626 private void checkDimension(int dimension) +627 throws DimensionMismatchException { +628 if (dimension != k) { +629 throw new DimensionMismatchException(dimension, k); +630 } +631 } +632 +633 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummary.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/StatisticalMultivariateSummary.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,186 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive; +018 +019 import org.apache.commons.math.linear.RealMatrix; +020 +021 /** +022 * Reporting interface for basic multivariate statistics. +023 * +024 * @since 1.2 +025 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +026 */ +027 public interface StatisticalMultivariateSummary { +028 +029 /** +030 * Returns the dimension of the data +031 * @return The dimension of the data +032 */ +033 int getDimension(); +034 +035 /** +036 * Returns an array whose i<sup>th</sup> entry is the +037 * mean of the i<sup>th</sup> entries of the arrays +038 * that correspond to each multivariate sample +039 * +040 * @return the array of component means +041 */ +042 double[] getMean(); +043 +044 /** +045 * Returns the covariance of the available values. +046 * @return The covariance, null if no multivariate sample +047 * have been added or a zeroed matrix for a single value set. +048 */ +049 RealMatrix getCovariance(); +050 +051 /** +052 * Returns an array whose i<sup>th</sup> entry is the +053 * standard deviation of the i<sup>th</sup> entries of the arrays +054 * that correspond to each multivariate sample +055 * +056 * @return the array of component standard deviations +057 */ +058 double[] getStandardDeviation(); +059 +060 /** +061 * Returns an array whose i<sup>th</sup> entry is the +062 * maximum of the i<sup>th</sup> entries of the arrays +063 * that correspond to each multivariate sample +064 * +065 * @return the array of component maxima +066 */ +067 double[] getMax(); +068 +069 /** +070 * Returns an array whose i<sup>th</sup> entry is the +071 * minimum of the i<sup>th</sup> entries of the arrays +072 * that correspond to each multivariate sample +073 * +074 * @return the array of component minima +075 */ +076 double[] getMin(); +077 +078 /** +079 * Returns the number of available values +080 * @return The number of available values +081 */ +082 long getN(); +083 +084 /** +085 * Returns an array whose i<sup>th</sup> entry is the +086 * geometric mean of the i<sup>th</sup> entries of the arrays +087 * that correspond to each multivariate sample +088 * +089 * @return the array of component geometric means +090 */ +091 double[] getGeometricMean(); +092 +093 /** +094 * Returns an array whose i<sup>th</sup> entry is the +095 * sum of the i<sup>th</sup> entries of the arrays +096 * that correspond to each multivariate sample +097 * +098 * @return the array of component sums +099 */ +100 double[] getSum(); +101 +102 /** +103 * Returns an array whose i<sup>th</sup> entry is the +104 * sum of squares of the i<sup>th</sup> entries of the arrays +105 * that correspond to each multivariate sample +106 * +107 * @return the array of component sums of squares +108 */ +109 double[] getSumSq(); +110 +111 /** +112 * Returns an array whose i<sup>th</sup> entry is the +113 * sum of logs of the i<sup>th</sup> entries of the arrays +114 * that correspond to each multivariate sample +115 * +116 * @return the array of component log sums +117 */ +118 double[] getSumLog(); +119 +120 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/StatisticalSummary.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/StatisticalSummary.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,131 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive; +018 +019 /** +020 * Reporting interface for basic univariate statistics. +021 * +022 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +023 */ +024 public interface StatisticalSummary { +025 +026 /** +027 * Returns the <a href="http://www.xycoon.com/arithmetic_mean.htm"> +028 * arithmetic mean </a> of the available values +029 * @return The mean or Double.NaN if no values have been added. +030 */ +031 double getMean(); +032 /** +033 * Returns the variance of the available values. +034 * @return The variance, Double.NaN if no values have been added +035 * or 0.0 for a single value set. +036 */ +037 double getVariance(); +038 /** +039 * Returns the standard deviation of the available values. +040 * @return The standard deviation, Double.NaN if no values have been added +041 * or 0.0 for a single value set. +042 */ +043 double getStandardDeviation(); +044 /** +045 * Returns the maximum of the available values +046 * @return The max or Double.NaN if no values have been added. +047 */ +048 double getMax(); +049 /** +050 * Returns the minimum of the available values +051 * @return The min or Double.NaN if no values have been added. +052 */ +053 double getMin(); +054 /** +055 * Returns the number of available values +056 * @return The number of available values +057 */ +058 long getN(); +059 /** +060 * Returns the sum of the values that have been added to Univariate. +061 * @return The sum or Double.NaN if no values have been added +062 */ +063 double getSum(); +064 +065 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/StatisticalSummaryValues.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/StatisticalSummaryValues.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,228 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive; +018 +019 import java.io.Serializable; +020 import org.apache.commons.math.util.MathUtils; +021 +022 /** +023 * Value object representing the results of a univariate statistical summary. +024 * +025 * @version $Revision: 811833 $ $Date: 2009-09-06 12:27:50 -0400 (Sun, 06 Sep 2009) $ +026 */ +027 public class StatisticalSummaryValues implements Serializable, +028 StatisticalSummary { +029 +030 /** Serialization id */ +031 private static final long serialVersionUID = -5108854841843722536L; +032 +033 /** The sample mean */ +034 private final double mean; +035 +036 /** The sample variance */ +037 private final double variance; +038 +039 /** The number of observations in the sample */ +040 private final long n; +041 +042 /** The maximum value */ +043 private final double max; +044 +045 /** The minimum value */ +046 private final double min; +047 +048 /** The sum of the sample values */ +049 private final double sum; +050 +051 /** +052 * Constructor +053 * +054 * @param mean the sample mean +055 * @param variance the sample variance +056 * @param n the number of observations in the sample +057 * @param max the maximum value +058 * @param min the minimum value +059 * @param sum the sum of the values +060 */ +061 public StatisticalSummaryValues(double mean, double variance, long n, +062 double max, double min, double sum) { +063 super(); +064 this.mean = mean; +065 this.variance = variance; +066 this.n = n; +067 this.max = max; +068 this.min = min; +069 this.sum = sum; +070 } +071 +072 /** +073 * @return Returns the max. +074 */ +075 public double getMax() { +076 return max; +077 } +078 +079 /** +080 * @return Returns the mean. +081 */ +082 public double getMean() { +083 return mean; +084 } +085 +086 /** +087 * @return Returns the min. +088 */ +089 public double getMin() { +090 return min; +091 } +092 +093 /** +094 * @return Returns the number of values. +095 */ +096 public long getN() { +097 return n; +098 } +099 +100 /** +101 * @return Returns the sum. +102 */ +103 public double getSum() { +104 return sum; +105 } +106 +107 /** +108 * @return Returns the standard deviation +109 */ +110 public double getStandardDeviation() { +111 return Math.sqrt(variance); +112 } +113 +114 /** +115 * @return Returns the variance. +116 */ +117 public double getVariance() { +118 return variance; +119 } +120 +121 /** +122 * Returns true iff <code>object</code> is a +123 * <code>StatisticalSummaryValues</code> instance and all statistics have +124 * the same values as this. +125 * +126 * @param object the object to test equality against. +127 * @return true if object equals this +128 */ +129 @Override +130 public boolean equals(Object object) { +131 if (object == this ) { +132 return true; +133 } +134 if (object instanceof StatisticalSummaryValues == false) { +135 return false; +136 } +137 StatisticalSummaryValues stat = (StatisticalSummaryValues) object; +138 return MathUtils.equals(stat.getMax(), getMax()) && +139 MathUtils.equals(stat.getMean(), getMean()) && +140 MathUtils.equals(stat.getMin(), getMin()) && +141 MathUtils.equals(stat.getN(), getN()) && +142 MathUtils.equals(stat.getSum(), getSum()) && +143 MathUtils.equals(stat.getVariance(), getVariance()); +144 } +145 +146 /** +147 * Returns hash code based on values of statistics +148 * +149 * @return hash code +150 */ +151 @Override +152 public int hashCode() { +153 int result = 31 + MathUtils.hash(getMax()); +154 result = result * 31 + MathUtils.hash(getMean()); +155 result = result * 31 + MathUtils.hash(getMin()); +156 result = result * 31 + MathUtils.hash(getN()); +157 result = result * 31 + MathUtils.hash(getSum()); +158 result = result * 31 + MathUtils.hash(getVariance()); +159 return result; +160 } +161 +162 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/StorelessUnivariateStatistic.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/StorelessUnivariateStatistic.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,152 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive; +018 +019 /** +020 * Extends the definition of {@link UnivariateStatistic} with +021 * {@link #increment} and {@link #incrementAll(double[])} methods for adding +022 * values and updating internal state. +023 * <p> +024 * This interface is designed to be used for calculating statistics that can be +025 * computed in one pass through the data without storing the full array of +026 * sample values.</p> +027 * +028 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +029 */ +030 public interface StorelessUnivariateStatistic extends UnivariateStatistic { +031 +032 /** +033 * Updates the internal state of the statistic to reflect the addition of the new value. +034 * @param d the new value. +035 */ +036 void increment(double d); +037 +038 /** +039 * Updates the internal state of the statistic to reflect addition of +040 * all values in the values array. Does not clear the statistic first -- +041 * i.e., the values are added <strong>incrementally</strong> to the dataset. +042 * +043 * @param values array holding the new values to add +044 * @throws IllegalArgumentException if the array is null +045 */ +046 void incrementAll(double[] values); +047 +048 /** +049 * Updates the internal state of the statistic to reflect addition of +050 * the values in the designated portion of the values array. Does not +051 * clear the statistic first -- i.e., the values are added +052 * <strong>incrementally</strong> to the dataset. +053 * +054 * @param values array holding the new values to add +055 * @param start the array index of the first value to add +056 * @param length the number of elements to add +057 * @throws IllegalArgumentException if the array is null or the index +058 */ +059 void incrementAll(double[] values, int start, int length); +060 +061 /** +062 * Returns the current value of the Statistic. +063 * @return value of the statistic, <code>Double.NaN</code> if it +064 * has been cleared or just instantiated. +065 */ +066 double getResult(); +067 +068 /** +069 * Returns the number of values that have been added. +070 * @return the number of values. +071 */ +072 long getN(); +073 +074 /** +075 * Clears the internal state of the Statistic +076 */ +077 void clear(); +078 +079 /** +080 * Returns a copy of the statistic with the same internal state. +081 * +082 * @return a copy of the statistic +083 */ +084 StorelessUnivariateStatistic copy(); +085 +086 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/SummaryStatistics.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/SummaryStatistics.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,781 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.stat.descriptive.moment.GeometricMean; +023 import org.apache.commons.math.stat.descriptive.moment.Mean; +024 import org.apache.commons.math.stat.descriptive.moment.SecondMoment; +025 import org.apache.commons.math.stat.descriptive.moment.Variance; +026 import org.apache.commons.math.stat.descriptive.rank.Max; +027 import org.apache.commons.math.stat.descriptive.rank.Min; +028 import org.apache.commons.math.stat.descriptive.summary.Sum; +029 import org.apache.commons.math.stat.descriptive.summary.SumOfLogs; +030 import org.apache.commons.math.stat.descriptive.summary.SumOfSquares; +031 import org.apache.commons.math.util.MathUtils; +032 +033 /** +034 * <p> +035 * Computes summary statistics for a stream of data values added using the +036 * {@link #addValue(double) addValue} method. The data values are not stored in +037 * memory, so this class can be used to compute statistics for very large data +038 * streams. +039 * </p> +040 * <p> +041 * The {@link StorelessUnivariateStatistic} instances used to maintain summary +042 * state and compute statistics are configurable via setters. For example, the +043 * default implementation for the variance can be overridden by calling +044 * {@link #setVarianceImpl(StorelessUnivariateStatistic)}. Actual parameters to +045 * these methods must implement the {@link StorelessUnivariateStatistic} +046 * interface and configuration must be completed before <code>addValue</code> +047 * is called. No configuration is necessary to use the default, commons-math +048 * provided implementations. +049 * </p> +050 * <p> +051 * Note: This class is not thread-safe. Use +052 * {@link SynchronizedSummaryStatistics} if concurrent access from multiple +053 * threads is required. +054 * </p> +055 * @version $Revision: 811833 $ $Date: 2009-09-06 12:27:50 -0400 (Sun, 06 Sep 2009) $ +056 */ +057 public class SummaryStatistics implements StatisticalSummary, Serializable { +058 +059 /** Serialization UID */ +060 private static final long serialVersionUID = -2021321786743555871L; +061 +062 /** count of values that have been added */ +063 protected long n = 0; +064 +065 /** SecondMoment is used to compute the mean and variance */ +066 protected SecondMoment secondMoment = new SecondMoment(); +067 +068 /** sum of values that have been added */ +069 protected Sum sum = new Sum(); +070 +071 /** sum of the square of each value that has been added */ +072 protected SumOfSquares sumsq = new SumOfSquares(); +073 +074 /** min of values that have been added */ +075 protected Min min = new Min(); +076 +077 /** max of values that have been added */ +078 protected Max max = new Max(); +079 +080 /** sumLog of values that have been added */ +081 protected SumOfLogs sumLog = new SumOfLogs(); +082 +083 /** geoMean of values that have been added */ +084 protected GeometricMean geoMean = new GeometricMean(sumLog); +085 +086 /** mean of values that have been added */ +087 protected Mean mean = new Mean(); +088 +089 /** variance of values that have been added */ +090 protected Variance variance = new Variance(); +091 +092 /** Sum statistic implementation - can be reset by setter. */ +093 private StorelessUnivariateStatistic sumImpl = sum; +094 +095 /** Sum of squares statistic implementation - can be reset by setter. */ +096 private StorelessUnivariateStatistic sumsqImpl = sumsq; +097 +098 /** Minimum statistic implementation - can be reset by setter. */ +099 private StorelessUnivariateStatistic minImpl = min; +100 +101 /** Maximum statistic implementation - can be reset by setter. */ +102 private StorelessUnivariateStatistic maxImpl = max; +103 +104 /** Sum of log statistic implementation - can be reset by setter. */ +105 private StorelessUnivariateStatistic sumLogImpl = sumLog; +106 +107 /** Geometric mean statistic implementation - can be reset by setter. */ +108 private StorelessUnivariateStatistic geoMeanImpl = geoMean; +109 +110 /** Mean statistic implementation - can be reset by setter. */ +111 private StorelessUnivariateStatistic meanImpl = mean; +112 +113 /** Variance statistic implementation - can be reset by setter. */ +114 private StorelessUnivariateStatistic varianceImpl = variance; +115 +116 /** +117 * Construct a SummaryStatistics instance +118 */ +119 public SummaryStatistics() { +120 } +121 +122 /** +123 * A copy constructor. Creates a deep-copy of the {@code original}. +124 * +125 * @param original the {@code SummaryStatistics} instance to copy +126 */ +127 public SummaryStatistics(SummaryStatistics original) { +128 copy(original, this); +129 } +130 +131 /** +132 * Return a {@link StatisticalSummaryValues} instance reporting current +133 * statistics. +134 * @return Current values of statistics +135 */ +136 public StatisticalSummary getSummary() { +137 return new StatisticalSummaryValues(getMean(), getVariance(), getN(), +138 getMax(), getMin(), getSum()); +139 } +140 +141 /** +142 * Add a value to the data +143 * @param value the value to add +144 */ +145 public void addValue(double value) { +146 sumImpl.increment(value); +147 sumsqImpl.increment(value); +148 minImpl.increment(value); +149 maxImpl.increment(value); +150 sumLogImpl.increment(value); +151 secondMoment.increment(value); +152 // If mean, variance or geomean have been overridden, +153 // need to increment these +154 if (!(meanImpl instanceof Mean)) { +155 meanImpl.increment(value); +156 } +157 if (!(varianceImpl instanceof Variance)) { +158 varianceImpl.increment(value); +159 } +160 if (!(geoMeanImpl instanceof GeometricMean)) { +161 geoMeanImpl.increment(value); +162 } +163 n++; +164 } +165 +166 /** +167 * Returns the number of available values +168 * @return The number of available values +169 */ +170 public long getN() { +171 return n; +172 } +173 +174 /** +175 * Returns the sum of the values that have been added +176 * @return The sum or <code>Double.NaN</code> if no values have been added +177 */ +178 public double getSum() { +179 return sumImpl.getResult(); +180 } +181 +182 /** +183 * Returns the sum of the squares of the values that have been added. +184 * <p> +185 * Double.NaN is returned if no values have been added. +186 * </p> +187 * @return The sum of squares +188 */ +189 public double getSumsq() { +190 return sumsqImpl.getResult(); +191 } +192 +193 /** +194 * Returns the mean of the values that have been added. +195 * <p> +196 * Double.NaN is returned if no values have been added. +197 * </p> +198 * @return the mean +199 */ +200 public double getMean() { +201 if (mean == meanImpl) { +202 return new Mean(secondMoment).getResult(); +203 } else { +204 return meanImpl.getResult(); +205 } +206 } +207 +208 /** +209 * Returns the standard deviation of the values that have been added. +210 * <p> +211 * Double.NaN is returned if no values have been added. +212 * </p> +213 * @return the standard deviation +214 */ +215 public double getStandardDeviation() { +216 double stdDev = Double.NaN; +217 if (getN() > 0) { +218 if (getN() > 1) { +219 stdDev = Math.sqrt(getVariance()); +220 } else { +221 stdDev = 0.0; +222 } +223 } +224 return stdDev; +225 } +226 +227 /** +228 * Returns the variance of the values that have been added. +229 * <p> +230 * Double.NaN is returned if no values have been added. +231 * </p> +232 * @return the variance +233 */ +234 public double getVariance() { +235 if (varianceImpl == variance) { +236 return new Variance(secondMoment).getResult(); +237 } else { +238 return varianceImpl.getResult(); +239 } +240 } +241 +242 /** +243 * Returns the maximum of the values that have been added. +244 * <p> +245 * Double.NaN is returned if no values have been added. +246 * </p> +247 * @return the maximum +248 */ +249 public double getMax() { +250 return maxImpl.getResult(); +251 } +252 +253 /** +254 * Returns the minimum of the values that have been added. +255 * <p> +256 * Double.NaN is returned if no values have been added. +257 * </p> +258 * @return the minimum +259 */ +260 public double getMin() { +261 return minImpl.getResult(); +262 } +263 +264 /** +265 * Returns the geometric mean of the values that have been added. +266 * <p> +267 * Double.NaN is returned if no values have been added. +268 * </p> +269 * @return the geometric mean +270 */ +271 public double getGeometricMean() { +272 return geoMeanImpl.getResult(); +273 } +274 +275 /** +276 * Returns the sum of the logs of the values that have been added. +277 * <p> +278 * Double.NaN is returned if no values have been added. +279 * </p> +280 * @return the sum of logs +281 * @since 1.2 +282 */ +283 public double getSumOfLogs() { +284 return sumLogImpl.getResult(); +285 } +286 +287 /** +288 * Returns a statistic related to the Second Central Moment. Specifically, +289 * what is returned is the sum of squared deviations from the sample mean +290 * among the values that have been added. +291 * <p> +292 * Returns <code>Double.NaN</code> if no data values have been added and +293 * returns <code>0</code> if there is just one value in the data set.</p> +294 * <p> +295 * @return second central moment statistic +296 * @since 2.0 +297 */ +298 public double getSecondMoment() { +299 return secondMoment.getResult(); +300 } +301 +302 /** +303 * Generates a text report displaying summary statistics from values that +304 * have been added. +305 * @return String with line feeds displaying statistics +306 * @since 1.2 +307 */ +308 @Override +309 public String toString() { +310 StringBuffer outBuffer = new StringBuffer(); +311 String endl = "\n"; +312 outBuffer.append("SummaryStatistics:").append(endl); +313 outBuffer.append("n: ").append(getN()).append(endl); +314 outBuffer.append("min: ").append(getMin()).append(endl); +315 outBuffer.append("max: ").append(getMax()).append(endl); +316 outBuffer.append("mean: ").append(getMean()).append(endl); +317 outBuffer.append("geometric mean: ").append(getGeometricMean()) +318 .append(endl); +319 outBuffer.append("variance: ").append(getVariance()).append(endl); +320 outBuffer.append("sum of squares: ").append(getSumsq()).append(endl); +321 outBuffer.append("standard deviation: ").append(getStandardDeviation()) +322 .append(endl); +323 outBuffer.append("sum of logs: ").append(getSumOfLogs()).append(endl); +324 return outBuffer.toString(); +325 } +326 +327 /** +328 * Resets all statistics and storage +329 */ +330 public void clear() { +331 this.n = 0; +332 minImpl.clear(); +333 maxImpl.clear(); +334 sumImpl.clear(); +335 sumLogImpl.clear(); +336 sumsqImpl.clear(); +337 geoMeanImpl.clear(); +338 secondMoment.clear(); +339 if (meanImpl != mean) { +340 meanImpl.clear(); +341 } +342 if (varianceImpl != variance) { +343 varianceImpl.clear(); +344 } +345 } +346 +347 /** +348 * Returns true iff <code>object</code> is a +349 * <code>SummaryStatistics</code> instance and all statistics have the +350 * same values as this. +351 * @param object the object to test equality against. +352 * @return true if object equals this +353 */ +354 @Override +355 public boolean equals(Object object) { +356 if (object == this) { +357 return true; +358 } +359 if (object instanceof SummaryStatistics == false) { +360 return false; +361 } +362 SummaryStatistics stat = (SummaryStatistics)object; +363 return MathUtils.equals(stat.getGeometricMean(), getGeometricMean()) && +364 MathUtils.equals(stat.getMax(), getMax()) && +365 MathUtils.equals(stat.getMean(), getMean()) && +366 MathUtils.equals(stat.getMin(), getMin()) && +367 MathUtils.equals(stat.getN(), getN()) && +368 MathUtils.equals(stat.getSum(), getSum()) && +369 MathUtils.equals(stat.getSumsq(), getSumsq()) && +370 MathUtils.equals(stat.getVariance(), getVariance()); +371 } +372 +373 /** +374 * Returns hash code based on values of statistics +375 * @return hash code +376 */ +377 @Override +378 public int hashCode() { +379 int result = 31 + MathUtils.hash(getGeometricMean()); +380 result = result * 31 + MathUtils.hash(getGeometricMean()); +381 result = result * 31 + MathUtils.hash(getMax()); +382 result = result * 31 + MathUtils.hash(getMean()); +383 result = result * 31 + MathUtils.hash(getMin()); +384 result = result * 31 + MathUtils.hash(getN()); +385 result = result * 31 + MathUtils.hash(getSum()); +386 result = result * 31 + MathUtils.hash(getSumsq()); +387 result = result * 31 + MathUtils.hash(getVariance()); +388 return result; +389 } +390 +391 // Getters and setters for statistics implementations +392 /** +393 * Returns the currently configured Sum implementation +394 * @return the StorelessUnivariateStatistic implementing the sum +395 * @since 1.2 +396 */ +397 public StorelessUnivariateStatistic getSumImpl() { +398 return sumImpl; +399 } +400 +401 /** +402 * <p> +403 * Sets the implementation for the Sum. +404 * </p> +405 * <p> +406 * This method must be activated before any data has been added - i.e., +407 * before {@link #addValue(double) addValue} has been used to add data; +408 * otherwise an IllegalStateException will be thrown. +409 * </p> +410 * @param sumImpl the StorelessUnivariateStatistic instance to use for +411 * computing the Sum +412 * @throws IllegalStateException if data has already been added (i.e if n > +413 * 0) +414 * @since 1.2 +415 */ +416 public void setSumImpl(StorelessUnivariateStatistic sumImpl) { +417 checkEmpty(); +418 this.sumImpl = sumImpl; +419 } +420 +421 /** +422 * Returns the currently configured sum of squares implementation +423 * @return the StorelessUnivariateStatistic implementing the sum of squares +424 * @since 1.2 +425 */ +426 public StorelessUnivariateStatistic getSumsqImpl() { +427 return sumsqImpl; +428 } +429 +430 /** +431 * <p> +432 * Sets the implementation for the sum of squares. +433 * </p> +434 * <p> +435 * This method must be activated before any data has been added - i.e., +436 * before {@link #addValue(double) addValue} has been used to add data; +437 * otherwise an IllegalStateException will be thrown. +438 * </p> +439 * @param sumsqImpl the StorelessUnivariateStatistic instance to use for +440 * computing the sum of squares +441 * @throws IllegalStateException if data has already been added (i.e if n > +442 * 0) +443 * @since 1.2 +444 */ +445 public void setSumsqImpl(StorelessUnivariateStatistic sumsqImpl) { +446 checkEmpty(); +447 this.sumsqImpl = sumsqImpl; +448 } +449 +450 /** +451 * Returns the currently configured minimum implementation +452 * @return the StorelessUnivariateStatistic implementing the minimum +453 * @since 1.2 +454 */ +455 public StorelessUnivariateStatistic getMinImpl() { +456 return minImpl; +457 } +458 +459 /** +460 * <p> +461 * Sets the implementation for the minimum. +462 * </p> +463 * <p> +464 * This method must be activated before any data has been added - i.e., +465 * before {@link #addValue(double) addValue} has been used to add data; +466 * otherwise an IllegalStateException will be thrown. +467 * </p> +468 * @param minImpl the StorelessUnivariateStatistic instance to use for +469 * computing the minimum +470 * @throws IllegalStateException if data has already been added (i.e if n > +471 * 0) +472 * @since 1.2 +473 */ +474 public void setMinImpl(StorelessUnivariateStatistic minImpl) { +475 checkEmpty(); +476 this.minImpl = minImpl; +477 } +478 +479 /** +480 * Returns the currently configured maximum implementation +481 * @return the StorelessUnivariateStatistic implementing the maximum +482 * @since 1.2 +483 */ +484 public StorelessUnivariateStatistic getMaxImpl() { +485 return maxImpl; +486 } +487 +488 /** +489 * <p> +490 * Sets the implementation for the maximum. +491 * </p> +492 * <p> +493 * This method must be activated before any data has been added - i.e., +494 * before {@link #addValue(double) addValue} has been used to add data; +495 * otherwise an IllegalStateException will be thrown. +496 * </p> +497 * @param maxImpl the StorelessUnivariateStatistic instance to use for +498 * computing the maximum +499 * @throws IllegalStateException if data has already been added (i.e if n > +500 * 0) +501 * @since 1.2 +502 */ +503 public void setMaxImpl(StorelessUnivariateStatistic maxImpl) { +504 checkEmpty(); +505 this.maxImpl = maxImpl; +506 } +507 +508 /** +509 * Returns the currently configured sum of logs implementation +510 * @return the StorelessUnivariateStatistic implementing the log sum +511 * @since 1.2 +512 */ +513 public StorelessUnivariateStatistic getSumLogImpl() { +514 return sumLogImpl; +515 } +516 +517 /** +518 * <p> +519 * Sets the implementation for the sum of logs. +520 * </p> +521 * <p> +522 * This method must be activated before any data has been added - i.e., +523 * before {@link #addValue(double) addValue} has been used to add data; +524 * otherwise an IllegalStateException will be thrown. +525 * </p> +526 * @param sumLogImpl the StorelessUnivariateStatistic instance to use for +527 * computing the log sum +528 * @throws IllegalStateException if data has already been added (i.e if n > +529 * 0) +530 * @since 1.2 +531 */ +532 public void setSumLogImpl(StorelessUnivariateStatistic sumLogImpl) { +533 checkEmpty(); +534 this.sumLogImpl = sumLogImpl; +535 geoMean.setSumLogImpl(sumLogImpl); +536 } +537 +538 /** +539 * Returns the currently configured geometric mean implementation +540 * @return the StorelessUnivariateStatistic implementing the geometric mean +541 * @since 1.2 +542 */ +543 public StorelessUnivariateStatistic getGeoMeanImpl() { +544 return geoMeanImpl; +545 } +546 +547 /** +548 * <p> +549 * Sets the implementation for the geometric mean. +550 * </p> +551 * <p> +552 * This method must be activated before any data has been added - i.e., +553 * before {@link #addValue(double) addValue} has been used to add data; +554 * otherwise an IllegalStateException will be thrown. +555 * </p> +556 * @param geoMeanImpl the StorelessUnivariateStatistic instance to use for +557 * computing the geometric mean +558 * @throws IllegalStateException if data has already been added (i.e if n > +559 * 0) +560 * @since 1.2 +561 */ +562 public void setGeoMeanImpl(StorelessUnivariateStatistic geoMeanImpl) { +563 checkEmpty(); +564 this.geoMeanImpl = geoMeanImpl; +565 } +566 +567 /** +568 * Returns the currently configured mean implementation +569 * @return the StorelessUnivariateStatistic implementing the mean +570 * @since 1.2 +571 */ +572 public StorelessUnivariateStatistic getMeanImpl() { +573 return meanImpl; +574 } +575 +576 /** +577 * <p> +578 * Sets the implementation for the mean. +579 * </p> +580 * <p> +581 * This method must be activated before any data has been added - i.e., +582 * before {@link #addValue(double) addValue} has been used to add data; +583 * otherwise an IllegalStateException will be thrown. +584 * </p> +585 * @param meanImpl the StorelessUnivariateStatistic instance to use for +586 * computing the mean +587 * @throws IllegalStateException if data has already been added (i.e if n > +588 * 0) +589 * @since 1.2 +590 */ +591 public void setMeanImpl(StorelessUnivariateStatistic meanImpl) { +592 checkEmpty(); +593 this.meanImpl = meanImpl; +594 } +595 +596 /** +597 * Returns the currently configured variance implementation +598 * @return the StorelessUnivariateStatistic implementing the variance +599 * @since 1.2 +600 */ +601 public StorelessUnivariateStatistic getVarianceImpl() { +602 return varianceImpl; +603 } +604 +605 /** +606 * <p> +607 * Sets the implementation for the variance. +608 * </p> +609 * <p> +610 * This method must be activated before any data has been added - i.e., +611 * before {@link #addValue(double) addValue} has been used to add data; +612 * otherwise an IllegalStateException will be thrown. +613 * </p> +614 * @param varianceImpl the StorelessUnivariateStatistic instance to use for +615 * computing the variance +616 * @throws IllegalStateException if data has already been added (i.e if n > +617 * 0) +618 * @since 1.2 +619 */ +620 public void setVarianceImpl(StorelessUnivariateStatistic varianceImpl) { +621 checkEmpty(); +622 this.varianceImpl = varianceImpl; +623 } +624 +625 /** +626 * Throws IllegalStateException if n > 0. +627 */ +628 private void checkEmpty() { +629 if (n > 0) { +630 throw MathRuntimeException.createIllegalStateException( +631 "{0} values have been added before statistic is configured", +632 n); +633 } +634 } +635 +636 /** +637 * Returns a copy of this SummaryStatistics instance with the same internal state. +638 * +639 * @return a copy of this +640 */ +641 public SummaryStatistics copy() { +642 SummaryStatistics result = new SummaryStatistics(); +643 copy(this, result); +644 return result; +645 } +646 +647 /** +648 * Copies source to dest. +649 * <p>Neither source nor dest can be null.</p> +650 * +651 * @param source SummaryStatistics to copy +652 * @param dest SummaryStatistics to copy to +653 * @throws NullPointerException if either source or dest is null +654 */ +655 public static void copy(SummaryStatistics source, SummaryStatistics dest) { +656 dest.maxImpl = source.maxImpl.copy(); +657 dest.meanImpl = source.meanImpl.copy(); +658 dest.minImpl = source.minImpl.copy(); +659 dest.sumImpl = source.sumImpl.copy(); +660 dest.varianceImpl = source.varianceImpl.copy(); +661 dest.sumLogImpl = source.sumLogImpl.copy(); +662 dest.sumsqImpl = source.sumsqImpl.copy(); +663 if (source.getGeoMeanImpl() instanceof GeometricMean) { +664 // Keep geoMeanImpl, sumLogImpl in synch +665 dest.geoMeanImpl = new GeometricMean((SumOfLogs) dest.sumLogImpl); +666 } else { +667 dest.geoMeanImpl = source.geoMeanImpl.copy(); +668 } +669 SecondMoment.copy(source.secondMoment, dest.secondMoment); +670 dest.n = source.n; +671 +672 // Make sure that if stat == statImpl in source, same +673 // holds in dest; otherwise copy stat +674 if (source.geoMean == source.geoMeanImpl) { +675 dest.geoMean = (GeometricMean) dest.geoMeanImpl; +676 } else { +677 GeometricMean.copy(source.geoMean, dest.geoMean); +678 } +679 if (source.max == source.maxImpl) { +680 dest.max = (Max) dest.maxImpl; +681 } else { +682 Max.copy(source.max, dest.max); +683 } +684 if (source.mean == source.meanImpl) { +685 dest.mean = (Mean) dest.meanImpl; +686 } else { +687 Mean.copy(source.mean, dest.mean); +688 } +689 if (source.min == source.minImpl) { +690 dest.min = (Min) dest.minImpl; +691 } else { +692 Min.copy(source.min, dest.min); +693 } +694 if (source.sum == source.sumImpl) { +695 dest.sum = (Sum) dest.sumImpl; +696 } else { +697 Sum.copy(source.sum, dest.sum); +698 } +699 if (source.variance == source.varianceImpl) { +700 dest.variance = (Variance) dest.varianceImpl; +701 } else { +702 Variance.copy(source.variance, dest.variance); +703 } +704 if (source.sumLog == source.sumLogImpl) { +705 dest.sumLog = (SumOfLogs) dest.sumLogImpl; +706 } else { +707 SumOfLogs.copy(source.sumLog, dest.sumLog); +708 } +709 if (source.sumsq == source.sumsqImpl) { +710 dest.sumsq = (SumOfSquares) dest.sumsqImpl; +711 } else { +712 SumOfSquares.copy(source.sumsq, dest.sumsq); +713 } +714 } +715 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/SynchronizedDescriptiveStatistics.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/SynchronizedDescriptiveStatistics.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,238 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive; +018 +019 /** +020 * Implementation of +021 * {@link org.apache.commons.math.stat.descriptive.DescriptiveStatistics} that +022 * is safe to use in a multithreaded environment. Multiple threads can safely +023 * operate on a single instance without causing runtime exceptions due to race +024 * conditions. In effect, this implementation makes modification and access +025 * methods atomic operations for a single instance. That is to say, as one +026 * thread is computing a statistic from the instance, no other thread can modify +027 * the instance nor compute another statistic. +028 * +029 * @since 1.2 +030 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +031 */ +032 public class SynchronizedDescriptiveStatistics extends DescriptiveStatistics { +033 +034 /** Serialization UID */ +035 private static final long serialVersionUID = 1L; +036 +037 /** +038 * Construct an instance with infinite window +039 */ +040 public SynchronizedDescriptiveStatistics() { +041 this(INFINITE_WINDOW); +042 } +043 +044 /** +045 * Construct an instance with finite window +046 * @param window the finite window size. +047 */ +048 public SynchronizedDescriptiveStatistics(int window) { +049 super(window); +050 } +051 +052 /** +053 * A copy constructor. Creates a deep-copy of the {@code original}. +054 * +055 * @param original the {@code SynchronizedDescriptiveStatistics} instance to copy +056 */ +057 public SynchronizedDescriptiveStatistics(SynchronizedDescriptiveStatistics original) { +058 copy(original, this); +059 } +060 +061 /** +062 * {@inheritDoc} +063 */ +064 @Override +065 public synchronized void addValue(double v) { +066 super.addValue(v); +067 } +068 +069 /** +070 * {@inheritDoc} +071 */ +072 @Override +073 public synchronized double apply(UnivariateStatistic stat) { +074 return super.apply(stat); +075 } +076 +077 /** +078 * {@inheritDoc} +079 */ +080 @Override +081 public synchronized void clear() { +082 super.clear(); +083 } +084 +085 /** +086 * {@inheritDoc} +087 */ +088 @Override +089 public synchronized double getElement(int index) { +090 return super.getElement(index); +091 } +092 +093 /** +094 * {@inheritDoc} +095 */ +096 @Override +097 public synchronized long getN() { +098 return super.getN(); +099 } +100 +101 /** +102 * {@inheritDoc} +103 */ +104 @Override +105 public synchronized double getStandardDeviation() { +106 return super.getStandardDeviation(); +107 } +108 +109 /** +110 * {@inheritDoc} +111 */ +112 @Override +113 public synchronized double[] getValues() { +114 return super.getValues(); +115 } +116 +117 /** +118 * {@inheritDoc} +119 */ +120 @Override +121 public synchronized int getWindowSize() { +122 return super.getWindowSize(); +123 } +124 +125 /** +126 * {@inheritDoc} +127 */ +128 @Override +129 public synchronized void setWindowSize(int windowSize) { +130 super.setWindowSize(windowSize); +131 } +132 +133 /** +134 * {@inheritDoc} +135 */ +136 @Override +137 public synchronized String toString() { +138 return super.toString(); +139 } +140 +141 /** +142 * Returns a copy of this SynchronizedDescriptiveStatistics instance with the +143 * same internal state. +144 * +145 * @return a copy of this +146 */ +147 @Override +148 public synchronized SynchronizedDescriptiveStatistics copy() { +149 SynchronizedDescriptiveStatistics result = +150 new SynchronizedDescriptiveStatistics(); +151 copy(this, result); +152 return result; +153 } +154 +155 /** +156 * Copies source to dest. +157 * <p>Neither source nor dest can be null.</p> +158 * <p>Acquires synchronization lock on source, then dest before copying.</p> +159 * +160 * @param source SynchronizedDescriptiveStatistics to copy +161 * @param dest SynchronizedDescriptiveStatistics to copy to +162 * @throws NullPointerException if either source or dest is null +163 */ +164 public static void copy(SynchronizedDescriptiveStatistics source, +165 SynchronizedDescriptiveStatistics dest) { +166 synchronized (source) { +167 synchronized (dest) { +168 DescriptiveStatistics.copy(source, dest); +169 } +170 } +171 } +172 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/SynchronizedMultivariateSummaryStatistics.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/SynchronizedMultivariateSummaryStatistics.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,365 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive; +018 +019 import org.apache.commons.math.DimensionMismatchException; +020 import org.apache.commons.math.linear.RealMatrix; +021 +022 /** +023 * Implementation of +024 * {@link org.apache.commons.math.stat.descriptive.MultivariateSummaryStatistics} that +025 * is safe to use in a multithreaded environment. Multiple threads can safely +026 * operate on a single instance without causing runtime exceptions due to race +027 * conditions. In effect, this implementation makes modification and access +028 * methods atomic operations for a single instance. That is to say, as one +029 * thread is computing a statistic from the instance, no other thread can modify +030 * the instance nor compute another statistic. +031 * @since 1.2 +032 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +033 */ +034 public class SynchronizedMultivariateSummaryStatistics +035 extends MultivariateSummaryStatistics { +036 +037 /** Serialization UID */ +038 private static final long serialVersionUID = 7099834153347155363L; +039 +040 /** +041 * Construct a SynchronizedMultivariateSummaryStatistics instance +042 * @param k dimension of the data +043 * @param isCovarianceBiasCorrected if true, the unbiased sample +044 * covariance is computed, otherwise the biased population covariance +045 * is computed +046 */ +047 public SynchronizedMultivariateSummaryStatistics(int k, boolean isCovarianceBiasCorrected) { +048 super(k, isCovarianceBiasCorrected); +049 } +050 +051 /** +052 * {@inheritDoc} +053 */ +054 @Override +055 public synchronized void addValue(double[] value) +056 throws DimensionMismatchException { +057 super.addValue(value); +058 } +059 +060 /** +061 * {@inheritDoc} +062 */ +063 @Override +064 public synchronized int getDimension() { +065 return super.getDimension(); +066 } +067 +068 /** +069 * {@inheritDoc} +070 */ +071 @Override +072 public synchronized long getN() { +073 return super.getN(); +074 } +075 +076 /** +077 * {@inheritDoc} +078 */ +079 @Override +080 public synchronized double[] getSum() { +081 return super.getSum(); +082 } +083 +084 /** +085 * {@inheritDoc} +086 */ +087 @Override +088 public synchronized double[] getSumSq() { +089 return super.getSumSq(); +090 } +091 +092 /** +093 * {@inheritDoc} +094 */ +095 @Override +096 public synchronized double[] getSumLog() { +097 return super.getSumLog(); +098 } +099 +100 /** +101 * {@inheritDoc} +102 */ +103 @Override +104 public synchronized double[] getMean() { +105 return super.getMean(); +106 } +107 +108 /** +109 * {@inheritDoc} +110 */ +111 @Override +112 public synchronized double[] getStandardDeviation() { +113 return super.getStandardDeviation(); +114 } +115 +116 /** +117 * {@inheritDoc} +118 */ +119 @Override +120 public synchronized RealMatrix getCovariance() { +121 return super.getCovariance(); +122 } +123 +124 /** +125 * {@inheritDoc} +126 */ +127 @Override +128 public synchronized double[] getMax() { +129 return super.getMax(); +130 } +131 +132 /** +133 * {@inheritDoc} +134 */ +135 @Override +136 public synchronized double[] getMin() { +137 return super.getMin(); +138 } +139 +140 /** +141 * {@inheritDoc} +142 */ +143 @Override +144 public synchronized double[] getGeometricMean() { +145 return super.getGeometricMean(); +146 } +147 +148 /** +149 * {@inheritDoc} +150 */ +151 @Override +152 public synchronized String toString() { +153 return super.toString(); +154 } +155 +156 /** +157 * {@inheritDoc} +158 */ +159 @Override +160 public synchronized void clear() { +161 super.clear(); +162 } +163 +164 /** +165 * {@inheritDoc} +166 */ +167 @Override +168 public synchronized boolean equals(Object object) { +169 return super.equals(object); +170 } +171 +172 /** +173 * {@inheritDoc} +174 */ +175 @Override +176 public synchronized int hashCode() { +177 return super.hashCode(); +178 } +179 +180 /** +181 * {@inheritDoc} +182 */ +183 @Override +184 public synchronized StorelessUnivariateStatistic[] getSumImpl() { +185 return super.getSumImpl(); +186 } +187 +188 /** +189 * {@inheritDoc} +190 */ +191 @Override +192 public synchronized void setSumImpl(StorelessUnivariateStatistic[] sumImpl) +193 throws DimensionMismatchException { +194 super.setSumImpl(sumImpl); +195 } +196 +197 /** +198 * {@inheritDoc} +199 */ +200 @Override +201 public synchronized StorelessUnivariateStatistic[] getSumsqImpl() { +202 return super.getSumsqImpl(); +203 } +204 +205 /** +206 * {@inheritDoc} +207 */ +208 @Override +209 public synchronized void setSumsqImpl(StorelessUnivariateStatistic[] sumsqImpl) +210 throws DimensionMismatchException { +211 super.setSumsqImpl(sumsqImpl); +212 } +213 +214 /** +215 * {@inheritDoc} +216 */ +217 @Override +218 public synchronized StorelessUnivariateStatistic[] getMinImpl() { +219 return super.getMinImpl(); +220 } +221 +222 /** +223 * {@inheritDoc} +224 */ +225 @Override +226 public synchronized void setMinImpl(StorelessUnivariateStatistic[] minImpl) +227 throws DimensionMismatchException { +228 super.setMinImpl(minImpl); +229 } +230 +231 /** +232 * {@inheritDoc} +233 */ +234 @Override +235 public synchronized StorelessUnivariateStatistic[] getMaxImpl() { +236 return super.getMaxImpl(); +237 } +238 +239 /** +240 * {@inheritDoc} +241 */ +242 @Override +243 public synchronized void setMaxImpl(StorelessUnivariateStatistic[] maxImpl) +244 throws DimensionMismatchException { +245 super.setMaxImpl(maxImpl); +246 } +247 +248 /** +249 * {@inheritDoc} +250 */ +251 @Override +252 public synchronized StorelessUnivariateStatistic[] getSumLogImpl() { +253 return super.getSumLogImpl(); +254 } +255 +256 /** +257 * {@inheritDoc} +258 */ +259 @Override +260 public synchronized void setSumLogImpl(StorelessUnivariateStatistic[] sumLogImpl) +261 throws DimensionMismatchException { +262 super.setSumLogImpl(sumLogImpl); +263 } +264 +265 /** +266 * {@inheritDoc} +267 */ +268 @Override +269 public synchronized StorelessUnivariateStatistic[] getGeoMeanImpl() { +270 return super.getGeoMeanImpl(); +271 } +272 +273 /** +274 * {@inheritDoc} +275 */ +276 @Override +277 public synchronized void setGeoMeanImpl(StorelessUnivariateStatistic[] geoMeanImpl) +278 throws DimensionMismatchException { +279 super.setGeoMeanImpl(geoMeanImpl); +280 } +281 +282 /** +283 * {@inheritDoc} +284 */ +285 @Override +286 public synchronized StorelessUnivariateStatistic[] getMeanImpl() { +287 return super.getMeanImpl(); +288 } +289 +290 /** +291 * {@inheritDoc} +292 */ +293 @Override +294 public synchronized void setMeanImpl(StorelessUnivariateStatistic[] meanImpl) +295 throws DimensionMismatchException { +296 super.setMeanImpl(meanImpl); +297 } +298 +299 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/SynchronizedSummaryStatistics.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/SynchronizedSummaryStatistics.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,399 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive; +018 +019 /** +020 * Implementation of +021 * {@link org.apache.commons.math.stat.descriptive.SummaryStatistics} that +022 * is safe to use in a multithreaded environment. Multiple threads can safely +023 * operate on a single instance without causing runtime exceptions due to race +024 * conditions. In effect, this implementation makes modification and access +025 * methods atomic operations for a single instance. That is to say, as one +026 * thread is computing a statistic from the instance, no other thread can modify +027 * the instance nor compute another statistic. +028 * +029 * @since 1.2 +030 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +031 */ +032 public class SynchronizedSummaryStatistics extends SummaryStatistics { +033 +034 /** Serialization UID */ +035 private static final long serialVersionUID = 1909861009042253704L; +036 +037 /** +038 * Construct a SynchronizedSummaryStatistics instance +039 */ +040 public SynchronizedSummaryStatistics() { +041 super(); +042 } +043 +044 /** +045 * A copy constructor. Creates a deep-copy of the {@code original}. +046 * +047 * @param original the {@code SynchronizedSummaryStatistics} instance to copy +048 */ +049 public SynchronizedSummaryStatistics(SynchronizedSummaryStatistics original) { +050 copy(original, this); +051 } +052 +053 /** +054 * {@inheritDoc} +055 */ +056 @Override +057 public synchronized StatisticalSummary getSummary() { +058 return super.getSummary(); +059 } +060 +061 /** +062 * {@inheritDoc} +063 */ +064 @Override +065 public synchronized void addValue(double value) { +066 super.addValue(value); +067 } +068 +069 /** +070 * {@inheritDoc} +071 */ +072 @Override +073 public synchronized long getN() { +074 return super.getN(); +075 } +076 +077 /** +078 * {@inheritDoc} +079 */ +080 @Override +081 public synchronized double getSum() { +082 return super.getSum(); +083 } +084 +085 /** +086 * {@inheritDoc} +087 */ +088 @Override +089 public synchronized double getSumsq() { +090 return super.getSumsq(); +091 } +092 +093 /** +094 * {@inheritDoc} +095 */ +096 @Override +097 public synchronized double getMean() { +098 return super.getMean(); +099 } +100 +101 /** +102 * {@inheritDoc} +103 */ +104 @Override +105 public synchronized double getStandardDeviation() { +106 return super.getStandardDeviation(); +107 } +108 +109 /** +110 * {@inheritDoc} +111 */ +112 @Override +113 public synchronized double getVariance() { +114 return super.getVariance(); +115 } +116 +117 /** +118 * {@inheritDoc} +119 */ +120 @Override +121 public synchronized double getMax() { +122 return super.getMax(); +123 } +124 +125 /** +126 * {@inheritDoc} +127 */ +128 @Override +129 public synchronized double getMin() { +130 return super.getMin(); +131 } +132 +133 /** +134 * {@inheritDoc} +135 */ +136 @Override +137 public synchronized double getGeometricMean() { +138 return super.getGeometricMean(); +139 } +140 +141 /** +142 * {@inheritDoc} +143 */ +144 @Override +145 public synchronized String toString() { +146 return super.toString(); +147 } +148 +149 /** +150 * {@inheritDoc} +151 */ +152 @Override +153 public synchronized void clear() { +154 super.clear(); +155 } +156 +157 /** +158 * {@inheritDoc} +159 */ +160 @Override +161 public synchronized boolean equals(Object object) { +162 return super.equals(object); +163 } +164 +165 /** +166 * {@inheritDoc} +167 */ +168 @Override +169 public synchronized int hashCode() { +170 return super.hashCode(); +171 } +172 +173 /** +174 * {@inheritDoc} +175 */ +176 @Override +177 public synchronized StorelessUnivariateStatistic getSumImpl() { +178 return super.getSumImpl(); +179 } +180 +181 /** +182 * {@inheritDoc} +183 */ +184 @Override +185 public synchronized void setSumImpl(StorelessUnivariateStatistic sumImpl) { +186 super.setSumImpl(sumImpl); +187 } +188 +189 /** +190 * {@inheritDoc} +191 */ +192 @Override +193 public synchronized StorelessUnivariateStatistic getSumsqImpl() { +194 return super.getSumsqImpl(); +195 } +196 +197 /** +198 * {@inheritDoc} +199 */ +200 @Override +201 public synchronized void setSumsqImpl(StorelessUnivariateStatistic sumsqImpl) { +202 super.setSumsqImpl(sumsqImpl); +203 } +204 +205 /** +206 * {@inheritDoc} +207 */ +208 @Override +209 public synchronized StorelessUnivariateStatistic getMinImpl() { +210 return super.getMinImpl(); +211 } +212 +213 /** +214 * {@inheritDoc} +215 */ +216 @Override +217 public synchronized void setMinImpl(StorelessUnivariateStatistic minImpl) { +218 super.setMinImpl(minImpl); +219 } +220 +221 /** +222 * {@inheritDoc} +223 */ +224 @Override +225 public synchronized StorelessUnivariateStatistic getMaxImpl() { +226 return super.getMaxImpl(); +227 } +228 +229 /** +230 * {@inheritDoc} +231 */ +232 @Override +233 public synchronized void setMaxImpl(StorelessUnivariateStatistic maxImpl) { +234 super.setMaxImpl(maxImpl); +235 } +236 +237 /** +238 * {@inheritDoc} +239 */ +240 @Override +241 public synchronized StorelessUnivariateStatistic getSumLogImpl() { +242 return super.getSumLogImpl(); +243 } +244 +245 /** +246 * {@inheritDoc} +247 */ +248 @Override +249 public synchronized void setSumLogImpl(StorelessUnivariateStatistic sumLogImpl) { +250 super.setSumLogImpl(sumLogImpl); +251 } +252 +253 /** +254 * {@inheritDoc} +255 */ +256 @Override +257 public synchronized StorelessUnivariateStatistic getGeoMeanImpl() { +258 return super.getGeoMeanImpl(); +259 } +260 +261 /** +262 * {@inheritDoc} +263 */ +264 @Override +265 public synchronized void setGeoMeanImpl(StorelessUnivariateStatistic geoMeanImpl) { +266 super.setGeoMeanImpl(geoMeanImpl); +267 } +268 +269 /** +270 * {@inheritDoc} +271 */ +272 @Override +273 public synchronized StorelessUnivariateStatistic getMeanImpl() { +274 return super.getMeanImpl(); +275 } +276 +277 /** +278 * {@inheritDoc} +279 */ +280 @Override +281 public synchronized void setMeanImpl(StorelessUnivariateStatistic meanImpl) { +282 super.setMeanImpl(meanImpl); +283 } +284 +285 /** +286 * {@inheritDoc} +287 */ +288 @Override +289 public synchronized StorelessUnivariateStatistic getVarianceImpl() { +290 return super.getVarianceImpl(); +291 } +292 +293 /** +294 * {@inheritDoc} +295 */ +296 @Override +297 public synchronized void setVarianceImpl(StorelessUnivariateStatistic varianceImpl) { +298 super.setVarianceImpl(varianceImpl); +299 } +300 +301 /** +302 * Returns a copy of this SynchronizedSummaryStatistics instance with the +303 * same internal state. +304 * +305 * @return a copy of this +306 */ +307 @Override +308 public synchronized SynchronizedSummaryStatistics copy() { +309 SynchronizedSummaryStatistics result = +310 new SynchronizedSummaryStatistics(); +311 copy(this, result); +312 return result; +313 } +314 +315 /** +316 * Copies source to dest. +317 * <p>Neither source nor dest can be null.</p> +318 * <p>Acquires synchronization lock on source, then dest before copying.</p> +319 * +320 * @param source SynchronizedSummaryStatistics to copy +321 * @param dest SynchronizedSummaryStatistics to copy to +322 * @throws NullPointerException if either source or dest is null +323 */ +324 public static void copy(SynchronizedSummaryStatistics source, +325 SynchronizedSummaryStatistics dest) { +326 synchronized (source) { +327 synchronized (dest) { +328 SummaryStatistics.copy(source, dest); +329 } +330 } +331 } +332 +333 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/UnivariateStatistic.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/UnivariateStatistic.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,119 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive; +018 +019 +020 /** +021 * Base interface implemented by all statistics. +022 * +023 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +024 */ +025 public interface UnivariateStatistic { +026 +027 /** +028 * Returns the result of evaluating the statistic over the input array. +029 * +030 * @param values input array +031 * @return the value of the statistic applied to the input array +032 */ +033 double evaluate(double[] values); +034 +035 /** +036 * Returns the result of evaluating the statistic over the specified entries +037 * in the input array. +038 * +039 * @param values the input array +040 * @param begin the index of the first element to include +041 * @param length the number of elements to include +042 * @return the value of the statistic applied to the included array entries +043 */ +044 double evaluate(double[] values, int begin, int length); +045 +046 /** +047 * Returns a copy of the statistic with the same internal state. +048 * +049 * @return a copy of the statistic +050 */ +051 UnivariateStatistic copy(); +052 +053 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/WeightedEvaluation.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/WeightedEvaluation.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,115 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive; +018 +019 /** +020 * Weighted evaluation for statistics. +021 * +022 * @since 2.1 +023 * @version $Revision: 894474 $ $Date: 2009-12-29 15:02:37 -0500 (Tue, 29 Dec 2009) $ +024 */ +025 public interface WeightedEvaluation { +026 +027 /** +028 * Returns the result of evaluating the statistic over the input array, +029 * using the supplied weights. +030 * +031 * @param values input array +032 * @param weights array of weights +033 * @return the value of the weighted statistic applied to the input array +034 */ +035 double evaluate(double[] values, double[] weights); +036 +037 /** +038 * Returns the result of evaluating the statistic over the specified entries +039 * in the input array, using corresponding entries in the supplied weights array. +040 * +041 * @param values the input array +042 * @param weights array of weights +043 * @param begin the index of the first element to include +044 * @param length the number of elements to include +045 * @return the value of the weighted statistic applied to the included array entries +046 */ +047 double evaluate(double[] values, double[] weights, int begin, int length); +048 +049 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/FirstMoment.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/FirstMoment.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,225 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.moment; +018 +019 import java.io.Serializable; +020 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; +021 +022 /** +023 * Computes the first moment (arithmetic mean). Uses the definitional formula: +024 * <p> +025 * mean = sum(x_i) / n </p> +026 * <p> +027 * where <code>n</code> is the number of observations. </p> +028 * <p> +029 * To limit numeric errors, the value of the statistic is computed using the +030 * following recursive updating algorithm: </p> +031 * <p> +032 * <ol> +033 * <li>Initialize <code>m = </code> the first value</li> +034 * <li>For each additional value, update using <br> +035 * <code>m = m + (new value - m) / (number of observations)</code></li> +036 * </ol></p> +037 * <p> +038 * Returns <code>Double.NaN</code> if the dataset is empty.</p> +039 * <p> +040 * <strong>Note that this implementation is not synchronized.</strong> If +041 * multiple threads access an instance of this class concurrently, and at least +042 * one of the threads invokes the <code>increment()</code> or +043 * <code>clear()</code> method, it must be synchronized externally.</p> +044 * +045 * @version $Revision: 902934 $ $Date: 2010-01-25 14:09:17 -0500 (Mon, 25 Jan 2010) $ +046 */ +047 public class FirstMoment extends AbstractStorelessUnivariateStatistic +048 implements Serializable { +049 +050 /** Serializable version identifier */ +051 private static final long serialVersionUID = 6112755307178490473L; +052 +053 +054 /** Count of values that have been added */ +055 protected long n; +056 +057 /** First moment of values that have been added */ +058 protected double m1; +059 +060 /** +061 * Deviation of most recently added value from previous first moment. +062 * Retained to prevent repeated computation in higher order moments. +063 */ +064 protected double dev; +065 +066 /** +067 * Deviation of most recently added value from previous first moment, +068 * normalized by previous sample size. Retained to prevent repeated +069 * computation in higher order moments +070 */ +071 protected double nDev; +072 +073 /** +074 * Create a FirstMoment instance +075 */ +076 public FirstMoment() { +077 n = 0; +078 m1 = Double.NaN; +079 dev = Double.NaN; +080 nDev = Double.NaN; +081 } +082 +083 /** +084 * Copy constructor, creates a new {@code FirstMoment} identical +085 * to the {@code original} +086 * +087 * @param original the {@code FirstMoment} instance to copy +088 */ +089 public FirstMoment(FirstMoment original) { +090 super(); +091 copy(original, this); +092 } +093 +094 /** +095 * {@inheritDoc} +096 */ +097 @Override +098 public void increment(final double d) { +099 if (n == 0) { +100 m1 = 0.0; +101 } +102 n++; +103 double n0 = n; +104 dev = d - m1; +105 nDev = dev / n0; +106 m1 += nDev; +107 } +108 +109 /** +110 * {@inheritDoc} +111 */ +112 @Override +113 public void clear() { +114 m1 = Double.NaN; +115 n = 0; +116 dev = Double.NaN; +117 nDev = Double.NaN; +118 } +119 +120 /** +121 * {@inheritDoc} +122 */ +123 @Override +124 public double getResult() { +125 return m1; +126 } +127 +128 /** +129 * {@inheritDoc} +130 */ +131 public long getN() { +132 return n; +133 } +134 +135 /** +136 * {@inheritDoc} +137 */ +138 @Override +139 public FirstMoment copy() { +140 FirstMoment result = new FirstMoment(); +141 copy(this, result); +142 return result; +143 } +144 +145 /** +146 * Copies source to dest. +147 * <p>Neither source nor dest can be null.</p> +148 * +149 * @param source FirstMoment to copy +150 * @param dest FirstMoment to copy to +151 * @throws NullPointerException if either source or dest is null +152 */ +153 public static void copy(FirstMoment source, FirstMoment dest) { +154 dest.n = source.n; +155 dest.m1 = source.m1; +156 dest.dev = source.dev; +157 dest.nDev = source.nDev; +158 } +159 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/FourthMoment.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/FourthMoment.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,208 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.moment; +018 +019 import java.io.Serializable; +020 +021 /** +022 * Computes a statistic related to the Fourth Central Moment. Specifically, +023 * what is computed is the sum of +024 * <p> +025 * (x_i - xbar) ^ 4, </p> +026 * <p> +027 * where the x_i are the +028 * sample observations and xbar is the sample mean. </p> +029 * <p> +030 * The following recursive updating formula is used: </p> +031 * <p> +032 * Let <ul> +033 * <li> dev = (current obs - previous mean) </li> +034 * <li> m2 = previous value of {@link SecondMoment} </li> +035 * <li> m2 = previous value of {@link ThirdMoment} </li> +036 * <li> n = number of observations (including current obs) </li> +037 * </ul> +038 * Then </p> +039 * <p> +040 * new value = old value - 4 * (dev/n) * m3 + 6 * (dev/n)^2 * m2 + <br> +041 * [n^2 - 3 * (n-1)] * dev^4 * (n-1) / n^3 </p> +042 * <p> +043 * Returns <code>Double.NaN</code> if no data values have been added and +044 * returns <code>0</code> if there is just one value in the data set. </p> +045 * <p> +046 * <strong>Note that this implementation is not synchronized.</strong> If +047 * multiple threads access an instance of this class concurrently, and at least +048 * one of the threads invokes the <code>increment()</code> or +049 * <code>clear()</code> method, it must be synchronized externally. </p> +050 * +051 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +052 */ +053 public class FourthMoment extends ThirdMoment implements Serializable{ +054 +055 /** Serializable version identifier */ +056 private static final long serialVersionUID = 4763990447117157611L; +057 +058 /** fourth moment of values that have been added */ +059 protected double m4; +060 +061 /** +062 * Create a FourthMoment instance +063 */ +064 public FourthMoment() { +065 super(); +066 m4 = Double.NaN; +067 } +068 +069 /** +070 * Copy constructor, creates a new {@code FourthMoment} identical +071 * to the {@code original} +072 * +073 * @param original the {@code FourthMoment} instance to copy +074 */ +075 public FourthMoment(FourthMoment original) { +076 super(); +077 copy(original, this); +078 } +079 +080 /** +081 * {@inheritDoc} +082 */ +083 @Override +084 public void increment(final double d) { +085 if (n < 1) { +086 m4 = 0.0; +087 m3 = 0.0; +088 m2 = 0.0; +089 m1 = 0.0; +090 } +091 +092 double prevM3 = m3; +093 double prevM2 = m2; +094 +095 super.increment(d); +096 +097 double n0 = n; +098 +099 m4 = m4 - 4.0 * nDev * prevM3 + 6.0 * nDevSq * prevM2 + +100 ((n0 * n0) - 3 * (n0 -1)) * (nDevSq * nDevSq * (n0 - 1) * n0); +101 } +102 +103 /** +104 * {@inheritDoc} +105 */ +106 @Override +107 public double getResult() { +108 return m4; +109 } +110 +111 /** +112 * {@inheritDoc} +113 */ +114 @Override +115 public void clear() { +116 super.clear(); +117 m4 = Double.NaN; +118 } +119 +120 /** +121 * {@inheritDoc} +122 */ +123 @Override +124 public FourthMoment copy() { +125 FourthMoment result = new FourthMoment(); +126 copy(this, result); +127 return result; +128 } +129 +130 /** +131 * Copies source to dest. +132 * <p>Neither source nor dest can be null.</p> +133 * +134 * @param source FourthMoment to copy +135 * @param dest FourthMoment to copy to +136 * @throws NullPointerException if either source or dest is null +137 */ +138 public static void copy(FourthMoment source, FourthMoment dest) { +139 ThirdMoment.copy(source, dest); +140 dest.m4 = source.m4; +141 } +142 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/GeometricMean.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/GeometricMean.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,268 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.moment; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; +023 import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic; +024 import org.apache.commons.math.stat.descriptive.summary.SumOfLogs; +025 +026 /** +027 * Returns the <a href="http://www.xycoon.com/geometric_mean.htm"> +028 * geometric mean </a> of the available values. +029 * <p> +030 * Uses a {@link SumOfLogs} instance to compute sum of logs and returns +031 * <code> exp( 1/n (sum of logs) ).</code> Therefore, </p> +032 * <ul> +033 * <li>If any of values are < 0, the result is <code>NaN.</code></li> +034 * <li>If all values are non-negative and less than +035 * <code>Double.POSITIVE_INFINITY</code>, but at least one value is 0, the +036 * result is <code>0.</code></li> +037 * <li>If both <code>Double.POSITIVE_INFINITY</code> and +038 * <code>Double.NEGATIVE_INFINITY</code> are among the values, the result is +039 * <code>NaN.</code></li> +040 * </ul> </p> +041 * <p> +042 * <strong>Note that this implementation is not synchronized.</strong> If +043 * multiple threads access an instance of this class concurrently, and at least +044 * one of the threads invokes the <code>increment()</code> or +045 * <code>clear()</code> method, it must be synchronized externally.</p> +046 * +047 * +048 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +049 */ +050 public class GeometricMean extends AbstractStorelessUnivariateStatistic implements Serializable { +051 +052 /** Serializable version identifier */ +053 private static final long serialVersionUID = -8178734905303459453L; +054 +055 /** Wrapped SumOfLogs instance */ +056 private StorelessUnivariateStatistic sumOfLogs; +057 +058 /** +059 * Create a GeometricMean instance +060 */ +061 public GeometricMean() { +062 sumOfLogs = new SumOfLogs(); +063 } +064 +065 /** +066 * Copy constructor, creates a new {@code GeometricMean} identical +067 * to the {@code original} +068 * +069 * @param original the {@code GeometricMean} instance to copy +070 */ +071 public GeometricMean(GeometricMean original) { +072 super(); +073 copy(original, this); +074 } +075 +076 /** +077 * Create a GeometricMean instance using the given SumOfLogs instance +078 * @param sumOfLogs sum of logs instance to use for computation +079 */ +080 public GeometricMean(SumOfLogs sumOfLogs) { +081 this.sumOfLogs = sumOfLogs; +082 } +083 +084 /** +085 * {@inheritDoc} +086 */ +087 @Override +088 public GeometricMean copy() { +089 GeometricMean result = new GeometricMean(); +090 copy(this, result); +091 return result; +092 } +093 +094 /** +095 * {@inheritDoc} +096 */ +097 @Override +098 public void increment(final double d) { +099 sumOfLogs.increment(d); +100 } +101 +102 /** +103 * {@inheritDoc} +104 */ +105 @Override +106 public double getResult() { +107 if (sumOfLogs.getN() > 0) { +108 return Math.exp(sumOfLogs.getResult() / sumOfLogs.getN()); +109 } else { +110 return Double.NaN; +111 } +112 } +113 +114 /** +115 * {@inheritDoc} +116 */ +117 @Override +118 public void clear() { +119 sumOfLogs.clear(); +120 } +121 +122 /** +123 * Returns the geometric mean of the entries in the specified portion +124 * of the input array. +125 * <p> +126 * See {@link GeometricMean} for details on the computing algorithm.</p> +127 * <p> +128 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +129 * +130 * @param values input array containing the values +131 * @param begin first array element to include +132 * @param length the number of elements to include +133 * @return the geometric mean or Double.NaN if length = 0 or +134 * any of the values are <= 0. +135 * @throws IllegalArgumentException if the input array is null or the array +136 * index parameters are not valid +137 */ +138 @Override +139 public double evaluate( +140 final double[] values, final int begin, final int length) { +141 return Math.exp( +142 sumOfLogs.evaluate(values, begin, length) / length); +143 } +144 +145 /** +146 * {@inheritDoc} +147 */ +148 public long getN() { +149 return sumOfLogs.getN(); +150 } +151 +152 /** +153 * <p>Sets the implementation for the sum of logs.</p> +154 * <p>This method must be activated before any data has been added - i.e., +155 * before {@link #increment(double) increment} has been used to add data; +156 * otherwise an IllegalStateException will be thrown.</p> +157 * +158 * @param sumLogImpl the StorelessUnivariateStatistic instance to use +159 * for computing the log sum +160 * @throws IllegalStateException if data has already been added +161 * (i.e if n > 0) +162 */ +163 public void setSumLogImpl( +164 StorelessUnivariateStatistic sumLogImpl) { +165 checkEmpty(); +166 this.sumOfLogs = sumLogImpl; +167 } +168 +169 /** +170 * Returns the currently configured sum of logs implementation +171 * +172 * @return the StorelessUnivariateStatistic implementing the log sum +173 */ +174 public StorelessUnivariateStatistic getSumLogImpl() { +175 return sumOfLogs; +176 } +177 +178 /** +179 * Copies source to dest. +180 * <p>Neither source nor dest can be null.</p> +181 * +182 * @param source GeometricMean to copy +183 * @param dest GeometricMean to copy to +184 * @throws NullPointerException if either source or dest is null +185 */ +186 public static void copy(GeometricMean source, GeometricMean dest) { +187 dest.sumOfLogs = source.sumOfLogs.copy(); +188 } +189 +190 +191 /** +192 * Throws IllegalStateException if n > 0. +193 */ +194 private void checkEmpty() { +195 if (getN() > 0) { +196 throw MathRuntimeException.createIllegalStateException( +197 "{0} values have been added before statistic is configured", +198 getN()); +199 } +200 } +201 +202 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/Kurtosis.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/Kurtosis.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,285 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.moment; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; +023 +024 +025 /** +026 * Computes the Kurtosis of the available values. +027 * <p> +028 * We use the following (unbiased) formula to define kurtosis:</p> +029 * <p> +030 * 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)] +031 * </p><p> +032 * where n is the number of values, mean is the {@link Mean} and std is the +033 * {@link StandardDeviation}</p> +034 * <p> +035 * Note that this statistic is undefined for n < 4. <code>Double.Nan</code> +036 * is returned when there is not sufficient data to compute the statistic.</p> +037 * <p> +038 * <strong>Note that this implementation is not synchronized.</strong> If +039 * multiple threads access an instance of this class concurrently, and at least +040 * one of the threads invokes the <code>increment()</code> or +041 * <code>clear()</code> method, it must be synchronized externally.</p> +042 * +043 * @version $Revision: 811833 $ $Date: 2009-09-06 12:27:50 -0400 (Sun, 06 Sep 2009) $ +044 */ +045 public class Kurtosis extends AbstractStorelessUnivariateStatistic implements Serializable { +046 +047 /** Serializable version identifier */ +048 private static final long serialVersionUID = 2784465764798260919L; +049 +050 /**Fourth Moment on which this statistic is based */ +051 protected FourthMoment moment; +052 +053 /** +054 * Determines whether or not this statistic can be incremented or cleared. +055 * <p> +056 * Statistics based on (constructed from) external moments cannot +057 * be incremented or cleared.</p> +058 */ +059 protected boolean incMoment; +060 +061 /** +062 * Construct a Kurtosis +063 */ +064 public Kurtosis() { +065 incMoment = true; +066 moment = new FourthMoment(); +067 } +068 +069 /** +070 * Construct a Kurtosis from an external moment +071 * +072 * @param m4 external Moment +073 */ +074 public Kurtosis(final FourthMoment m4) { +075 incMoment = false; +076 this.moment = m4; +077 } +078 +079 /** +080 * Copy constructor, creates a new {@code Kurtosis} identical +081 * to the {@code original} +082 * +083 * @param original the {@code Kurtosis} instance to copy +084 */ +085 public Kurtosis(Kurtosis original) { +086 copy(original, this); +087 } +088 +089 /** +090 * {@inheritDoc} +091 */ +092 @Override +093 public void increment(final double d) { +094 if (incMoment) { +095 moment.increment(d); +096 } else { +097 throw MathRuntimeException.createIllegalStateException( +098 "statistics constructed from external moments cannot be incremented"); +099 } +100 } +101 +102 /** +103 * {@inheritDoc} +104 */ +105 @Override +106 public double getResult() { +107 double kurtosis = Double.NaN; +108 if (moment.getN() > 3) { +109 double variance = moment.m2 / (moment.n - 1); +110 if (moment.n <= 3 || variance < 10E-20) { +111 kurtosis = 0.0; +112 } else { +113 double n = moment.n; +114 kurtosis = +115 (n * (n + 1) * moment.m4 - +116 3 * moment.m2 * moment.m2 * (n - 1)) / +117 ((n - 1) * (n -2) * (n -3) * variance * variance); +118 } +119 } +120 return kurtosis; +121 } +122 +123 /** +124 * {@inheritDoc} +125 */ +126 @Override +127 public void clear() { +128 if (incMoment) { +129 moment.clear(); +130 } else { +131 throw MathRuntimeException.createIllegalStateException( +132 "statistics constructed from external moments cannot be cleared"); +133 } +134 } +135 +136 /** +137 * {@inheritDoc} +138 */ +139 public long getN() { +140 return moment.getN(); +141 } +142 +143 /* UnvariateStatistic Approach */ +144 +145 /** +146 * Returns the kurtosis of the entries in the specified portion of the +147 * input array. +148 * <p> +149 * See {@link Kurtosis} for details on the computing algorithm.</p> +150 * <p> +151 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +152 * +153 * @param values the input array +154 * @param begin index of the first array element to include +155 * @param length the number of elements to include +156 * @return the kurtosis of the values or Double.NaN if length is less than +157 * 4 +158 * @throws IllegalArgumentException if the input array is null or the array +159 * index parameters are not valid +160 */ +161 @Override +162 public double evaluate(final double[] values,final int begin, final int length) { +163 // Initialize the kurtosis +164 double kurt = Double.NaN; +165 +166 if (test(values, begin, length) && length > 3) { +167 +168 // Compute the mean and standard deviation +169 Variance variance = new Variance(); +170 variance.incrementAll(values, begin, length); +171 double mean = variance.moment.m1; +172 double stdDev = Math.sqrt(variance.getResult()); +173 +174 // Sum the ^4 of the distance from the mean divided by the +175 // standard deviation +176 double accum3 = 0.0; +177 for (int i = begin; i < begin + length; i++) { +178 accum3 += Math.pow(values[i] - mean, 4.0); +179 } +180 accum3 /= Math.pow(stdDev, 4.0d); +181 +182 // Get N +183 double n0 = length; +184 +185 double coefficientOne = +186 (n0 * (n0 + 1)) / ((n0 - 1) * (n0 - 2) * (n0 - 3)); +187 double termTwo = +188 (3 * Math.pow(n0 - 1, 2.0)) / ((n0 - 2) * (n0 - 3)); +189 +190 // Calculate kurtosis +191 kurt = (coefficientOne * accum3) - termTwo; +192 } +193 return kurt; +194 } +195 +196 /** +197 * {@inheritDoc} +198 */ +199 @Override +200 public Kurtosis copy() { +201 Kurtosis result = new Kurtosis(); +202 copy(this, result); +203 return result; +204 } +205 +206 /** +207 * Copies source to dest. +208 * <p>Neither source nor dest can be null.</p> +209 * +210 * @param source Kurtosis to copy +211 * @param dest Kurtosis to copy to +212 * @throws NullPointerException if either source or dest is null +213 */ +214 public static void copy(Kurtosis source, Kurtosis dest) { +215 dest.moment = source.moment.copy(); +216 dest.incMoment = source.incMoment; +217 } +218 +219 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/Mean.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/Mean.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,337 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.moment; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; +022 import org.apache.commons.math.stat.descriptive.WeightedEvaluation; +023 import org.apache.commons.math.stat.descriptive.summary.Sum; +024 +025 /** +026 * <p>Computes the arithmetic mean of a set of values. Uses the definitional +027 * formula:</p> +028 * <p> +029 * mean = sum(x_i) / n +030 * </p> +031 * <p>where <code>n</code> is the number of observations. +032 * </p> +033 * <p>When {@link #increment(double)} is used to add data incrementally from a +034 * stream of (unstored) values, the value of the statistic that +035 * {@link #getResult()} returns is computed using the following recursive +036 * updating algorithm: </p> +037 * <ol> +038 * <li>Initialize <code>m = </code> the first value</li> +039 * <li>For each additional value, update using <br> +040 * <code>m = m + (new value - m) / (number of observations)</code></li> +041 * </ol> +042 * <p> If {@link #evaluate(double[])} is used to compute the mean of an array +043 * of stored values, a two-pass, corrected algorithm is used, starting with +044 * the definitional formula computed using the array of stored values and then +045 * correcting this by adding the mean deviation of the data values from the +046 * arithmetic mean. See, e.g. "Comparison of Several Algorithms for Computing +047 * Sample Means and Variances," Robert F. Ling, Journal of the American +048 * Statistical Association, Vol. 69, No. 348 (Dec., 1974), pp. 859-866. </p> +049 * <p> +050 * Returns <code>Double.NaN</code> if the dataset is empty. +051 * </p> +052 * <strong>Note that this implementation is not synchronized.</strong> If +053 * multiple threads access an instance of this class concurrently, and at least +054 * one of the threads invokes the <code>increment()</code> or +055 * <code>clear()</code> method, it must be synchronized externally. +056 * +057 * @version $Revision: 908626 $ $Date: 2010-02-10 13:44:42 -0500 (Wed, 10 Feb 2010) $ +058 */ +059 public class Mean extends AbstractStorelessUnivariateStatistic +060 implements Serializable, WeightedEvaluation { +061 +062 /** Serializable version identifier */ +063 private static final long serialVersionUID = -1296043746617791564L; +064 +065 /** First moment on which this statistic is based. */ +066 protected FirstMoment moment; +067 +068 /** +069 * Determines whether or not this statistic can be incremented or cleared. +070 * <p> +071 * Statistics based on (constructed from) external moments cannot +072 * be incremented or cleared.</p> +073 */ +074 protected boolean incMoment; +075 +076 /** Constructs a Mean. */ +077 public Mean() { +078 incMoment = true; +079 moment = new FirstMoment(); +080 } +081 +082 /** +083 * Constructs a Mean with an External Moment. +084 * +085 * @param m1 the moment +086 */ +087 public Mean(final FirstMoment m1) { +088 this.moment = m1; +089 incMoment = false; +090 } +091 +092 /** +093 * Copy constructor, creates a new {@code Mean} identical +094 * to the {@code original} +095 * +096 * @param original the {@code Mean} instance to copy +097 */ +098 public Mean(Mean original) { +099 copy(original, this); +100 } +101 +102 /** +103 * {@inheritDoc} +104 */ +105 @Override +106 public void increment(final double d) { +107 if (incMoment) { +108 moment.increment(d); +109 } +110 } +111 +112 /** +113 * {@inheritDoc} +114 */ +115 @Override +116 public void clear() { +117 if (incMoment) { +118 moment.clear(); +119 } +120 } +121 +122 /** +123 * {@inheritDoc} +124 */ +125 @Override +126 public double getResult() { +127 return moment.m1; +128 } +129 +130 /** +131 * {@inheritDoc} +132 */ +133 public long getN() { +134 return moment.getN(); +135 } +136 +137 /** +138 * Returns the arithmetic mean of the entries in the specified portion of +139 * the input array, or <code>Double.NaN</code> if the designated subarray +140 * is empty. +141 * <p> +142 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +143 * <p> +144 * See {@link Mean} for details on the computing algorithm.</p> +145 * +146 * @param values the input array +147 * @param begin index of the first array element to include +148 * @param length the number of elements to include +149 * @return the mean of the values or Double.NaN if length = 0 +150 * @throws IllegalArgumentException if the array is null or the array index +151 * parameters are not valid +152 */ +153 @Override +154 public double evaluate(final double[] values,final int begin, final int length) { +155 if (test(values, begin, length)) { +156 Sum sum = new Sum(); +157 double sampleSize = length; +158 +159 // Compute initial estimate using definitional formula +160 double xbar = sum.evaluate(values, begin, length) / sampleSize; +161 +162 // Compute correction factor in second pass +163 double correction = 0; +164 for (int i = begin; i < begin + length; i++) { +165 correction += values[i] - xbar; +166 } +167 return xbar + (correction/sampleSize); +168 } +169 return Double.NaN; +170 } +171 +172 /** +173 * Returns the weighted arithmetic mean of the entries in the specified portion of +174 * the input array, or <code>Double.NaN</code> if the designated subarray +175 * is empty. +176 * <p> +177 * Throws <code>IllegalArgumentException</code> if either array is null.</p> +178 * <p> +179 * See {@link Mean} for details on the computing algorithm. The two-pass algorithm +180 * described above is used here, with weights applied in computing both the original +181 * estimate and the correction factor.</p> +182 * <p> +183 * Throws <code>IllegalArgumentException</code> if any of the following are true: +184 * <ul><li>the values array is null</li> +185 * <li>the weights array is null</li> +186 * <li>the weights array does not have the same length as the values array</li> +187 * <li>the weights array contains one or more infinite values</li> +188 * <li>the weights array contains one or more NaN values</li> +189 * <li>the weights array contains negative values</li> +190 * <li>the start and length arguments do not determine a valid array</li> +191 * </ul></p> +192 * +193 * @param values the input array +194 * @param weights the weights array +195 * @param begin index of the first array element to include +196 * @param length the number of elements to include +197 * @return the mean of the values or Double.NaN if length = 0 +198 * @throws IllegalArgumentException if the parameters are not valid +199 * @since 2.1 +200 */ +201 public double evaluate(final double[] values, final double[] weights, +202 final int begin, final int length) { +203 if (test(values, weights, begin, length)) { +204 Sum sum = new Sum(); +205 +206 // Compute initial estimate using definitional formula +207 double sumw = sum.evaluate(weights,begin,length); +208 double xbarw = sum.evaluate(values, weights, begin, length) / sumw; +209 +210 // Compute correction factor in second pass +211 double correction = 0; +212 for (int i = begin; i < begin + length; i++) { +213 correction += weights[i] * (values[i] - xbarw); +214 } +215 return xbarw + (correction/sumw); +216 } +217 return Double.NaN; +218 } +219 +220 /** +221 * Returns the weighted arithmetic mean of the entries in the input array. +222 * <p> +223 * Throws <code>IllegalArgumentException</code> if either array is null.</p> +224 * <p> +225 * See {@link Mean} for details on the computing algorithm. The two-pass algorithm +226 * described above is used here, with weights applied in computing both the original +227 * estimate and the correction factor.</p> +228 * <p> +229 * Throws <code>IllegalArgumentException</code> if any of the following are true: +230 * <ul><li>the values array is null</li> +231 * <li>the weights array is null</li> +232 * <li>the weights array does not have the same length as the values array</li> +233 * <li>the weights array contains one or more infinite values</li> +234 * <li>the weights array contains one or more NaN values</li> +235 * <li>the weights array contains negative values</li> +236 * </ul></p> +237 * +238 * @param values the input array +239 * @param weights the weights array +240 * @return the mean of the values or Double.NaN if length = 0 +241 * @throws IllegalArgumentException if the parameters are not valid +242 * @since 2.1 +243 */ +244 public double evaluate(final double[] values, final double[] weights) { +245 return evaluate(values, weights, 0, values.length); +246 } +247 +248 /** +249 * {@inheritDoc} +250 */ +251 @Override +252 public Mean copy() { +253 Mean result = new Mean(); +254 copy(this, result); +255 return result; +256 } +257 +258 +259 /** +260 * Copies source to dest. +261 * <p>Neither source nor dest can be null.</p> +262 * +263 * @param source Mean to copy +264 * @param dest Mean to copy to +265 * @throws NullPointerException if either source or dest is null +266 */ +267 public static void copy(Mean source, Mean dest) { +268 dest.incMoment = source.incMoment; +269 dest.moment = source.moment.copy(); +270 } +271 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/SecondMoment.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/SecondMoment.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,190 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.moment; +018 +019 import java.io.Serializable; +020 +021 /** +022 * Computes a statistic related to the Second Central Moment. Specifically, +023 * what is computed is the sum of squared deviations from the sample mean. +024 * <p> +025 * The following recursive updating formula is used:</p> +026 * <p> +027 * Let <ul> +028 * <li> dev = (current obs - previous mean) </li> +029 * <li> n = number of observations (including current obs) </li> +030 * </ul> +031 * Then</p> +032 * <p> +033 * new value = old value + dev^2 * (n -1) / n.</p> +034 * <p> +035 * Returns <code>Double.NaN</code> if no data values have been added and +036 * returns <code>0</code> if there is just one value in the data set.</p> +037 * <p> +038 * <strong>Note that this implementation is not synchronized.</strong> If +039 * multiple threads access an instance of this class concurrently, and at least +040 * one of the threads invokes the <code>increment()</code> or +041 * <code>clear()</code> method, it must be synchronized externally.</p> +042 * +043 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +044 */ +045 public class SecondMoment extends FirstMoment implements Serializable { +046 +047 /** Serializable version identifier */ +048 private static final long serialVersionUID = 3942403127395076445L; +049 +050 /** second moment of values that have been added */ +051 protected double m2; +052 +053 /** +054 * Create a SecondMoment instance +055 */ +056 public SecondMoment() { +057 super(); +058 m2 = Double.NaN; +059 } +060 +061 /** +062 * Copy constructor, creates a new {@code SecondMoment} identical +063 * to the {@code original} +064 * +065 * @param original the {@code SecondMoment} instance to copy +066 */ +067 public SecondMoment(SecondMoment original) { +068 super(original); +069 this.m2 = original.m2; +070 } +071 +072 /** +073 * {@inheritDoc} +074 */ +075 @Override +076 public void increment(final double d) { +077 if (n < 1) { +078 m1 = m2 = 0.0; +079 } +080 super.increment(d); +081 m2 += ((double) n - 1) * dev * nDev; +082 } +083 +084 /** +085 * {@inheritDoc} +086 */ +087 @Override +088 public void clear() { +089 super.clear(); +090 m2 = Double.NaN; +091 } +092 +093 /** +094 * {@inheritDoc} +095 */ +096 @Override +097 public double getResult() { +098 return m2; +099 } +100 +101 /** +102 * {@inheritDoc} +103 */ +104 @Override +105 public SecondMoment copy() { +106 SecondMoment result = new SecondMoment(); +107 copy(this, result); +108 return result; +109 } +110 +111 /** +112 * Copies source to dest. +113 * <p>Neither source nor dest can be null.</p> +114 * +115 * @param source SecondMoment to copy +116 * @param dest SecondMoment to copy to +117 * @throws NullPointerException if either source or dest is null +118 */ +119 public static void copy(SecondMoment source, SecondMoment dest) { +120 FirstMoment.copy(source, dest); +121 dest.m2 = source.m2; +122 } +123 +124 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/SemiVariance.Direction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/SemiVariance.Direction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,443 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.stat.descriptive.moment; +019 +020 import java.io.Serializable; +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.stat.descriptive.AbstractUnivariateStatistic; +023 +024 /** +025 * <p>Computes the semivariance of a set of values with respect to a given cutoff value. +026 * We define the <i>downside semivariance</i> of a set of values <code>x</code> +027 * against the <i>cutoff value</i> <code>cutoff</code> to be <br/> +028 * <code>Σ (x[i] - target)<sup>2</sup> / df</code> <br/> +029 * where the sum is taken over all <code>i</code> such that <code>x[i] < cutoff</code> +030 * and <code>df</code> is the length of <code>x</code> (non-bias-corrected) or +031 * one less than this number (bias corrected). The <i>upside semivariance</i> +032 * is defined similarly, with the sum taken over values of <code>x</code> that +033 * exceed the cutoff value.</p> +034 * +035 * <p>The cutoff value defaults to the mean, bias correction defaults to <code>true</code> +036 * and the "variance direction" (upside or downside) defaults to downside. The variance direction +037 * and bias correction may be set using property setters or their values can provided as +038 * parameters to {@link #evaluate(double[], double, Direction, boolean, int, int)}.</p> +039 * +040 * <p>If the input array is null, <code>evaluate</code> methods throw +041 * <code>IllegalArgumentException.</code> If the array has length 1, <code>0</code> +042 * is returned, regardless of the value of the <code>cutoff.</code> +043 * +044 * <p><strong>Note that this class is not intended to be threadsafe.</strong> If +045 * multiple threads access an instance of this class concurrently, and one or +046 * more of these threads invoke property setters, external synchronization must +047 * be provided to ensure correct results.</p> +048 * +049 * @version $Revision: 917275 $ $Date: 2010-02-28 14:43:11 -0500 (Sun, 28 Feb 2010) $ +050 * @since 2.1 +051 */ +052 +053 public class SemiVariance extends AbstractUnivariateStatistic implements Serializable { +054 +055 /** +056 * The UPSIDE Direction is used to specify that the observations above the +057 * cutoff point will be used to calculate SemiVariance. +058 */ +059 public static final Direction UPSIDE_VARIANCE = Direction.UPSIDE; +060 +061 /** +062 * The DOWNSIDE Direction is used to specify that the observations below +063 * the cutoff point will be used to calculate SemiVariance +064 */ +065 public static final Direction DOWNSIDE_VARIANCE = Direction.DOWNSIDE; +066 +067 /** Serializable version identifier */ +068 private static final long serialVersionUID = -2653430366886024994L; +069 +070 /** +071 * Determines whether or not bias correction is applied when computing the +072 * value of the statisic. True means that bias is corrected. +073 */ +074 private boolean biasCorrected = true; +075 +076 /** +077 * Determines whether to calculate downside or upside SemiVariance. +078 */ +079 private Direction varianceDirection = Direction.DOWNSIDE; +080 +081 /** +082 * Constructs a SemiVariance with default (true) <code>biasCorrected</code> +083 * property and default (Downside) <code>varianceDirection</code> property. +084 */ +085 public SemiVariance() { +086 } +087 +088 /** +089 * Constructs a SemiVariance with the specified <code>biasCorrected</code> +090 * property and default (Downside) <code>varianceDirection</code> property. +091 * +092 * @param biasCorrected setting for bias correction - true means +093 * bias will be corrected and is equivalent to using the argumentless +094 * constructor +095 */ +096 public SemiVariance(final boolean biasCorrected) { +097 this.biasCorrected = biasCorrected; +098 } +099 +100 +101 /** +102 * Constructs a SemiVariance with the specified <code>Direction</code> property +103 * and default (true) <code>biasCorrected</code> property +104 * +105 * @param direction setting for the direction of the SemiVariance +106 * to calculate +107 */ +108 public SemiVariance(final Direction direction) { +109 this.varianceDirection = direction; +110 } +111 +112 +113 /** +114 * Constructs a SemiVariance with the specified <code>isBiasCorrected</code> +115 * property and the specified <code>Direction</code> property. +116 * +117 * @param corrected setting for bias correction - true means +118 * bias will be corrected and is equivalent to using the argumentless +119 * constructor +120 * +121 * @param direction setting for the direction of the SemiVariance +122 * to calculate +123 */ +124 public SemiVariance(final boolean corrected, final Direction direction) { +125 this.biasCorrected = corrected; +126 this.varianceDirection = direction; +127 } +128 +129 +130 /** +131 * Copy constructor, creates a new {@code SemiVariance} identical +132 * to the {@code original} +133 * +134 * @param original the {@code SemiVariance} instance to copy +135 */ +136 public SemiVariance(final SemiVariance original) { +137 copy(original, this); +138 } +139 +140 +141 /** +142 * {@inheritDoc} +143 */ +144 @Override +145 public SemiVariance copy() { +146 SemiVariance result = new SemiVariance(); +147 copy(this, result); +148 return result; +149 } +150 +151 +152 /** +153 * Copies source to dest. +154 * <p>Neither source nor dest can be null.</p> +155 * +156 * @param source SemiVariance to copy +157 * @param dest SemiVariance to copy to +158 * @throws NullPointerException if either source or dest is null +159 */ +160 public static void copy(final SemiVariance source, SemiVariance dest) { +161 dest.biasCorrected = source.biasCorrected; +162 dest.varianceDirection = source.varianceDirection; +163 } +164 +165 +166 /** +167 * This method calculates {@link SemiVariance} for the entire array against the mean, using +168 * instance properties varianceDirection and biasCorrection. +169 * +170 * @param values the input array +171 * @return the SemiVariance +172 * @throws IllegalArgumentException if values is null +173 * +174 */ +175 @Override +176 public double evaluate(final double[] values) { +177 if (values == null) { +178 throw MathRuntimeException.createIllegalArgumentException("input values array is null"); +179 } +180 return evaluate(values, 0, values.length); +181 } +182 +183 +184 /** +185 * <p>Returns the {@link SemiVariance} of the designated values against the mean, using +186 * instance properties varianceDirection and biasCorrection.</p> +187 * +188 * <p>Returns <code>NaN</code> if the array is empty and throws +189 * <code>IllegalArgumentException</code> if the array is null.</p> +190 * +191 * @param values the input array +192 * @param start index of the first array element to include +193 * @param length the number of elements to include +194 * @return the SemiVariance +195 * @throws IllegalArgumentException if the parameters are not valid +196 * +197 */ +198 @Override +199 public double evaluate(final double[] values, final int start, final int length) { +200 double m = (new Mean()).evaluate(values, start, length); +201 return evaluate(values, m, varianceDirection, biasCorrected, 0, values.length); +202 } +203 +204 +205 /** +206 * This method calculates {@link SemiVariance} for the entire array against the mean, using +207 * the current value of the biasCorrection instance property. +208 * +209 * @param values the input array +210 * @param direction the {@link Direction} of the semivariance +211 * @return the SemiVariance +212 * @throws IllegalArgumentException if values is null +213 * +214 */ +215 public double evaluate(final double[] values, Direction direction) { +216 double m = (new Mean()).evaluate(values); +217 return evaluate (values, m, direction, biasCorrected, 0, values.length); +218 } +219 +220 /** +221 * <p>Returns the {@link SemiVariance} of the designated values against the cutoff, using +222 * instance properties variancDirection and biasCorrection.</p> +223 * +224 * <p>Returns <code>NaN</code> if the array is empty and throws +225 * <code>IllegalArgumentException</code> if the array is null.</p> +226 * +227 * @param values the input array +228 * @param cutoff the reference point +229 * @return the SemiVariance +230 * @throws IllegalArgumentException if values is null +231 */ +232 public double evaluate(final double[] values, final double cutoff) { +233 return evaluate(values, cutoff, varianceDirection, biasCorrected, 0, values.length); +234 } +235 +236 /** +237 * <p>Returns the {@link SemiVariance} of the designated values against the cutoff in the +238 * given direction, using the current value of the biasCorrection instance property.</p> +239 * +240 * <p>Returns <code>NaN</code> if the array is empty and throws +241 * <code>IllegalArgumentException</code> if the array is null.</p> +242 * +243 * @param values the input array +244 * @param cutoff the reference point +245 * @param direction the {@link Direction} of the semivariance +246 * @return the SemiVariance +247 * @throws IllegalArgumentException if values is null +248 */ +249 public double evaluate(final double[] values, final double cutoff, final Direction direction) { +250 return evaluate(values, cutoff, direction, biasCorrected, 0, values.length); +251 } +252 +253 +254 /** +255 * <p>Returns the {@link SemiVariance} of the designated values against the cutoff +256 * in the given direction with the provided bias correction.</p> +257 * +258 * <p>Returns <code>NaN</code> if the array is empty and throws +259 * <code>IllegalArgumentException</code> if the array is null.</p> +260 * +261 * @param values the input array +262 * @param cutoff the reference point +263 * @param direction the {@link Direction} of the semivariance +264 * @param corrected the BiasCorrection flag +265 * @param start index of the first array element to include +266 * @param length the number of elements to include +267 * @return the SemiVariance +268 * @throws IllegalArgumentException if the parameters are not valid +269 * +270 */ +271 public double evaluate (final double[] values, final double cutoff, final Direction direction, +272 final boolean corrected, final int start, final int length) { +273 +274 test(values, start, length); +275 if (values.length == 0) { +276 return Double.NaN; +277 } else { +278 if (values.length == 1) { +279 return 0.0; +280 } else { +281 final boolean booleanDirection = direction.getDirection(); +282 +283 double dev = 0.0; +284 double sumsq = 0.0; +285 for (int i = start; i < length; i++) { +286 if ((values[i] > cutoff) == booleanDirection) { +287 dev = values[i] - cutoff; +288 sumsq += dev * dev; +289 } +290 } +291 +292 if (corrected) { +293 return sumsq / (length - 1.0); +294 } else { +295 return sumsq / length; +296 } +297 } +298 } +299 } +300 +301 /** +302 * Returns true iff biasCorrected property is set to true. +303 * +304 * @return the value of biasCorrected. +305 */ +306 public boolean isBiasCorrected() { +307 return biasCorrected; +308 } +309 +310 /** +311 * Sets the biasCorrected property. +312 * +313 * @param biasCorrected new biasCorrected property value +314 */ +315 public void setBiasCorrected(boolean biasCorrected) { +316 this.biasCorrected = biasCorrected; +317 } +318 +319 /** +320 * Returns the varianceDirection property. +321 * +322 * @return the varianceDirection +323 */ +324 public Direction getVarianceDirection () { +325 return varianceDirection; +326 } +327 +328 /** +329 * Sets the variance direction +330 * +331 * @param varianceDirection the direction of the semivariance +332 */ +333 public void setVarianceDirection(Direction varianceDirection) { +334 this.varianceDirection = varianceDirection; +335 } +336 +337 /** +338 * The direction of the semivariance - either upside or downside. The direction +339 * is represented by boolean, with true corresponding to UPSIDE semivariance. +340 */ +341 public enum Direction { +342 /** +343 * The UPSIDE Direction is used to specify that the observations above the +344 * cutoff point will be used to calculate SemiVariance +345 */ +346 UPSIDE (true), +347 +348 /** +349 * The DOWNSIDE Direction is used to specify that the observations below +350 * the cutoff point will be used to calculate SemiVariance +351 */ +352 DOWNSIDE (false); +353 +354 /** +355 * boolean value UPSIDE <-> true +356 */ +357 private boolean direction; +358 +359 /** +360 * Create a Direction with the given value. +361 * +362 * @param b boolean value representing the Direction. True corresponds to UPSIDE. +363 */ +364 Direction (boolean b) { +365 direction = b; +366 } +367 +368 /** +369 * Returns the value of this Direction. True corresponds to UPSIDE. +370 * +371 * @return true if direction is UPSIDE; false otherwise +372 */ +373 boolean getDirection () { +374 return direction; +375 } +376 } +377 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/SemiVariance.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/SemiVariance.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,443 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.stat.descriptive.moment; +019 +020 import java.io.Serializable; +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.stat.descriptive.AbstractUnivariateStatistic; +023 +024 /** +025 * <p>Computes the semivariance of a set of values with respect to a given cutoff value. +026 * We define the <i>downside semivariance</i> of a set of values <code>x</code> +027 * against the <i>cutoff value</i> <code>cutoff</code> to be <br/> +028 * <code>Σ (x[i] - target)<sup>2</sup> / df</code> <br/> +029 * where the sum is taken over all <code>i</code> such that <code>x[i] < cutoff</code> +030 * and <code>df</code> is the length of <code>x</code> (non-bias-corrected) or +031 * one less than this number (bias corrected). The <i>upside semivariance</i> +032 * is defined similarly, with the sum taken over values of <code>x</code> that +033 * exceed the cutoff value.</p> +034 * +035 * <p>The cutoff value defaults to the mean, bias correction defaults to <code>true</code> +036 * and the "variance direction" (upside or downside) defaults to downside. The variance direction +037 * and bias correction may be set using property setters or their values can provided as +038 * parameters to {@link #evaluate(double[], double, Direction, boolean, int, int)}.</p> +039 * +040 * <p>If the input array is null, <code>evaluate</code> methods throw +041 * <code>IllegalArgumentException.</code> If the array has length 1, <code>0</code> +042 * is returned, regardless of the value of the <code>cutoff.</code> +043 * +044 * <p><strong>Note that this class is not intended to be threadsafe.</strong> If +045 * multiple threads access an instance of this class concurrently, and one or +046 * more of these threads invoke property setters, external synchronization must +047 * be provided to ensure correct results.</p> +048 * +049 * @version $Revision: 917275 $ $Date: 2010-02-28 14:43:11 -0500 (Sun, 28 Feb 2010) $ +050 * @since 2.1 +051 */ +052 +053 public class SemiVariance extends AbstractUnivariateStatistic implements Serializable { +054 +055 /** +056 * The UPSIDE Direction is used to specify that the observations above the +057 * cutoff point will be used to calculate SemiVariance. +058 */ +059 public static final Direction UPSIDE_VARIANCE = Direction.UPSIDE; +060 +061 /** +062 * The DOWNSIDE Direction is used to specify that the observations below +063 * the cutoff point will be used to calculate SemiVariance +064 */ +065 public static final Direction DOWNSIDE_VARIANCE = Direction.DOWNSIDE; +066 +067 /** Serializable version identifier */ +068 private static final long serialVersionUID = -2653430366886024994L; +069 +070 /** +071 * Determines whether or not bias correction is applied when computing the +072 * value of the statisic. True means that bias is corrected. +073 */ +074 private boolean biasCorrected = true; +075 +076 /** +077 * Determines whether to calculate downside or upside SemiVariance. +078 */ +079 private Direction varianceDirection = Direction.DOWNSIDE; +080 +081 /** +082 * Constructs a SemiVariance with default (true) <code>biasCorrected</code> +083 * property and default (Downside) <code>varianceDirection</code> property. +084 */ +085 public SemiVariance() { +086 } +087 +088 /** +089 * Constructs a SemiVariance with the specified <code>biasCorrected</code> +090 * property and default (Downside) <code>varianceDirection</code> property. +091 * +092 * @param biasCorrected setting for bias correction - true means +093 * bias will be corrected and is equivalent to using the argumentless +094 * constructor +095 */ +096 public SemiVariance(final boolean biasCorrected) { +097 this.biasCorrected = biasCorrected; +098 } +099 +100 +101 /** +102 * Constructs a SemiVariance with the specified <code>Direction</code> property +103 * and default (true) <code>biasCorrected</code> property +104 * +105 * @param direction setting for the direction of the SemiVariance +106 * to calculate +107 */ +108 public SemiVariance(final Direction direction) { +109 this.varianceDirection = direction; +110 } +111 +112 +113 /** +114 * Constructs a SemiVariance with the specified <code>isBiasCorrected</code> +115 * property and the specified <code>Direction</code> property. +116 * +117 * @param corrected setting for bias correction - true means +118 * bias will be corrected and is equivalent to using the argumentless +119 * constructor +120 * +121 * @param direction setting for the direction of the SemiVariance +122 * to calculate +123 */ +124 public SemiVariance(final boolean corrected, final Direction direction) { +125 this.biasCorrected = corrected; +126 this.varianceDirection = direction; +127 } +128 +129 +130 /** +131 * Copy constructor, creates a new {@code SemiVariance} identical +132 * to the {@code original} +133 * +134 * @param original the {@code SemiVariance} instance to copy +135 */ +136 public SemiVariance(final SemiVariance original) { +137 copy(original, this); +138 } +139 +140 +141 /** +142 * {@inheritDoc} +143 */ +144 @Override +145 public SemiVariance copy() { +146 SemiVariance result = new SemiVariance(); +147 copy(this, result); +148 return result; +149 } +150 +151 +152 /** +153 * Copies source to dest. +154 * <p>Neither source nor dest can be null.</p> +155 * +156 * @param source SemiVariance to copy +157 * @param dest SemiVariance to copy to +158 * @throws NullPointerException if either source or dest is null +159 */ +160 public static void copy(final SemiVariance source, SemiVariance dest) { +161 dest.biasCorrected = source.biasCorrected; +162 dest.varianceDirection = source.varianceDirection; +163 } +164 +165 +166 /** +167 * This method calculates {@link SemiVariance} for the entire array against the mean, using +168 * instance properties varianceDirection and biasCorrection. +169 * +170 * @param values the input array +171 * @return the SemiVariance +172 * @throws IllegalArgumentException if values is null +173 * +174 */ +175 @Override +176 public double evaluate(final double[] values) { +177 if (values == null) { +178 throw MathRuntimeException.createIllegalArgumentException("input values array is null"); +179 } +180 return evaluate(values, 0, values.length); +181 } +182 +183 +184 /** +185 * <p>Returns the {@link SemiVariance} of the designated values against the mean, using +186 * instance properties varianceDirection and biasCorrection.</p> +187 * +188 * <p>Returns <code>NaN</code> if the array is empty and throws +189 * <code>IllegalArgumentException</code> if the array is null.</p> +190 * +191 * @param values the input array +192 * @param start index of the first array element to include +193 * @param length the number of elements to include +194 * @return the SemiVariance +195 * @throws IllegalArgumentException if the parameters are not valid +196 * +197 */ +198 @Override +199 public double evaluate(final double[] values, final int start, final int length) { +200 double m = (new Mean()).evaluate(values, start, length); +201 return evaluate(values, m, varianceDirection, biasCorrected, 0, values.length); +202 } +203 +204 +205 /** +206 * This method calculates {@link SemiVariance} for the entire array against the mean, using +207 * the current value of the biasCorrection instance property. +208 * +209 * @param values the input array +210 * @param direction the {@link Direction} of the semivariance +211 * @return the SemiVariance +212 * @throws IllegalArgumentException if values is null +213 * +214 */ +215 public double evaluate(final double[] values, Direction direction) { +216 double m = (new Mean()).evaluate(values); +217 return evaluate (values, m, direction, biasCorrected, 0, values.length); +218 } +219 +220 /** +221 * <p>Returns the {@link SemiVariance} of the designated values against the cutoff, using +222 * instance properties variancDirection and biasCorrection.</p> +223 * +224 * <p>Returns <code>NaN</code> if the array is empty and throws +225 * <code>IllegalArgumentException</code> if the array is null.</p> +226 * +227 * @param values the input array +228 * @param cutoff the reference point +229 * @return the SemiVariance +230 * @throws IllegalArgumentException if values is null +231 */ +232 public double evaluate(final double[] values, final double cutoff) { +233 return evaluate(values, cutoff, varianceDirection, biasCorrected, 0, values.length); +234 } +235 +236 /** +237 * <p>Returns the {@link SemiVariance} of the designated values against the cutoff in the +238 * given direction, using the current value of the biasCorrection instance property.</p> +239 * +240 * <p>Returns <code>NaN</code> if the array is empty and throws +241 * <code>IllegalArgumentException</code> if the array is null.</p> +242 * +243 * @param values the input array +244 * @param cutoff the reference point +245 * @param direction the {@link Direction} of the semivariance +246 * @return the SemiVariance +247 * @throws IllegalArgumentException if values is null +248 */ +249 public double evaluate(final double[] values, final double cutoff, final Direction direction) { +250 return evaluate(values, cutoff, direction, biasCorrected, 0, values.length); +251 } +252 +253 +254 /** +255 * <p>Returns the {@link SemiVariance} of the designated values against the cutoff +256 * in the given direction with the provided bias correction.</p> +257 * +258 * <p>Returns <code>NaN</code> if the array is empty and throws +259 * <code>IllegalArgumentException</code> if the array is null.</p> +260 * +261 * @param values the input array +262 * @param cutoff the reference point +263 * @param direction the {@link Direction} of the semivariance +264 * @param corrected the BiasCorrection flag +265 * @param start index of the first array element to include +266 * @param length the number of elements to include +267 * @return the SemiVariance +268 * @throws IllegalArgumentException if the parameters are not valid +269 * +270 */ +271 public double evaluate (final double[] values, final double cutoff, final Direction direction, +272 final boolean corrected, final int start, final int length) { +273 +274 test(values, start, length); +275 if (values.length == 0) { +276 return Double.NaN; +277 } else { +278 if (values.length == 1) { +279 return 0.0; +280 } else { +281 final boolean booleanDirection = direction.getDirection(); +282 +283 double dev = 0.0; +284 double sumsq = 0.0; +285 for (int i = start; i < length; i++) { +286 if ((values[i] > cutoff) == booleanDirection) { +287 dev = values[i] - cutoff; +288 sumsq += dev * dev; +289 } +290 } +291 +292 if (corrected) { +293 return sumsq / (length - 1.0); +294 } else { +295 return sumsq / length; +296 } +297 } +298 } +299 } +300 +301 /** +302 * Returns true iff biasCorrected property is set to true. +303 * +304 * @return the value of biasCorrected. +305 */ +306 public boolean isBiasCorrected() { +307 return biasCorrected; +308 } +309 +310 /** +311 * Sets the biasCorrected property. +312 * +313 * @param biasCorrected new biasCorrected property value +314 */ +315 public void setBiasCorrected(boolean biasCorrected) { +316 this.biasCorrected = biasCorrected; +317 } +318 +319 /** +320 * Returns the varianceDirection property. +321 * +322 * @return the varianceDirection +323 */ +324 public Direction getVarianceDirection () { +325 return varianceDirection; +326 } +327 +328 /** +329 * Sets the variance direction +330 * +331 * @param varianceDirection the direction of the semivariance +332 */ +333 public void setVarianceDirection(Direction varianceDirection) { +334 this.varianceDirection = varianceDirection; +335 } +336 +337 /** +338 * The direction of the semivariance - either upside or downside. The direction +339 * is represented by boolean, with true corresponding to UPSIDE semivariance. +340 */ +341 public enum Direction { +342 /** +343 * The UPSIDE Direction is used to specify that the observations above the +344 * cutoff point will be used to calculate SemiVariance +345 */ +346 UPSIDE (true), +347 +348 /** +349 * The DOWNSIDE Direction is used to specify that the observations below +350 * the cutoff point will be used to calculate SemiVariance +351 */ +352 DOWNSIDE (false); +353 +354 /** +355 * boolean value UPSIDE <-> true +356 */ +357 private boolean direction; +358 +359 /** +360 * Create a Direction with the given value. +361 * +362 * @param b boolean value representing the Direction. True corresponds to UPSIDE. +363 */ +364 Direction (boolean b) { +365 direction = b; +366 } +367 +368 /** +369 * Returns the value of this Direction. True corresponds to UPSIDE. +370 * +371 * @return true if direction is UPSIDE; false otherwise +372 */ +373 boolean getDirection () { +374 return direction; +375 } +376 } +377 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/Skewness.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/Skewness.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,277 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.moment; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; +022 +023 /** +024 * Computes the skewness of the available values. +025 * <p> +026 * We use the following (unbiased) formula to define skewness:</p> +027 * <p> +028 * skewness = [n / (n -1) (n - 2)] sum[(x_i - mean)^3] / std^3 </p> +029 * <p> +030 * where n is the number of values, mean is the {@link Mean} and std is the +031 * {@link StandardDeviation} </p> +032 * <p> +033 * <strong>Note that this implementation is not synchronized.</strong> If +034 * multiple threads access an instance of this class concurrently, and at least +035 * one of the threads invokes the <code>increment()</code> or +036 * <code>clear()</code> method, it must be synchronized externally. </p> +037 * +038 * @version $Revision: 811833 $ $Date: 2009-09-06 12:27:50 -0400 (Sun, 06 Sep 2009) $ +039 */ +040 public class Skewness extends AbstractStorelessUnivariateStatistic implements Serializable { +041 +042 /** Serializable version identifier */ +043 private static final long serialVersionUID = 7101857578996691352L; +044 +045 /** Third moment on which this statistic is based */ +046 protected ThirdMoment moment = null; +047 +048 /** +049 * Determines whether or not this statistic can be incremented or cleared. +050 * <p> +051 * Statistics based on (constructed from) external moments cannot +052 * be incremented or cleared.</p> +053 */ +054 protected boolean incMoment; +055 +056 /** +057 * Constructs a Skewness +058 */ +059 public Skewness() { +060 incMoment = true; +061 moment = new ThirdMoment(); +062 } +063 +064 /** +065 * Constructs a Skewness with an external moment +066 * @param m3 external moment +067 */ +068 public Skewness(final ThirdMoment m3) { +069 incMoment = false; +070 this.moment = m3; +071 } +072 +073 /** +074 * Copy constructor, creates a new {@code Skewness} identical +075 * to the {@code original} +076 * +077 * @param original the {@code Skewness} instance to copy +078 */ +079 public Skewness(Skewness original) { +080 copy(original, this); +081 } +082 +083 /** +084 * {@inheritDoc} +085 */ +086 @Override +087 public void increment(final double d) { +088 if (incMoment) { +089 moment.increment(d); +090 } +091 } +092 +093 /** +094 * Returns the value of the statistic based on the values that have been added. +095 * <p> +096 * See {@link Skewness} for the definition used in the computation.</p> +097 * +098 * @return the skewness of the available values. +099 */ +100 @Override +101 public double getResult() { +102 +103 if (moment.n < 3) { +104 return Double.NaN; +105 } +106 double variance = moment.m2 / (moment.n - 1); +107 if (variance < 10E-20) { +108 return 0.0d; +109 } else { +110 double n0 = moment.getN(); +111 return (n0 * moment.m3) / +112 ((n0 - 1) * (n0 -2) * Math.sqrt(variance) * variance); +113 } +114 } +115 +116 /** +117 * {@inheritDoc} +118 */ +119 public long getN() { +120 return moment.getN(); +121 } +122 +123 /** +124 * {@inheritDoc} +125 */ +126 @Override +127 public void clear() { +128 if (incMoment) { +129 moment.clear(); +130 } +131 } +132 +133 /** +134 * Returns the Skewness of the entries in the specifed portion of the +135 * input array. +136 * <p> +137 * See {@link Skewness} for the definition used in the computation.</p> +138 * <p> +139 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +140 * +141 * @param values the input array +142 * @param begin the index of the first array element to include +143 * @param length the number of elements to include +144 * @return the skewness of the values or Double.NaN if length is less than +145 * 3 +146 * @throws IllegalArgumentException if the array is null or the array index +147 * parameters are not valid +148 */ +149 @Override +150 public double evaluate(final double[] values,final int begin, +151 final int length) { +152 +153 // Initialize the skewness +154 double skew = Double.NaN; +155 +156 if (test(values, begin, length) && length > 2 ){ +157 Mean mean = new Mean(); +158 // Get the mean and the standard deviation +159 double m = mean.evaluate(values, begin, length); +160 +161 // Calc the std, this is implemented here instead +162 // of using the standardDeviation method eliminate +163 // a duplicate pass to get the mean +164 double accum = 0.0; +165 double accum2 = 0.0; +166 for (int i = begin; i < begin + length; i++) { +167 final double d = values[i] - m; +168 accum += d * d; +169 accum2 += d; +170 } +171 final double variance = (accum - (accum2 * accum2 / length)) / (length - 1); +172 +173 double accum3 = 0.0; +174 for (int i = begin; i < begin + length; i++) { +175 final double d = values[i] - m; +176 accum3 += d * d * d; +177 } +178 accum3 /= variance * Math.sqrt(variance); +179 +180 // Get N +181 double n0 = length; +182 +183 // Calculate skewness +184 skew = (n0 / ((n0 - 1) * (n0 - 2))) * accum3; +185 } +186 return skew; +187 } +188 +189 /** +190 * {@inheritDoc} +191 */ +192 @Override +193 public Skewness copy() { +194 Skewness result = new Skewness(); +195 copy(this, result); +196 return result; +197 } +198 +199 /** +200 * Copies source to dest. +201 * <p>Neither source nor dest can be null.</p> +202 * +203 * @param source Skewness to copy +204 * @param dest Skewness to copy to +205 * @throws NullPointerException if either source or dest is null +206 */ +207 public static void copy(Skewness source, Skewness dest) { +208 dest.moment = new ThirdMoment(source.moment.copy()); +209 dest.incMoment = source.incMoment; +210 } +211 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/StandardDeviation.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/StandardDeviation.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,335 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.moment; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; +022 +023 /** +024 * Computes the sample standard deviation. The standard deviation +025 * is the positive square root of the variance. This implementation wraps a +026 * {@link Variance} instance. The <code>isBiasCorrected</code> property of the +027 * wrapped Variance instance is exposed, so that this class can be used to +028 * compute both the "sample standard deviation" (the square root of the +029 * bias-corrected "sample variance") or the "population standard deviation" +030 * (the square root of the non-bias-corrected "population variance"). See +031 * {@link Variance} for more information. +032 * <p> +033 * <strong>Note that this implementation is not synchronized.</strong> If +034 * multiple threads access an instance of this class concurrently, and at least +035 * one of the threads invokes the <code>increment()</code> or +036 * <code>clear()</code> method, it must be synchronized externally.</p> +037 * +038 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +039 */ +040 public class StandardDeviation extends AbstractStorelessUnivariateStatistic +041 implements Serializable { +042 +043 /** Serializable version identifier */ +044 private static final long serialVersionUID = 5728716329662425188L; +045 +046 /** Wrapped Variance instance */ +047 private Variance variance = null; +048 +049 /** +050 * Constructs a StandardDeviation. Sets the underlying {@link Variance} +051 * instance's <code>isBiasCorrected</code> property to true. +052 */ +053 public StandardDeviation() { +054 variance = new Variance(); +055 } +056 +057 /** +058 * Constructs a StandardDeviation from an external second moment. +059 * +060 * @param m2 the external moment +061 */ +062 public StandardDeviation(final SecondMoment m2) { +063 variance = new Variance(m2); +064 } +065 +066 /** +067 * Copy constructor, creates a new {@code StandardDeviation} identical +068 * to the {@code original} +069 * +070 * @param original the {@code StandardDeviation} instance to copy +071 */ +072 public StandardDeviation(StandardDeviation original) { +073 copy(original, this); +074 } +075 +076 /** +077 * Contructs a StandardDeviation with the specified value for the +078 * <code>isBiasCorrected</code> property. If this property is set to +079 * <code>true</code>, the {@link Variance} used in computing results will +080 * use the bias-corrected, or "sample" formula. See {@link Variance} for +081 * details. +082 * +083 * @param isBiasCorrected whether or not the variance computation will use +084 * the bias-corrected formula +085 */ +086 public StandardDeviation(boolean isBiasCorrected) { +087 variance = new Variance(isBiasCorrected); +088 } +089 +090 /** +091 * Contructs a StandardDeviation with the specified value for the +092 * <code>isBiasCorrected</code> property and the supplied external moment. +093 * If <code>isBiasCorrected</code> is set to <code>true</code>, the +094 * {@link Variance} used in computing results will use the bias-corrected, +095 * or "sample" formula. See {@link Variance} for details. +096 * +097 * @param isBiasCorrected whether or not the variance computation will use +098 * the bias-corrected formula +099 * @param m2 the external moment +100 */ +101 public StandardDeviation(boolean isBiasCorrected, SecondMoment m2) { +102 variance = new Variance(isBiasCorrected, m2); +103 } +104 +105 /** +106 * {@inheritDoc} +107 */ +108 @Override +109 public void increment(final double d) { +110 variance.increment(d); +111 } +112 +113 /** +114 * {@inheritDoc} +115 */ +116 public long getN() { +117 return variance.getN(); +118 } +119 +120 /** +121 * {@inheritDoc} +122 */ +123 @Override +124 public double getResult() { +125 return Math.sqrt(variance.getResult()); +126 } +127 +128 /** +129 * {@inheritDoc} +130 */ +131 @Override +132 public void clear() { +133 variance.clear(); +134 } +135 +136 /** +137 * Returns the Standard Deviation of the entries in the input array, or +138 * <code>Double.NaN</code> if the array is empty. +139 * <p> +140 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +141 * <p> +142 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +143 * <p> +144 * Does not change the internal state of the statistic.</p> +145 * +146 * @param values the input array +147 * @return the standard deviation of the values or Double.NaN if length = 0 +148 * @throws IllegalArgumentException if the array is null +149 */ +150 @Override +151 public double evaluate(final double[] values) { +152 return Math.sqrt(variance.evaluate(values)); +153 } +154 +155 /** +156 * Returns the Standard Deviation of the entries in the specified portion of +157 * the input array, or <code>Double.NaN</code> if the designated subarray +158 * is empty. +159 * <p> +160 * Returns 0 for a single-value (i.e. length = 1) sample. </p> +161 * <p> +162 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +163 * <p> +164 * Does not change the internal state of the statistic.</p> +165 * +166 * @param values the input array +167 * @param begin index of the first array element to include +168 * @param length the number of elements to include +169 * @return the standard deviation of the values or Double.NaN if length = 0 +170 * @throws IllegalArgumentException if the array is null or the array index +171 * parameters are not valid +172 */ +173 @Override +174 public double evaluate(final double[] values, final int begin, final int length) { +175 return Math.sqrt(variance.evaluate(values, begin, length)); +176 } +177 +178 /** +179 * Returns the Standard Deviation of the entries in the specified portion of +180 * the input array, using the precomputed mean value. Returns +181 * <code>Double.NaN</code> if the designated subarray is empty. +182 * <p> +183 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +184 * <p> +185 * The formula used assumes that the supplied mean value is the arithmetic +186 * mean of the sample data, not a known population parameter. This method +187 * is supplied only to save computation when the mean has already been +188 * computed.</p> +189 * <p> +190 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +191 * <p> +192 * Does not change the internal state of the statistic.</p> +193 * +194 * @param values the input array +195 * @param mean the precomputed mean value +196 * @param begin index of the first array element to include +197 * @param length the number of elements to include +198 * @return the standard deviation of the values or Double.NaN if length = 0 +199 * @throws IllegalArgumentException if the array is null or the array index +200 * parameters are not valid +201 */ +202 public double evaluate(final double[] values, final double mean, +203 final int begin, final int length) { +204 return Math.sqrt(variance.evaluate(values, mean, begin, length)); +205 } +206 +207 /** +208 * Returns the Standard Deviation of the entries in the input array, using +209 * the precomputed mean value. Returns +210 * <code>Double.NaN</code> if the designated subarray is empty. +211 * <p> +212 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +213 * <p> +214 * The formula used assumes that the supplied mean value is the arithmetic +215 * mean of the sample data, not a known population parameter. This method +216 * is supplied only to save computation when the mean has already been +217 * computed.</p> +218 * <p> +219 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +220 * <p> +221 * Does not change the internal state of the statistic.</p> +222 * +223 * @param values the input array +224 * @param mean the precomputed mean value +225 * @return the standard deviation of the values or Double.NaN if length = 0 +226 * @throws IllegalArgumentException if the array is null +227 */ +228 public double evaluate(final double[] values, final double mean) { +229 return Math.sqrt(variance.evaluate(values, mean)); +230 } +231 +232 /** +233 * @return Returns the isBiasCorrected. +234 */ +235 public boolean isBiasCorrected() { +236 return variance.isBiasCorrected(); +237 } +238 +239 /** +240 * @param isBiasCorrected The isBiasCorrected to set. +241 */ +242 public void setBiasCorrected(boolean isBiasCorrected) { +243 variance.setBiasCorrected(isBiasCorrected); +244 } +245 +246 /** +247 * {@inheritDoc} +248 */ +249 @Override +250 public StandardDeviation copy() { +251 StandardDeviation result = new StandardDeviation(); +252 copy(this, result); +253 return result; +254 } +255 +256 +257 /** +258 * Copies source to dest. +259 * <p>Neither source nor dest can be null.</p> +260 * +261 * @param source StandardDeviation to copy +262 * @param dest StandardDeviation to copy to +263 * @throws NullPointerException if either source or dest is null +264 */ +265 public static void copy(StandardDeviation source, StandardDeviation dest) { +266 dest.variance = source.variance.copy(); +267 } +268 +269 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/ThirdMoment.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/ThirdMoment.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,205 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.moment; +018 +019 import java.io.Serializable; +020 +021 +022 /** +023 * Computes a statistic related to the Third Central Moment. Specifically, +024 * what is computed is the sum of cubed deviations from the sample mean. +025 * <p> +026 * The following recursive updating formula is used:</p> +027 * <p> +028 * Let <ul> +029 * <li> dev = (current obs - previous mean) </li> +030 * <li> m2 = previous value of {@link SecondMoment} </li> +031 * <li> n = number of observations (including current obs) </li> +032 * </ul> +033 * Then</p> +034 * <p> +035 * new value = old value - 3 * (dev/n) * m2 + (n-1) * (n -2) * (dev^3/n^2)</p> +036 * <p> +037 * Returns <code>Double.NaN</code> if no data values have been added and +038 * returns <code>0</code> if there is just one value in the data set.</p> +039 * <p> +040 * <strong>Note that this implementation is not synchronized.</strong> If +041 * multiple threads access an instance of this class concurrently, and at least +042 * one of the threads invokes the <code>increment()</code> or +043 * <code>clear()</code> method, it must be synchronized externally.</p> +044 * +045 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +046 */ +047 public class ThirdMoment extends SecondMoment implements Serializable { +048 +049 /** Serializable version identifier */ +050 private static final long serialVersionUID = -7818711964045118679L; +051 +052 /** third moment of values that have been added */ +053 protected double m3; +054 +055 /** +056 * Square of deviation of most recently added value from previous first +057 * moment, normalized by previous sample size. Retained to prevent +058 * repeated computation in higher order moments. nDevSq = nDev * nDev. +059 */ +060 protected double nDevSq; +061 +062 /** +063 * Create a FourthMoment instance +064 */ +065 public ThirdMoment() { +066 super(); +067 m3 = Double.NaN; +068 nDevSq = Double.NaN; +069 } +070 +071 /** +072 * Copy constructor, creates a new {@code ThirdMoment} identical +073 * to the {@code original} +074 * +075 * @param original the {@code ThirdMoment} instance to copy +076 */ +077 public ThirdMoment(ThirdMoment original) { +078 copy(original, this); +079 } +080 +081 /** +082 * {@inheritDoc} +083 */ +084 @Override +085 public void increment(final double d) { +086 if (n < 1) { +087 m3 = m2 = m1 = 0.0; +088 } +089 +090 double prevM2 = m2; +091 super.increment(d); +092 nDevSq = nDev * nDev; +093 double n0 = n; +094 m3 = m3 - 3.0 * nDev * prevM2 + (n0 - 1) * (n0 - 2) * nDevSq * dev; +095 } +096 +097 /** +098 * {@inheritDoc} +099 */ +100 @Override +101 public double getResult() { +102 return m3; +103 } +104 +105 /** +106 * {@inheritDoc} +107 */ +108 @Override +109 public void clear() { +110 super.clear(); +111 m3 = Double.NaN; +112 nDevSq = Double.NaN; +113 } +114 +115 /** +116 * {@inheritDoc} +117 */ +118 @Override +119 public ThirdMoment copy() { +120 ThirdMoment result = new ThirdMoment(); +121 copy(this, result); +122 return result; +123 } +124 +125 /** +126 * Copies source to dest. +127 * <p>Neither source nor dest can be null.</p> +128 * +129 * @param source ThirdMoment to copy +130 * @param dest ThirdMoment to copy to +131 * @throws NullPointerException if either source or dest is null +132 */ +133 public static void copy(ThirdMoment source, ThirdMoment dest) { +134 SecondMoment.copy(source, dest); +135 dest.m3 = source.m3; +136 dest.nDevSq = source.nDevSq; +137 } +138 +139 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/Variance.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/Variance.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,672 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.moment; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathRuntimeException; +022 import org.apache.commons.math.stat.descriptive.WeightedEvaluation; +023 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; +024 +025 /** +026 * Computes the variance of the available values. By default, the unbiased +027 * "sample variance" definitional formula is used: +028 * <p> +029 * variance = sum((x_i - mean)^2) / (n - 1) </p> +030 * <p> +031 * where mean is the {@link Mean} and <code>n</code> is the number +032 * of sample observations.</p> +033 * <p> +034 * The definitional formula does not have good numerical properties, so +035 * this implementation does not compute the statistic using the definitional +036 * formula. <ul> +037 * <li> The <code>getResult</code> method computes the variance using +038 * updating formulas based on West's algorithm, as described in +039 * <a href="http://doi.acm.org/10.1145/359146.359152"> Chan, T. F. and +040 * J. G. Lewis 1979, <i>Communications of the ACM</i>, +041 * vol. 22 no. 9, pp. 526-531.</a></li> +042 * <li> The <code>evaluate</code> methods leverage the fact that they have the +043 * full array of values in memory to execute a two-pass algorithm. +044 * Specifically, these methods use the "corrected two-pass algorithm" from +045 * Chan, Golub, Levesque, <i>Algorithms for Computing the Sample Variance</i>, +046 * American Statistician, vol. 37, no. 3 (1983) pp. 242-247.</li></ul> +047 * Note that adding values using <code>increment</code> or +048 * <code>incrementAll</code> and then executing <code>getResult</code> will +049 * sometimes give a different, less accurate, result than executing +050 * <code>evaluate</code> with the full array of values. The former approach +051 * should only be used when the full array of values is not available.</p> +052 * <p> +053 * The "population variance" ( sum((x_i - mean)^2) / n ) can also +054 * be computed using this statistic. The <code>isBiasCorrected</code> +055 * property determines whether the "population" or "sample" value is +056 * returned by the <code>evaluate</code> and <code>getResult</code> methods. +057 * To compute population variances, set this property to <code>false.</code> +058 * </p> +059 * <p> +060 * <strong>Note that this implementation is not synchronized.</strong> If +061 * multiple threads access an instance of this class concurrently, and at least +062 * one of the threads invokes the <code>increment()</code> or +063 * <code>clear()</code> method, it must be synchronized externally.</p> +064 * +065 * @version $Revision: 908626 $ $Date: 2010-02-10 13:44:42 -0500 (Wed, 10 Feb 2010) $ +066 */ +067 public class Variance extends AbstractStorelessUnivariateStatistic implements Serializable, WeightedEvaluation { +068 +069 /** Serializable version identifier */ +070 private static final long serialVersionUID = -9111962718267217978L; +071 +072 /** SecondMoment is used in incremental calculation of Variance*/ +073 protected SecondMoment moment = null; +074 +075 /** +076 * Boolean test to determine if this Variance should also increment +077 * the second moment, this evaluates to false when this Variance is +078 * constructed with an external SecondMoment as a parameter. +079 */ +080 protected boolean incMoment = true; +081 +082 /** +083 * Determines whether or not bias correction is applied when computing the +084 * value of the statisic. True means that bias is corrected. See +085 * {@link Variance} for details on the formula. +086 */ +087 private boolean isBiasCorrected = true; +088 +089 /** +090 * Constructs a Variance with default (true) <code>isBiasCorrected</code> +091 * property. +092 */ +093 public Variance() { +094 moment = new SecondMoment(); +095 } +096 +097 /** +098 * Constructs a Variance based on an external second moment. +099 * +100 * @param m2 the SecondMoment (Third or Fourth moments work +101 * here as well.) +102 */ +103 public Variance(final SecondMoment m2) { +104 incMoment = false; +105 this.moment = m2; +106 } +107 +108 /** +109 * Constructs a Variance with the specified <code>isBiasCorrected</code> +110 * property +111 * +112 * @param isBiasCorrected setting for bias correction - true means +113 * bias will be corrected and is equivalent to using the argumentless +114 * constructor +115 */ +116 public Variance(boolean isBiasCorrected) { +117 moment = new SecondMoment(); +118 this.isBiasCorrected = isBiasCorrected; +119 } +120 +121 /** +122 * Constructs a Variance with the specified <code>isBiasCorrected</code> +123 * property and the supplied external second moment. +124 * +125 * @param isBiasCorrected setting for bias correction - true means +126 * bias will be corrected +127 * @param m2 the SecondMoment (Third or Fourth moments work +128 * here as well.) +129 */ +130 public Variance(boolean isBiasCorrected, SecondMoment m2) { +131 incMoment = false; +132 this.moment = m2; +133 this.isBiasCorrected = isBiasCorrected; +134 } +135 +136 /** +137 * Copy constructor, creates a new {@code Variance} identical +138 * to the {@code original} +139 * +140 * @param original the {@code Variance} instance to copy +141 */ +142 public Variance(Variance original) { +143 copy(original, this); +144 } +145 +146 /** +147 * {@inheritDoc} +148 * <p>If all values are available, it is more accurate to use +149 * {@link #evaluate(double[])} rather than adding values one at a time +150 * using this method and then executing {@link #getResult}, since +151 * <code>evaluate</code> leverages the fact that is has the full +152 * list of values together to execute a two-pass algorithm. +153 * See {@link Variance}.</p> +154 */ +155 @Override +156 public void increment(final double d) { +157 if (incMoment) { +158 moment.increment(d); +159 } +160 } +161 +162 /** +163 * {@inheritDoc} +164 */ +165 @Override +166 public double getResult() { +167 if (moment.n == 0) { +168 return Double.NaN; +169 } else if (moment.n == 1) { +170 return 0d; +171 } else { +172 if (isBiasCorrected) { +173 return moment.m2 / (moment.n - 1d); +174 } else { +175 return moment.m2 / (moment.n); +176 } +177 } +178 } +179 +180 /** +181 * {@inheritDoc} +182 */ +183 public long getN() { +184 return moment.getN(); +185 } +186 +187 /** +188 * {@inheritDoc} +189 */ +190 @Override +191 public void clear() { +192 if (incMoment) { +193 moment.clear(); +194 } +195 } +196 +197 /** +198 * Returns the variance of the entries in the input array, or +199 * <code>Double.NaN</code> if the array is empty. +200 * <p> +201 * See {@link Variance} for details on the computing algorithm.</p> +202 * <p> +203 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +204 * <p> +205 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +206 * <p> +207 * Does not change the internal state of the statistic.</p> +208 * +209 * @param values the input array +210 * @return the variance of the values or Double.NaN if length = 0 +211 * @throws IllegalArgumentException if the array is null +212 */ +213 @Override +214 public double evaluate(final double[] values) { +215 if (values == null) { +216 throw MathRuntimeException.createIllegalArgumentException("input values array is null"); +217 } +218 return evaluate(values, 0, values.length); +219 } +220 +221 /** +222 * Returns the variance of the entries in the specified portion of +223 * the input array, or <code>Double.NaN</code> if the designated subarray +224 * is empty. +225 * <p> +226 * See {@link Variance} for details on the computing algorithm.</p> +227 * <p> +228 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +229 * <p> +230 * Does not change the internal state of the statistic.</p> +231 * <p> +232 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +233 * +234 * @param values the input array +235 * @param begin index of the first array element to include +236 * @param length the number of elements to include +237 * @return the variance of the values or Double.NaN if length = 0 +238 * @throws IllegalArgumentException if the array is null or the array index +239 * parameters are not valid +240 */ +241 @Override +242 public double evaluate(final double[] values, final int begin, final int length) { +243 +244 double var = Double.NaN; +245 +246 if (test(values, begin, length)) { +247 clear(); +248 if (length == 1) { +249 var = 0.0; +250 } else if (length > 1) { +251 Mean mean = new Mean(); +252 double m = mean.evaluate(values, begin, length); +253 var = evaluate(values, m, begin, length); +254 } +255 } +256 return var; +257 } +258 +259 /** +260 * <p>Returns the weighted variance of the entries in the specified portion of +261 * the input array, or <code>Double.NaN</code> if the designated subarray +262 * is empty.</p> +263 * <p> +264 * Uses the formula <pre> +265 * Σ(weights[i]*(values[i] - weightedMean)<sup>2</sup>)/(Σ(weights[i]) - 1) +266 * </pre> +267 * where weightedMean is the weighted mean</p> +268 * <p> +269 * This formula will not return the same result as the unweighted variance when all +270 * weights are equal, unless all weights are equal to 1. The formula assumes that +271 * weights are to be treated as "expansion values," as will be the case if for example +272 * the weights represent frequency counts. To normalize weights so that the denominator +273 * in the variance computation equals the length of the input vector minus one, use <pre> +274 * <code>evaluate(values, MathUtils.normalizeArray(weights, values.length)); </code> +275 * </pre> +276 * <p> +277 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +278 * <p> +279 * Throws <code>IllegalArgumentException</code> if any of the following are true: +280 * <ul><li>the values array is null</li> +281 * <li>the weights array is null</li> +282 * <li>the weights array does not have the same length as the values array</li> +283 * <li>the weights array contains one or more infinite values</li> +284 * <li>the weights array contains one or more NaN values</li> +285 * <li>the weights array contains negative values</li> +286 * <li>the start and length arguments do not determine a valid array</li> +287 * </ul></p> +288 * <p> +289 * Does not change the internal state of the statistic.</p> +290 * <p> +291 * Throws <code>IllegalArgumentException</code> if either array is null.</p> +292 * +293 * @param values the input array +294 * @param weights the weights array +295 * @param begin index of the first array element to include +296 * @param length the number of elements to include +297 * @return the weighted variance of the values or Double.NaN if length = 0 +298 * @throws IllegalArgumentException if the parameters are not valid +299 * @since 2.1 +300 */ +301 public double evaluate(final double[] values, final double[] weights, +302 final int begin, final int length) { +303 +304 double var = Double.NaN; +305 +306 if (test(values, weights,begin, length)) { +307 clear(); +308 if (length == 1) { +309 var = 0.0; +310 } else if (length > 1) { +311 Mean mean = new Mean(); +312 double m = mean.evaluate(values, weights, begin, length); +313 var = evaluate(values, weights, m, begin, length); +314 } +315 } +316 return var; +317 } +318 +319 /** +320 * <p> +321 * Returns the weighted variance of the entries in the the input array.</p> +322 * <p> +323 * Uses the formula <pre> +324 * Σ(weights[i]*(values[i] - weightedMean)<sup>2</sup>)/(Σ(weights[i]) - 1) +325 * </pre> +326 * where weightedMean is the weighted mean</p> +327 * <p> +328 * This formula will not return the same result as the unweighted variance when all +329 * weights are equal, unless all weights are equal to 1. The formula assumes that +330 * weights are to be treated as "expansion values," as will be the case if for example +331 * the weights represent frequency counts. To normalize weights so that the denominator +332 * in the variance computation equals the length of the input vector minus one, use <pre> +333 * <code>evaluate(values, MathUtils.normalizeArray(weights, values.length)); </code> +334 * </pre> +335 * <p> +336 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +337 * <p> +338 * Throws <code>IllegalArgumentException</code> if any of the following are true: +339 * <ul><li>the values array is null</li> +340 * <li>the weights array is null</li> +341 * <li>the weights array does not have the same length as the values array</li> +342 * <li>the weights array contains one or more infinite values</li> +343 * <li>the weights array contains one or more NaN values</li> +344 * <li>the weights array contains negative values</li> +345 * </ul></p> +346 * <p> +347 * Does not change the internal state of the statistic.</p> +348 * <p> +349 * Throws <code>IllegalArgumentException</code> if either array is null.</p> +350 * +351 * @param values the input array +352 * @param weights the weights array +353 * @return the weighted variance of the values +354 * @throws IllegalArgumentException if the parameters are not valid +355 * @since 2.1 +356 */ +357 public double evaluate(final double[] values, final double[] weights) { +358 return evaluate(values, weights, 0, values.length); +359 } +360 +361 /** +362 * Returns the variance of the entries in the specified portion of +363 * the input array, using the precomputed mean value. Returns +364 * <code>Double.NaN</code> if the designated subarray is empty. +365 * <p> +366 * See {@link Variance} for details on the computing algorithm.</p> +367 * <p> +368 * The formula used assumes that the supplied mean value is the arithmetic +369 * mean of the sample data, not a known population parameter. This method +370 * is supplied only to save computation when the mean has already been +371 * computed.</p> +372 * <p> +373 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +374 * <p> +375 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +376 * <p> +377 * Does not change the internal state of the statistic.</p> +378 * +379 * @param values the input array +380 * @param mean the precomputed mean value +381 * @param begin index of the first array element to include +382 * @param length the number of elements to include +383 * @return the variance of the values or Double.NaN if length = 0 +384 * @throws IllegalArgumentException if the array is null or the array index +385 * parameters are not valid +386 */ +387 public double evaluate(final double[] values, final double mean, +388 final int begin, final int length) { +389 +390 double var = Double.NaN; +391 +392 if (test(values, begin, length)) { +393 if (length == 1) { +394 var = 0.0; +395 } else if (length > 1) { +396 double accum = 0.0; +397 double dev = 0.0; +398 double accum2 = 0.0; +399 for (int i = begin; i < begin + length; i++) { +400 dev = values[i] - mean; +401 accum += dev * dev; +402 accum2 += dev; +403 } +404 double len = length; +405 if (isBiasCorrected) { +406 var = (accum - (accum2 * accum2 / len)) / (len - 1.0); +407 } else { +408 var = (accum - (accum2 * accum2 / len)) / len; +409 } +410 } +411 } +412 return var; +413 } +414 +415 /** +416 * Returns the variance of the entries in the input array, using the +417 * precomputed mean value. Returns <code>Double.NaN</code> if the array +418 * is empty. +419 * <p> +420 * See {@link Variance} for details on the computing algorithm.</p> +421 * <p> +422 * If <code>isBiasCorrected</code> is <code>true</code> the formula used +423 * assumes that the supplied mean value is the arithmetic mean of the +424 * sample data, not a known population parameter. If the mean is a known +425 * population parameter, or if the "population" version of the variance is +426 * desired, set <code>isBiasCorrected</code> to <code>false</code> before +427 * invoking this method.</p> +428 * <p> +429 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +430 * <p> +431 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +432 * <p> +433 * Does not change the internal state of the statistic.</p> +434 * +435 * @param values the input array +436 * @param mean the precomputed mean value +437 * @return the variance of the values or Double.NaN if the array is empty +438 * @throws IllegalArgumentException if the array is null +439 */ +440 public double evaluate(final double[] values, final double mean) { +441 return evaluate(values, mean, 0, values.length); +442 } +443 +444 /** +445 * Returns the weighted variance of the entries in the specified portion of +446 * the input array, using the precomputed weighted mean value. Returns +447 * <code>Double.NaN</code> if the designated subarray is empty. +448 * <p> +449 * Uses the formula <pre> +450 * Σ(weights[i]*(values[i] - mean)<sup>2</sup>)/(Σ(weights[i]) - 1) +451 * </pre></p> +452 * <p> +453 * The formula used assumes that the supplied mean value is the weighted arithmetic +454 * mean of the sample data, not a known population parameter. This method +455 * is supplied only to save computation when the mean has already been +456 * computed.</p> +457 * <p> +458 * This formula will not return the same result as the unweighted variance when all +459 * weights are equal, unless all weights are equal to 1. The formula assumes that +460 * weights are to be treated as "expansion values," as will be the case if for example +461 * the weights represent frequency counts. To normalize weights so that the denominator +462 * in the variance computation equals the length of the input vector minus one, use <pre> +463 * <code>evaluate(values, MathUtils.normalizeArray(weights, values.length), mean); </code> +464 * </pre> +465 * <p> +466 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +467 * <p> +468 * Throws <code>IllegalArgumentException</code> if any of the following are true: +469 * <ul><li>the values array is null</li> +470 * <li>the weights array is null</li> +471 * <li>the weights array does not have the same length as the values array</li> +472 * <li>the weights array contains one or more infinite values</li> +473 * <li>the weights array contains one or more NaN values</li> +474 * <li>the weights array contains negative values</li> +475 * <li>the start and length arguments do not determine a valid array</li> +476 * </ul></p> +477 * <p> +478 * Does not change the internal state of the statistic.</p> +479 * +480 * @param values the input array +481 * @param weights the weights array +482 * @param mean the precomputed weighted mean value +483 * @param begin index of the first array element to include +484 * @param length the number of elements to include +485 * @return the variance of the values or Double.NaN if length = 0 +486 * @throws IllegalArgumentException if the parameters are not valid +487 * @since 2.1 +488 */ +489 public double evaluate(final double[] values, final double[] weights, +490 final double mean, final int begin, final int length) { +491 +492 double var = Double.NaN; +493 +494 if (test(values, weights, begin, length)) { +495 if (length == 1) { +496 var = 0.0; +497 } else if (length > 1) { +498 double accum = 0.0; +499 double dev = 0.0; +500 double accum2 = 0.0; +501 for (int i = begin; i < begin + length; i++) { +502 dev = values[i] - mean; +503 accum += weights[i] * (dev * dev); +504 accum2 += weights[i] * dev; +505 } +506 +507 double sumWts = 0; +508 for (int i = 0; i < weights.length; i++) { +509 sumWts += weights[i]; +510 } +511 +512 if (isBiasCorrected) { +513 var = (accum - (accum2 * accum2 / sumWts)) / (sumWts - 1.0); +514 } else { +515 var = (accum - (accum2 * accum2 / sumWts)) / sumWts; +516 } +517 } +518 } +519 return var; +520 } +521 +522 /** +523 * <p>Returns the weighted variance of the values in the input array, using +524 * the precomputed weighted mean value.</p> +525 * <p> +526 * Uses the formula <pre> +527 * Σ(weights[i]*(values[i] - mean)<sup>2</sup>)/(Σ(weights[i]) - 1) +528 * </pre></p> +529 * <p> +530 * The formula used assumes that the supplied mean value is the weighted arithmetic +531 * mean of the sample data, not a known population parameter. This method +532 * is supplied only to save computation when the mean has already been +533 * computed.</p> +534 * <p> +535 * This formula will not return the same result as the unweighted variance when all +536 * weights are equal, unless all weights are equal to 1. The formula assumes that +537 * weights are to be treated as "expansion values," as will be the case if for example +538 * the weights represent frequency counts. To normalize weights so that the denominator +539 * in the variance computation equals the length of the input vector minus one, use <pre> +540 * <code>evaluate(values, MathUtils.normalizeArray(weights, values.length), mean); </code> +541 * </pre> +542 * <p> +543 * Returns 0 for a single-value (i.e. length = 1) sample.</p> +544 * <p> +545 * Throws <code>IllegalArgumentException</code> if any of the following are true: +546 * <ul><li>the values array is null</li> +547 * <li>the weights array is null</li> +548 * <li>the weights array does not have the same length as the values array</li> +549 * <li>the weights array contains one or more infinite values</li> +550 * <li>the weights array contains one or more NaN values</li> +551 * <li>the weights array contains negative values</li> +552 * </ul></p> +553 * <p> +554 * Does not change the internal state of the statistic.</p> +555 * +556 * @param values the input array +557 * @param weights the weights array +558 * @param mean the precomputed weighted mean value +559 * @return the variance of the values or Double.NaN if length = 0 +560 * @throws IllegalArgumentException if the parameters are not valid +561 * @since 2.1 +562 */ +563 public double evaluate(final double[] values, final double[] weights, final double mean) { +564 return evaluate(values, weights, mean, 0, values.length); +565 } +566 +567 /** +568 * @return Returns the isBiasCorrected. +569 */ +570 public boolean isBiasCorrected() { +571 return isBiasCorrected; +572 } +573 +574 /** +575 * @param biasCorrected The isBiasCorrected to set. +576 */ +577 public void setBiasCorrected(boolean biasCorrected) { +578 this.isBiasCorrected = biasCorrected; +579 } +580 +581 /** +582 * {@inheritDoc} +583 */ +584 @Override +585 public Variance copy() { +586 Variance result = new Variance(); +587 copy(this, result); +588 return result; +589 } +590 +591 +592 /** +593 * Copies source to dest. +594 * <p>Neither source nor dest can be null.</p> +595 * +596 * @param source Variance to copy +597 * @param dest Variance to copy to +598 * @throws NullPointerException if either source or dest is null +599 */ +600 public static void copy(Variance source, Variance dest) { +601 dest.moment = source.moment.copy(); +602 dest.isBiasCorrected = source.isBiasCorrected; +603 dest.incMoment = source.incMoment; +604 } +605 +606 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/VectorialCovariance.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/VectorialCovariance.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,218 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.moment; +018 +019 import java.io.Serializable; +020 import java.util.Arrays; +021 +022 import org.apache.commons.math.DimensionMismatchException; +023 import org.apache.commons.math.linear.MatrixUtils; +024 import org.apache.commons.math.linear.RealMatrix; +025 +026 /** +027 * Returns the covariance matrix of the available vectors. +028 * @since 1.2 +029 * @version $Revision: 922714 $ $Date: 2010-03-13 20:35:14 -0500 (Sat, 13 Mar 2010) $ +030 */ +031 public class VectorialCovariance implements Serializable { +032 +033 /** Serializable version identifier */ +034 private static final long serialVersionUID = 4118372414238930270L; +035 +036 /** Sums for each component. */ +037 private final double[] sums; +038 +039 /** Sums of products for each component. */ +040 private final double[] productsSums; +041 +042 /** Indicator for bias correction. */ +043 private final boolean isBiasCorrected; +044 +045 /** Number of vectors in the sample. */ +046 private long n; +047 +048 /** Constructs a VectorialCovariance. +049 * @param dimension vectors dimension +050 * @param isBiasCorrected if true, computed the unbiased sample covariance, +051 * otherwise computes the biased population covariance +052 */ +053 public VectorialCovariance(int dimension, boolean isBiasCorrected) { +054 sums = new double[dimension]; +055 productsSums = new double[dimension * (dimension + 1) / 2]; +056 n = 0; +057 this.isBiasCorrected = isBiasCorrected; +058 } +059 +060 /** +061 * Add a new vector to the sample. +062 * @param v vector to add +063 * @exception DimensionMismatchException if the vector does not have the right dimension +064 */ +065 public void increment(double[] v) throws DimensionMismatchException { +066 if (v.length != sums.length) { +067 throw new DimensionMismatchException(v.length, sums.length); +068 } +069 int k = 0; +070 for (int i = 0; i < v.length; ++i) { +071 sums[i] += v[i]; +072 for (int j = 0; j <= i; ++j) { +073 productsSums[k++] += v[i] * v[j]; +074 } +075 } +076 n++; +077 } +078 +079 /** +080 * Get the covariance matrix. +081 * @return covariance matrix +082 */ +083 public RealMatrix getResult() { +084 +085 int dimension = sums.length; +086 RealMatrix result = MatrixUtils.createRealMatrix(dimension, dimension); +087 +088 if (n > 1) { +089 double c = 1.0 / (n * (isBiasCorrected ? (n - 1) : n)); +090 int k = 0; +091 for (int i = 0; i < dimension; ++i) { +092 for (int j = 0; j <= i; ++j) { +093 double e = c * (n * productsSums[k++] - sums[i] * sums[j]); +094 result.setEntry(i, j, e); +095 result.setEntry(j, i, e); +096 } +097 } +098 } +099 +100 return result; +101 +102 } +103 +104 /** +105 * Get the number of vectors in the sample. +106 * @return number of vectors in the sample +107 */ +108 public long getN() { +109 return n; +110 } +111 +112 /** +113 * Clears the internal state of the Statistic +114 */ +115 public void clear() { +116 n = 0; +117 Arrays.fill(sums, 0.0); +118 Arrays.fill(productsSums, 0.0); +119 } +120 +121 /** {@inheritDoc} */ +122 @Override +123 public int hashCode() { +124 final int prime = 31; +125 int result = 1; +126 result = prime * result + (isBiasCorrected ? 1231 : 1237); +127 result = prime * result + (int) (n ^ (n >>> 32)); +128 result = prime * result + Arrays.hashCode(productsSums); +129 result = prime * result + Arrays.hashCode(sums); +130 return result; +131 } +132 +133 /** {@inheritDoc} */ +134 @Override +135 public boolean equals(Object obj) { +136 if (this == obj) +137 return true; +138 if (!(obj instanceof VectorialCovariance)) +139 return false; +140 VectorialCovariance other = (VectorialCovariance) obj; +141 if (isBiasCorrected != other.isBiasCorrected) +142 return false; +143 if (n != other.n) +144 return false; +145 if (!Arrays.equals(productsSums, other.productsSums)) +146 return false; +147 if (!Arrays.equals(sums, other.sums)) +148 return false; +149 return true; +150 } +151 +152 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/VectorialMean.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/moment/VectorialMean.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,169 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.moment; +018 +019 import java.io.Serializable; +020 import java.util.Arrays; +021 +022 import org.apache.commons.math.DimensionMismatchException; +023 +024 /** +025 * Returns the arithmetic mean of the available vectors. +026 * @since 1.2 +027 * @version $Revision: 922714 $ $Date: 2010-03-13 20:35:14 -0500 (Sat, 13 Mar 2010) $ +028 */ +029 public class VectorialMean implements Serializable { +030 +031 /** Serializable version identifier */ +032 private static final long serialVersionUID = 8223009086481006892L; +033 +034 /** Means for each component. */ +035 private final Mean[] means; +036 +037 /** Constructs a VectorialMean. +038 * @param dimension vectors dimension +039 */ +040 public VectorialMean(int dimension) { +041 means = new Mean[dimension]; +042 for (int i = 0; i < dimension; ++i) { +043 means[i] = new Mean(); +044 } +045 } +046 +047 /** +048 * Add a new vector to the sample. +049 * @param v vector to add +050 * @exception DimensionMismatchException if the vector does not have the right dimension +051 */ +052 public void increment(double[] v) throws DimensionMismatchException { +053 if (v.length != means.length) { +054 throw new DimensionMismatchException(v.length, means.length); +055 } +056 for (int i = 0; i < v.length; ++i) { +057 means[i].increment(v[i]); +058 } +059 } +060 +061 /** +062 * Get the mean vector. +063 * @return mean vector +064 */ +065 public double[] getResult() { +066 double[] result = new double[means.length]; +067 for (int i = 0; i < result.length; ++i) { +068 result[i] = means[i].getResult(); +069 } +070 return result; +071 } +072 +073 /** +074 * Get the number of vectors in the sample. +075 * @return number of vectors in the sample +076 */ +077 public long getN() { +078 return (means.length == 0) ? 0 : means[0].getN(); +079 } +080 +081 /** {@inheritDoc} */ +082 @Override +083 public int hashCode() { +084 final int prime = 31; +085 int result = 1; +086 result = prime * result + Arrays.hashCode(means); +087 return result; +088 } +089 +090 /** {@inheritDoc} */ +091 @Override +092 public boolean equals(Object obj) { +093 if (this == obj) +094 return true; +095 if (!(obj instanceof VectorialMean)) +096 return false; +097 VectorialMean other = (VectorialMean) obj; +098 if (!Arrays.equals(means, other.means)) +099 return false; +100 return true; +101 } +102 +103 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/rank/Max.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/rank/Max.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,228 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.rank; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; +022 +023 /** +024 * Returns the maximum of the available values. +025 * <p> +026 * <ul> +027 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code> +028 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li> +029 * <li>If any of the values equals <code>Double.POSITIVE_INFINITY</code>, +030 * the result is <code>Double.POSITIVE_INFINITY.</code></li> +031 * </ul></p> +032 * <p> +033 * <strong>Note that this implementation is not synchronized.</strong> If +034 * multiple threads access an instance of this class concurrently, and at least +035 * one of the threads invokes the <code>increment()</code> or +036 * <code>clear()</code> method, it must be synchronized externally.</p> +037 * +038 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +039 */ +040 public class Max extends AbstractStorelessUnivariateStatistic implements Serializable { +041 +042 /** Serializable version identifier */ +043 private static final long serialVersionUID = -5593383832225844641L; +044 +045 /** Number of values that have been added */ +046 private long n; +047 +048 /** Current value of the statistic */ +049 private double value; +050 +051 /** +052 * Create a Max instance +053 */ +054 public Max() { +055 n = 0; +056 value = Double.NaN; +057 } +058 +059 /** +060 * Copy constructor, creates a new {@code Max} identical +061 * to the {@code original} +062 * +063 * @param original the {@code Max} instance to copy +064 */ +065 public Max(Max original) { +066 copy(original, this); +067 } +068 +069 /** +070 * {@inheritDoc} +071 */ +072 @Override +073 public void increment(final double d) { +074 if (d > value || Double.isNaN(value)) { +075 value = d; +076 } +077 n++; +078 } +079 +080 /** +081 * {@inheritDoc} +082 */ +083 @Override +084 public void clear() { +085 value = Double.NaN; +086 n = 0; +087 } +088 +089 /** +090 * {@inheritDoc} +091 */ +092 @Override +093 public double getResult() { +094 return value; +095 } +096 +097 /** +098 * {@inheritDoc} +099 */ +100 public long getN() { +101 return n; +102 } +103 +104 /** +105 * Returns the maximum of the entries in the specified portion of +106 * the input array, or <code>Double.NaN</code> if the designated subarray +107 * is empty. +108 * <p> +109 * Throws <code>IllegalArgumentException</code> if the array is null or +110 * the array index parameters are not valid.</p> +111 * <p> +112 * <ul> +113 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code> +114 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li> +115 * <li>If any of the values equals <code>Double.POSITIVE_INFINITY</code>, +116 * the result is <code>Double.POSITIVE_INFINITY.</code></li> +117 * </ul></p> +118 * +119 * @param values the input array +120 * @param begin index of the first array element to include +121 * @param length the number of elements to include +122 * @return the maximum of the values or Double.NaN if length = 0 +123 * @throws IllegalArgumentException if the array is null or the array index +124 * parameters are not valid +125 */ +126 @Override +127 public double evaluate(final double[] values, final int begin, final int length) { +128 double max = Double.NaN; +129 if (test(values, begin, length)) { +130 max = values[begin]; +131 for (int i = begin; i < begin + length; i++) { +132 if (!Double.isNaN(values[i])) { +133 max = (max > values[i]) ? max : values[i]; +134 } +135 } +136 } +137 return max; +138 } +139 +140 /** +141 * {@inheritDoc} +142 */ +143 @Override +144 public Max copy() { +145 Max result = new Max(); +146 copy(this, result); +147 return result; +148 } +149 +150 /** +151 * Copies source to dest. +152 * <p>Neither source nor dest can be null.</p> +153 * +154 * @param source Max to copy +155 * @param dest Max to copy to +156 * @throws NullPointerException if either source or dest is null +157 */ +158 public static void copy(Max source, Max dest) { +159 dest.n = source.n; +160 dest.value = source.value; +161 } +162 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/rank/Median.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/rank/Median.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,121 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.rank; +018 +019 import java.io.Serializable; +020 +021 +022 /** +023 * Returns the median of the available values. This is the same as the 50th percentile. +024 * See {@link Percentile} for a description of the algorithm used. +025 * <p> +026 * <strong>Note that this implementation is not synchronized.</strong> If +027 * multiple threads access an instance of this class concurrently, and at least +028 * one of the threads invokes the <code>increment()</code> or +029 * <code>clear()</code> method, it must be synchronized externally.</p> +030 * +031 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +032 */ +033 public class Median extends Percentile implements Serializable { +034 +035 /** Serializable version identifier */ +036 private static final long serialVersionUID = -3961477041290915687L; +037 +038 /** +039 * Default constructor. +040 */ +041 public Median() { +042 super(50.0); +043 } +044 +045 /** +046 * Copy constructor, creates a new {@code Median} identical +047 * to the {@code original} +048 * +049 * @param original the {@code Median} instance to copy +050 */ +051 public Median(Median original) { +052 super(original); +053 } +054 +055 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/rank/Min.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/rank/Min.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,228 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.rank; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; +022 +023 /** +024 * Returns the minimum of the available values. +025 * <p> +026 * <ul> +027 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code> +028 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li> +029 * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>, +030 * the result is <code>Double.NEGATIVE_INFINITY.</code></li> +031 * </ul></p> +032 * <p> +033 * <strong>Note that this implementation is not synchronized.</strong> If +034 * multiple threads access an instance of this class concurrently, and at least +035 * one of the threads invokes the <code>increment()</code> or +036 * <code>clear()</code> method, it must be synchronized externally.</p> +037 * +038 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +039 */ +040 public class Min extends AbstractStorelessUnivariateStatistic implements Serializable { +041 +042 /** Serializable version identifier */ +043 private static final long serialVersionUID = -2941995784909003131L; +044 +045 /**Number of values that have been added */ +046 private long n; +047 +048 /**Current value of the statistic */ +049 private double value; +050 +051 /** +052 * Create a Min instance +053 */ +054 public Min() { +055 n = 0; +056 value = Double.NaN; +057 } +058 +059 /** +060 * Copy constructor, creates a new {@code Min} identical +061 * to the {@code original} +062 * +063 * @param original the {@code Min} instance to copy +064 */ +065 public Min(Min original) { +066 copy(original, this); +067 } +068 +069 /** +070 * {@inheritDoc} +071 */ +072 @Override +073 public void increment(final double d) { +074 if (d < value || Double.isNaN(value)) { +075 value = d; +076 } +077 n++; +078 } +079 +080 /** +081 * {@inheritDoc} +082 */ +083 @Override +084 public void clear() { +085 value = Double.NaN; +086 n = 0; +087 } +088 +089 /** +090 * {@inheritDoc} +091 */ +092 @Override +093 public double getResult() { +094 return value; +095 } +096 +097 /** +098 * {@inheritDoc} +099 */ +100 public long getN() { +101 return n; +102 } +103 +104 /** +105 * Returns the minimum of the entries in the specified portion of +106 * the input array, or <code>Double.NaN</code> if the designated subarray +107 * is empty. +108 * <p> +109 * Throws <code>IllegalArgumentException</code> if the array is null or +110 * the array index parameters are not valid.</p> +111 * <p> +112 * <ul> +113 * <li>The result is <code>NaN</code> iff all values are <code>NaN</code> +114 * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li> +115 * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>, +116 * the result is <code>Double.NEGATIVE_INFINITY.</code></li> +117 * </ul> </p> +118 * +119 * @param values the input array +120 * @param begin index of the first array element to include +121 * @param length the number of elements to include +122 * @return the minimum of the values or Double.NaN if length = 0 +123 * @throws IllegalArgumentException if the array is null or the array index +124 * parameters are not valid +125 */ +126 @Override +127 public double evaluate(final double[] values,final int begin, final int length) { +128 double min = Double.NaN; +129 if (test(values, begin, length)) { +130 min = values[begin]; +131 for (int i = begin; i < begin + length; i++) { +132 if (!Double.isNaN(values[i])) { +133 min = (min < values[i]) ? min : values[i]; +134 } +135 } +136 } +137 return min; +138 } +139 +140 /** +141 * {@inheritDoc} +142 */ +143 @Override +144 public Min copy() { +145 Min result = new Min(); +146 copy(this, result); +147 return result; +148 } +149 +150 /** +151 * Copies source to dest. +152 * <p>Neither source nor dest can be null.</p> +153 * +154 * @param source Min to copy +155 * @param dest Min to copy to +156 * @throws NullPointerException if either source or dest is null +157 */ +158 public static void copy(Min source, Min dest) { +159 dest.n = source.n; +160 dest.value = source.value; +161 } +162 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/rank/Percentile.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/rank/Percentile.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,344 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.rank; +018 +019 import java.io.Serializable; +020 import java.util.Arrays; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.stat.descriptive.AbstractUnivariateStatistic; +024 +025 /** +026 * Provides percentile computation. +027 * <p> +028 * There are several commonly used methods for estimating percentiles (a.k.a. +029 * quantiles) based on sample data. For large samples, the different methods +030 * agree closely, but when sample sizes are small, different methods will give +031 * significantly different results. The algorithm implemented here works as follows: +032 * <ol> +033 * <li>Let <code>n</code> be the length of the (sorted) array and +034 * <code>0 < p <= 100</code> be the desired percentile.</li> +035 * <li>If <code> n = 1 </code> return the unique array element (regardless of +036 * the value of <code>p</code>); otherwise </li> +037 * <li>Compute the estimated percentile position +038 * <code> pos = p * (n + 1) / 100</code> and the difference, <code>d</code> +039 * between <code>pos</code> and <code>floor(pos)</code> (i.e. the fractional +040 * part of <code>pos</code>). If <code>pos >= n</code> return the largest +041 * element in the array; otherwise</li> +042 * <li>Let <code>lower</code> be the element in position +043 * <code>floor(pos)</code> in the array and let <code>upper</code> be the +044 * next element in the array. Return <code>lower + d * (upper - lower)</code> +045 * </li> +046 * </ol></p> +047 * <p> +048 * To compute percentiles, the data must be (totally) ordered. Input arrays +049 * are copied and then sorted using {@link java.util.Arrays#sort(double[])}. +050 * The ordering used by <code>Arrays.sort(double[])</code> is the one determined +051 * by {@link java.lang.Double#compareTo(Double)}. This ordering makes +052 * <code>Double.NaN</code> larger than any other value (including +053 * <code>Double.POSITIVE_INFINITY</code>). Therefore, for example, the median +054 * (50th percentile) of +055 * <code>{0, 1, 2, 3, 4, Double.NaN}</code> evaluates to <code>2.5.</code></p> +056 * <p> +057 * Since percentile estimation usually involves interpolation between array +058 * elements, arrays containing <code>NaN</code> or infinite values will often +059 * result in <code>NaN<code> or infinite values returned.</p> +060 * <p> +061 * <strong>Note that this implementation is not synchronized.</strong> If +062 * multiple threads access an instance of this class concurrently, and at least +063 * one of the threads invokes the <code>increment()</code> or +064 * <code>clear()</code> method, it must be synchronized externally.</p> +065 * +066 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +067 */ +068 public class Percentile extends AbstractUnivariateStatistic implements Serializable { +069 +070 /** Serializable version identifier */ +071 private static final long serialVersionUID = -8091216485095130416L; +072 +073 /** Determines what percentile is computed when evaluate() is activated +074 * with no quantile argument */ +075 private double quantile = 0.0; +076 +077 /** +078 * Constructs a Percentile with a default quantile +079 * value of 50.0. +080 */ +081 public Percentile() { +082 this(50.0); +083 } +084 +085 /** +086 * Constructs a Percentile with the specific quantile value. +087 * @param p the quantile +088 * @throws IllegalArgumentException if p is not greater than 0 and less +089 * than or equal to 100 +090 */ +091 public Percentile(final double p) { +092 setQuantile(p); +093 } +094 +095 /** +096 * Copy constructor, creates a new {@code Percentile} identical +097 * to the {@code original} +098 * +099 * @param original the {@code Percentile} instance to copy +100 */ +101 public Percentile(Percentile original) { +102 copy(original, this); +103 } +104 +105 /** +106 * Returns an estimate of the <code>p</code>th percentile of the values +107 * in the <code>values</code> array. +108 * <p> +109 * Calls to this method do not modify the internal <code>quantile</code> +110 * state of this statistic.</p> +111 * <p> +112 * <ul> +113 * <li>Returns <code>Double.NaN</code> if <code>values</code> has length +114 * <code>0</code></li> +115 * <li>Returns (for any value of <code>p</code>) <code>values[0]</code> +116 * if <code>values</code> has length <code>1</code></li> +117 * <li>Throws <code>IllegalArgumentException</code> if <code>values</code> +118 * is null or p is not a valid quantile value (p must be greater than 0 +119 * and less than or equal to 100) </li> +120 * </ul></p> +121 * <p> +122 * See {@link Percentile} for a description of the percentile estimation +123 * algorithm used.</p> +124 * +125 * @param values input array of values +126 * @param p the percentile value to compute +127 * @return the percentile value or Double.NaN if the array is empty +128 * @throws IllegalArgumentException if <code>values</code> is null +129 * or p is invalid +130 */ +131 public double evaluate(final double[] values, final double p) { +132 test(values, 0, 0); +133 return evaluate(values, 0, values.length, p); +134 } +135 +136 /** +137 * Returns an estimate of the <code>quantile</code>th percentile of the +138 * designated values in the <code>values</code> array. The quantile +139 * estimated is determined by the <code>quantile</code> property. +140 * <p> +141 * <ul> +142 * <li>Returns <code>Double.NaN</code> if <code>length = 0</code></li> +143 * <li>Returns (for any value of <code>quantile</code>) +144 * <code>values[begin]</code> if <code>length = 1 </code></li> +145 * <li>Throws <code>IllegalArgumentException</code> if <code>values</code> +146 * is null, or <code>start</code> or <code>length</code> +147 * is invalid</li> +148 * </ul></p> +149 * <p> +150 * See {@link Percentile} for a description of the percentile estimation +151 * algorithm used.</p> +152 * +153 * @param values the input array +154 * @param start index of the first array element to include +155 * @param length the number of elements to include +156 * @return the percentile value +157 * @throws IllegalArgumentException if the parameters are not valid +158 * +159 */ +160 @Override +161 public double evaluate( final double[] values, final int start, final int length) { +162 return evaluate(values, start, length, quantile); +163 } +164 +165 /** +166 * Returns an estimate of the <code>p</code>th percentile of the values +167 * in the <code>values</code> array, starting with the element in (0-based) +168 * position <code>begin</code> in the array and including <code>length</code> +169 * values. +170 * <p> +171 * Calls to this method do not modify the internal <code>quantile</code> +172 * state of this statistic.</p> +173 * <p> +174 * <ul> +175 * <li>Returns <code>Double.NaN</code> if <code>length = 0</code></li> +176 * <li>Returns (for any value of <code>p</code>) <code>values[begin]</code> +177 * if <code>length = 1 </code></li> +178 * <li>Throws <code>IllegalArgumentException</code> if <code>values</code> +179 * is null , <code>begin</code> or <code>length</code> is invalid, or +180 * <code>p</code> is not a valid quantile value (p must be greater than 0 +181 * and less than or equal to 100)</li> +182 * </ul></p> +183 * <p> +184 * See {@link Percentile} for a description of the percentile estimation +185 * algorithm used.</p> +186 * +187 * @param values array of input values +188 * @param p the percentile to compute +189 * @param begin the first (0-based) element to include in the computation +190 * @param length the number of array elements to include +191 * @return the percentile value +192 * @throws IllegalArgumentException if the parameters are not valid or the +193 * input array is null +194 */ +195 public double evaluate(final double[] values, final int begin, +196 final int length, final double p) { +197 +198 test(values, begin, length); +199 +200 if ((p > 100) || (p <= 0)) { +201 throw MathRuntimeException.createIllegalArgumentException( +202 "out of bounds quantile value: {0}, must be in (0, 100]", p); +203 } +204 if (length == 0) { +205 return Double.NaN; +206 } +207 if (length == 1) { +208 return values[begin]; // always return single value for n = 1 +209 } +210 double n = length; +211 double pos = p * (n + 1) / 100; +212 double fpos = Math.floor(pos); +213 int intPos = (int) fpos; +214 double dif = pos - fpos; +215 double[] sorted = new double[length]; +216 System.arraycopy(values, begin, sorted, 0, length); +217 Arrays.sort(sorted); +218 +219 if (pos < 1) { +220 return sorted[0]; +221 } +222 if (pos >= n) { +223 return sorted[length - 1]; +224 } +225 double lower = sorted[intPos - 1]; +226 double upper = sorted[intPos]; +227 return lower + dif * (upper - lower); +228 } +229 +230 /** +231 * Returns the value of the quantile field (determines what percentile is +232 * computed when evaluate() is called with no quantile argument). +233 * +234 * @return quantile +235 */ +236 public double getQuantile() { +237 return quantile; +238 } +239 +240 /** +241 * Sets the value of the quantile field (determines what percentile is +242 * computed when evaluate() is called with no quantile argument). +243 * +244 * @param p a value between 0 < p <= 100 +245 * @throws IllegalArgumentException if p is not greater than 0 and less +246 * than or equal to 100 +247 */ +248 public void setQuantile(final double p) { +249 if (p <= 0 || p > 100) { +250 throw MathRuntimeException.createIllegalArgumentException( +251 "out of bounds quantile value: {0}, must be in (0, 100]", p); +252 } +253 quantile = p; +254 } +255 +256 /** +257 * {@inheritDoc} +258 */ +259 @Override +260 public Percentile copy() { +261 Percentile result = new Percentile(); +262 copy(this, result); +263 return result; +264 } +265 +266 /** +267 * Copies source to dest. +268 * <p>Neither source nor dest can be null.</p> +269 * +270 * @param source Percentile to copy +271 * @param dest Percentile to copy to +272 * @throws NullPointerException if either source or dest is null +273 */ +274 public static void copy(Percentile source, Percentile dest) { +275 dest.quantile = source.quantile; +276 } +277 +278 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/summary/Product.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/summary/Product.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,288 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.summary; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; +022 import org.apache.commons.math.stat.descriptive.WeightedEvaluation; +023 +024 /** +025 * Returns the product of the available values. +026 * <p> +027 * If there are no values in the dataset, or any of the values are +028 * <code>NaN</code>, then <code>NaN</code> is returned.</p> +029 * <p> +030 * <strong>Note that this implementation is not synchronized.</strong> If +031 * multiple threads access an instance of this class concurrently, and at least +032 * one of the threads invokes the <code>increment()</code> or +033 * <code>clear()</code> method, it must be synchronized externally.</p> +034 * +035 * @version $Revision: 917270 $ $Date: 2010-02-28 14:37:53 -0500 (Sun, 28 Feb 2010) $ +036 */ +037 public class Product extends AbstractStorelessUnivariateStatistic implements Serializable, WeightedEvaluation { +038 +039 /** Serializable version identifier */ +040 private static final long serialVersionUID = 2824226005990582538L; +041 +042 /**The number of values that have been added */ +043 private long n; +044 +045 /** +046 * The current Running Product. +047 */ +048 private double value; +049 +050 /** +051 * Create a Product instance +052 */ +053 public Product() { +054 n = 0; +055 value = Double.NaN; +056 } +057 +058 /** +059 * Copy constructor, creates a new {@code Product} identical +060 * to the {@code original} +061 * +062 * @param original the {@code Product} instance to copy +063 */ +064 public Product(Product original) { +065 copy(original, this); +066 } +067 +068 /** +069 * {@inheritDoc} +070 */ +071 @Override +072 public void increment(final double d) { +073 if (n == 0) { +074 value = d; +075 } else { +076 value *= d; +077 } +078 n++; +079 } +080 +081 /** +082 * {@inheritDoc} +083 */ +084 @Override +085 public double getResult() { +086 return value; +087 } +088 +089 /** +090 * {@inheritDoc} +091 */ +092 public long getN() { +093 return n; +094 } +095 +096 /** +097 * {@inheritDoc} +098 */ +099 @Override +100 public void clear() { +101 value = Double.NaN; +102 n = 0; +103 } +104 +105 /** +106 * Returns the product of the entries in the specified portion of +107 * the input array, or <code>Double.NaN</code> if the designated subarray +108 * is empty. +109 * <p> +110 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +111 * +112 * @param values the input array +113 * @param begin index of the first array element to include +114 * @param length the number of elements to include +115 * @return the product of the values or Double.NaN if length = 0 +116 * @throws IllegalArgumentException if the array is null or the array index +117 * parameters are not valid +118 */ +119 @Override +120 public double evaluate(final double[] values, final int begin, final int length) { +121 double product = Double.NaN; +122 if (test(values, begin, length)) { +123 product = 1.0; +124 for (int i = begin; i < begin + length; i++) { +125 product *= values[i]; +126 } +127 } +128 return product; +129 } +130 +131 /** +132 * <p>Returns the weighted product of the entries in the specified portion of +133 * the input array, or <code>Double.NaN</code> if the designated subarray +134 * is empty.</p> +135 * +136 * <p>Throws <code>IllegalArgumentException</code> if any of the following are true: +137 * <ul><li>the values array is null</li> +138 * <li>the weights array is null</li> +139 * <li>the weights array does not have the same length as the values array</li> +140 * <li>the weights array contains one or more infinite values</li> +141 * <li>the weights array contains one or more NaN values</li> +142 * <li>the weights array contains negative values</li> +143 * <li>the start and length arguments do not determine a valid array</li> +144 * </ul></p> +145 * +146 * <p>Uses the formula, <pre> +147 * weighted product = ∏values[i]<sup>weights[i]</sup> +148 * </pre> +149 * that is, the weights are applied as exponents when computing the weighted product.</p> +150 * +151 * @param values the input array +152 * @param weights the weights array +153 * @param begin index of the first array element to include +154 * @param length the number of elements to include +155 * @return the product of the values or Double.NaN if length = 0 +156 * @throws IllegalArgumentException if the parameters are not valid +157 * @since 2.1 +158 */ +159 public double evaluate(final double[] values, final double[] weights, +160 final int begin, final int length) { +161 double product = Double.NaN; +162 if (test(values, weights, begin, length)) { +163 product = 1.0; +164 for (int i = begin; i < begin + length; i++) { +165 product *= Math.pow(values[i], weights[i]); +166 } +167 } +168 return product; +169 } +170 +171 /** +172 * <p>Returns the weighted product of the entries in the input array.</p> +173 * +174 * <p>Throws <code>IllegalArgumentException</code> if any of the following are true: +175 * <ul><li>the values array is null</li> +176 * <li>the weights array is null</li> +177 * <li>the weights array does not have the same length as the values array</li> +178 * <li>the weights array contains one or more infinite values</li> +179 * <li>the weights array contains one or more NaN values</li> +180 * <li>the weights array contains negative values</li> +181 * </ul></p> +182 * +183 * <p>Uses the formula, <pre> +184 * weighted product = ∏values[i]<sup>weights[i]</sup> +185 * </pre> +186 * that is, the weights are applied as exponents when computing the weighted product.</p> +187 * +188 * @param values the input array +189 * @param weights the weights array +190 * @return the product of the values or Double.NaN if length = 0 +191 * @throws IllegalArgumentException if the parameters are not valid +192 * @since 2.1 +193 */ +194 public double evaluate(final double[] values, final double[] weights) { +195 return evaluate(values, weights, 0, values.length); +196 } +197 +198 +199 /** +200 * {@inheritDoc} +201 */ +202 @Override +203 public Product copy() { +204 Product result = new Product(); +205 copy(this, result); +206 return result; +207 } +208 +209 /** +210 * Copies source to dest. +211 * <p>Neither source nor dest can be null.</p> +212 * +213 * @param source Product to copy +214 * @param dest Product to copy to +215 * @throws NullPointerException if either source or dest is null +216 */ +217 public static void copy(Product source, Product dest) { +218 dest.n = source.n; +219 dest.value = source.value; +220 } +221 +222 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/summary/Sum.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/summary/Sum.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,285 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.summary; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; +022 +023 +024 /** +025 * Returns the sum of the available values. +026 * <p> +027 * If there are no values in the dataset, or any of the values are +028 * <code>NaN</code>, then <code>NaN</code> is returned.</p> +029 * <p> +030 * <strong>Note that this implementation is not synchronized.</strong> If +031 * multiple threads access an instance of this class concurrently, and at least +032 * one of the threads invokes the <code>increment()</code> or +033 * <code>clear()</code> method, it must be synchronized externally.</p> +034 * +035 * @version $Revision: 917270 $ $Date: 2010-02-28 14:37:53 -0500 (Sun, 28 Feb 2010) $ +036 */ +037 public class Sum extends AbstractStorelessUnivariateStatistic implements Serializable { +038 +039 /** Serializable version identifier */ +040 private static final long serialVersionUID = -8231831954703408316L; +041 +042 /** */ +043 private long n; +044 +045 /** +046 * The currently running sum. +047 */ +048 private double value; +049 +050 /** +051 * Create a Sum instance +052 */ +053 public Sum() { +054 n = 0; +055 value = Double.NaN; +056 } +057 +058 /** +059 * Copy constructor, creates a new {@code Sum} identical +060 * to the {@code original} +061 * +062 * @param original the {@code Sum} instance to copy +063 */ +064 public Sum(Sum original) { +065 copy(original, this); +066 } +067 +068 /** +069 * {@inheritDoc} +070 */ +071 @Override +072 public void increment(final double d) { +073 if (n == 0) { +074 value = d; +075 } else { +076 value += d; +077 } +078 n++; +079 } +080 +081 /** +082 * {@inheritDoc} +083 */ +084 @Override +085 public double getResult() { +086 return value; +087 } +088 +089 /** +090 * {@inheritDoc} +091 */ +092 public long getN() { +093 return n; +094 } +095 +096 /** +097 * {@inheritDoc} +098 */ +099 @Override +100 public void clear() { +101 value = Double.NaN; +102 n = 0; +103 } +104 +105 /** +106 * The sum of the entries in the specified portion of +107 * the input array, or <code>Double.NaN</code> if the designated subarray +108 * is empty. +109 * <p> +110 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +111 * +112 * @param values the input array +113 * @param begin index of the first array element to include +114 * @param length the number of elements to include +115 * @return the sum of the values or Double.NaN if length = 0 +116 * @throws IllegalArgumentException if the array is null or the array index +117 * parameters are not valid +118 */ +119 @Override +120 public double evaluate(final double[] values, final int begin, final int length) { +121 double sum = Double.NaN; +122 if (test(values, begin, length)) { +123 sum = 0.0; +124 for (int i = begin; i < begin + length; i++) { +125 sum += values[i]; +126 } +127 } +128 return sum; +129 } +130 +131 /** +132 * The weighted sum of the entries in the specified portion of +133 * the input array, or <code>Double.NaN</code> if the designated subarray +134 * is empty. +135 * <p> +136 * Throws <code>IllegalArgumentException</code> if any of the following are true: +137 * <ul><li>the values array is null</li> +138 * <li>the weights array is null</li> +139 * <li>the weights array does not have the same length as the values array</li> +140 * <li>the weights array contains one or more infinite values</li> +141 * <li>the weights array contains one or more NaN values</li> +142 * <li>the weights array contains negative values</li> +143 * <li>the start and length arguments do not determine a valid array</li> +144 * </ul></p> +145 * <p> +146 * Uses the formula, <pre> +147 * weighted sum = Σ(values[i] * weights[i]) +148 * </pre></p> +149 * +150 * @param values the input array +151 * @param weights the weights array +152 * @param begin index of the first array element to include +153 * @param length the number of elements to include +154 * @return the sum of the values or Double.NaN if length = 0 +155 * @throws IllegalArgumentException if the parameters are not valid +156 * @since 2.1 +157 */ +158 public double evaluate(final double[] values, final double[] weights, +159 final int begin, final int length) { +160 double sum = Double.NaN; +161 if (test(values, weights, begin, length)) { +162 sum = 0.0; +163 for (int i = begin; i < begin + length; i++) { +164 sum += values[i] * weights[i]; +165 } +166 } +167 return sum; +168 } +169 +170 /** +171 * The weighted sum of the entries in the the input array. +172 * <p> +173 * Throws <code>IllegalArgumentException</code> if any of the following are true: +174 * <ul><li>the values array is null</li> +175 * <li>the weights array is null</li> +176 * <li>the weights array does not have the same length as the values array</li> +177 * <li>the weights array contains one or more infinite values</li> +178 * <li>the weights array contains one or more NaN values</li> +179 * <li>the weights array contains negative values</li> +180 * </ul></p> +181 * <p> +182 * Uses the formula, <pre> +183 * weighted sum = Σ(values[i] * weights[i]) +184 * </pre></p> +185 * +186 * @param values the input array +187 * @param weights the weights array +188 * @return the sum of the values or Double.NaN if length = 0 +189 * @throws IllegalArgumentException if the parameters are not valid +190 * @since 2.1 +191 */ +192 public double evaluate(final double[] values, final double[] weights) { +193 return evaluate(values, weights, 0, values.length); +194 } +195 +196 /** +197 * {@inheritDoc} +198 */ +199 @Override +200 public Sum copy() { +201 Sum result = new Sum(); +202 copy(this, result); +203 return result; +204 } +205 +206 /** +207 * Copies source to dest. +208 * <p>Neither source nor dest can be null.</p> +209 * +210 * @param source Sum to copy +211 * @param dest Sum to copy to +212 * @throws NullPointerException if either source or dest is null +213 */ +214 public static void copy(Sum source, Sum dest) { +215 dest.n = source.n; +216 dest.value = source.value; +217 } +218 +219 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/summary/SumOfLogs.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/summary/SumOfLogs.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,229 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.summary; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; +022 +023 /** +024 * Returns the sum of the natural logs for this collection of values. +025 * <p> +026 * Uses {@link java.lang.Math#log(double)} to compute the logs. Therefore, +027 * <ul> +028 * <li>If any of values are < 0, the result is <code>NaN.</code></li> +029 * <li>If all values are non-negative and less than +030 * <code>Double.POSITIVE_INFINITY</code>, but at least one value is 0, the +031 * result is <code>Double.NEGATIVE_INFINITY.</code></li> +032 * <li>If both <code>Double.POSITIVE_INFINITY</code> and +033 * <code>Double.NEGATIVE_INFINITY</code> are among the values, the result is +034 * <code>NaN.</code></li> +035 * </ul></p> +036 * <p> +037 * <strong>Note that this implementation is not synchronized.</strong> If +038 * multiple threads access an instance of this class concurrently, and at least +039 * one of the threads invokes the <code>increment()</code> or +040 * <code>clear()</code> method, it must be synchronized externally.</p> +041 * +042 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +043 */ +044 public class SumOfLogs extends AbstractStorelessUnivariateStatistic implements Serializable { +045 +046 /** Serializable version identifier */ +047 private static final long serialVersionUID = -370076995648386763L; +048 +049 /**Number of values that have been added */ +050 private int n; +051 +052 /** +053 * The currently running value +054 */ +055 private double value; +056 +057 /** +058 * Create a SumOfLogs instance +059 */ +060 public SumOfLogs() { +061 value = 0d; +062 n = 0; +063 } +064 +065 /** +066 * Copy constructor, creates a new {@code SumOfLogs} identical +067 * to the {@code original} +068 * +069 * @param original the {@code SumOfLogs} instance to copy +070 */ +071 public SumOfLogs(SumOfLogs original) { +072 copy(original, this); +073 } +074 +075 /** +076 * {@inheritDoc} +077 */ +078 @Override +079 public void increment(final double d) { +080 value += Math.log(d); +081 n++; +082 } +083 +084 /** +085 * {@inheritDoc} +086 */ +087 @Override +088 public double getResult() { +089 if (n > 0) { +090 return value; +091 } else { +092 return Double.NaN; +093 } +094 } +095 +096 /** +097 * {@inheritDoc} +098 */ +099 public long getN() { +100 return n; +101 } +102 +103 /** +104 * {@inheritDoc} +105 */ +106 @Override +107 public void clear() { +108 value = 0d; +109 n = 0; +110 } +111 +112 /** +113 * Returns the sum of the natural logs of the entries in the specified portion of +114 * the input array, or <code>Double.NaN</code> if the designated subarray +115 * is empty. +116 * <p> +117 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +118 * <p> +119 * See {@link SumOfLogs}.</p> +120 * +121 * @param values the input array +122 * @param begin index of the first array element to include +123 * @param length the number of elements to include +124 * @return the sum of the natural logs of the values or Double.NaN if +125 * length = 0 +126 * @throws IllegalArgumentException if the array is null or the array index +127 * parameters are not valid +128 */ +129 @Override +130 public double evaluate(final double[] values, final int begin, final int length) { +131 double sumLog = Double.NaN; +132 if (test(values, begin, length)) { +133 sumLog = 0.0; +134 for (int i = begin; i < begin + length; i++) { +135 sumLog += Math.log(values[i]); +136 } +137 } +138 return sumLog; +139 } +140 +141 /** +142 * {@inheritDoc} +143 */ +144 @Override +145 public SumOfLogs copy() { +146 SumOfLogs result = new SumOfLogs(); +147 copy(this, result); +148 return result; +149 } +150 +151 /** +152 * Copies source to dest. +153 * <p>Neither source nor dest can be null.</p> +154 * +155 * @param source SumOfLogs to copy +156 * @param dest SumOfLogs to copy to +157 * @throws NullPointerException if either source or dest is null +158 */ +159 public static void copy(SumOfLogs source, SumOfLogs dest) { +160 dest.n = source.n; +161 dest.value = source.value; +162 } +163 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/summary/SumOfSquares.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/descriptive/summary/SumOfSquares.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,219 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.descriptive.summary; +018 +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; +022 +023 /** +024 * Returns the sum of the squares of the available values. +025 * <p> +026 * If there are no values in the dataset, or any of the values are +027 * <code>NaN</code>, then <code>NaN</code> is returned.</p> +028 * <p> +029 * <strong>Note that this implementation is not synchronized.</strong> If +030 * multiple threads access an instance of this class concurrently, and at least +031 * one of the threads invokes the <code>increment()</code> or +032 * <code>clear()</code> method, it must be synchronized externally.</p> +033 * +034 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +035 */ +036 public class SumOfSquares extends AbstractStorelessUnivariateStatistic implements Serializable { +037 +038 /** Serializable version identifier */ +039 private static final long serialVersionUID = 1460986908574398008L; +040 +041 /** */ +042 private long n; +043 +044 /** +045 * The currently running sumSq +046 */ +047 private double value; +048 +049 /** +050 * Create a SumOfSquares instance +051 */ +052 public SumOfSquares() { +053 n = 0; +054 value = Double.NaN; +055 } +056 +057 /** +058 * Copy constructor, creates a new {@code SumOfSquares} identical +059 * to the {@code original} +060 * +061 * @param original the {@code SumOfSquares} instance to copy +062 */ +063 public SumOfSquares(SumOfSquares original) { +064 copy(original, this); +065 } +066 +067 /** +068 * {@inheritDoc} +069 */ +070 @Override +071 public void increment(final double d) { +072 if (n == 0) { +073 value = d * d; +074 } else { +075 value += d * d; +076 } +077 n++; +078 } +079 +080 /** +081 * {@inheritDoc} +082 */ +083 @Override +084 public double getResult() { +085 return value; +086 } +087 +088 /** +089 * {@inheritDoc} +090 */ +091 public long getN() { +092 return n; +093 } +094 +095 /** +096 * {@inheritDoc} +097 */ +098 @Override +099 public void clear() { +100 value = Double.NaN; +101 n = 0; +102 } +103 +104 /** +105 * Returns the sum of the squares of the entries in the specified portion of +106 * the input array, or <code>Double.NaN</code> if the designated subarray +107 * is empty. +108 * <p> +109 * Throws <code>IllegalArgumentException</code> if the array is null.</p> +110 * +111 * @param values the input array +112 * @param begin index of the first array element to include +113 * @param length the number of elements to include +114 * @return the sum of the squares of the values or Double.NaN if length = 0 +115 * @throws IllegalArgumentException if the array is null or the array index +116 * parameters are not valid +117 */ +118 @Override +119 public double evaluate(final double[] values,final int begin, final int length) { +120 double sumSq = Double.NaN; +121 if (test(values, begin, length)) { +122 sumSq = 0.0; +123 for (int i = begin; i < begin + length; i++) { +124 sumSq += values[i] * values[i]; +125 } +126 } +127 return sumSq; +128 } +129 +130 /** +131 * {@inheritDoc} +132 */ +133 @Override +134 public SumOfSquares copy() { +135 SumOfSquares result = new SumOfSquares(); +136 copy(this, result); +137 return result; +138 } +139 +140 /** +141 * Copies source to dest. +142 * <p>Neither source nor dest can be null.</p> +143 * +144 * @param source SumOfSquares to copy +145 * @param dest SumOfSquares to copy to +146 * @throws NullPointerException if either source or dest is null +147 */ +148 public static void copy(SumOfSquares source, SumOfSquares dest) { +149 dest.n = source.n; +150 dest.value = source.value; +151 } +152 +153 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/ChiSquareTest.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/ChiSquareTest.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,288 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.inference; +018 +019 import org.apache.commons.math.MathException; +020 +021 /** +022 * An interface for Chi-Square tests. +023 * <p>This interface handles only known distributions. If the distribution is +024 * unknown and should be provided by a sample, then the {@link UnknownDistributionChiSquareTest +025 * UnknownDistributionChiSquareTest} extended interface should be used instead.</p> +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 */ +028 public interface ChiSquareTest { +029 +030 /** +031 * Computes the <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda35f.htm"> +032 * Chi-Square statistic</a> comparing <code>observed</code> and <code>expected</code> +033 * frequency counts. +034 * <p> +035 * This statistic can be used to perform a Chi-Square test evaluating the null hypothesis that +036 * the observed counts follow the expected distribution.</p> +037 * <p> +038 * <strong>Preconditions</strong>: <ul> +039 * <li>Expected counts must all be positive. +040 * </li> +041 * <li>Observed counts must all be >= 0. +042 * </li> +043 * <li>The observed and expected arrays must have the same length and +044 * their common length must be at least 2. +045 * </li></ul></p><p> +046 * If any of the preconditions are not met, an +047 * <code>IllegalArgumentException</code> is thrown.</p> +048 * +049 * @param observed array of observed frequency counts +050 * @param expected array of expected frequency counts +051 * @return chiSquare statistic +052 * @throws IllegalArgumentException if preconditions are not met +053 */ +054 double chiSquare(double[] expected, long[] observed) +055 throws IllegalArgumentException; +056 +057 /** +058 * Returns the <i>observed significance level</i>, or <a href= +059 * "http://www.cas.lancs.ac.uk/glossary_v1.1/hyptest.html#pvalue"> +060 * p-value</a>, associated with a +061 * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda35f.htm"> +062 * Chi-square goodness of fit test</a> comparing the <code>observed</code> +063 * frequency counts to those in the <code>expected</code> array. +064 * <p> +065 * The number returned is the smallest significance level at which one can reject +066 * the null hypothesis that the observed counts conform to the frequency distribution +067 * described by the expected counts.</p> +068 * <p> +069 * <strong>Preconditions</strong>: <ul> +070 * <li>Expected counts must all be positive. +071 * </li> +072 * <li>Observed counts must all be >= 0. +073 * </li> +074 * <li>The observed and expected arrays must have the same length and +075 * their common length must be at least 2. +076 * </li></ul></p><p> +077 * If any of the preconditions are not met, an +078 * <code>IllegalArgumentException</code> is thrown.</p> +079 * +080 * @param observed array of observed frequency counts +081 * @param expected array of expected frequency counts +082 * @return p-value +083 * @throws IllegalArgumentException if preconditions are not met +084 * @throws MathException if an error occurs computing the p-value +085 */ +086 double chiSquareTest(double[] expected, long[] observed) +087 throws IllegalArgumentException, MathException; +088 +089 /** +090 * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda35f.htm"> +091 * Chi-square goodness of fit test</a> evaluating the null hypothesis that the observed counts +092 * conform to the frequency distribution described by the expected counts, with +093 * significance level <code>alpha</code>. Returns true iff the null hypothesis can be rejected +094 * with 100 * (1 - alpha) percent confidence. +095 * <p> +096 * <strong>Example:</strong><br> +097 * To test the hypothesis that <code>observed</code> follows +098 * <code>expected</code> at the 99% level, use </p><p> +099 * <code>chiSquareTest(expected, observed, 0.01) </code></p> +100 * <p> +101 * <strong>Preconditions</strong>: <ul> +102 * <li>Expected counts must all be positive. +103 * </li> +104 * <li>Observed counts must all be >= 0. +105 * </li> +106 * <li>The observed and expected arrays must have the same length and +107 * their common length must be at least 2. +108 * <li> <code> 0 < alpha < 0.5 </code> +109 * </li></ul></p><p> +110 * If any of the preconditions are not met, an +111 * <code>IllegalArgumentException</code> is thrown.</p> +112 * +113 * @param observed array of observed frequency counts +114 * @param expected array of expected frequency counts +115 * @param alpha significance level of the test +116 * @return true iff null hypothesis can be rejected with confidence +117 * 1 - alpha +118 * @throws IllegalArgumentException if preconditions are not met +119 * @throws MathException if an error occurs performing the test +120 */ +121 boolean chiSquareTest(double[] expected, long[] observed, double alpha) +122 throws IllegalArgumentException, MathException; +123 +124 /** +125 * Computes the Chi-Square statistic associated with a +126 * <a href="http://www.itl.nist.gov/div898/handbook/prc/section4/prc45.htm"> +127 * chi-square test of independence</a> based on the input <code>counts</code> +128 * array, viewed as a two-way table. +129 * <p> +130 * The rows of the 2-way table are +131 * <code>count[0], ... , count[count.length - 1] </code></p> +132 * <p> +133 * <strong>Preconditions</strong>: <ul> +134 * <li>All counts must be >= 0. +135 * </li> +136 * <li>The count array must be rectangular (i.e. all count[i] subarrays +137 * must have the same length). +138 * </li> +139 * <li>The 2-way table represented by <code>counts</code> must have at +140 * least 2 columns and at least 2 rows. +141 * </li> +142 * </li></ul></p><p> +143 * If any of the preconditions are not met, an +144 * <code>IllegalArgumentException</code> is thrown.</p> +145 * +146 * @param counts array representation of 2-way table +147 * @return chiSquare statistic +148 * @throws IllegalArgumentException if preconditions are not met +149 */ +150 double chiSquare(long[][] counts) +151 throws IllegalArgumentException; +152 +153 /** +154 * Returns the <i>observed significance level</i>, or <a href= +155 * "http://www.cas.lancs.ac.uk/glossary_v1.1/hyptest.html#pvalue"> +156 * p-value</a>, associated with a +157 * <a href="http://www.itl.nist.gov/div898/handbook/prc/section4/prc45.htm"> +158 * chi-square test of independence</a> based on the input <code>counts</code> +159 * array, viewed as a two-way table. +160 * <p> +161 * The rows of the 2-way table are +162 * <code>count[0], ... , count[count.length - 1] </code></p> +163 * <p> +164 * <strong>Preconditions</strong>: <ul> +165 * <li>All counts must be >= 0. +166 * </li> +167 * <li>The count array must be rectangular (i.e. all count[i] subarrays must have the same length). +168 * </li> +169 * <li>The 2-way table represented by <code>counts</code> must have at least 2 columns and +170 * at least 2 rows. +171 * </li> +172 * </li></ul></p><p> +173 * If any of the preconditions are not met, an +174 * <code>IllegalArgumentException</code> is thrown.</p> +175 * +176 * @param counts array representation of 2-way table +177 * @return p-value +178 * @throws IllegalArgumentException if preconditions are not met +179 * @throws MathException if an error occurs computing the p-value +180 */ +181 double chiSquareTest(long[][] counts) +182 throws IllegalArgumentException, MathException; +183 +184 /** +185 * Performs a <a href="http://www.itl.nist.gov/div898/handbook/prc/section4/prc45.htm"> +186 * chi-square test of independence</a> evaluating the null hypothesis that the classifications +187 * represented by the counts in the columns of the input 2-way table are independent of the rows, +188 * with significance level <code>alpha</code>. Returns true iff the null hypothesis can be rejected +189 * with 100 * (1 - alpha) percent confidence. +190 * <p> +191 * The rows of the 2-way table are +192 * <code>count[0], ... , count[count.length - 1] </code></p> +193 * <p> +194 * <strong>Example:</strong><br> +195 * To test the null hypothesis that the counts in +196 * <code>count[0], ... , count[count.length - 1] </code> +197 * all correspond to the same underlying probability distribution at the 99% level, use </p><p> +198 * <code>chiSquareTest(counts, 0.01) </code></p> +199 * <p> +200 * <strong>Preconditions</strong>: <ul> +201 * <li>All counts must be >= 0. +202 * </li> +203 * <li>The count array must be rectangular (i.e. all count[i] subarrays must have the same length). +204 * </li> +205 * <li>The 2-way table represented by <code>counts</code> must have at least 2 columns and +206 * at least 2 rows. +207 * </li> +208 * </li></ul></p><p> +209 * If any of the preconditions are not met, an +210 * <code>IllegalArgumentException</code> is thrown.</p> +211 * +212 * @param counts array representation of 2-way table +213 * @param alpha significance level of the test +214 * @return true iff null hypothesis can be rejected with confidence +215 * 1 - alpha +216 * @throws IllegalArgumentException if preconditions are not met +217 * @throws MathException if an error occurs performing the test +218 */ +219 boolean chiSquareTest(long[][] counts, double alpha) +220 throws IllegalArgumentException, MathException; +221 +222 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/ChiSquareTestImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/ChiSquareTestImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,492 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.inference; +018 +019 import org.apache.commons.math.MathException; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.distribution.ChiSquaredDistribution; +022 import org.apache.commons.math.distribution.ChiSquaredDistributionImpl; +023 +024 /** +025 * Implements Chi-Square test statistics defined in the +026 * {@link UnknownDistributionChiSquareTest} interface. +027 * +028 * @version $Revision: 811833 $ $Date: 2009-09-06 12:27:50 -0400 (Sun, 06 Sep 2009) $ +029 */ +030 public class ChiSquareTestImpl implements UnknownDistributionChiSquareTest { +031 +032 /** Distribution used to compute inference statistics. */ +033 private ChiSquaredDistribution distribution; +034 +035 /** +036 * Construct a ChiSquareTestImpl +037 */ +038 public ChiSquareTestImpl() { +039 this(new ChiSquaredDistributionImpl(1.0)); +040 } +041 +042 /** +043 * Create a test instance using the given distribution for computing +044 * inference statistics. +045 * @param x distribution used to compute inference statistics. +046 * @since 1.2 +047 */ +048 public ChiSquareTestImpl(ChiSquaredDistribution x) { +049 super(); +050 setDistribution(x); +051 } +052 /** +053 * {@inheritDoc} +054 * <p><strong>Note: </strong>This implementation rescales the +055 * <code>expected</code> array if necessary to ensure that the sum of the +056 * expected and observed counts are equal.</p> +057 * +058 * @param observed array of observed frequency counts +059 * @param expected array of expected frequency counts +060 * @return chi-square test statistic +061 * @throws IllegalArgumentException if preconditions are not met +062 * or length is less than 2 +063 */ +064 public double chiSquare(double[] expected, long[] observed) +065 throws IllegalArgumentException { +066 if (expected.length < 2) { +067 throw MathRuntimeException.createIllegalArgumentException( +068 "expected array length = {0}, must be at least 2", +069 expected.length); +070 } +071 if (expected.length != observed.length) { +072 throw MathRuntimeException.createIllegalArgumentException( +073 "dimension mismatch {0} != {1}", expected.length, observed.length); +074 } +075 checkPositive(expected); +076 checkNonNegative(observed); +077 double sumExpected = 0d; +078 double sumObserved = 0d; +079 for (int i = 0; i < observed.length; i++) { +080 sumExpected += expected[i]; +081 sumObserved += observed[i]; +082 } +083 double ratio = 1.0d; +084 boolean rescale = false; +085 if (Math.abs(sumExpected - sumObserved) > 10E-6) { +086 ratio = sumObserved / sumExpected; +087 rescale = true; +088 } +089 double sumSq = 0.0d; +090 for (int i = 0; i < observed.length; i++) { +091 if (rescale) { +092 final double dev = observed[i] - ratio * expected[i]; +093 sumSq += dev * dev / (ratio * expected[i]); +094 } else { +095 final double dev = observed[i] - expected[i]; +096 sumSq += dev * dev / expected[i]; +097 } +098 } +099 return sumSq; +100 } +101 +102 /** +103 * {@inheritDoc} +104 * <p><strong>Note: </strong>This implementation rescales the +105 * <code>expected</code> array if necessary to ensure that the sum of the +106 * expected and observed counts are equal.</p> +107 * +108 * @param observed array of observed frequency counts +109 * @param expected array of expected frequency counts +110 * @return p-value +111 * @throws IllegalArgumentException if preconditions are not met +112 * @throws MathException if an error occurs computing the p-value +113 */ +114 public double chiSquareTest(double[] expected, long[] observed) +115 throws IllegalArgumentException, MathException { +116 distribution.setDegreesOfFreedom(expected.length - 1.0); +117 return 1.0 - distribution.cumulativeProbability( +118 chiSquare(expected, observed)); +119 } +120 +121 /** +122 * {@inheritDoc} +123 * <p><strong>Note: </strong>This implementation rescales the +124 * <code>expected</code> array if necessary to ensure that the sum of the +125 * expected and observed counts are equal.</p> +126 * +127 * @param observed array of observed frequency counts +128 * @param expected array of expected frequency counts +129 * @param alpha significance level of the test +130 * @return true iff null hypothesis can be rejected with confidence +131 * 1 - alpha +132 * @throws IllegalArgumentException if preconditions are not met +133 * @throws MathException if an error occurs performing the test +134 */ +135 public boolean chiSquareTest(double[] expected, long[] observed, +136 double alpha) throws IllegalArgumentException, MathException { +137 if ((alpha <= 0) || (alpha > 0.5)) { +138 throw MathRuntimeException.createIllegalArgumentException( +139 "out of bounds significance level {0}, must be between {1} and {2}", +140 alpha, 0, 0.5); +141 } +142 return chiSquareTest(expected, observed) < alpha; +143 } +144 +145 /** +146 * @param counts array representation of 2-way table +147 * @return chi-square test statistic +148 * @throws IllegalArgumentException if preconditions are not met +149 */ +150 public double chiSquare(long[][] counts) throws IllegalArgumentException { +151 +152 checkArray(counts); +153 int nRows = counts.length; +154 int nCols = counts[0].length; +155 +156 // compute row, column and total sums +157 double[] rowSum = new double[nRows]; +158 double[] colSum = new double[nCols]; +159 double total = 0.0d; +160 for (int row = 0; row < nRows; row++) { +161 for (int col = 0; col < nCols; col++) { +162 rowSum[row] += counts[row][col]; +163 colSum[col] += counts[row][col]; +164 total += counts[row][col]; +165 } +166 } +167 +168 // compute expected counts and chi-square +169 double sumSq = 0.0d; +170 double expected = 0.0d; +171 for (int row = 0; row < nRows; row++) { +172 for (int col = 0; col < nCols; col++) { +173 expected = (rowSum[row] * colSum[col]) / total; +174 sumSq += ((counts[row][col] - expected) * +175 (counts[row][col] - expected)) / expected; +176 } +177 } +178 return sumSq; +179 } +180 +181 /** +182 * @param counts array representation of 2-way table +183 * @return p-value +184 * @throws IllegalArgumentException if preconditions are not met +185 * @throws MathException if an error occurs computing the p-value +186 */ +187 public double chiSquareTest(long[][] counts) +188 throws IllegalArgumentException, MathException { +189 checkArray(counts); +190 double df = ((double) counts.length -1) * ((double) counts[0].length - 1); +191 distribution.setDegreesOfFreedom(df); +192 return 1 - distribution.cumulativeProbability(chiSquare(counts)); +193 } +194 +195 /** +196 * @param counts array representation of 2-way table +197 * @param alpha significance level of the test +198 * @return true iff null hypothesis can be rejected with confidence +199 * 1 - alpha +200 * @throws IllegalArgumentException if preconditions are not met +201 * @throws MathException if an error occurs performing the test +202 */ +203 public boolean chiSquareTest(long[][] counts, double alpha) +204 throws IllegalArgumentException, MathException { +205 if ((alpha <= 0) || (alpha > 0.5)) { +206 throw MathRuntimeException.createIllegalArgumentException( +207 "out of bounds significance level {0}, must be between {1} and {2}", +208 alpha, 0.0, 0.5); +209 } +210 return chiSquareTest(counts) < alpha; +211 } +212 +213 /** +214 * @param observed1 array of observed frequency counts of the first data set +215 * @param observed2 array of observed frequency counts of the second data set +216 * @return chi-square test statistic +217 * @throws IllegalArgumentException if preconditions are not met +218 * @since 1.2 +219 */ +220 public double chiSquareDataSetsComparison(long[] observed1, long[] observed2) +221 throws IllegalArgumentException { +222 +223 // Make sure lengths are same +224 if (observed1.length < 2) { +225 throw MathRuntimeException.createIllegalArgumentException( +226 "observed array length = {0}, must be at least 2", +227 observed1.length); +228 } +229 if (observed1.length != observed2.length) { +230 throw MathRuntimeException.createIllegalArgumentException( +231 "dimension mismatch {0} != {1}", +232 observed1.length, observed2.length); +233 } +234 +235 // Ensure non-negative counts +236 checkNonNegative(observed1); +237 checkNonNegative(observed2); +238 +239 // Compute and compare count sums +240 long countSum1 = 0; +241 long countSum2 = 0; +242 boolean unequalCounts = false; +243 double weight = 0.0; +244 for (int i = 0; i < observed1.length; i++) { +245 countSum1 += observed1[i]; +246 countSum2 += observed2[i]; +247 } +248 // Ensure neither sample is uniformly 0 +249 if (countSum1 == 0) { +250 throw MathRuntimeException.createIllegalArgumentException( +251 "observed counts are all 0 in first observed array"); +252 } +253 if (countSum2 == 0) { +254 throw MathRuntimeException.createIllegalArgumentException( +255 "observed counts are all 0 in second observed array"); +256 } +257 // Compare and compute weight only if different +258 unequalCounts = countSum1 != countSum2; +259 if (unequalCounts) { +260 weight = Math.sqrt((double) countSum1 / (double) countSum2); +261 } +262 // Compute ChiSquare statistic +263 double sumSq = 0.0d; +264 double dev = 0.0d; +265 double obs1 = 0.0d; +266 double obs2 = 0.0d; +267 for (int i = 0; i < observed1.length; i++) { +268 if (observed1[i] == 0 && observed2[i] == 0) { +269 throw MathRuntimeException.createIllegalArgumentException( +270 "observed counts are both zero for entry {0}", i); +271 } else { +272 obs1 = observed1[i]; +273 obs2 = observed2[i]; +274 if (unequalCounts) { // apply weights +275 dev = obs1/weight - obs2 * weight; +276 } else { +277 dev = obs1 - obs2; +278 } +279 sumSq += (dev * dev) / (obs1 + obs2); +280 } +281 } +282 return sumSq; +283 } +284 +285 /** +286 * @param observed1 array of observed frequency counts of the first data set +287 * @param observed2 array of observed frequency counts of the second data set +288 * @return p-value +289 * @throws IllegalArgumentException if preconditions are not met +290 * @throws MathException if an error occurs computing the p-value +291 * @since 1.2 +292 */ +293 public double chiSquareTestDataSetsComparison(long[] observed1, long[] observed2) +294 throws IllegalArgumentException, MathException { +295 distribution.setDegreesOfFreedom((double) observed1.length - 1); +296 return 1 - distribution.cumulativeProbability( +297 chiSquareDataSetsComparison(observed1, observed2)); +298 } +299 +300 /** +301 * @param observed1 array of observed frequency counts of the first data set +302 * @param observed2 array of observed frequency counts of the second data set +303 * @param alpha significance level of the test +304 * @return true iff null hypothesis can be rejected with confidence +305 * 1 - alpha +306 * @throws IllegalArgumentException if preconditions are not met +307 * @throws MathException if an error occurs performing the test +308 * @since 1.2 +309 */ +310 public boolean chiSquareTestDataSetsComparison(long[] observed1, long[] observed2, +311 double alpha) throws IllegalArgumentException, MathException { +312 if ((alpha <= 0) || (alpha > 0.5)) { +313 throw MathRuntimeException.createIllegalArgumentException( +314 "out of bounds significance level {0}, must be between {1} and {2}", +315 alpha, 0.0, 0.5); +316 } +317 return chiSquareTestDataSetsComparison(observed1, observed2) < alpha; +318 } +319 +320 /** +321 * Checks to make sure that the input long[][] array is rectangular, +322 * has at least 2 rows and 2 columns, and has all non-negative entries, +323 * throwing IllegalArgumentException if any of these checks fail. +324 * +325 * @param in input 2-way table to check +326 * @throws IllegalArgumentException if the array is not valid +327 */ +328 private void checkArray(long[][] in) throws IllegalArgumentException { +329 +330 if (in.length < 2) { +331 throw MathRuntimeException.createIllegalArgumentException( +332 "invalid row dimension: {0} (must be at least 2)", +333 in.length); +334 } +335 +336 if (in[0].length < 2) { +337 throw MathRuntimeException.createIllegalArgumentException( +338 "invalid column dimension: {0} (must be at least 2)", +339 in[0].length); +340 } +341 +342 checkRectangular(in); +343 checkNonNegative(in); +344 +345 } +346 +347 //--------------------- Private array methods -- should find a utility home for these +348 +349 /** +350 * Throws IllegalArgumentException if the input array is not rectangular. +351 * +352 * @param in array to be tested +353 * @throws NullPointerException if input array is null +354 * @throws IllegalArgumentException if input array is not rectangular +355 */ +356 private void checkRectangular(long[][] in) { +357 for (int i = 1; i < in.length; i++) { +358 if (in[i].length != in[0].length) { +359 throw MathRuntimeException.createIllegalArgumentException( +360 "some rows have length {0} while others have length {1}", +361 in[i].length, in[0].length); +362 } +363 } +364 } +365 +366 /** +367 * Check all entries of the input array are > 0. +368 * +369 * @param in array to be tested +370 * @exception IllegalArgumentException if one entry is not positive +371 */ +372 private void checkPositive(double[] in) throws IllegalArgumentException { +373 for (int i = 0; i < in.length; i++) { +374 if (in[i] <= 0) { +375 throw MathRuntimeException.createIllegalArgumentException( +376 "element {0} is not positive: {1}", +377 i, in[i]); +378 } +379 } +380 } +381 +382 /** +383 * Check all entries of the input array are >= 0. +384 * +385 * @param in array to be tested +386 * @exception IllegalArgumentException if one entry is negative +387 */ +388 private void checkNonNegative(long[] in) throws IllegalArgumentException { +389 for (int i = 0; i < in.length; i++) { +390 if (in[i] < 0) { +391 throw MathRuntimeException.createIllegalArgumentException( +392 "element {0} is negative: {1}", +393 i, in[i]); +394 } +395 } +396 } +397 +398 /** +399 * Check all entries of the input array are >= 0. +400 * +401 * @param in array to be tested +402 * @exception IllegalArgumentException if one entry is negative +403 */ +404 private void checkNonNegative(long[][] in) throws IllegalArgumentException { +405 for (int i = 0; i < in.length; i ++) { +406 for (int j = 0; j < in[i].length; j++) { +407 if (in[i][j] < 0) { +408 throw MathRuntimeException.createIllegalArgumentException( +409 "element ({0}, {1}) is negative: {2}", +410 i, j, in[i][j]); +411 } +412 } +413 } +414 } +415 +416 /** +417 * Modify the distribution used to compute inference statistics. +418 * +419 * @param value +420 * the new distribution +421 * @since 1.2 +422 */ +423 public void setDistribution(ChiSquaredDistribution value) { +424 distribution = value; +425 } +426 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/OneWayAnova.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/OneWayAnova.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,169 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.inference; +018 +019 import org.apache.commons.math.MathException; +020 import java.util.Collection; +021 +022 /** +023 * An interface for one-way ANOVA (analysis of variance). +024 * +025 * <p> Tests for differences between two or more categories of univariate data +026 * (for example, the body mass index of accountants, lawyers, doctors and +027 * computer programmers). When two categories are given, this is equivalent to +028 * the {@link org.apache.commons.math.stat.inference.TTest}. +029 * </p> +030 * +031 * @since 1.2 +032 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +033 */ +034 public interface OneWayAnova { +035 +036 /** +037 * Computes the ANOVA F-value for a collection of <code>double[]</code> +038 * arrays. +039 * +040 * <p><strong>Preconditions</strong>: <ul> +041 * <li>The categoryData <code>Collection</code> must contain +042 * <code>double[]</code> arrays.</li> +043 * <li> There must be at least two <code>double[]</code> arrays in the +044 * <code>categoryData</code> collection and each of these arrays must +045 * contain at least two values.</li></ul></p> +046 * +047 * @param categoryData <code>Collection</code> of <code>double[]</code> +048 * arrays each containing data for one category +049 * @return Fvalue +050 * @throws IllegalArgumentException if the preconditions are not met +051 * @throws MathException if the statistic can not be computed do to a +052 * convergence or other numerical error. +053 */ +054 double anovaFValue(Collection<double[]> categoryData) +055 throws IllegalArgumentException, MathException; +056 +057 /** +058 * Computes the ANOVA P-value for a collection of <code>double[]</code> +059 * arrays. +060 * +061 * <p><strong>Preconditions</strong>: <ul> +062 * <li>The categoryData <code>Collection</code> must contain +063 * <code>double[]</code> arrays.</li> +064 * <li> There must be at least two <code>double[]</code> arrays in the +065 * <code>categoryData</code> collection and each of these arrays must +066 * contain at least two values.</li></ul></p> +067 * +068 * @param categoryData <code>Collection</code> of <code>double[]</code> +069 * arrays each containing data for one category +070 * @return Pvalue +071 * @throws IllegalArgumentException if the preconditions are not met +072 * @throws MathException if the statistic can not be computed do to a +073 * convergence or other numerical error. +074 */ +075 double anovaPValue(Collection<double[]> categoryData) +076 throws IllegalArgumentException, MathException; +077 +078 /** +079 * Performs an ANOVA test, evaluating the null hypothesis that there +080 * is no difference among the means of the data categories. +081 * +082 * <p><strong>Preconditions</strong>: <ul> +083 * <li>The categoryData <code>Collection</code> must contain +084 * <code>double[]</code> arrays.</li> +085 * <li> There must be at least two <code>double[]</code> arrays in the +086 * <code>categoryData</code> collection and each of these arrays must +087 * contain at least two values.</li> +088 * <li>alpha must be strictly greater than 0 and less than or equal to 0.5. +089 * </li></ul></p> +090 * +091 * @param categoryData <code>Collection</code> of <code>double[]</code> +092 * arrays each containing data for one category +093 * @param alpha significance level of the test +094 * @return true if the null hypothesis can be rejected with +095 * confidence 1 - alpha +096 * @throws IllegalArgumentException if the preconditions are not met +097 * @throws MathException if the statistic can not be computed do to a +098 * convergence or other numerical error. +099 */ +100 boolean anovaTest(Collection<double[]> categoryData, double alpha) +101 throws IllegalArgumentException, MathException; +102 +103 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/OneWayAnovaImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/OneWayAnovaImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,275 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.inference; +018 +019 import java.util.Collection; +020 +021 import org.apache.commons.math.MathException; +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.distribution.FDistribution; +024 import org.apache.commons.math.distribution.FDistributionImpl; +025 import org.apache.commons.math.stat.descriptive.summary.Sum; +026 import org.apache.commons.math.stat.descriptive.summary.SumOfSquares; +027 +028 +029 /** +030 * Implements one-way ANOVA statistics defined in the {@link OneWayAnovaImpl} +031 * interface. +032 * +033 * <p>Uses the +034 * {@link org.apache.commons.math.distribution.FDistribution +035 * commons-math F Distribution implementation} to estimate exact p-values.</p> +036 * +037 * <p>This implementation is based on a description at +038 * http://faculty.vassar.edu/lowry/ch13pt1.html</p> +039 * <pre> +040 * Abbreviations: bg = between groups, +041 * wg = within groups, +042 * ss = sum squared deviations +043 * </pre> +044 * +045 * @since 1.2 +046 * @version $Revision: 825917 $ $Date: 2009-10-16 10:47:27 -0400 (Fri, 16 Oct 2009) $ +047 */ +048 public class OneWayAnovaImpl implements OneWayAnova { +049 +050 /** +051 * Default constructor. +052 */ +053 public OneWayAnovaImpl() { +054 } +055 +056 /** +057 * {@inheritDoc}<p> +058 * This implementation computes the F statistic using the definitional +059 * formula<pre> +060 * F = msbg/mswg</pre> +061 * where<pre> +062 * msbg = between group mean square +063 * mswg = within group mean square</pre> +064 * are as defined <a href="http://faculty.vassar.edu/lowry/ch13pt1.html"> +065 * here</a></p> +066 */ +067 public double anovaFValue(Collection<double[]> categoryData) +068 throws IllegalArgumentException, MathException { +069 AnovaStats a = anovaStats(categoryData); +070 return a.F; +071 } +072 +073 /** +074 * {@inheritDoc}<p> +075 * This implementation uses the +076 * {@link org.apache.commons.math.distribution.FDistribution +077 * commons-math F Distribution implementation} to estimate the exact +078 * p-value, using the formula<pre> +079 * p = 1 - cumulativeProbability(F)</pre> +080 * where <code>F</code> is the F value and <code>cumulativeProbability</code> +081 * is the commons-math implementation of the F distribution.</p> +082 */ +083 public double anovaPValue(Collection<double[]> categoryData) +084 throws IllegalArgumentException, MathException { +085 AnovaStats a = anovaStats(categoryData); +086 FDistribution fdist = new FDistributionImpl(a.dfbg, a.dfwg); +087 return 1.0 - fdist.cumulativeProbability(a.F); +088 } +089 +090 /** +091 * {@inheritDoc}<p> +092 * This implementation uses the +093 * {@link org.apache.commons.math.distribution.FDistribution +094 * commons-math F Distribution implementation} to estimate the exact +095 * p-value, using the formula<pre> +096 * p = 1 - cumulativeProbability(F)</pre> +097 * where <code>F</code> is the F value and <code>cumulativeProbability</code> +098 * is the commons-math implementation of the F distribution.</p> +099 * <p>True is returned iff the estimated p-value is less than alpha.</p> +100 */ +101 public boolean anovaTest(Collection<double[]> categoryData, double alpha) +102 throws IllegalArgumentException, MathException { +103 if ((alpha <= 0) || (alpha > 0.5)) { +104 throw MathRuntimeException.createIllegalArgumentException( +105 "out of bounds significance level {0}, must be between {1} and {2}", +106 alpha, 0, 0.5); +107 } +108 return anovaPValue(categoryData) < alpha; +109 } +110 +111 +112 /** +113 * This method actually does the calculations (except P-value). +114 * +115 * @param categoryData <code>Collection</code> of <code>double[]</code> +116 * arrays each containing data for one category +117 * @return computed AnovaStats +118 * @throws IllegalArgumentException if categoryData does not meet +119 * preconditions specified in the interface definition +120 * @throws MathException if an error occurs computing the Anova stats +121 */ +122 private AnovaStats anovaStats(Collection<double[]> categoryData) +123 throws IllegalArgumentException, MathException { +124 +125 // check if we have enough categories +126 if (categoryData.size() < 2) { +127 throw MathRuntimeException.createIllegalArgumentException( +128 "two or more categories required, got {0}", +129 categoryData.size()); +130 } +131 +132 // check if each category has enough data and all is double[] +133 for (double[] array : categoryData) { +134 if (array.length <= 1) { +135 throw MathRuntimeException.createIllegalArgumentException( +136 "two or more values required in each category, one has {0}", +137 array.length); +138 } +139 } +140 +141 int dfwg = 0; +142 double sswg = 0; +143 Sum totsum = new Sum(); +144 SumOfSquares totsumsq = new SumOfSquares(); +145 int totnum = 0; +146 +147 for (double[] data : categoryData) { +148 +149 Sum sum = new Sum(); +150 SumOfSquares sumsq = new SumOfSquares(); +151 int num = 0; +152 +153 for (int i = 0; i < data.length; i++) { +154 double val = data[i]; +155 +156 // within category +157 num++; +158 sum.increment(val); +159 sumsq.increment(val); +160 +161 // for all categories +162 totnum++; +163 totsum.increment(val); +164 totsumsq.increment(val); +165 } +166 dfwg += num - 1; +167 double ss = sumsq.getResult() - sum.getResult() * sum.getResult() / num; +168 sswg += ss; +169 } +170 double sst = totsumsq.getResult() - totsum.getResult() * +171 totsum.getResult()/totnum; +172 double ssbg = sst - sswg; +173 int dfbg = categoryData.size() - 1; +174 double msbg = ssbg/dfbg; +175 double mswg = sswg/dfwg; +176 double F = msbg/mswg; +177 +178 return new AnovaStats(dfbg, dfwg, F); +179 } +180 +181 /** +182 Convenience class to pass dfbg,dfwg,F values around within AnovaImpl. +183 No get/set methods provided. +184 */ +185 private static class AnovaStats { +186 +187 /** Degrees of freedom in numerator (between groups). */ +188 private int dfbg; +189 +190 /** Degrees of freedom in denominator (within groups). */ +191 private int dfwg; +192 +193 /** Statistic. */ +194 private double F; +195 +196 /** +197 * Constructor +198 * @param dfbg degrees of freedom in numerator (between groups) +199 * @param dfwg degrees of freedom in denominator (within groups) +200 * @param F statistic +201 */ +202 private AnovaStats(int dfbg, int dfwg, double F) { +203 this.dfbg = dfbg; +204 this.dfwg = dfwg; +205 this.F = F; +206 } +207 } +208 +209 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/TTest.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/TTest.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,837 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.inference; +018 +019 import org.apache.commons.math.MathException; +020 import org.apache.commons.math.stat.descriptive.StatisticalSummary; +021 +022 /** +023 * An interface for Student's t-tests. +024 * <p> +025 * Tests can be:<ul> +026 * <li>One-sample or two-sample</li> +027 * <li>One-sided or two-sided</li> +028 * <li>Paired or unpaired (for two-sample tests)</li> +029 * <li>Homoscedastic (equal variance assumption) or heteroscedastic +030 * (for two sample tests)</li> +031 * <li>Fixed significance level (boolean-valued) or returning p-values. +032 * </li></ul></p> +033 * <p> +034 * Test statistics are available for all tests. Methods including "Test" in +035 * in their names perform tests, all other methods return t-statistics. Among +036 * the "Test" methods, <code>double-</code>valued methods return p-values; +037 * <code>boolean-</code>valued methods perform fixed significance level tests. +038 * Significance levels are always specified as numbers between 0 and 0.5 +039 * (e.g. tests at the 95% level use <code>alpha=0.05</code>).</p> +040 * <p> +041 * Input to tests can be either <code>double[]</code> arrays or +042 * {@link StatisticalSummary} instances.</p> +043 * +044 * +045 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +046 */ +047 public interface TTest { +048 /** +049 * Computes a paired, 2-sample t-statistic based on the data in the input +050 * arrays. The t-statistic returned is equivalent to what would be returned by +051 * computing the one-sample t-statistic {@link #t(double, double[])}, with +052 * <code>mu = 0</code> and the sample array consisting of the (signed) +053 * differences between corresponding entries in <code>sample1</code> and +054 * <code>sample2.</code> +055 * <p> +056 * <strong>Preconditions</strong>: <ul> +057 * <li>The input arrays must have the same length and their common length +058 * must be at least 2. +059 * </li></ul></p> +060 * +061 * @param sample1 array of sample data values +062 * @param sample2 array of sample data values +063 * @return t statistic +064 * @throws IllegalArgumentException if the precondition is not met +065 * @throws MathException if the statistic can not be computed do to a +066 * convergence or other numerical error. +067 */ +068 double pairedT(double[] sample1, double[] sample2) +069 throws IllegalArgumentException, MathException; +070 /** +071 * Returns the <i>observed significance level</i>, or +072 * <i> p-value</i>, associated with a paired, two-sample, two-tailed t-test +073 * based on the data in the input arrays. +074 * <p> +075 * The number returned is the smallest significance level +076 * at which one can reject the null hypothesis that the mean of the paired +077 * differences is 0 in favor of the two-sided alternative that the mean paired +078 * difference is not equal to 0. For a one-sided test, divide the returned +079 * value by 2.</p> +080 * <p> +081 * This test is equivalent to a one-sample t-test computed using +082 * {@link #tTest(double, double[])} with <code>mu = 0</code> and the sample +083 * array consisting of the signed differences between corresponding elements of +084 * <code>sample1</code> and <code>sample2.</code></p> +085 * <p> +086 * <strong>Usage Note:</strong><br> +087 * The validity of the p-value depends on the assumptions of the parametric +088 * t-test procedure, as discussed +089 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +090 * here</a></p> +091 * <p> +092 * <strong>Preconditions</strong>: <ul> +093 * <li>The input array lengths must be the same and their common length must +094 * be at least 2. +095 * </li></ul></p> +096 * +097 * @param sample1 array of sample data values +098 * @param sample2 array of sample data values +099 * @return p-value for t-test +100 * @throws IllegalArgumentException if the precondition is not met +101 * @throws MathException if an error occurs computing the p-value +102 */ +103 double pairedTTest(double[] sample1, double[] sample2) +104 throws IllegalArgumentException, MathException; +105 /** +106 * Performs a paired t-test evaluating the null hypothesis that the +107 * mean of the paired differences between <code>sample1</code> and +108 * <code>sample2</code> is 0 in favor of the two-sided alternative that the +109 * mean paired difference is not equal to 0, with significance level +110 * <code>alpha</code>. +111 * <p> +112 * Returns <code>true</code> iff the null hypothesis can be rejected with +113 * confidence <code>1 - alpha</code>. To perform a 1-sided test, use +114 * <code>alpha * 2</code></p> +115 * <p> +116 * <strong>Usage Note:</strong><br> +117 * The validity of the test depends on the assumptions of the parametric +118 * t-test procedure, as discussed +119 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +120 * here</a></p> +121 * <p> +122 * <strong>Preconditions</strong>: <ul> +123 * <li>The input array lengths must be the same and their common length +124 * must be at least 2. +125 * </li> +126 * <li> <code> 0 < alpha < 0.5 </code> +127 * </li></ul></p> +128 * +129 * @param sample1 array of sample data values +130 * @param sample2 array of sample data values +131 * @param alpha significance level of the test +132 * @return true if the null hypothesis can be rejected with +133 * confidence 1 - alpha +134 * @throws IllegalArgumentException if the preconditions are not met +135 * @throws MathException if an error occurs performing the test +136 */ +137 boolean pairedTTest( +138 double[] sample1, +139 double[] sample2, +140 double alpha) +141 throws IllegalArgumentException, MathException; +142 /** +143 * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/section2/prc22.htm#formula"> +144 * t statistic </a> given observed values and a comparison constant. +145 * <p> +146 * This statistic can be used to perform a one sample t-test for the mean. +147 * </p><p> +148 * <strong>Preconditions</strong>: <ul> +149 * <li>The observed array length must be at least 2. +150 * </li></ul></p> +151 * +152 * @param mu comparison constant +153 * @param observed array of values +154 * @return t statistic +155 * @throws IllegalArgumentException if input array length is less than 2 +156 */ +157 double t(double mu, double[] observed) +158 throws IllegalArgumentException; +159 /** +160 * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/section2/prc22.htm#formula"> +161 * t statistic </a> to use in comparing the mean of the dataset described by +162 * <code>sampleStats</code> to <code>mu</code>. +163 * <p> +164 * This statistic can be used to perform a one sample t-test for the mean. +165 * </p><p> +166 * <strong>Preconditions</strong>: <ul> +167 * <li><code>observed.getN() > = 2</code>. +168 * </li></ul></p> +169 * +170 * @param mu comparison constant +171 * @param sampleStats DescriptiveStatistics holding sample summary statitstics +172 * @return t statistic +173 * @throws IllegalArgumentException if the precondition is not met +174 */ +175 double t(double mu, StatisticalSummary sampleStats) +176 throws IllegalArgumentException; +177 /** +178 * Computes a 2-sample t statistic, under the hypothesis of equal +179 * subpopulation variances. To compute a t-statistic without the +180 * equal variances hypothesis, use {@link #t(double[], double[])}. +181 * <p> +182 * This statistic can be used to perform a (homoscedastic) two-sample +183 * t-test to compare sample means.</p> +184 * <p> +185 * The t-statisitc is</p> +186 * <p> +187 * <code> t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var))</code> +188 * </p><p> +189 * where <strong><code>n1</code></strong> is the size of first sample; +190 * <strong><code> n2</code></strong> is the size of second sample; +191 * <strong><code> m1</code></strong> is the mean of first sample; +192 * <strong><code> m2</code></strong> is the mean of second sample</li> +193 * </ul> +194 * and <strong><code>var</code></strong> is the pooled variance estimate: +195 * </p><p> +196 * <code>var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1)))</code> +197 * </p><p> +198 * with <strong><code>var1<code></strong> the variance of the first sample and +199 * <strong><code>var2</code></strong> the variance of the second sample. +200 * </p><p> +201 * <strong>Preconditions</strong>: <ul> +202 * <li>The observed array lengths must both be at least 2. +203 * </li></ul></p> +204 * +205 * @param sample1 array of sample data values +206 * @param sample2 array of sample data values +207 * @return t statistic +208 * @throws IllegalArgumentException if the precondition is not met +209 */ +210 double homoscedasticT(double[] sample1, double[] sample2) +211 throws IllegalArgumentException; +212 /** +213 * Computes a 2-sample t statistic, without the hypothesis of equal +214 * subpopulation variances. To compute a t-statistic assuming equal +215 * variances, use {@link #homoscedasticT(double[], double[])}. +216 * <p> +217 * This statistic can be used to perform a two-sample t-test to compare +218 * sample means.</p> +219 * <p> +220 * The t-statisitc is</p> +221 * <p> +222 * <code> t = (m1 - m2) / sqrt(var1/n1 + var2/n2)</code> +223 * </p><p> +224 * where <strong><code>n1</code></strong> is the size of the first sample +225 * <strong><code> n2</code></strong> is the size of the second sample; +226 * <strong><code> m1</code></strong> is the mean of the first sample; +227 * <strong><code> m2</code></strong> is the mean of the second sample; +228 * <strong><code> var1</code></strong> is the variance of the first sample; +229 * <strong><code> var2</code></strong> is the variance of the second sample; +230 * </p><p> +231 * <strong>Preconditions</strong>: <ul> +232 * <li>The observed array lengths must both be at least 2. +233 * </li></ul></p> +234 * +235 * @param sample1 array of sample data values +236 * @param sample2 array of sample data values +237 * @return t statistic +238 * @throws IllegalArgumentException if the precondition is not met +239 */ +240 double t(double[] sample1, double[] sample2) +241 throws IllegalArgumentException; +242 /** +243 * Computes a 2-sample t statistic </a>, comparing the means of the datasets +244 * described by two {@link StatisticalSummary} instances, without the +245 * assumption of equal subpopulation variances. Use +246 * {@link #homoscedasticT(StatisticalSummary, StatisticalSummary)} to +247 * compute a t-statistic under the equal variances assumption. +248 * <p> +249 * This statistic can be used to perform a two-sample t-test to compare +250 * sample means.</p> +251 * <p> +252 * The returned t-statisitc is</p> +253 * <p> +254 * <code> t = (m1 - m2) / sqrt(var1/n1 + var2/n2)</code> +255 * </p><p> +256 * where <strong><code>n1</code></strong> is the size of the first sample; +257 * <strong><code> n2</code></strong> is the size of the second sample; +258 * <strong><code> m1</code></strong> is the mean of the first sample; +259 * <strong><code> m2</code></strong> is the mean of the second sample +260 * <strong><code> var1</code></strong> is the variance of the first sample; +261 * <strong><code> var2</code></strong> is the variance of the second sample +262 * </p><p> +263 * <strong>Preconditions</strong>: <ul> +264 * <li>The datasets described by the two Univariates must each contain +265 * at least 2 observations. +266 * </li></ul></p> +267 * +268 * @param sampleStats1 StatisticalSummary describing data from the first sample +269 * @param sampleStats2 StatisticalSummary describing data from the second sample +270 * @return t statistic +271 * @throws IllegalArgumentException if the precondition is not met +272 */ +273 double t( +274 StatisticalSummary sampleStats1, +275 StatisticalSummary sampleStats2) +276 throws IllegalArgumentException; +277 /** +278 * Computes a 2-sample t statistic, comparing the means of the datasets +279 * described by two {@link StatisticalSummary} instances, under the +280 * assumption of equal subpopulation variances. To compute a t-statistic +281 * without the equal variances assumption, use +282 * {@link #t(StatisticalSummary, StatisticalSummary)}. +283 * <p> +284 * This statistic can be used to perform a (homoscedastic) two-sample +285 * t-test to compare sample means.</p> +286 * <p> +287 * The t-statisitc returned is</p> +288 * <p> +289 * <code> t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var))</code> +290 * </p><p> +291 * where <strong><code>n1</code></strong> is the size of first sample; +292 * <strong><code> n2</code></strong> is the size of second sample; +293 * <strong><code> m1</code></strong> is the mean of first sample; +294 * <strong><code> m2</code></strong> is the mean of second sample +295 * and <strong><code>var</code></strong> is the pooled variance estimate: +296 * </p><p> +297 * <code>var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1)))</code> +298 * </p><p> +299 * with <strong><code>var1<code></strong> the variance of the first sample and +300 * <strong><code>var2</code></strong> the variance of the second sample. +301 * </p><p> +302 * <strong>Preconditions</strong>: <ul> +303 * <li>The datasets described by the two Univariates must each contain +304 * at least 2 observations. +305 * </li></ul></p> +306 * +307 * @param sampleStats1 StatisticalSummary describing data from the first sample +308 * @param sampleStats2 StatisticalSummary describing data from the second sample +309 * @return t statistic +310 * @throws IllegalArgumentException if the precondition is not met +311 */ +312 double homoscedasticT( +313 StatisticalSummary sampleStats1, +314 StatisticalSummary sampleStats2) +315 throws IllegalArgumentException; +316 /** +317 * Returns the <i>observed significance level</i>, or +318 * <i>p-value</i>, associated with a one-sample, two-tailed t-test +319 * comparing the mean of the input array with the constant <code>mu</code>. +320 * <p> +321 * The number returned is the smallest significance level +322 * at which one can reject the null hypothesis that the mean equals +323 * <code>mu</code> in favor of the two-sided alternative that the mean +324 * is different from <code>mu</code>. For a one-sided test, divide the +325 * returned value by 2.</p> +326 * <p> +327 * <strong>Usage Note:</strong><br> +328 * The validity of the test depends on the assumptions of the parametric +329 * t-test procedure, as discussed +330 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">here</a> +331 * </p><p> +332 * <strong>Preconditions</strong>: <ul> +333 * <li>The observed array length must be at least 2. +334 * </li></ul></p> +335 * +336 * @param mu constant value to compare sample mean against +337 * @param sample array of sample data values +338 * @return p-value +339 * @throws IllegalArgumentException if the precondition is not met +340 * @throws MathException if an error occurs computing the p-value +341 */ +342 double tTest(double mu, double[] sample) +343 throws IllegalArgumentException, MathException; +344 /** +345 * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm"> +346 * two-sided t-test</a> evaluating the null hypothesis that the mean of the population from +347 * which <code>sample</code> is drawn equals <code>mu</code>. +348 * <p> +349 * Returns <code>true</code> iff the null hypothesis can be +350 * rejected with confidence <code>1 - alpha</code>. To +351 * perform a 1-sided test, use <code>alpha * 2</code></p> +352 * <p> +353 * <strong>Examples:</strong><br><ol> +354 * <li>To test the (2-sided) hypothesis <code>sample mean = mu </code> at +355 * the 95% level, use <br><code>tTest(mu, sample, 0.05) </code> +356 * </li> +357 * <li>To test the (one-sided) hypothesis <code> sample mean < mu </code> +358 * at the 99% level, first verify that the measured sample mean is less +359 * than <code>mu</code> and then use +360 * <br><code>tTest(mu, sample, 0.02) </code> +361 * </li></ol></p> +362 * <p> +363 * <strong>Usage Note:</strong><br> +364 * The validity of the test depends on the assumptions of the one-sample +365 * parametric t-test procedure, as discussed +366 * <a href="http://www.basic.nwu.edu/statguidefiles/sg_glos.html#one-sample">here</a> +367 * </p><p> +368 * <strong>Preconditions</strong>: <ul> +369 * <li>The observed array length must be at least 2. +370 * </li></ul></p> +371 * +372 * @param mu constant value to compare sample mean against +373 * @param sample array of sample data values +374 * @param alpha significance level of the test +375 * @return p-value +376 * @throws IllegalArgumentException if the precondition is not met +377 * @throws MathException if an error computing the p-value +378 */ +379 boolean tTest(double mu, double[] sample, double alpha) +380 throws IllegalArgumentException, MathException; +381 /** +382 * Returns the <i>observed significance level</i>, or +383 * <i>p-value</i>, associated with a one-sample, two-tailed t-test +384 * comparing the mean of the dataset described by <code>sampleStats</code> +385 * with the constant <code>mu</code>. +386 * <p> +387 * The number returned is the smallest significance level +388 * at which one can reject the null hypothesis that the mean equals +389 * <code>mu</code> in favor of the two-sided alternative that the mean +390 * is different from <code>mu</code>. For a one-sided test, divide the +391 * returned value by 2.</p> +392 * <p> +393 * <strong>Usage Note:</strong><br> +394 * The validity of the test depends on the assumptions of the parametric +395 * t-test procedure, as discussed +396 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +397 * here</a></p> +398 * <p> +399 * <strong>Preconditions</strong>: <ul> +400 * <li>The sample must contain at least 2 observations. +401 * </li></ul></p> +402 * +403 * @param mu constant value to compare sample mean against +404 * @param sampleStats StatisticalSummary describing sample data +405 * @return p-value +406 * @throws IllegalArgumentException if the precondition is not met +407 * @throws MathException if an error occurs computing the p-value +408 */ +409 double tTest(double mu, StatisticalSummary sampleStats) +410 throws IllegalArgumentException, MathException; +411 /** +412 * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm"> +413 * two-sided t-test</a> evaluating the null hypothesis that the mean of the +414 * population from which the dataset described by <code>stats</code> is +415 * drawn equals <code>mu</code>. +416 * <p> +417 * Returns <code>true</code> iff the null hypothesis can be rejected with +418 * confidence <code>1 - alpha</code>. To perform a 1-sided test, use +419 * <code>alpha * 2.</code></p> +420 * <p> +421 * <strong>Examples:</strong><br><ol> +422 * <li>To test the (2-sided) hypothesis <code>sample mean = mu </code> at +423 * the 95% level, use <br><code>tTest(mu, sampleStats, 0.05) </code> +424 * </li> +425 * <li>To test the (one-sided) hypothesis <code> sample mean < mu </code> +426 * at the 99% level, first verify that the measured sample mean is less +427 * than <code>mu</code> and then use +428 * <br><code>tTest(mu, sampleStats, 0.02) </code> +429 * </li></ol></p> +430 * <p> +431 * <strong>Usage Note:</strong><br> +432 * The validity of the test depends on the assumptions of the one-sample +433 * parametric t-test procedure, as discussed +434 * <a href="http://www.basic.nwu.edu/statguidefiles/sg_glos.html#one-sample">here</a> +435 * </p><p> +436 * <strong>Preconditions</strong>: <ul> +437 * <li>The sample must include at least 2 observations. +438 * </li></ul></p> +439 * +440 * @param mu constant value to compare sample mean against +441 * @param sampleStats StatisticalSummary describing sample data values +442 * @param alpha significance level of the test +443 * @return p-value +444 * @throws IllegalArgumentException if the precondition is not met +445 * @throws MathException if an error occurs computing the p-value +446 */ +447 boolean tTest( +448 double mu, +449 StatisticalSummary sampleStats, +450 double alpha) +451 throws IllegalArgumentException, MathException; +452 /** +453 * Returns the <i>observed significance level</i>, or +454 * <i>p-value</i>, associated with a two-sample, two-tailed t-test +455 * comparing the means of the input arrays. +456 * <p> +457 * The number returned is the smallest significance level +458 * at which one can reject the null hypothesis that the two means are +459 * equal in favor of the two-sided alternative that they are different. +460 * For a one-sided test, divide the returned value by 2.</p> +461 * <p> +462 * The test does not assume that the underlying popuation variances are +463 * equal and it uses approximated degrees of freedom computed from the +464 * sample data to compute the p-value. The t-statistic used is as defined in +465 * {@link #t(double[], double[])} and the Welch-Satterthwaite approximation +466 * to the degrees of freedom is used, +467 * as described +468 * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm"> +469 * here.</a> To perform the test under the assumption of equal subpopulation +470 * variances, use {@link #homoscedasticTTest(double[], double[])}.</p> +471 * <p> +472 * <strong>Usage Note:</strong><br> +473 * The validity of the p-value depends on the assumptions of the parametric +474 * t-test procedure, as discussed +475 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +476 * here</a></p> +477 * <p> +478 * <strong>Preconditions</strong>: <ul> +479 * <li>The observed array lengths must both be at least 2. +480 * </li></ul></p> +481 * +482 * @param sample1 array of sample data values +483 * @param sample2 array of sample data values +484 * @return p-value for t-test +485 * @throws IllegalArgumentException if the precondition is not met +486 * @throws MathException if an error occurs computing the p-value +487 */ +488 double tTest(double[] sample1, double[] sample2) +489 throws IllegalArgumentException, MathException; +490 /** +491 * Returns the <i>observed significance level</i>, or +492 * <i>p-value</i>, associated with a two-sample, two-tailed t-test +493 * comparing the means of the input arrays, under the assumption that +494 * the two samples are drawn from subpopulations with equal variances. +495 * To perform the test without the equal variances assumption, use +496 * {@link #tTest(double[], double[])}.</p> +497 * <p> +498 * The number returned is the smallest significance level +499 * at which one can reject the null hypothesis that the two means are +500 * equal in favor of the two-sided alternative that they are different. +501 * For a one-sided test, divide the returned value by 2.</p> +502 * <p> +503 * A pooled variance estimate is used to compute the t-statistic. See +504 * {@link #homoscedasticT(double[], double[])}. The sum of the sample sizes +505 * minus 2 is used as the degrees of freedom.</p> +506 * <p> +507 * <strong>Usage Note:</strong><br> +508 * The validity of the p-value depends on the assumptions of the parametric +509 * t-test procedure, as discussed +510 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +511 * here</a></p> +512 * <p> +513 * <strong>Preconditions</strong>: <ul> +514 * <li>The observed array lengths must both be at least 2. +515 * </li></ul></p> +516 * +517 * @param sample1 array of sample data values +518 * @param sample2 array of sample data values +519 * @return p-value for t-test +520 * @throws IllegalArgumentException if the precondition is not met +521 * @throws MathException if an error occurs computing the p-value +522 */ +523 double homoscedasticTTest( +524 double[] sample1, +525 double[] sample2) +526 throws IllegalArgumentException, MathException; +527 /** +528 * Performs a +529 * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm"> +530 * two-sided t-test</a> evaluating the null hypothesis that <code>sample1</code> +531 * and <code>sample2</code> are drawn from populations with the same mean, +532 * with significance level <code>alpha</code>. This test does not assume +533 * that the subpopulation variances are equal. To perform the test assuming +534 * equal variances, use +535 * {@link #homoscedasticTTest(double[], double[], double)}. +536 * <p> +537 * Returns <code>true</code> iff the null hypothesis that the means are +538 * equal can be rejected with confidence <code>1 - alpha</code>. To +539 * perform a 1-sided test, use <code>alpha * 2</code></p> +540 * <p> +541 * See {@link #t(double[], double[])} for the formula used to compute the +542 * t-statistic. Degrees of freedom are approximated using the +543 * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm"> +544 * Welch-Satterthwaite approximation.</a></p> +545 * <p> +546 * <strong>Examples:</strong><br><ol> +547 * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at +548 * the 95% level, use +549 * <br><code>tTest(sample1, sample2, 0.05). </code> +550 * </li> +551 * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2 </code>, +552 * at the 99% level, first verify that the measured mean of <code>sample 1</code> +553 * is less than the mean of <code>sample 2</code> and then use +554 * <br><code>tTest(sample1, sample2, 0.02) </code> +555 * </li></ol></p> +556 * <p> +557 * <strong>Usage Note:</strong><br> +558 * The validity of the test depends on the assumptions of the parametric +559 * t-test procedure, as discussed +560 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +561 * here</a></p> +562 * <p> +563 * <strong>Preconditions</strong>: <ul> +564 * <li>The observed array lengths must both be at least 2. +565 * </li> +566 * <li> <code> 0 < alpha < 0.5 </code> +567 * </li></ul></p> +568 * +569 * @param sample1 array of sample data values +570 * @param sample2 array of sample data values +571 * @param alpha significance level of the test +572 * @return true if the null hypothesis can be rejected with +573 * confidence 1 - alpha +574 * @throws IllegalArgumentException if the preconditions are not met +575 * @throws MathException if an error occurs performing the test +576 */ +577 boolean tTest( +578 double[] sample1, +579 double[] sample2, +580 double alpha) +581 throws IllegalArgumentException, MathException; +582 /** +583 * Performs a +584 * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm"> +585 * two-sided t-test</a> evaluating the null hypothesis that <code>sample1</code> +586 * and <code>sample2</code> are drawn from populations with the same mean, +587 * with significance level <code>alpha</code>, assuming that the +588 * subpopulation variances are equal. Use +589 * {@link #tTest(double[], double[], double)} to perform the test without +590 * the assumption of equal variances. +591 * <p> +592 * Returns <code>true</code> iff the null hypothesis that the means are +593 * equal can be rejected with confidence <code>1 - alpha</code>. To +594 * perform a 1-sided test, use <code>alpha * 2.</code> To perform the test +595 * without the assumption of equal subpopulation variances, use +596 * {@link #tTest(double[], double[], double)}.</p> +597 * <p> +598 * A pooled variance estimate is used to compute the t-statistic. See +599 * {@link #t(double[], double[])} for the formula. The sum of the sample +600 * sizes minus 2 is used as the degrees of freedom.</p> +601 * <p> +602 * <strong>Examples:</strong><br><ol> +603 * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at +604 * the 95% level, use <br><code>tTest(sample1, sample2, 0.05). </code> +605 * </li> +606 * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2, </code> +607 * at the 99% level, first verify that the measured mean of +608 * <code>sample 1</code> is less than the mean of <code>sample 2</code> +609 * and then use +610 * <br><code>tTest(sample1, sample2, 0.02) </code> +611 * </li></ol></p> +612 * <p> +613 * <strong>Usage Note:</strong><br> +614 * The validity of the test depends on the assumptions of the parametric +615 * t-test procedure, as discussed +616 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +617 * here</a></p> +618 * <p> +619 * <strong>Preconditions</strong>: <ul> +620 * <li>The observed array lengths must both be at least 2. +621 * </li> +622 * <li> <code> 0 < alpha < 0.5 </code> +623 * </li></ul></p> +624 * +625 * @param sample1 array of sample data values +626 * @param sample2 array of sample data values +627 * @param alpha significance level of the test +628 * @return true if the null hypothesis can be rejected with +629 * confidence 1 - alpha +630 * @throws IllegalArgumentException if the preconditions are not met +631 * @throws MathException if an error occurs performing the test +632 */ +633 boolean homoscedasticTTest( +634 double[] sample1, +635 double[] sample2, +636 double alpha) +637 throws IllegalArgumentException, MathException; +638 /** +639 * Returns the <i>observed significance level</i>, or +640 * <i>p-value</i>, associated with a two-sample, two-tailed t-test +641 * comparing the means of the datasets described by two StatisticalSummary +642 * instances. +643 * <p> +644 * The number returned is the smallest significance level +645 * at which one can reject the null hypothesis that the two means are +646 * equal in favor of the two-sided alternative that they are different. +647 * For a one-sided test, divide the returned value by 2.</p> +648 * <p> +649 * The test does not assume that the underlying popuation variances are +650 * equal and it uses approximated degrees of freedom computed from the +651 * sample data to compute the p-value. To perform the test assuming +652 * equal variances, use +653 * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}.</p> +654 * <p> +655 * <strong>Usage Note:</strong><br> +656 * The validity of the p-value depends on the assumptions of the parametric +657 * t-test procedure, as discussed +658 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +659 * here</a></p> +660 * <p> +661 * <strong>Preconditions</strong>: <ul> +662 * <li>The datasets described by the two Univariates must each contain +663 * at least 2 observations. +664 * </li></ul></p> +665 * +666 * @param sampleStats1 StatisticalSummary describing data from the first sample +667 * @param sampleStats2 StatisticalSummary describing data from the second sample +668 * @return p-value for t-test +669 * @throws IllegalArgumentException if the precondition is not met +670 * @throws MathException if an error occurs computing the p-value +671 */ +672 double tTest( +673 StatisticalSummary sampleStats1, +674 StatisticalSummary sampleStats2) +675 throws IllegalArgumentException, MathException; +676 /** +677 * Returns the <i>observed significance level</i>, or +678 * <i>p-value</i>, associated with a two-sample, two-tailed t-test +679 * comparing the means of the datasets described by two StatisticalSummary +680 * instances, under the hypothesis of equal subpopulation variances. To +681 * perform a test without the equal variances assumption, use +682 * {@link #tTest(StatisticalSummary, StatisticalSummary)}. +683 * <p> +684 * The number returned is the smallest significance level +685 * at which one can reject the null hypothesis that the two means are +686 * equal in favor of the two-sided alternative that they are different. +687 * For a one-sided test, divide the returned value by 2.</p> +688 * <p> +689 * See {@link #homoscedasticT(double[], double[])} for the formula used to +690 * compute the t-statistic. The sum of the sample sizes minus 2 is used as +691 * the degrees of freedom.</p> +692 * <p> +693 * <strong>Usage Note:</strong><br> +694 * The validity of the p-value depends on the assumptions of the parametric +695 * t-test procedure, as discussed +696 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">here</a> +697 * </p><p> +698 * <strong>Preconditions</strong>: <ul> +699 * <li>The datasets described by the two Univariates must each contain +700 * at least 2 observations. +701 * </li></ul></p> +702 * +703 * @param sampleStats1 StatisticalSummary describing data from the first sample +704 * @param sampleStats2 StatisticalSummary describing data from the second sample +705 * @return p-value for t-test +706 * @throws IllegalArgumentException if the precondition is not met +707 * @throws MathException if an error occurs computing the p-value +708 */ +709 double homoscedasticTTest( +710 StatisticalSummary sampleStats1, +711 StatisticalSummary sampleStats2) +712 throws IllegalArgumentException, MathException; +713 /** +714 * Performs a +715 * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm"> +716 * two-sided t-test</a> evaluating the null hypothesis that +717 * <code>sampleStats1</code> and <code>sampleStats2</code> describe +718 * datasets drawn from populations with the same mean, with significance +719 * level <code>alpha</code>. This test does not assume that the +720 * subpopulation variances are equal. To perform the test under the equal +721 * variances assumption, use +722 * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}. +723 * <p> +724 * Returns <code>true</code> iff the null hypothesis that the means are +725 * equal can be rejected with confidence <code>1 - alpha</code>. To +726 * perform a 1-sided test, use <code>alpha * 2</code></p> +727 * <p> +728 * See {@link #t(double[], double[])} for the formula used to compute the +729 * t-statistic. Degrees of freedom are approximated using the +730 * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm"> +731 * Welch-Satterthwaite approximation.</a></p> +732 * <p> +733 * <strong>Examples:</strong><br><ol> +734 * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at +735 * the 95%, use +736 * <br><code>tTest(sampleStats1, sampleStats2, 0.05) </code> +737 * </li> +738 * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2 </code> +739 * at the 99% level, first verify that the measured mean of +740 * <code>sample 1</code> is less than the mean of <code>sample 2</code> +741 * and then use +742 * <br><code>tTest(sampleStats1, sampleStats2, 0.02) </code> +743 * </li></ol></p> +744 * <p> +745 * <strong>Usage Note:</strong><br> +746 * The validity of the test depends on the assumptions of the parametric +747 * t-test procedure, as discussed +748 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +749 * here</a></p> +750 * <p> +751 * <strong>Preconditions</strong>: <ul> +752 * <li>The datasets described by the two Univariates must each contain +753 * at least 2 observations. +754 * </li> +755 * <li> <code> 0 < alpha < 0.5 </code> +756 * </li></ul></p> +757 * +758 * @param sampleStats1 StatisticalSummary describing sample data values +759 * @param sampleStats2 StatisticalSummary describing sample data values +760 * @param alpha significance level of the test +761 * @return true if the null hypothesis can be rejected with +762 * confidence 1 - alpha +763 * @throws IllegalArgumentException if the preconditions are not met +764 * @throws MathException if an error occurs performing the test +765 */ +766 boolean tTest( +767 StatisticalSummary sampleStats1, +768 StatisticalSummary sampleStats2, +769 double alpha) +770 throws IllegalArgumentException, MathException; +771 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/TTestImpl.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/TTestImpl.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1130 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.inference; +018 +019 import org.apache.commons.math.MathException; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.distribution.TDistribution; +022 import org.apache.commons.math.distribution.TDistributionImpl; +023 import org.apache.commons.math.stat.StatUtils; +024 import org.apache.commons.math.stat.descriptive.StatisticalSummary; +025 +026 /** +027 * Implements t-test statistics defined in the {@link TTest} interface. +028 * <p> +029 * Uses commons-math {@link org.apache.commons.math.distribution.TDistribution} +030 * implementation to estimate exact p-values.</p> +031 * +032 * @version $Revision: 885278 $ $Date: 2009-11-29 16:47:51 -0500 (Sun, 29 Nov 2009) $ +033 */ +034 public class TTestImpl implements TTest { +035 +036 /** Message for insufficient data. */ +037 private static final String INSUFFICIENT_DATA_MESSAGE = +038 "insufficient data for t statistic, needs at least 2, got {0}"; +039 +040 /** Distribution used to compute inference statistics. */ +041 private TDistribution distribution; +042 +043 /** +044 * Default constructor. +045 */ +046 public TTestImpl() { +047 this(new TDistributionImpl(1.0)); +048 } +049 +050 /** +051 * Create a test instance using the given distribution for computing +052 * inference statistics. +053 * @param t distribution used to compute inference statistics. +054 * @since 1.2 +055 */ +056 public TTestImpl(TDistribution t) { +057 super(); +058 setDistribution(t); +059 } +060 +061 /** +062 * Computes a paired, 2-sample t-statistic based on the data in the input +063 * arrays. The t-statistic returned is equivalent to what would be returned by +064 * computing the one-sample t-statistic {@link #t(double, double[])}, with +065 * <code>mu = 0</code> and the sample array consisting of the (signed) +066 * differences between corresponding entries in <code>sample1</code> and +067 * <code>sample2.</code> +068 * <p> +069 * <strong>Preconditions</strong>: <ul> +070 * <li>The input arrays must have the same length and their common length +071 * must be at least 2. +072 * </li></ul></p> +073 * +074 * @param sample1 array of sample data values +075 * @param sample2 array of sample data values +076 * @return t statistic +077 * @throws IllegalArgumentException if the precondition is not met +078 * @throws MathException if the statistic can not be computed do to a +079 * convergence or other numerical error. +080 */ +081 public double pairedT(double[] sample1, double[] sample2) +082 throws IllegalArgumentException, MathException { +083 checkSampleData(sample1); +084 checkSampleData(sample2); +085 double meanDifference = StatUtils.meanDifference(sample1, sample2); +086 return t(meanDifference, 0, +087 StatUtils.varianceDifference(sample1, sample2, meanDifference), +088 sample1.length); +089 } +090 +091 /** +092 * Returns the <i>observed significance level</i>, or +093 * <i> p-value</i>, associated with a paired, two-sample, two-tailed t-test +094 * based on the data in the input arrays. +095 * <p> +096 * The number returned is the smallest significance level +097 * at which one can reject the null hypothesis that the mean of the paired +098 * differences is 0 in favor of the two-sided alternative that the mean paired +099 * difference is not equal to 0. For a one-sided test, divide the returned +100 * value by 2.</p> +101 * <p> +102 * This test is equivalent to a one-sample t-test computed using +103 * {@link #tTest(double, double[])} with <code>mu = 0</code> and the sample +104 * array consisting of the signed differences between corresponding elements of +105 * <code>sample1</code> and <code>sample2.</code></p> +106 * <p> +107 * <strong>Usage Note:</strong><br> +108 * The validity of the p-value depends on the assumptions of the parametric +109 * t-test procedure, as discussed +110 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +111 * here</a></p> +112 * <p> +113 * <strong>Preconditions</strong>: <ul> +114 * <li>The input array lengths must be the same and their common length must +115 * be at least 2. +116 * </li></ul></p> +117 * +118 * @param sample1 array of sample data values +119 * @param sample2 array of sample data values +120 * @return p-value for t-test +121 * @throws IllegalArgumentException if the precondition is not met +122 * @throws MathException if an error occurs computing the p-value +123 */ +124 public double pairedTTest(double[] sample1, double[] sample2) +125 throws IllegalArgumentException, MathException { +126 double meanDifference = StatUtils.meanDifference(sample1, sample2); +127 return tTest(meanDifference, 0, +128 StatUtils.varianceDifference(sample1, sample2, meanDifference), +129 sample1.length); +130 } +131 +132 /** +133 * Performs a paired t-test evaluating the null hypothesis that the +134 * mean of the paired differences between <code>sample1</code> and +135 * <code>sample2</code> is 0 in favor of the two-sided alternative that the +136 * mean paired difference is not equal to 0, with significance level +137 * <code>alpha</code>. +138 * <p> +139 * Returns <code>true</code> iff the null hypothesis can be rejected with +140 * confidence <code>1 - alpha</code>. To perform a 1-sided test, use +141 * <code>alpha * 2</code></p> +142 * <p> +143 * <strong>Usage Note:</strong><br> +144 * The validity of the test depends on the assumptions of the parametric +145 * t-test procedure, as discussed +146 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +147 * here</a></p> +148 * <p> +149 * <strong>Preconditions</strong>: <ul> +150 * <li>The input array lengths must be the same and their common length +151 * must be at least 2. +152 * </li> +153 * <li> <code> 0 < alpha < 0.5 </code> +154 * </li></ul></p> +155 * +156 * @param sample1 array of sample data values +157 * @param sample2 array of sample data values +158 * @param alpha significance level of the test +159 * @return true if the null hypothesis can be rejected with +160 * confidence 1 - alpha +161 * @throws IllegalArgumentException if the preconditions are not met +162 * @throws MathException if an error occurs performing the test +163 */ +164 public boolean pairedTTest(double[] sample1, double[] sample2, double alpha) +165 throws IllegalArgumentException, MathException { +166 checkSignificanceLevel(alpha); +167 return pairedTTest(sample1, sample2) < alpha; +168 } +169 +170 /** +171 * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/section2/prc22.htm#formula"> +172 * t statistic </a> given observed values and a comparison constant. +173 * <p> +174 * This statistic can be used to perform a one sample t-test for the mean. +175 * </p><p> +176 * <strong>Preconditions</strong>: <ul> +177 * <li>The observed array length must be at least 2. +178 * </li></ul></p> +179 * +180 * @param mu comparison constant +181 * @param observed array of values +182 * @return t statistic +183 * @throws IllegalArgumentException if input array length is less than 2 +184 */ +185 public double t(double mu, double[] observed) +186 throws IllegalArgumentException { +187 checkSampleData(observed); +188 return t(StatUtils.mean(observed), mu, StatUtils.variance(observed), +189 observed.length); +190 } +191 +192 /** +193 * Computes a <a href="http://www.itl.nist.gov/div898/handbook/prc/section2/prc22.htm#formula"> +194 * t statistic </a> to use in comparing the mean of the dataset described by +195 * <code>sampleStats</code> to <code>mu</code>. +196 * <p> +197 * This statistic can be used to perform a one sample t-test for the mean. +198 * </p><p> +199 * <strong>Preconditions</strong>: <ul> +200 * <li><code>observed.getN() > = 2</code>. +201 * </li></ul></p> +202 * +203 * @param mu comparison constant +204 * @param sampleStats DescriptiveStatistics holding sample summary statitstics +205 * @return t statistic +206 * @throws IllegalArgumentException if the precondition is not met +207 */ +208 public double t(double mu, StatisticalSummary sampleStats) +209 throws IllegalArgumentException { +210 checkSampleData(sampleStats); +211 return t(sampleStats.getMean(), mu, sampleStats.getVariance(), +212 sampleStats.getN()); +213 } +214 +215 /** +216 * Computes a 2-sample t statistic, under the hypothesis of equal +217 * subpopulation variances. To compute a t-statistic without the +218 * equal variances hypothesis, use {@link #t(double[], double[])}. +219 * <p> +220 * This statistic can be used to perform a (homoscedastic) two-sample +221 * t-test to compare sample means.</p> +222 * <p> +223 * The t-statisitc is</p> +224 * <p> +225 * <code> t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var))</code> +226 * </p><p> +227 * where <strong><code>n1</code></strong> is the size of first sample; +228 * <strong><code> n2</code></strong> is the size of second sample; +229 * <strong><code> m1</code></strong> is the mean of first sample; +230 * <strong><code> m2</code></strong> is the mean of second sample</li> +231 * </ul> +232 * and <strong><code>var</code></strong> is the pooled variance estimate: +233 * </p><p> +234 * <code>var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1)))</code> +235 * </p><p> +236 * with <strong><code>var1<code></strong> the variance of the first sample and +237 * <strong><code>var2</code></strong> the variance of the second sample. +238 * </p><p> +239 * <strong>Preconditions</strong>: <ul> +240 * <li>The observed array lengths must both be at least 2. +241 * </li></ul></p> +242 * +243 * @param sample1 array of sample data values +244 * @param sample2 array of sample data values +245 * @return t statistic +246 * @throws IllegalArgumentException if the precondition is not met +247 */ +248 public double homoscedasticT(double[] sample1, double[] sample2) +249 throws IllegalArgumentException { +250 checkSampleData(sample1); +251 checkSampleData(sample2); +252 return homoscedasticT(StatUtils.mean(sample1), StatUtils.mean(sample2), +253 StatUtils.variance(sample1), StatUtils.variance(sample2), +254 sample1.length, sample2.length); +255 } +256 +257 /** +258 * Computes a 2-sample t statistic, without the hypothesis of equal +259 * subpopulation variances. To compute a t-statistic assuming equal +260 * variances, use {@link #homoscedasticT(double[], double[])}. +261 * <p> +262 * This statistic can be used to perform a two-sample t-test to compare +263 * sample means.</p> +264 * <p> +265 * The t-statisitc is</p> +266 * <p> +267 * <code> t = (m1 - m2) / sqrt(var1/n1 + var2/n2)</code> +268 * </p><p> +269 * where <strong><code>n1</code></strong> is the size of the first sample +270 * <strong><code> n2</code></strong> is the size of the second sample; +271 * <strong><code> m1</code></strong> is the mean of the first sample; +272 * <strong><code> m2</code></strong> is the mean of the second sample; +273 * <strong><code> var1</code></strong> is the variance of the first sample; +274 * <strong><code> var2</code></strong> is the variance of the second sample; +275 * </p><p> +276 * <strong>Preconditions</strong>: <ul> +277 * <li>The observed array lengths must both be at least 2. +278 * </li></ul></p> +279 * +280 * @param sample1 array of sample data values +281 * @param sample2 array of sample data values +282 * @return t statistic +283 * @throws IllegalArgumentException if the precondition is not met +284 */ +285 public double t(double[] sample1, double[] sample2) +286 throws IllegalArgumentException { +287 checkSampleData(sample1); +288 checkSampleData(sample2); +289 return t(StatUtils.mean(sample1), StatUtils.mean(sample2), +290 StatUtils.variance(sample1), StatUtils.variance(sample2), +291 sample1.length, sample2.length); +292 } +293 +294 /** +295 * Computes a 2-sample t statistic </a>, comparing the means of the datasets +296 * described by two {@link StatisticalSummary} instances, without the +297 * assumption of equal subpopulation variances. Use +298 * {@link #homoscedasticT(StatisticalSummary, StatisticalSummary)} to +299 * compute a t-statistic under the equal variances assumption. +300 * <p> +301 * This statistic can be used to perform a two-sample t-test to compare +302 * sample means.</p> +303 * <p> +304 * The returned t-statisitc is</p> +305 * <p> +306 * <code> t = (m1 - m2) / sqrt(var1/n1 + var2/n2)</code> +307 * </p><p> +308 * where <strong><code>n1</code></strong> is the size of the first sample; +309 * <strong><code> n2</code></strong> is the size of the second sample; +310 * <strong><code> m1</code></strong> is the mean of the first sample; +311 * <strong><code> m2</code></strong> is the mean of the second sample +312 * <strong><code> var1</code></strong> is the variance of the first sample; +313 * <strong><code> var2</code></strong> is the variance of the second sample +314 * </p><p> +315 * <strong>Preconditions</strong>: <ul> +316 * <li>The datasets described by the two Univariates must each contain +317 * at least 2 observations. +318 * </li></ul></p> +319 * +320 * @param sampleStats1 StatisticalSummary describing data from the first sample +321 * @param sampleStats2 StatisticalSummary describing data from the second sample +322 * @return t statistic +323 * @throws IllegalArgumentException if the precondition is not met +324 */ +325 public double t(StatisticalSummary sampleStats1, +326 StatisticalSummary sampleStats2) +327 throws IllegalArgumentException { +328 checkSampleData(sampleStats1); +329 checkSampleData(sampleStats2); +330 return t(sampleStats1.getMean(), sampleStats2.getMean(), +331 sampleStats1.getVariance(), sampleStats2.getVariance(), +332 sampleStats1.getN(), sampleStats2.getN()); +333 } +334 +335 /** +336 * Computes a 2-sample t statistic, comparing the means of the datasets +337 * described by two {@link StatisticalSummary} instances, under the +338 * assumption of equal subpopulation variances. To compute a t-statistic +339 * without the equal variances assumption, use +340 * {@link #t(StatisticalSummary, StatisticalSummary)}. +341 * <p> +342 * This statistic can be used to perform a (homoscedastic) two-sample +343 * t-test to compare sample means.</p> +344 * <p> +345 * The t-statisitc returned is</p> +346 * <p> +347 * <code> t = (m1 - m2) / (sqrt(1/n1 +1/n2) sqrt(var))</code> +348 * </p><p> +349 * where <strong><code>n1</code></strong> is the size of first sample; +350 * <strong><code> n2</code></strong> is the size of second sample; +351 * <strong><code> m1</code></strong> is the mean of first sample; +352 * <strong><code> m2</code></strong> is the mean of second sample +353 * and <strong><code>var</code></strong> is the pooled variance estimate: +354 * </p><p> +355 * <code>var = sqrt(((n1 - 1)var1 + (n2 - 1)var2) / ((n1-1) + (n2-1)))</code> +356 * <p> +357 * with <strong><code>var1<code></strong> the variance of the first sample and +358 * <strong><code>var2</code></strong> the variance of the second sample. +359 * </p><p> +360 * <strong>Preconditions</strong>: <ul> +361 * <li>The datasets described by the two Univariates must each contain +362 * at least 2 observations. +363 * </li></ul></p> +364 * +365 * @param sampleStats1 StatisticalSummary describing data from the first sample +366 * @param sampleStats2 StatisticalSummary describing data from the second sample +367 * @return t statistic +368 * @throws IllegalArgumentException if the precondition is not met +369 */ +370 public double homoscedasticT(StatisticalSummary sampleStats1, +371 StatisticalSummary sampleStats2) +372 throws IllegalArgumentException { +373 checkSampleData(sampleStats1); +374 checkSampleData(sampleStats2); +375 return homoscedasticT(sampleStats1.getMean(), sampleStats2.getMean(), +376 sampleStats1.getVariance(), sampleStats2.getVariance(), +377 sampleStats1.getN(), sampleStats2.getN()); +378 } +379 +380 /** +381 * Returns the <i>observed significance level</i>, or +382 * <i>p-value</i>, associated with a one-sample, two-tailed t-test +383 * comparing the mean of the input array with the constant <code>mu</code>. +384 * <p> +385 * The number returned is the smallest significance level +386 * at which one can reject the null hypothesis that the mean equals +387 * <code>mu</code> in favor of the two-sided alternative that the mean +388 * is different from <code>mu</code>. For a one-sided test, divide the +389 * returned value by 2.</p> +390 * <p> +391 * <strong>Usage Note:</strong><br> +392 * The validity of the test depends on the assumptions of the parametric +393 * t-test procedure, as discussed +394 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">here</a> +395 * </p><p> +396 * <strong>Preconditions</strong>: <ul> +397 * <li>The observed array length must be at least 2. +398 * </li></ul></p> +399 * +400 * @param mu constant value to compare sample mean against +401 * @param sample array of sample data values +402 * @return p-value +403 * @throws IllegalArgumentException if the precondition is not met +404 * @throws MathException if an error occurs computing the p-value +405 */ +406 public double tTest(double mu, double[] sample) +407 throws IllegalArgumentException, MathException { +408 checkSampleData(sample); +409 return tTest( StatUtils.mean(sample), mu, StatUtils.variance(sample), +410 sample.length); +411 } +412 +413 /** +414 * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm"> +415 * two-sided t-test</a> evaluating the null hypothesis that the mean of the population from +416 * which <code>sample</code> is drawn equals <code>mu</code>. +417 * <p> +418 * Returns <code>true</code> iff the null hypothesis can be +419 * rejected with confidence <code>1 - alpha</code>. To +420 * perform a 1-sided test, use <code>alpha * 2</code> +421 * </p><p> +422 * <strong>Examples:</strong><br><ol> +423 * <li>To test the (2-sided) hypothesis <code>sample mean = mu </code> at +424 * the 95% level, use <br><code>tTest(mu, sample, 0.05) </code> +425 * </li> +426 * <li>To test the (one-sided) hypothesis <code> sample mean < mu </code> +427 * at the 99% level, first verify that the measured sample mean is less +428 * than <code>mu</code> and then use +429 * <br><code>tTest(mu, sample, 0.02) </code> +430 * </li></ol></p> +431 * <p> +432 * <strong>Usage Note:</strong><br> +433 * The validity of the test depends on the assumptions of the one-sample +434 * parametric t-test procedure, as discussed +435 * <a href="http://www.basic.nwu.edu/statguidefiles/sg_glos.html#one-sample">here</a> +436 * </p><p> +437 * <strong>Preconditions</strong>: <ul> +438 * <li>The observed array length must be at least 2. +439 * </li></ul></p> +440 * +441 * @param mu constant value to compare sample mean against +442 * @param sample array of sample data values +443 * @param alpha significance level of the test +444 * @return p-value +445 * @throws IllegalArgumentException if the precondition is not met +446 * @throws MathException if an error computing the p-value +447 */ +448 public boolean tTest(double mu, double[] sample, double alpha) +449 throws IllegalArgumentException, MathException { +450 checkSignificanceLevel(alpha); +451 return tTest(mu, sample) < alpha; +452 } +453 +454 /** +455 * Returns the <i>observed significance level</i>, or +456 * <i>p-value</i>, associated with a one-sample, two-tailed t-test +457 * comparing the mean of the dataset described by <code>sampleStats</code> +458 * with the constant <code>mu</code>. +459 * <p> +460 * The number returned is the smallest significance level +461 * at which one can reject the null hypothesis that the mean equals +462 * <code>mu</code> in favor of the two-sided alternative that the mean +463 * is different from <code>mu</code>. For a one-sided test, divide the +464 * returned value by 2.</p> +465 * <p> +466 * <strong>Usage Note:</strong><br> +467 * The validity of the test depends on the assumptions of the parametric +468 * t-test procedure, as discussed +469 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +470 * here</a></p> +471 * <p> +472 * <strong>Preconditions</strong>: <ul> +473 * <li>The sample must contain at least 2 observations. +474 * </li></ul></p> +475 * +476 * @param mu constant value to compare sample mean against +477 * @param sampleStats StatisticalSummary describing sample data +478 * @return p-value +479 * @throws IllegalArgumentException if the precondition is not met +480 * @throws MathException if an error occurs computing the p-value +481 */ +482 public double tTest(double mu, StatisticalSummary sampleStats) +483 throws IllegalArgumentException, MathException { +484 checkSampleData(sampleStats); +485 return tTest(sampleStats.getMean(), mu, sampleStats.getVariance(), +486 sampleStats.getN()); +487 } +488 +489 /** +490 * Performs a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm"> +491 * two-sided t-test</a> evaluating the null hypothesis that the mean of the +492 * population from which the dataset described by <code>stats</code> is +493 * drawn equals <code>mu</code>. +494 * <p> +495 * Returns <code>true</code> iff the null hypothesis can be rejected with +496 * confidence <code>1 - alpha</code>. To perform a 1-sided test, use +497 * <code>alpha * 2.</code></p> +498 * <p> +499 * <strong>Examples:</strong><br><ol> +500 * <li>To test the (2-sided) hypothesis <code>sample mean = mu </code> at +501 * the 95% level, use <br><code>tTest(mu, sampleStats, 0.05) </code> +502 * </li> +503 * <li>To test the (one-sided) hypothesis <code> sample mean < mu </code> +504 * at the 99% level, first verify that the measured sample mean is less +505 * than <code>mu</code> and then use +506 * <br><code>tTest(mu, sampleStats, 0.02) </code> +507 * </li></ol></p> +508 * <p> +509 * <strong>Usage Note:</strong><br> +510 * The validity of the test depends on the assumptions of the one-sample +511 * parametric t-test procedure, as discussed +512 * <a href="http://www.basic.nwu.edu/statguidefiles/sg_glos.html#one-sample">here</a> +513 * </p><p> +514 * <strong>Preconditions</strong>: <ul> +515 * <li>The sample must include at least 2 observations. +516 * </li></ul></p> +517 * +518 * @param mu constant value to compare sample mean against +519 * @param sampleStats StatisticalSummary describing sample data values +520 * @param alpha significance level of the test +521 * @return p-value +522 * @throws IllegalArgumentException if the precondition is not met +523 * @throws MathException if an error occurs computing the p-value +524 */ +525 public boolean tTest( double mu, StatisticalSummary sampleStats, +526 double alpha) +527 throws IllegalArgumentException, MathException { +528 checkSignificanceLevel(alpha); +529 return tTest(mu, sampleStats) < alpha; +530 } +531 +532 /** +533 * Returns the <i>observed significance level</i>, or +534 * <i>p-value</i>, associated with a two-sample, two-tailed t-test +535 * comparing the means of the input arrays. +536 * <p> +537 * The number returned is the smallest significance level +538 * at which one can reject the null hypothesis that the two means are +539 * equal in favor of the two-sided alternative that they are different. +540 * For a one-sided test, divide the returned value by 2.</p> +541 * <p> +542 * The test does not assume that the underlying popuation variances are +543 * equal and it uses approximated degrees of freedom computed from the +544 * sample data to compute the p-value. The t-statistic used is as defined in +545 * {@link #t(double[], double[])} and the Welch-Satterthwaite approximation +546 * to the degrees of freedom is used, +547 * as described +548 * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm"> +549 * here.</a> To perform the test under the assumption of equal subpopulation +550 * variances, use {@link #homoscedasticTTest(double[], double[])}.</p> +551 * <p> +552 * <strong>Usage Note:</strong><br> +553 * The validity of the p-value depends on the assumptions of the parametric +554 * t-test procedure, as discussed +555 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +556 * here</a></p> +557 * <p> +558 * <strong>Preconditions</strong>: <ul> +559 * <li>The observed array lengths must both be at least 2. +560 * </li></ul></p> +561 * +562 * @param sample1 array of sample data values +563 * @param sample2 array of sample data values +564 * @return p-value for t-test +565 * @throws IllegalArgumentException if the precondition is not met +566 * @throws MathException if an error occurs computing the p-value +567 */ +568 public double tTest(double[] sample1, double[] sample2) +569 throws IllegalArgumentException, MathException { +570 checkSampleData(sample1); +571 checkSampleData(sample2); +572 return tTest(StatUtils.mean(sample1), StatUtils.mean(sample2), +573 StatUtils.variance(sample1), StatUtils.variance(sample2), +574 sample1.length, sample2.length); +575 } +576 +577 /** +578 * Returns the <i>observed significance level</i>, or +579 * <i>p-value</i>, associated with a two-sample, two-tailed t-test +580 * comparing the means of the input arrays, under the assumption that +581 * the two samples are drawn from subpopulations with equal variances. +582 * To perform the test without the equal variances assumption, use +583 * {@link #tTest(double[], double[])}. +584 * <p> +585 * The number returned is the smallest significance level +586 * at which one can reject the null hypothesis that the two means are +587 * equal in favor of the two-sided alternative that they are different. +588 * For a one-sided test, divide the returned value by 2.</p> +589 * <p> +590 * A pooled variance estimate is used to compute the t-statistic. See +591 * {@link #homoscedasticT(double[], double[])}. The sum of the sample sizes +592 * minus 2 is used as the degrees of freedom.</p> +593 * <p> +594 * <strong>Usage Note:</strong><br> +595 * The validity of the p-value depends on the assumptions of the parametric +596 * t-test procedure, as discussed +597 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +598 * here</a></p> +599 * <p> +600 * <strong>Preconditions</strong>: <ul> +601 * <li>The observed array lengths must both be at least 2. +602 * </li></ul></p> +603 * +604 * @param sample1 array of sample data values +605 * @param sample2 array of sample data values +606 * @return p-value for t-test +607 * @throws IllegalArgumentException if the precondition is not met +608 * @throws MathException if an error occurs computing the p-value +609 */ +610 public double homoscedasticTTest(double[] sample1, double[] sample2) +611 throws IllegalArgumentException, MathException { +612 checkSampleData(sample1); +613 checkSampleData(sample2); +614 return homoscedasticTTest(StatUtils.mean(sample1), +615 StatUtils.mean(sample2), StatUtils.variance(sample1), +616 StatUtils.variance(sample2), sample1.length, +617 sample2.length); +618 } +619 +620 +621 /** +622 * Performs a +623 * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm"> +624 * two-sided t-test</a> evaluating the null hypothesis that <code>sample1</code> +625 * and <code>sample2</code> are drawn from populations with the same mean, +626 * with significance level <code>alpha</code>. This test does not assume +627 * that the subpopulation variances are equal. To perform the test assuming +628 * equal variances, use +629 * {@link #homoscedasticTTest(double[], double[], double)}. +630 * <p> +631 * Returns <code>true</code> iff the null hypothesis that the means are +632 * equal can be rejected with confidence <code>1 - alpha</code>. To +633 * perform a 1-sided test, use <code>alpha / 2</code></p> +634 * <p> +635 * See {@link #t(double[], double[])} for the formula used to compute the +636 * t-statistic. Degrees of freedom are approximated using the +637 * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm"> +638 * Welch-Satterthwaite approximation.</a></p> +639 +640 * <p> +641 * <strong>Examples:</strong><br><ol> +642 * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at +643 * the 95% level, use +644 * <br><code>tTest(sample1, sample2, 0.05). </code> +645 * </li> +646 * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2 </code> at +647 * the 99% level, first verify that the measured mean of <code>sample 1</code> +648 * is less than the mean of <code>sample 2</code> and then use +649 * <br><code>tTest(sample1, sample2, 0.02) </code> +650 * </li></ol></p> +651 * <p> +652 * <strong>Usage Note:</strong><br> +653 * The validity of the test depends on the assumptions of the parametric +654 * t-test procedure, as discussed +655 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +656 * here</a></p> +657 * <p> +658 * <strong>Preconditions</strong>: <ul> +659 * <li>The observed array lengths must both be at least 2. +660 * </li> +661 * <li> <code> 0 < alpha < 0.5 </code> +662 * </li></ul></p> +663 * +664 * @param sample1 array of sample data values +665 * @param sample2 array of sample data values +666 * @param alpha significance level of the test +667 * @return true if the null hypothesis can be rejected with +668 * confidence 1 - alpha +669 * @throws IllegalArgumentException if the preconditions are not met +670 * @throws MathException if an error occurs performing the test +671 */ +672 public boolean tTest(double[] sample1, double[] sample2, +673 double alpha) +674 throws IllegalArgumentException, MathException { +675 checkSignificanceLevel(alpha); +676 return tTest(sample1, sample2) < alpha; +677 } +678 +679 /** +680 * Performs a +681 * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm"> +682 * two-sided t-test</a> evaluating the null hypothesis that <code>sample1</code> +683 * and <code>sample2</code> are drawn from populations with the same mean, +684 * with significance level <code>alpha</code>, assuming that the +685 * subpopulation variances are equal. Use +686 * {@link #tTest(double[], double[], double)} to perform the test without +687 * the assumption of equal variances. +688 * <p> +689 * Returns <code>true</code> iff the null hypothesis that the means are +690 * equal can be rejected with confidence <code>1 - alpha</code>. To +691 * perform a 1-sided test, use <code>alpha * 2.</code> To perform the test +692 * without the assumption of equal subpopulation variances, use +693 * {@link #tTest(double[], double[], double)}.</p> +694 * <p> +695 * A pooled variance estimate is used to compute the t-statistic. See +696 * {@link #t(double[], double[])} for the formula. The sum of the sample +697 * sizes minus 2 is used as the degrees of freedom.</p> +698 * <p> +699 * <strong>Examples:</strong><br><ol> +700 * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at +701 * the 95% level, use <br><code>tTest(sample1, sample2, 0.05). </code> +702 * </li> +703 * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2, </code> +704 * at the 99% level, first verify that the measured mean of +705 * <code>sample 1</code> is less than the mean of <code>sample 2</code> +706 * and then use +707 * <br><code>tTest(sample1, sample2, 0.02) </code> +708 * </li></ol></p> +709 * <p> +710 * <strong>Usage Note:</strong><br> +711 * The validity of the test depends on the assumptions of the parametric +712 * t-test procedure, as discussed +713 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +714 * here</a></p> +715 * <p> +716 * <strong>Preconditions</strong>: <ul> +717 * <li>The observed array lengths must both be at least 2. +718 * </li> +719 * <li> <code> 0 < alpha < 0.5 </code> +720 * </li></ul></p> +721 * +722 * @param sample1 array of sample data values +723 * @param sample2 array of sample data values +724 * @param alpha significance level of the test +725 * @return true if the null hypothesis can be rejected with +726 * confidence 1 - alpha +727 * @throws IllegalArgumentException if the preconditions are not met +728 * @throws MathException if an error occurs performing the test +729 */ +730 public boolean homoscedasticTTest(double[] sample1, double[] sample2, +731 double alpha) +732 throws IllegalArgumentException, MathException { +733 checkSignificanceLevel(alpha); +734 return homoscedasticTTest(sample1, sample2) < alpha; +735 } +736 +737 /** +738 * Returns the <i>observed significance level</i>, or +739 * <i>p-value</i>, associated with a two-sample, two-tailed t-test +740 * comparing the means of the datasets described by two StatisticalSummary +741 * instances. +742 * <p> +743 * The number returned is the smallest significance level +744 * at which one can reject the null hypothesis that the two means are +745 * equal in favor of the two-sided alternative that they are different. +746 * For a one-sided test, divide the returned value by 2.</p> +747 * <p> +748 * The test does not assume that the underlying popuation variances are +749 * equal and it uses approximated degrees of freedom computed from the +750 * sample data to compute the p-value. To perform the test assuming +751 * equal variances, use +752 * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}.</p> +753 * <p> +754 * <strong>Usage Note:</strong><br> +755 * The validity of the p-value depends on the assumptions of the parametric +756 * t-test procedure, as discussed +757 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +758 * here</a></p> +759 * <p> +760 * <strong>Preconditions</strong>: <ul> +761 * <li>The datasets described by the two Univariates must each contain +762 * at least 2 observations. +763 * </li></ul></p> +764 * +765 * @param sampleStats1 StatisticalSummary describing data from the first sample +766 * @param sampleStats2 StatisticalSummary describing data from the second sample +767 * @return p-value for t-test +768 * @throws IllegalArgumentException if the precondition is not met +769 * @throws MathException if an error occurs computing the p-value +770 */ +771 public double tTest(StatisticalSummary sampleStats1, StatisticalSummary sampleStats2) +772 throws IllegalArgumentException, MathException { +773 checkSampleData(sampleStats1); +774 checkSampleData(sampleStats2); +775 return tTest(sampleStats1.getMean(), sampleStats2.getMean(), sampleStats1.getVariance(), +776 sampleStats2.getVariance(), sampleStats1.getN(), +777 sampleStats2.getN()); +778 } +779 +780 /** +781 * Returns the <i>observed significance level</i>, or +782 * <i>p-value</i>, associated with a two-sample, two-tailed t-test +783 * comparing the means of the datasets described by two StatisticalSummary +784 * instances, under the hypothesis of equal subpopulation variances. To +785 * perform a test without the equal variances assumption, use +786 * {@link #tTest(StatisticalSummary, StatisticalSummary)}. +787 * <p> +788 * The number returned is the smallest significance level +789 * at which one can reject the null hypothesis that the two means are +790 * equal in favor of the two-sided alternative that they are different. +791 * For a one-sided test, divide the returned value by 2.</p> +792 * <p> +793 * See {@link #homoscedasticT(double[], double[])} for the formula used to +794 * compute the t-statistic. The sum of the sample sizes minus 2 is used as +795 * the degrees of freedom.</p> +796 * <p> +797 * <strong>Usage Note:</strong><br> +798 * The validity of the p-value depends on the assumptions of the parametric +799 * t-test procedure, as discussed +800 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html">here</a> +801 * </p><p> +802 * <strong>Preconditions</strong>: <ul> +803 * <li>The datasets described by the two Univariates must each contain +804 * at least 2 observations. +805 * </li></ul></p> +806 * +807 * @param sampleStats1 StatisticalSummary describing data from the first sample +808 * @param sampleStats2 StatisticalSummary describing data from the second sample +809 * @return p-value for t-test +810 * @throws IllegalArgumentException if the precondition is not met +811 * @throws MathException if an error occurs computing the p-value +812 */ +813 public double homoscedasticTTest(StatisticalSummary sampleStats1, +814 StatisticalSummary sampleStats2) +815 throws IllegalArgumentException, MathException { +816 checkSampleData(sampleStats1); +817 checkSampleData(sampleStats2); +818 return homoscedasticTTest(sampleStats1.getMean(), +819 sampleStats2.getMean(), sampleStats1.getVariance(), +820 sampleStats2.getVariance(), sampleStats1.getN(), +821 sampleStats2.getN()); +822 } +823 +824 /** +825 * Performs a +826 * <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm"> +827 * two-sided t-test</a> evaluating the null hypothesis that +828 * <code>sampleStats1</code> and <code>sampleStats2</code> describe +829 * datasets drawn from populations with the same mean, with significance +830 * level <code>alpha</code>. This test does not assume that the +831 * subpopulation variances are equal. To perform the test under the equal +832 * variances assumption, use +833 * {@link #homoscedasticTTest(StatisticalSummary, StatisticalSummary)}. +834 * <p> +835 * Returns <code>true</code> iff the null hypothesis that the means are +836 * equal can be rejected with confidence <code>1 - alpha</code>. To +837 * perform a 1-sided test, use <code>alpha * 2</code></p> +838 * <p> +839 * See {@link #t(double[], double[])} for the formula used to compute the +840 * t-statistic. Degrees of freedom are approximated using the +841 * <a href="http://www.itl.nist.gov/div898/handbook/prc/section3/prc31.htm"> +842 * Welch-Satterthwaite approximation.</a></p> +843 * <p> +844 * <strong>Examples:</strong><br><ol> +845 * <li>To test the (2-sided) hypothesis <code>mean 1 = mean 2 </code> at +846 * the 95%, use +847 * <br><code>tTest(sampleStats1, sampleStats2, 0.05) </code> +848 * </li> +849 * <li>To test the (one-sided) hypothesis <code> mean 1 < mean 2 </code> +850 * at the 99% level, first verify that the measured mean of +851 * <code>sample 1</code> is less than the mean of <code>sample 2</code> +852 * and then use +853 * <br><code>tTest(sampleStats1, sampleStats2, 0.02) </code> +854 * </li></ol></p> +855 * <p> +856 * <strong>Usage Note:</strong><br> +857 * The validity of the test depends on the assumptions of the parametric +858 * t-test procedure, as discussed +859 * <a href="http://www.basic.nwu.edu/statguidefiles/ttest_unpaired_ass_viol.html"> +860 * here</a></p> +861 * <p> +862 * <strong>Preconditions</strong>: <ul> +863 * <li>The datasets described by the two Univariates must each contain +864 * at least 2 observations. +865 * </li> +866 * <li> <code> 0 < alpha < 0.5 </code> +867 * </li></ul></p> +868 * +869 * @param sampleStats1 StatisticalSummary describing sample data values +870 * @param sampleStats2 StatisticalSummary describing sample data values +871 * @param alpha significance level of the test +872 * @return true if the null hypothesis can be rejected with +873 * confidence 1 - alpha +874 * @throws IllegalArgumentException if the preconditions are not met +875 * @throws MathException if an error occurs performing the test +876 */ +877 public boolean tTest(StatisticalSummary sampleStats1, +878 StatisticalSummary sampleStats2, double alpha) +879 throws IllegalArgumentException, MathException { +880 checkSignificanceLevel(alpha); +881 return tTest(sampleStats1, sampleStats2) < alpha; +882 } +883 +884 //----------------------------------------------- Protected methods +885 +886 /** +887 * Computes approximate degrees of freedom for 2-sample t-test. +888 * +889 * @param v1 first sample variance +890 * @param v2 second sample variance +891 * @param n1 first sample n +892 * @param n2 second sample n +893 * @return approximate degrees of freedom +894 */ +895 protected double df(double v1, double v2, double n1, double n2) { +896 return (((v1 / n1) + (v2 / n2)) * ((v1 / n1) + (v2 / n2))) / +897 ((v1 * v1) / (n1 * n1 * (n1 - 1d)) + (v2 * v2) / +898 (n2 * n2 * (n2 - 1d))); +899 } +900 +901 /** +902 * Computes t test statistic for 1-sample t-test. +903 * +904 * @param m sample mean +905 * @param mu constant to test against +906 * @param v sample variance +907 * @param n sample n +908 * @return t test statistic +909 */ +910 protected double t(double m, double mu, double v, double n) { +911 return (m - mu) / Math.sqrt(v / n); +912 } +913 +914 /** +915 * Computes t test statistic for 2-sample t-test. +916 * <p> +917 * Does not assume that subpopulation variances are equal.</p> +918 * +919 * @param m1 first sample mean +920 * @param m2 second sample mean +921 * @param v1 first sample variance +922 * @param v2 second sample variance +923 * @param n1 first sample n +924 * @param n2 second sample n +925 * @return t test statistic +926 */ +927 protected double t(double m1, double m2, double v1, double v2, double n1, +928 double n2) { +929 return (m1 - m2) / Math.sqrt((v1 / n1) + (v2 / n2)); +930 } +931 +932 /** +933 * Computes t test statistic for 2-sample t-test under the hypothesis +934 * of equal subpopulation variances. +935 * +936 * @param m1 first sample mean +937 * @param m2 second sample mean +938 * @param v1 first sample variance +939 * @param v2 second sample variance +940 * @param n1 first sample n +941 * @param n2 second sample n +942 * @return t test statistic +943 */ +944 protected double homoscedasticT(double m1, double m2, double v1, +945 double v2, double n1, double n2) { +946 double pooledVariance = ((n1 - 1) * v1 + (n2 -1) * v2 ) / (n1 + n2 - 2); +947 return (m1 - m2) / Math.sqrt(pooledVariance * (1d / n1 + 1d / n2)); +948 } +949 +950 /** +951 * Computes p-value for 2-sided, 1-sample t-test. +952 * +953 * @param m sample mean +954 * @param mu constant to test against +955 * @param v sample variance +956 * @param n sample n +957 * @return p-value +958 * @throws MathException if an error occurs computing the p-value +959 */ +960 protected double tTest(double m, double mu, double v, double n) +961 throws MathException { +962 double t = Math.abs(t(m, mu, v, n)); +963 distribution.setDegreesOfFreedom(n - 1); +964 return 2.0 * distribution.cumulativeProbability(-t); +965 } +966 +967 /** +968 * Computes p-value for 2-sided, 2-sample t-test. +969 * <p> +970 * Does not assume subpopulation variances are equal. Degrees of freedom +971 * are estimated from the data.</p> +972 * +973 * @param m1 first sample mean +974 * @param m2 second sample mean +975 * @param v1 first sample variance +976 * @param v2 second sample variance +977 * @param n1 first sample n +978 * @param n2 second sample n +979 * @return p-value +980 * @throws MathException if an error occurs computing the p-value +981 */ +982 protected double tTest(double m1, double m2, double v1, double v2, +983 double n1, double n2) +984 throws MathException { +985 double t = Math.abs(t(m1, m2, v1, v2, n1, n2)); +986 double degreesOfFreedom = 0; +987 degreesOfFreedom = df(v1, v2, n1, n2); +988 distribution.setDegreesOfFreedom(degreesOfFreedom); +989 return 2.0 * distribution.cumulativeProbability(-t); +990 } +991 +992 /** +993 * Computes p-value for 2-sided, 2-sample t-test, under the assumption +994 * of equal subpopulation variances. +995 * <p> +996 * The sum of the sample sizes minus 2 is used as degrees of freedom.</p> +997 * +998 * @param m1 first sample mean +999 * @param m2 second sample mean +1000 * @param v1 first sample variance +1001 * @param v2 second sample variance +1002 * @param n1 first sample n +1003 * @param n2 second sample n +1004 * @return p-value +1005 * @throws MathException if an error occurs computing the p-value +1006 */ +1007 protected double homoscedasticTTest(double m1, double m2, double v1, +1008 double v2, double n1, double n2) +1009 throws MathException { +1010 double t = Math.abs(homoscedasticT(m1, m2, v1, v2, n1, n2)); +1011 double degreesOfFreedom = n1 + n2 - 2; +1012 distribution.setDegreesOfFreedom(degreesOfFreedom); +1013 return 2.0 * distribution.cumulativeProbability(-t); +1014 } +1015 +1016 /** +1017 * Modify the distribution used to compute inference statistics. +1018 * @param value the new distribution +1019 * @since 1.2 +1020 */ +1021 public void setDistribution(TDistribution value) { +1022 distribution = value; +1023 } +1024 +1025 /** Check significance level. +1026 * @param alpha significance level +1027 * @exception IllegalArgumentException if significance level is out of bounds +1028 */ +1029 private void checkSignificanceLevel(final double alpha) +1030 throws IllegalArgumentException { +1031 if ((alpha <= 0) || (alpha > 0.5)) { +1032 throw MathRuntimeException.createIllegalArgumentException( +1033 "out of bounds significance level {0}, must be between {1} and {2}", +1034 alpha, 0.0, 0.5); +1035 } +1036 } +1037 +1038 /** Check sample data. +1039 * @param data sample data +1040 * @exception IllegalArgumentException if there is not enough sample data +1041 */ +1042 private void checkSampleData(final double[] data) +1043 throws IllegalArgumentException { +1044 if ((data == null) || (data.length < 2)) { +1045 throw MathRuntimeException.createIllegalArgumentException( +1046 INSUFFICIENT_DATA_MESSAGE, +1047 (data == null) ? 0 : data.length); +1048 } +1049 } +1050 +1051 /** Check sample data. +1052 * @param stat statistical summary +1053 * @exception IllegalArgumentException if there is not enough sample data +1054 */ +1055 private void checkSampleData(final StatisticalSummary stat) +1056 throws IllegalArgumentException { +1057 if ((stat == null) || (stat.getN() < 2)) { +1058 throw MathRuntimeException.createIllegalArgumentException( +1059 INSUFFICIENT_DATA_MESSAGE, +1060 (stat == null) ? 0 : stat.getN()); +1061 } +1062 } +1063 +1064 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/TestUtils.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/TestUtils.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,481 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.inference; +018 +019 import java.util.Collection; +020 import org.apache.commons.math.MathException; +021 import org.apache.commons.math.stat.descriptive.StatisticalSummary; +022 +023 /** +024 * A collection of static methods to create inference test instances or to +025 * perform inference tests. +026 * +027 * @since 1.1 +028 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +029 */ +030 public class TestUtils { +031 +032 /** Singleton TTest instance using default implementation. */ +033 private static TTest tTest = new TTestImpl(); +034 +035 /** Singleton ChiSquareTest instance using default implementation. */ +036 private static ChiSquareTest chiSquareTest = +037 new ChiSquareTestImpl(); +038 +039 /** Singleton ChiSquareTest instance using default implementation. */ +040 private static UnknownDistributionChiSquareTest unknownDistributionChiSquareTest = +041 new ChiSquareTestImpl(); +042 +043 /** Singleton OneWayAnova instance using default implementation. */ +044 private static OneWayAnova oneWayAnova = +045 new OneWayAnovaImpl(); +046 +047 /** +048 * Prevent instantiation. +049 */ +050 protected TestUtils() { +051 super(); +052 } +053 +054 /** +055 * Set the (singleton) TTest instance. +056 * +057 * @param chiSquareTest the new instance to use +058 * @since 1.2 +059 */ +060 public static void setChiSquareTest(TTest chiSquareTest) { +061 TestUtils.tTest = chiSquareTest; +062 } +063 +064 /** +065 * Return a (singleton) TTest instance. Does not create a new instance. +066 * +067 * @return a TTest instance +068 */ +069 public static TTest getTTest() { +070 return tTest; +071 } +072 +073 /** +074 * Set the (singleton) ChiSquareTest instance. +075 * +076 * @param chiSquareTest the new instance to use +077 * @since 1.2 +078 */ +079 public static void setChiSquareTest(ChiSquareTest chiSquareTest) { +080 TestUtils.chiSquareTest = chiSquareTest; +081 } +082 +083 /** +084 * Return a (singleton) ChiSquareTest instance. Does not create a new instance. +085 * +086 * @return a ChiSquareTest instance +087 */ +088 public static ChiSquareTest getChiSquareTest() { +089 return chiSquareTest; +090 } +091 +092 /** +093 * Set the (singleton) UnknownDistributionChiSquareTest instance. +094 * +095 * @param unknownDistributionChiSquareTest the new instance to use +096 * @since 1.2 +097 */ +098 public static void setUnknownDistributionChiSquareTest(UnknownDistributionChiSquareTest unknownDistributionChiSquareTest) { +099 TestUtils.unknownDistributionChiSquareTest = unknownDistributionChiSquareTest; +100 } +101 +102 /** +103 * Return a (singleton) UnknownDistributionChiSquareTest instance. Does not create a new instance. +104 * +105 * @return a UnknownDistributionChiSquareTest instance +106 */ +107 public static UnknownDistributionChiSquareTest getUnknownDistributionChiSquareTest() { +108 return unknownDistributionChiSquareTest; +109 } +110 +111 /** +112 * Set the (singleton) OneWayAnova instance +113 * +114 * @param oneWayAnova the new instance to use +115 * @since 1.2 +116 */ +117 public static void setOneWayAnova(OneWayAnova oneWayAnova) { +118 TestUtils.oneWayAnova = oneWayAnova; +119 } +120 +121 /** +122 * Return a (singleton) OneWayAnova instance. Does not create a new instance. +123 * +124 * @return a OneWayAnova instance +125 * @since 1.2 +126 */ +127 public static OneWayAnova getOneWayAnova() { +128 return oneWayAnova; +129 } +130 +131 +132 // CHECKSTYLE: stop JavadocMethodCheck +133 +134 /** +135 * @see org.apache.commons.math.stat.inference.TTest#homoscedasticT(double[], double[]) +136 */ +137 public static double homoscedasticT(double[] sample1, double[] sample2) +138 throws IllegalArgumentException { +139 return tTest.homoscedasticT(sample1, sample2); +140 } +141 +142 /** +143 * @see org.apache.commons.math.stat.inference.TTest#homoscedasticT(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary) +144 */ +145 public static double homoscedasticT(StatisticalSummary sampleStats1, +146 StatisticalSummary sampleStats2) +147 throws IllegalArgumentException { +148 return tTest.homoscedasticT(sampleStats1, sampleStats2); +149 } +150 +151 /** +152 * @see org.apache.commons.math.stat.inference.TTest#homoscedasticTTest(double[], double[], double) +153 */ +154 public static boolean homoscedasticTTest(double[] sample1, double[] sample2, +155 double alpha) +156 throws IllegalArgumentException, MathException { +157 return tTest. homoscedasticTTest(sample1, sample2, alpha); +158 } +159 +160 /** +161 * @see org.apache.commons.math.stat.inference.TTest#homoscedasticTTest(double[], double[]) +162 */ +163 public static double homoscedasticTTest(double[] sample1, double[] sample2) +164 throws IllegalArgumentException, MathException { +165 return tTest.homoscedasticTTest(sample1, sample2); +166 } +167 +168 /** +169 * @see org.apache.commons.math.stat.inference.TTest#homoscedasticTTest(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary) +170 */ +171 public static double homoscedasticTTest(StatisticalSummary sampleStats1, +172 StatisticalSummary sampleStats2) +173 throws IllegalArgumentException, MathException { +174 return tTest.homoscedasticTTest(sampleStats1, sampleStats2); +175 } +176 +177 /** +178 * @see org.apache.commons.math.stat.inference.TTest#pairedT(double[], double[]) +179 */ +180 public static double pairedT(double[] sample1, double[] sample2) +181 throws IllegalArgumentException, MathException { +182 return tTest.pairedT(sample1, sample2); +183 } +184 +185 /** +186 * @see org.apache.commons.math.stat.inference.TTest#pairedTTest(double[], double[], double) +187 */ +188 public static boolean pairedTTest(double[] sample1, double[] sample2, +189 double alpha) +190 throws IllegalArgumentException, MathException { +191 return tTest.pairedTTest(sample1, sample2, alpha); +192 } +193 +194 /** +195 * @see org.apache.commons.math.stat.inference.TTest#pairedTTest(double[], double[]) +196 */ +197 public static double pairedTTest(double[] sample1, double[] sample2) +198 throws IllegalArgumentException, MathException { +199 return tTest.pairedTTest(sample1, sample2); +200 } +201 +202 /** +203 * @see org.apache.commons.math.stat.inference.TTest#t(double, double[]) +204 */ +205 public static double t(double mu, double[] observed) +206 throws IllegalArgumentException { +207 return tTest.t(mu, observed); +208 } +209 +210 /** +211 * @see org.apache.commons.math.stat.inference.TTest#t(double, org.apache.commons.math.stat.descriptive.StatisticalSummary) +212 */ +213 public static double t(double mu, StatisticalSummary sampleStats) +214 throws IllegalArgumentException { +215 return tTest.t(mu, sampleStats); +216 } +217 +218 /** +219 * @see org.apache.commons.math.stat.inference.TTest#t(double[], double[]) +220 */ +221 public static double t(double[] sample1, double[] sample2) +222 throws IllegalArgumentException { +223 return tTest.t(sample1, sample2); +224 } +225 +226 /** +227 * @see org.apache.commons.math.stat.inference.TTest#t(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary) +228 */ +229 public static double t(StatisticalSummary sampleStats1, +230 StatisticalSummary sampleStats2) +231 throws IllegalArgumentException { +232 return tTest.t(sampleStats1, sampleStats2); +233 } +234 +235 /** +236 * @see org.apache.commons.math.stat.inference.TTest#tTest(double, double[], double) +237 */ +238 public static boolean tTest(double mu, double[] sample, double alpha) +239 throws IllegalArgumentException, MathException { +240 return tTest.tTest(mu, sample, alpha); +241 } +242 +243 /** +244 * @see org.apache.commons.math.stat.inference.TTest#tTest(double, double[]) +245 */ +246 public static double tTest(double mu, double[] sample) +247 throws IllegalArgumentException, MathException { +248 return tTest.tTest(mu, sample); +249 } +250 +251 /** +252 * @see org.apache.commons.math.stat.inference.TTest#tTest(double, org.apache.commons.math.stat.descriptive.StatisticalSummary, double) +253 */ +254 public static boolean tTest(double mu, StatisticalSummary sampleStats, +255 double alpha) +256 throws IllegalArgumentException, MathException { +257 return tTest. tTest(mu, sampleStats, alpha); +258 } +259 +260 /** +261 * @see org.apache.commons.math.stat.inference.TTest#tTest(double, org.apache.commons.math.stat.descriptive.StatisticalSummary) +262 */ +263 public static double tTest(double mu, StatisticalSummary sampleStats) +264 throws IllegalArgumentException, MathException { +265 return tTest.tTest(mu, sampleStats); +266 } +267 +268 /** +269 * @see org.apache.commons.math.stat.inference.TTest#tTest(double[], double[], double) +270 */ +271 public static boolean tTest(double[] sample1, double[] sample2, double alpha) +272 throws IllegalArgumentException, MathException { +273 return tTest.tTest(sample1, sample2, alpha); +274 } +275 +276 /** +277 * @see org.apache.commons.math.stat.inference.TTest#tTest(double[], double[]) +278 */ +279 public static double tTest(double[] sample1, double[] sample2) +280 throws IllegalArgumentException, MathException { +281 return tTest.tTest(sample1, sample2); +282 } +283 +284 /** +285 * @see org.apache.commons.math.stat.inference.TTest#tTest(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary, double) +286 */ +287 public static boolean tTest(StatisticalSummary sampleStats1, +288 StatisticalSummary sampleStats2, double alpha) +289 throws IllegalArgumentException, MathException { +290 return tTest. tTest(sampleStats1, sampleStats2, alpha); +291 } +292 +293 /** +294 * @see org.apache.commons.math.stat.inference.TTest#tTest(org.apache.commons.math.stat.descriptive.StatisticalSummary, org.apache.commons.math.stat.descriptive.StatisticalSummary) +295 */ +296 public static double tTest(StatisticalSummary sampleStats1, +297 StatisticalSummary sampleStats2) +298 throws IllegalArgumentException, MathException { +299 return tTest.tTest(sampleStats1, sampleStats2); +300 } +301 +302 /** +303 * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquare(double[], long[]) +304 */ +305 public static double chiSquare(double[] expected, long[] observed) +306 throws IllegalArgumentException { +307 return chiSquareTest.chiSquare(expected, observed); +308 } +309 +310 /** +311 * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquare(long[][]) +312 */ +313 public static double chiSquare(long[][] counts) +314 throws IllegalArgumentException { +315 return chiSquareTest.chiSquare(counts); +316 } +317 +318 /** +319 * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquareTest(double[], long[], double) +320 */ +321 public static boolean chiSquareTest(double[] expected, long[] observed, +322 double alpha) +323 throws IllegalArgumentException, MathException { +324 return chiSquareTest.chiSquareTest(expected, observed, alpha); +325 } +326 +327 /** +328 * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquareTest(double[], long[]) +329 */ +330 public static double chiSquareTest(double[] expected, long[] observed) +331 throws IllegalArgumentException, MathException { +332 return chiSquareTest.chiSquareTest(expected, observed); +333 } +334 +335 /** +336 * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquareTest(long[][], double) +337 */ +338 public static boolean chiSquareTest(long[][] counts, double alpha) +339 throws IllegalArgumentException, MathException { +340 return chiSquareTest. chiSquareTest(counts, alpha); +341 } +342 +343 /** +344 * @see org.apache.commons.math.stat.inference.ChiSquareTest#chiSquareTest(long[][]) +345 */ +346 public static double chiSquareTest(long[][] counts) +347 throws IllegalArgumentException, MathException { +348 return chiSquareTest. chiSquareTest(counts); +349 } +350 +351 /** +352 * @see org.apache.commons.math.stat.inference.UnknownDistributionChiSquareTest#chiSquareDataSetsComparison(long[], long[]) +353 * +354 * @since 1.2 +355 */ +356 public static double chiSquareDataSetsComparison(long[] observed1, long[] observed2) +357 throws IllegalArgumentException { +358 return unknownDistributionChiSquareTest.chiSquareDataSetsComparison(observed1, observed2); +359 } +360 +361 /** +362 * @see org.apache.commons.math.stat.inference.UnknownDistributionChiSquareTest#chiSquareTestDataSetsComparison(long[], long[]) +363 * +364 * @since 1.2 +365 */ +366 public static double chiSquareTestDataSetsComparison(long[] observed1, long[] observed2) +367 throws IllegalArgumentException, MathException { +368 return unknownDistributionChiSquareTest.chiSquareTestDataSetsComparison(observed1, observed2); +369 } +370 +371 +372 /** +373 * @see org.apache.commons.math.stat.inference.UnknownDistributionChiSquareTest#chiSquareTestDataSetsComparison(long[], long[], double) +374 * +375 * @since 1.2 +376 */ +377 public static boolean chiSquareTestDataSetsComparison(long[] observed1, long[] observed2, +378 double alpha) +379 throws IllegalArgumentException, MathException { +380 return unknownDistributionChiSquareTest.chiSquareTestDataSetsComparison(observed1, observed2, alpha); +381 } +382 +383 /** +384 * @see org.apache.commons.math.stat.inference.OneWayAnova#anovaFValue(Collection) +385 * +386 * @since 1.2 +387 */ +388 public static double oneWayAnovaFValue(Collection<double[]> categoryData) +389 throws IllegalArgumentException, MathException { +390 return oneWayAnova.anovaFValue(categoryData); +391 } +392 +393 /** +394 * @see org.apache.commons.math.stat.inference.OneWayAnova#anovaPValue(Collection) +395 * +396 * @since 1.2 +397 */ +398 public static double oneWayAnovaPValue(Collection<double[]> categoryData) +399 throws IllegalArgumentException, MathException { +400 return oneWayAnova.anovaPValue(categoryData); +401 } +402 +403 /** +404 * @see org.apache.commons.math.stat.inference.OneWayAnova#anovaTest(Collection,double) +405 * +406 * @since 1.2 +407 */ +408 public static boolean oneWayAnovaTest(Collection<double[]> categoryData, double alpha) +409 throws IllegalArgumentException, MathException { +410 return oneWayAnova.anovaTest(categoryData, alpha); +411 } +412 +413 // CHECKSTYLE: resume JavadocMethodCheck +414 +415 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/UnknownDistributionChiSquareTest.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/inference/UnknownDistributionChiSquareTest.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,210 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.inference; +018 +019 import org.apache.commons.math.MathException; +020 +021 /** +022 * An interface for Chi-Square tests for unknown distributions. +023 * <p>Two samples tests are used when the distribution is unknown <i>a priori</i> +024 * but provided by one sample. We compare the second sample against the first.</p> +025 * +026 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +027 * @since 1.2 +028 */ +029 public interface UnknownDistributionChiSquareTest extends ChiSquareTest { +030 +031 /** +032 * <p>Computes a +033 * <a href="http://www.itl.nist.gov/div898/software/dataplot/refman1/auxillar/chi2samp.htm"> +034 * Chi-Square two sample test statistic</a> comparing bin frequency counts +035 * in <code>observed1</code> and <code>observed2</code>. The +036 * sums of frequency counts in the two samples are not required to be the +037 * same. The formula used to compute the test statistic is</p> +038 * <code> +039 * ∑[(K * observed1[i] - observed2[i]/K)<sup>2</sup> / (observed1[i] + observed2[i])] +040 * </code> where +041 * <br/><code>K = &sqrt;[&sum(observed2 / ∑(observed1)]</code> +042 * </p> +043 * <p>This statistic can be used to perform a Chi-Square test evaluating the null hypothesis that +044 * both observed counts follow the same distribution.</p> +045 * <p> +046 * <strong>Preconditions</strong>: <ul> +047 * <li>Observed counts must be non-negative. +048 * </li> +049 * <li>Observed counts for a specific bin must not both be zero. +050 * </li> +051 * <li>Observed counts for a specific sample must not all be 0. +052 * </li> +053 * <li>The arrays <code>observed1</code> and <code>observed2</code> must have the same length and +054 * their common length must be at least 2. +055 * </li></ul></p><p> +056 * If any of the preconditions are not met, an +057 * <code>IllegalArgumentException</code> is thrown.</p> +058 * +059 * @param observed1 array of observed frequency counts of the first data set +060 * @param observed2 array of observed frequency counts of the second data set +061 * @return chiSquare statistic +062 * @throws IllegalArgumentException if preconditions are not met +063 */ +064 double chiSquareDataSetsComparison(long[] observed1, long[] observed2) +065 throws IllegalArgumentException; +066 +067 /** +068 * <p>Returns the <i>observed significance level</i>, or <a href= +069 * "http://www.cas.lancs.ac.uk/glossary_v1.1/hyptest.html#pvalue"> +070 * p-value</a>, associated with a Chi-Square two sample test comparing +071 * bin frequency counts in <code>observed1</code> and +072 * <code>observed2</code>. +073 * </p> +074 * <p>The number returned is the smallest significance level at which one +075 * can reject the null hypothesis that the observed counts conform to the +076 * same distribution. +077 * </p> +078 * <p>See {@link #chiSquareDataSetsComparison(long[], long[])} for details +079 * on the formula used to compute the test statistic. The degrees of +080 * of freedom used to perform the test is one less than the common length +081 * of the input observed count arrays. +082 * </p> +083 * <strong>Preconditions</strong>: <ul> +084 * <li>Observed counts must be non-negative. +085 * </li> +086 * <li>Observed counts for a specific bin must not both be zero. +087 * </li> +088 * <li>Observed counts for a specific sample must not all be 0. +089 * </li> +090 * <li>The arrays <code>observed1</code> and <code>observed2</code> must +091 * have the same length and +092 * their common length must be at least 2. +093 * </li></ul><p> +094 * If any of the preconditions are not met, an +095 * <code>IllegalArgumentException</code> is thrown.</p> +096 * +097 * @param observed1 array of observed frequency counts of the first data set +098 * @param observed2 array of observed frequency counts of the second data set +099 * @return p-value +100 * @throws IllegalArgumentException if preconditions are not met +101 * @throws MathException if an error occurs computing the p-value +102 */ +103 double chiSquareTestDataSetsComparison(long[] observed1, long[] observed2) +104 throws IllegalArgumentException, MathException; +105 +106 /** +107 * <p>Performs a Chi-Square two sample test comparing two binned data +108 * sets. The test evaluates the null hypothesis that the two lists of +109 * observed counts conform to the same frequency distribution, with +110 * significance level <code>alpha</code>. Returns true iff the null +111 * hypothesis can be rejected with 100 * (1 - alpha) percent confidence. +112 * </p> +113 * <p>See {@link #chiSquareDataSetsComparison(long[], long[])} for +114 * details on the formula used to compute the Chisquare statistic used +115 * in the test. The degrees of of freedom used to perform the test is +116 * one less than the common length of the input observed count arrays. +117 * </p> +118 * <strong>Preconditions</strong>: <ul> +119 * <li>Observed counts must be non-negative. +120 * </li> +121 * <li>Observed counts for a specific bin must not both be zero. +122 * </li> +123 * <li>Observed counts for a specific sample must not all be 0. +124 * </li> +125 * <li>The arrays <code>observed1</code> and <code>observed2</code> must +126 * have the same length and their common length must be at least 2. +127 * </li> +128 * <li> <code> 0 < alpha < 0.5 </code> +129 * </li></ul><p> +130 * If any of the preconditions are not met, an +131 * <code>IllegalArgumentException</code> is thrown.</p> +132 * +133 * @param observed1 array of observed frequency counts of the first data set +134 * @param observed2 array of observed frequency counts of the second data set +135 * @param alpha significance level of the test +136 * @return true iff null hypothesis can be rejected with confidence +137 * 1 - alpha +138 * @throws IllegalArgumentException if preconditions are not met +139 * @throws MathException if an error occurs performing the test +140 */ +141 boolean chiSquareTestDataSetsComparison(long[] observed1, long[] observed2, double alpha) +142 throws IllegalArgumentException, MathException; +143 +144 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/ranking/NaNStrategy.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/ranking/NaNStrategy.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,115 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.stat.ranking; +019 +020 /** +021 * Strategies for handling NaN values in rank transformations. +022 * <ul> +023 * <li>MINIMAL - NaNs are treated as minimal in the ordering, equivalent to +024 * (that is, tied with) <code>Double.NEGATIVE_INFINITY</code>.</li> +025 * <li>MAXIMAL - NaNs are treated as maximal in the ordering, equivalent to +026 * <code>Double.POSITIVE_INFINITY</code></li> +027 * <li>REMOVED - NaNs are removed before the rank transform is applied</li> +028 * <li>FIXED - NaNs are left "in place," that is the rank transformation is +029 * applied to the other elements in the input array, but the NaN elements +030 * are returned unchanged.</li> +031 * </ul> +032 * +033 * @since 2.0 +034 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +035 */ +036 public enum NaNStrategy { +037 +038 /** NaNs are considered minimal in the ordering */ +039 MINIMAL, +040 +041 /** NaNs are considered maximal in the ordering */ +042 MAXIMAL, +043 +044 /** NaNs are removed before computing ranks */ +045 REMOVED, +046 +047 /** NaNs are left in place */ +048 FIXED +049 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/ranking/NaturalRanking.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/ranking/NaturalRanking.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,529 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.stat.ranking; +019 +020 import java.util.ArrayList; +021 import java.util.Arrays; +022 import java.util.Iterator; +023 import java.util.List; +024 +025 import org.apache.commons.math.MathRuntimeException; +026 import org.apache.commons.math.random.RandomData; +027 import org.apache.commons.math.random.RandomDataImpl; +028 import org.apache.commons.math.random.RandomGenerator; +029 +030 +031 /** +032 * <p> Ranking based on the natural ordering on doubles.</p> +033 * <p>NaNs are treated according to the configured {@link NaNStrategy} and ties +034 * are handled using the selected {@link TiesStrategy}. +035 * Configuration settings are supplied in optional constructor arguments. +036 * Defaults are {@link NaNStrategy#MAXIMAL} and {@link TiesStrategy#AVERAGE}, +037 * respectively. When using {@link TiesStrategy#RANDOM}, a +038 * {@link RandomGenerator} may be supplied as a constructor argument.</p> +039 * <p>Examples: +040 * <table border="1" cellpadding="3"> +041 * <tr><th colspan="3"> +042 * Input data: (20, 17, 30, 42.3, 17, 50, Double.NaN, Double.NEGATIVE_INFINITY, 17) +043 * </th></tr> +044 * <tr><th>NaNStrategy</th><th>TiesStrategy</th> +045 * <th><code>rank(data)</code></th> +046 * <tr> +047 * <td>default (NaNs maximal)</td> +048 * <td>default (ties averaged)</td> +049 * <td>(5, 3, 6, 7, 3, 8, 9, 1, 3)</td></tr> +050 * <tr> +051 * <td>default (NaNs maximal)</td> +052 * <td>MINIMUM</td> +053 * <td>(5, 2, 6, 7, 2, 8, 9, 1, 2)</td></tr> +054 * <tr> +055 * <td>MINIMAL</td> +056 * <td>default (ties averaged)</td> +057 * <td>(6, 4, 7, 8, 4, 9, 1.5, 1.5, 4)</td></tr> +058 * <tr> +059 * <td>REMOVED</td> +060 * <td>SEQUENTIAL</td> +061 * <td>(5, 2, 6, 7, 3, 8, 1, 4)</td></tr> +062 * <tr> +063 * <td>MINIMAL</td> +064 * <td>MAXIMUM</td> +065 * <td>(6, 5, 7, 8, 5, 9, 2, 2, 5)</td></tr></table></p> +066 * +067 * @since 2.0 +068 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +069 */ +070 public class NaturalRanking implements RankingAlgorithm { +071 +072 /** default NaN strategy */ +073 public static final NaNStrategy DEFAULT_NAN_STRATEGY = NaNStrategy.MAXIMAL; +074 +075 /** default ties strategy */ +076 public static final TiesStrategy DEFAULT_TIES_STRATEGY = TiesStrategy.AVERAGE; +077 +078 /** NaN strategy - defaults to NaNs maximal */ +079 private final NaNStrategy nanStrategy; +080 +081 /** Ties strategy - defaults to ties averaged */ +082 private final TiesStrategy tiesStrategy; +083 +084 /** Source of random data - used only when ties strategy is RANDOM */ +085 private final RandomData randomData; +086 +087 /** +088 * Create a NaturalRanking with default strategies for handling ties and NaNs. +089 */ +090 public NaturalRanking() { +091 super(); +092 tiesStrategy = DEFAULT_TIES_STRATEGY; +093 nanStrategy = DEFAULT_NAN_STRATEGY; +094 randomData = null; +095 } +096 +097 /** +098 * Create a NaturalRanking with the given TiesStrategy. +099 * +100 * @param tiesStrategy the TiesStrategy to use +101 */ +102 public NaturalRanking(TiesStrategy tiesStrategy) { +103 super(); +104 this.tiesStrategy = tiesStrategy; +105 nanStrategy = DEFAULT_NAN_STRATEGY; +106 randomData = new RandomDataImpl(); +107 } +108 +109 /** +110 * Create a NaturalRanking with the given NaNStrategy. +111 * +112 * @param nanStrategy the NaNStrategy to use +113 */ +114 public NaturalRanking(NaNStrategy nanStrategy) { +115 super(); +116 this.nanStrategy = nanStrategy; +117 tiesStrategy = DEFAULT_TIES_STRATEGY; +118 randomData = null; +119 } +120 +121 /** +122 * Create a NaturalRanking with the given NaNStrategy and TiesStrategy. +123 * +124 * @param nanStrategy NaNStrategy to use +125 * @param tiesStrategy TiesStrategy to use +126 */ +127 public NaturalRanking(NaNStrategy nanStrategy, TiesStrategy tiesStrategy) { +128 super(); +129 this.nanStrategy = nanStrategy; +130 this.tiesStrategy = tiesStrategy; +131 randomData = new RandomDataImpl(); +132 } +133 +134 /** +135 * Create a NaturalRanking with TiesStrategy.RANDOM and the given +136 * RandomGenerator as the source of random data. +137 * +138 * @param randomGenerator source of random data +139 */ +140 public NaturalRanking(RandomGenerator randomGenerator) { +141 super(); +142 this.tiesStrategy = TiesStrategy.RANDOM; +143 nanStrategy = DEFAULT_NAN_STRATEGY; +144 randomData = new RandomDataImpl(randomGenerator); +145 } +146 +147 +148 /** +149 * Create a NaturalRanking with the given NaNStrategy, TiesStrategy.RANDOM +150 * and the given source of random data. +151 * +152 * @param nanStrategy NaNStrategy to use +153 * @param randomGenerator source of random data +154 */ +155 public NaturalRanking(NaNStrategy nanStrategy, +156 RandomGenerator randomGenerator) { +157 super(); +158 this.nanStrategy = nanStrategy; +159 this.tiesStrategy = TiesStrategy.RANDOM; +160 randomData = new RandomDataImpl(randomGenerator); +161 } +162 +163 /** +164 * Return the NaNStrategy +165 * +166 * @return returns the NaNStrategy +167 */ +168 public NaNStrategy getNanStrategy() { +169 return nanStrategy; +170 } +171 +172 /** +173 * Return the TiesStrategy +174 * +175 * @return the TiesStrategy +176 */ +177 public TiesStrategy getTiesStrategy() { +178 return tiesStrategy; +179 } +180 +181 /** +182 * Rank <code>data</code> using the natural ordering on Doubles, with +183 * NaN values handled according to <code>nanStrategy</code> and ties +184 * resolved using <code>tiesStrategy.</code> +185 * +186 * @param data array to be ranked +187 * @return array of ranks +188 */ +189 public double[] rank(double[] data) { +190 +191 // Array recording initial positions of data to be ranked +192 IntDoublePair[] ranks = new IntDoublePair[data.length]; +193 for (int i = 0; i < data.length; i++) { +194 ranks[i] = new IntDoublePair(data[i], i); +195 } +196 +197 // Recode, remove or record positions of NaNs +198 List<Integer> nanPositions = null; +199 switch (nanStrategy) { +200 case MAXIMAL: // Replace NaNs with +INFs +201 recodeNaNs(ranks, Double.POSITIVE_INFINITY); +202 break; +203 case MINIMAL: // Replace NaNs with -INFs +204 recodeNaNs(ranks, Double.NEGATIVE_INFINITY); +205 break; +206 case REMOVED: // Drop NaNs from data +207 ranks = removeNaNs(ranks); +208 break; +209 case FIXED: // Record positions of NaNs +210 nanPositions = getNanPositions(ranks); +211 break; +212 default: // this should not happen unless NaNStrategy enum is changed +213 throw MathRuntimeException.createInternalError(null); +214 } +215 +216 // Sort the IntDoublePairs +217 Arrays.sort(ranks); +218 +219 // Walk the sorted array, filling output array using sorted positions, +220 // resolving ties as we go +221 double[] out = new double[ranks.length]; +222 int pos = 1; // position in sorted array +223 out[ranks[0].getPosition()] = pos; +224 List<Integer> tiesTrace = new ArrayList<Integer>(); +225 tiesTrace.add(ranks[0].getPosition()); +226 for (int i = 1; i < ranks.length; i++) { +227 if (Double.compare(ranks[i].getValue(), ranks[i - 1].getValue()) > 0) { +228 // tie sequence has ended (or had length 1) +229 pos = i + 1; +230 if (tiesTrace.size() > 1) { // if seq is nontrivial, resolve +231 resolveTie(out, tiesTrace); +232 } +233 tiesTrace = new ArrayList<Integer>(); +234 tiesTrace.add(ranks[i].getPosition()); +235 } else { +236 // tie sequence continues +237 tiesTrace.add(ranks[i].getPosition()); +238 } +239 out[ranks[i].getPosition()] = pos; +240 } +241 if (tiesTrace.size() > 1) { // handle tie sequence at end +242 resolveTie(out, tiesTrace); +243 } +244 if (nanStrategy == NaNStrategy.FIXED) { +245 restoreNaNs(out, nanPositions); +246 } +247 return out; +248 } +249 +250 /** +251 * Returns an array that is a copy of the input array with IntDoublePairs +252 * having NaN values removed. +253 * +254 * @param ranks input array +255 * @return array with NaN-valued entries removed +256 */ +257 private IntDoublePair[] removeNaNs(IntDoublePair[] ranks) { +258 if (!containsNaNs(ranks)) { +259 return ranks; +260 } +261 IntDoublePair[] outRanks = new IntDoublePair[ranks.length]; +262 int j = 0; +263 for (int i = 0; i < ranks.length; i++) { +264 if (Double.isNaN(ranks[i].getValue())) { +265 // drop, but adjust original ranks of later elements +266 for (int k = i + 1; k < ranks.length; k++) { +267 ranks[k] = new IntDoublePair( +268 ranks[k].getValue(), ranks[k].getPosition() - 1); +269 } +270 } else { +271 outRanks[j] = new IntDoublePair( +272 ranks[i].getValue(), ranks[i].getPosition()); +273 j++; +274 } +275 } +276 IntDoublePair[] returnRanks = new IntDoublePair[j]; +277 System.arraycopy(outRanks, 0, returnRanks, 0, j); +278 return returnRanks; +279 } +280 +281 /** +282 * Recodes NaN values to the given value. +283 * +284 * @param ranks array to recode +285 * @param value the value to replace NaNs with +286 */ +287 private void recodeNaNs(IntDoublePair[] ranks, double value) { +288 for (int i = 0; i < ranks.length; i++) { +289 if (Double.isNaN(ranks[i].getValue())) { +290 ranks[i] = new IntDoublePair( +291 value, ranks[i].getPosition()); +292 } +293 } +294 } +295 +296 /** +297 * Checks for presence of NaNs in <code>ranks.</code> +298 * +299 * @param ranks array to be searched for NaNs +300 * @return true iff ranks contains one or more NaNs +301 */ +302 private boolean containsNaNs(IntDoublePair[] ranks) { +303 for (int i = 0; i < ranks.length; i++) { +304 if (Double.isNaN(ranks[i].getValue())) { +305 return true; +306 } +307 } +308 return false; +309 } +310 +311 /** +312 * Resolve a sequence of ties, using the configured {@link TiesStrategy}. +313 * The input <code>ranks</code> array is expected to take the same value +314 * for all indices in <code>tiesTrace</code>. The common value is recoded +315 * according to the tiesStrategy. For example, if ranks = <5,8,2,6,2,7,1,2>, +316 * tiesTrace = <2,4,7> and tiesStrategy is MINIMUM, ranks will be unchanged. +317 * The same array and trace with tiesStrategy AVERAGE will come out +318 * <5,8,3,6,3,7,1,3>. +319 * +320 * @param ranks array of ranks +321 * @param tiesTrace list of indices where <code>ranks</code> is constant +322 * -- that is, for any i and j in TiesTrace, <code> ranks[i] == ranks[j] +323 * </code> +324 */ +325 private void resolveTie(double[] ranks, List<Integer> tiesTrace) { +326 +327 // constant value of ranks over tiesTrace +328 final double c = ranks[tiesTrace.get(0)]; +329 +330 // length of sequence of tied ranks +331 final int length = tiesTrace.size(); +332 +333 switch (tiesStrategy) { +334 case AVERAGE: // Replace ranks with average +335 fill(ranks, tiesTrace, (2 * c + length - 1) / 2d); +336 break; +337 case MAXIMUM: // Replace ranks with maximum values +338 fill(ranks, tiesTrace, c + length - 1); +339 break; +340 case MINIMUM: // Replace ties with minimum +341 fill(ranks, tiesTrace, c); +342 break; +343 case RANDOM: // Fill with random integral values in [c, c + length - 1] +344 Iterator<Integer> iterator = tiesTrace.iterator(); +345 long f = Math.round(c); +346 while (iterator.hasNext()) { +347 ranks[iterator.next()] = +348 randomData.nextLong(f, f + length - 1); +349 } +350 break; +351 case SEQUENTIAL: // Fill sequentially from c to c + length - 1 +352 // walk and fill +353 iterator = tiesTrace.iterator(); +354 f = Math.round(c); +355 int i = 0; +356 while (iterator.hasNext()) { +357 ranks[iterator.next()] = f + i++; +358 } +359 break; +360 default: // this should not happen unless TiesStrategy enum is changed +361 throw MathRuntimeException.createInternalError(null); +362 } +363 } +364 +365 /** +366 * Sets<code>data[i] = value</code> for each i in <code>tiesTrace.</code> +367 * +368 * @param data array to modify +369 * @param tiesTrace list of index values to set +370 * @param value value to set +371 */ +372 private void fill(double[] data, List<Integer> tiesTrace, double value) { +373 Iterator<Integer> iterator = tiesTrace.iterator(); +374 while (iterator.hasNext()) { +375 data[iterator.next()] = value; +376 } +377 } +378 +379 /** +380 * Set <code>ranks[i] = Double.NaN</code> for each i in <code>nanPositions.</code> +381 * +382 * @param ranks array to modify +383 * @param nanPositions list of index values to set to <code>Double.NaN</code> +384 */ +385 private void restoreNaNs(double[] ranks, List<Integer> nanPositions) { +386 if (nanPositions.size() == 0) { +387 return; +388 } +389 Iterator<Integer> iterator = nanPositions.iterator(); +390 while (iterator.hasNext()) { +391 ranks[iterator.next().intValue()] = Double.NaN; +392 } +393 +394 } +395 +396 /** +397 * Returns a list of indexes where <code>ranks</code> is <code>NaN.</code> +398 * +399 * @param ranks array to search for <code>NaNs</code> +400 * @return list of indexes i such that <code>ranks[i] = NaN</code> +401 */ +402 private List<Integer> getNanPositions(IntDoublePair[] ranks) { +403 ArrayList<Integer> out = new ArrayList<Integer>(); +404 for (int i = 0; i < ranks.length; i++) { +405 if (Double.isNaN(ranks[i].getValue())) { +406 out.add(Integer.valueOf(i)); +407 } +408 } +409 return out; +410 } +411 +412 /** +413 * Represents the position of a double value in an ordering. +414 * Comparable interface is implemented so Arrays.sort can be used +415 * to sort an array of IntDoublePairs by value. Note that the +416 * implicitly defined natural ordering is NOT consistent with equals. +417 */ +418 private static class IntDoublePair implements Comparable<IntDoublePair> { +419 +420 /** Value of the pair */ +421 private final double value; +422 +423 /** Original position of the pair */ +424 private final int position; +425 +426 /** +427 * Construct an IntDoublePair with the given value and position. +428 * @param value the value of the pair +429 * @param position the original position +430 */ +431 public IntDoublePair(double value, int position) { +432 this.value = value; +433 this.position = position; +434 } +435 +436 /** +437 * Compare this IntDoublePair to another pair. +438 * Only the <strong>values</strong> are compared. +439 * +440 * @param other the other pair to compare this to +441 * @return result of <code>Double.compare(value, other.value)</code> +442 */ +443 public int compareTo(IntDoublePair other) { +444 return Double.compare(value, other.value); +445 } +446 +447 /** +448 * Returns the value of the pair. +449 * @return value +450 */ +451 public double getValue() { +452 return value; +453 } +454 +455 /** +456 * Returns the original position of the pair. +457 * @return position +458 */ +459 public int getPosition() { +460 return position; +461 } +462 } +463 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/ranking/RankingAlgorithm.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/ranking/RankingAlgorithm.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,107 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.stat.ranking; +019 +020 /** +021 * Interface representing a rank transformation. +022 * +023 * @since 2.0 +024 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +025 */ +026 public interface RankingAlgorithm { +027 /** +028 * <p>Performs a rank transformation on the input data, returning an array +029 * of ranks.</p> +030 * +031 * <p>Ranks should be 1-based - that is, the smallest value +032 * returned in an array of ranks should be greater than or equal to one, +033 * rather than 0. Ranks should in general take integer values, though +034 * implementations may return averages or other floating point values +035 * to resolve ties in the input data.</p> +036 * +037 * @param data array of data to be ranked +038 * @return an array of ranks corresponding to the elements of the input array +039 */ +040 double[] rank (double[] data); +041 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/ranking/TiesStrategy.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/ranking/TiesStrategy.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,121 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.stat.ranking; +019 +020 /** +021 * Strategies for handling tied values in rank transformations. +022 * <ul> +023 * <li>SEQUENTIAL - Ties are assigned ranks in order of occurrence in the original array, +024 * for example (1,3,4,3) is ranked as (1,2,4,3)</li> +025 * <li>MINIMUM - Tied values are assigned the minimum applicable rank, or the rank +026 * of the first occurrence. For example, (1,3,4,3) is ranked as (1,2,4,2)</li> +027 * <li>MAXIMUM - Tied values are assigned the maximum applicable rank, or the rank +028 * of the last occurrence. For example, (1,3,4,3) is ranked as (1,3,4,3)</li> +029 * <li>AVERAGE - Tied values are assigned the average of the applicable ranks. +030 * For example, (1,3,4,3) is ranked as (1,2.5,4,2.5)</li> +031 * <li>AVERAGE - Tied values are assigned a random integer rank from among the +032 * applicable values. The assigned rank will always be an integer, (inclusively) +033 * between the values retured by the MINIMUM and MAXIMUM strategies.</li> +034 * </ul> +035 * +036 * @since 2.0 +037 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +038 */ +039 public enum TiesStrategy { +040 +041 /** Ties assigned sequential ranks in order of occurrence */ +042 SEQUENTIAL, +043 +044 /** Ties get the minimum applicable rank */ +045 MINIMUM, +046 +047 /** Ties get the maximum applicable rank */ +048 MAXIMUM, +049 +050 /** Ties get the average of applicable ranks */ +051 AVERAGE, +052 +053 /** Ties get a random integral value from among applicable ranks */ +054 RANDOM +055 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,269 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.regression; +018 +019 import org.apache.commons.math.MathRuntimeException; +020 import org.apache.commons.math.linear.RealMatrix; +021 import org.apache.commons.math.linear.Array2DRowRealMatrix; +022 import org.apache.commons.math.linear.RealVector; +023 import org.apache.commons.math.linear.ArrayRealVector; +024 +025 /** +026 * Abstract base class for implementations of MultipleLinearRegression. +027 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +028 * @since 2.0 +029 */ +030 public abstract class AbstractMultipleLinearRegression implements +031 MultipleLinearRegression { +032 +033 /** X sample data. */ +034 protected RealMatrix X; +035 +036 /** Y sample data. */ +037 protected RealVector Y; +038 +039 /** +040 * Loads model x and y sample data from a flat array of data, overriding any previous sample. +041 * Assumes that rows are concatenated with y values first in each row. +042 * +043 * @param data input data array +044 * @param nobs number of observations (rows) +045 * @param nvars number of independent variables (columns, not counting y) +046 */ +047 public void newSampleData(double[] data, int nobs, int nvars) { +048 double[] y = new double[nobs]; +049 double[][] x = new double[nobs][nvars + 1]; +050 int pointer = 0; +051 for (int i = 0; i < nobs; i++) { +052 y[i] = data[pointer++]; +053 x[i][0] = 1.0d; +054 for (int j = 1; j < nvars + 1; j++) { +055 x[i][j] = data[pointer++]; +056 } +057 } +058 this.X = new Array2DRowRealMatrix(x); +059 this.Y = new ArrayRealVector(y); +060 } +061 +062 /** +063 * Loads new y sample data, overriding any previous sample +064 * +065 * @param y the [n,1] array representing the y sample +066 */ +067 protected void newYSampleData(double[] y) { +068 this.Y = new ArrayRealVector(y); +069 } +070 +071 /** +072 * Loads new x sample data, overriding any previous sample +073 * +074 * @param x the [n,k] array representing the x sample +075 */ +076 protected void newXSampleData(double[][] x) { +077 this.X = new Array2DRowRealMatrix(x); +078 } +079 +080 /** +081 * Validates sample data. +082 * +083 * @param x the [n,k] array representing the x sample +084 * @param y the [n,1] array representing the y sample +085 * @throws IllegalArgumentException if the x and y array data are not +086 * compatible for the regression +087 */ +088 protected void validateSampleData(double[][] x, double[] y) { +089 if ((x == null) || (y == null) || (x.length != y.length)) { +090 throw MathRuntimeException.createIllegalArgumentException( +091 "dimension mismatch {0} != {1}", +092 (x == null) ? 0 : x.length, +093 (y == null) ? 0 : y.length); +094 } else if ((x.length > 0) && (x[0].length > x.length)) { +095 throw MathRuntimeException.createIllegalArgumentException( +096 "not enough data ({0} rows) for this many predictors ({1} predictors)", +097 x.length, x[0].length); +098 } +099 } +100 +101 /** +102 * Validates sample data. +103 * +104 * @param x the [n,k] array representing the x sample +105 * @param covariance the [n,n] array representing the covariance matrix +106 * @throws IllegalArgumentException if the x sample data or covariance +107 * matrix are not compatible for the regression +108 */ +109 protected void validateCovarianceData(double[][] x, double[][] covariance) { +110 if (x.length != covariance.length) { +111 throw MathRuntimeException.createIllegalArgumentException( +112 "dimension mismatch {0} != {1}", x.length, covariance.length); +113 } +114 if (covariance.length > 0 && covariance.length != covariance[0].length) { +115 throw MathRuntimeException.createIllegalArgumentException( +116 "a {0}x{1} matrix was provided instead of a square matrix", +117 covariance.length, covariance[0].length); +118 } +119 } +120 +121 /** +122 * {@inheritDoc} +123 */ +124 public double[] estimateRegressionParameters() { +125 RealVector b = calculateBeta(); +126 return b.getData(); +127 } +128 +129 /** +130 * {@inheritDoc} +131 */ +132 public double[] estimateResiduals() { +133 RealVector b = calculateBeta(); +134 RealVector e = Y.subtract(X.operate(b)); +135 return e.getData(); +136 } +137 +138 /** +139 * {@inheritDoc} +140 */ +141 public double[][] estimateRegressionParametersVariance() { +142 return calculateBetaVariance().getData(); +143 } +144 +145 /** +146 * {@inheritDoc} +147 */ +148 public double[] estimateRegressionParametersStandardErrors() { +149 double[][] betaVariance = estimateRegressionParametersVariance(); +150 double sigma = calculateYVariance(); +151 int length = betaVariance[0].length; +152 double[] result = new double[length]; +153 for (int i = 0; i < length; i++) { +154 result[i] = Math.sqrt(sigma * betaVariance[i][i]); +155 } +156 return result; +157 } +158 +159 /** +160 * {@inheritDoc} +161 */ +162 public double estimateRegressandVariance() { +163 return calculateYVariance(); +164 } +165 +166 /** +167 * Calculates the beta of multiple linear regression in matrix notation. +168 * +169 * @return beta +170 */ +171 protected abstract RealVector calculateBeta(); +172 +173 /** +174 * Calculates the beta variance of multiple linear regression in matrix +175 * notation. +176 * +177 * @return beta variance +178 */ +179 protected abstract RealMatrix calculateBetaVariance(); +180 +181 /** +182 * Calculates the Y variance of multiple linear regression. +183 * +184 * @return Y variance +185 */ +186 protected abstract double calculateYVariance(); +187 +188 /** +189 * Calculates the residuals of multiple linear regression in matrix +190 * notation. +191 * +192 * <pre> +193 * u = y - X * b +194 * </pre> +195 * +196 * @return The residuals [n,1] matrix +197 */ +198 protected RealVector calculateResiduals() { +199 RealVector b = calculateBeta(); +200 return Y.subtract(X.operate(b)); +201 } +202 +203 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,197 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.regression; +018 +019 import org.apache.commons.math.linear.LUDecompositionImpl; +020 import org.apache.commons.math.linear.RealMatrix; +021 import org.apache.commons.math.linear.Array2DRowRealMatrix; +022 import org.apache.commons.math.linear.RealVector; +023 +024 +025 /** +026 * The GLS implementation of the multiple linear regression. +027 * +028 * GLS assumes a general covariance matrix Omega of the error +029 * <pre> +030 * u ~ N(0, Omega) +031 * </pre> +032 * +033 * Estimated by GLS, +034 * <pre> +035 * b=(X' Omega^-1 X)^-1X'Omega^-1 y +036 * </pre> +037 * whose variance is +038 * <pre> +039 * Var(b)=(X' Omega^-1 X)^-1 +040 * </pre> +041 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +042 * @since 2.0 +043 */ +044 public class GLSMultipleLinearRegression extends AbstractMultipleLinearRegression { +045 +046 /** Covariance matrix. */ +047 private RealMatrix Omega; +048 +049 /** Inverse of covariance matrix. */ +050 private RealMatrix OmegaInverse; +051 +052 /** Replace sample data, overriding any previous sample. +053 * @param y y values of the sample +054 * @param x x values of the sample +055 * @param covariance array representing the covariance matrix +056 */ +057 public void newSampleData(double[] y, double[][] x, double[][] covariance) { +058 validateSampleData(x, y); +059 newYSampleData(y); +060 newXSampleData(x); +061 validateCovarianceData(x, covariance); +062 newCovarianceData(covariance); +063 } +064 +065 /** +066 * Add the covariance data. +067 * +068 * @param omega the [n,n] array representing the covariance +069 */ +070 protected void newCovarianceData(double[][] omega){ +071 this.Omega = new Array2DRowRealMatrix(omega); +072 this.OmegaInverse = null; +073 } +074 +075 /** +076 * Get the inverse of the covariance. +077 * <p>The inverse of the covariance matrix is lazily evaluated and cached.</p> +078 * @return inverse of the covariance +079 */ +080 protected RealMatrix getOmegaInverse() { +081 if (OmegaInverse == null) { +082 OmegaInverse = new LUDecompositionImpl(Omega).getSolver().getInverse(); +083 } +084 return OmegaInverse; +085 } +086 +087 /** +088 * Calculates beta by GLS. +089 * <pre> +090 * b=(X' Omega^-1 X)^-1X'Omega^-1 y +091 * </pre> +092 * @return beta +093 */ +094 @Override +095 protected RealVector calculateBeta() { +096 RealMatrix OI = getOmegaInverse(); +097 RealMatrix XT = X.transpose(); +098 RealMatrix XTOIX = XT.multiply(OI).multiply(X); +099 RealMatrix inverse = new LUDecompositionImpl(XTOIX).getSolver().getInverse(); +100 return inverse.multiply(XT).multiply(OI).operate(Y); +101 } +102 +103 /** +104 * Calculates the variance on the beta by GLS. +105 * <pre> +106 * Var(b)=(X' Omega^-1 X)^-1 +107 * </pre> +108 * @return The beta variance matrix +109 */ +110 @Override +111 protected RealMatrix calculateBetaVariance() { +112 RealMatrix OI = getOmegaInverse(); +113 RealMatrix XTOIX = X.transpose().multiply(OI).multiply(X); +114 return new LUDecompositionImpl(XTOIX).getSolver().getInverse(); +115 } +116 +117 /** +118 * Calculates the variance on the y by GLS. +119 * <pre> +120 * Var(y)=Tr(u' Omega^-1 u)/(n-k) +121 * </pre> +122 * @return The Y variance +123 */ +124 @Override +125 protected double calculateYVariance() { +126 RealVector residuals = calculateResiduals(); +127 double t = residuals.dotProduct(getOmegaInverse().operate(residuals)); +128 return t / (X.getRowDimension() - X.getColumnDimension()); +129 } +130 +131 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/regression/MultipleLinearRegression.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/regression/MultipleLinearRegression.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,136 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.regression; +018 +019 /** +020 * The multiple linear regression can be represented in matrix-notation. +021 * <pre> +022 * y=X*b+u +023 * </pre> +024 * 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 +025 * <b>regressors</b>, b is <code>k-vector</code> of <b>regression parameters</b> and <code>u</code> is an <code>n-vector</code> +026 * of <b>error terms</b> or <b>residuals</b>. +027 * +028 * The notation is quite standard in literature, +029 * cf eg <a href="http://www.econ.queensu.ca/ETM">Davidson and MacKinnon, Econometrics Theory and Methods, 2004</a>. +030 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +031 * @since 2.0 +032 */ +033 public interface MultipleLinearRegression { +034 +035 /** +036 * Estimates the regression parameters b. +037 * +038 * @return The [k,1] array representing b +039 */ +040 double[] estimateRegressionParameters(); +041 +042 /** +043 * Estimates the variance of the regression parameters, ie Var(b). +044 * +045 * @return The [k,k] array representing the variance of b +046 */ +047 double[][] estimateRegressionParametersVariance(); +048 +049 /** +050 * Estimates the residuals, ie u = y - X*b. +051 * +052 * @return The [n,1] array representing the residuals +053 */ +054 double[] estimateResiduals(); +055 +056 /** +057 * Returns the variance of the regressand, ie Var(y). +058 * +059 * @return The double representing the variance of y +060 */ +061 double estimateRegressandVariance(); +062 +063 /** +064 * Returns the standard errors of the regression parameters. +065 * +066 * @return standard errors of estimated regression parameters +067 */ +068 double[] estimateRegressionParametersStandardErrors(); +069 +070 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,245 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.stat.regression; +018 +019 import org.apache.commons.math.linear.Array2DRowRealMatrix; +020 import org.apache.commons.math.linear.LUDecompositionImpl; +021 import org.apache.commons.math.linear.QRDecomposition; +022 import org.apache.commons.math.linear.QRDecompositionImpl; +023 import org.apache.commons.math.linear.RealMatrix; +024 import org.apache.commons.math.linear.RealVector; +025 +026 /** +027 * <p>Implements ordinary least squares (OLS) to estimate the parameters of a +028 * multiple linear regression model.</p> +029 * +030 * <p>OLS assumes the covariance matrix of the error to be diagonal and with +031 * equal variance.</p> +032 * <p> +033 * u ~ N(0, σ<sup>2</sup>I) +034 * </p> +035 * +036 * <p>The regression coefficients, b, satisfy the normal equations: +037 * <p> +038 * X<sup>T</sup> X b = X<sup>T</sup> y +039 * </p> +040 * +041 * <p>To solve the normal equations, this implementation uses QR decomposition +042 * of the X matrix. (See {@link QRDecompositionImpl} for details on the +043 * decomposition algorithm.) +044 * </p> +045 * <p>X<sup>T</sup>X b = X<sup>T</sup> y <br/> +046 * (QR)<sup>T</sup> (QR) b = (QR)<sup>T</sup>y <br/> +047 * R<sup>T</sup> (Q<sup>T</sup>Q) R b = R<sup>T</sup> Q<sup>T</sup> y <br/> +048 * R<sup>T</sup> R b = R<sup>T</sup> Q<sup>T</sup> y <br/> +049 * (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 <br/> +050 * R b = Q<sup>T</sup> y +051 * </p> +052 * Given Q and R, the last equation is solved by back-subsitution.</p> +053 * +054 * @version $Revision: 825925 $ $Date: 2009-10-16 11:11:47 -0400 (Fri, 16 Oct 2009) $ +055 * @since 2.0 +056 */ +057 public class OLSMultipleLinearRegression extends AbstractMultipleLinearRegression { +058 +059 /** Cached QR decomposition of X matrix */ +060 private QRDecomposition qr = null; +061 +062 /** +063 * Loads model x and y sample data, overriding any previous sample. +064 * +065 * Computes and caches QR decomposition of the X matrix. +066 * @param y the [n,1] array representing the y sample +067 * @param x the [n,k] array representing the x sample +068 * @throws IllegalArgumentException if the x and y array data are not +069 * compatible for the regression +070 */ +071 public void newSampleData(double[] y, double[][] x) { +072 validateSampleData(x, y); +073 newYSampleData(y); +074 newXSampleData(x); +075 } +076 +077 /** +078 * {@inheritDoc} +079 * +080 * Computes and caches QR decomposition of the X matrix +081 */ +082 @Override +083 public void newSampleData(double[] data, int nobs, int nvars) { +084 super.newSampleData(data, nobs, nvars); +085 qr = new QRDecompositionImpl(X); +086 } +087 +088 /** +089 * <p>Compute the "hat" matrix. +090 * </p> +091 * <p>The hat matrix is defined in terms of the design matrix X +092 * by X(X<sup>T</sup>X)<sup>-1</sup>X<sup>T</sup> +093 * </p> +094 * <p>The implementation here uses the QR decomposition to compute the +095 * hat matrix as Q I<sub>p</sub>Q<sup>T</sup> where I<sub>p</sub> is the +096 * p-dimensional identity matrix augmented by 0's. This computational +097 * formula is from "The Hat Matrix in Regression and ANOVA", +098 * David C. Hoaglin and Roy E. Welsch, +099 * <i>The American Statistician</i>, Vol. 32, No. 1 (Feb., 1978), pp. 17-22. +100 * +101 * @return the hat matrix +102 */ +103 public RealMatrix calculateHat() { +104 // Create augmented identity matrix +105 RealMatrix Q = qr.getQ(); +106 final int p = qr.getR().getColumnDimension(); +107 final int n = Q.getColumnDimension(); +108 Array2DRowRealMatrix augI = new Array2DRowRealMatrix(n, n); +109 double[][] augIData = augI.getDataRef(); +110 for (int i = 0; i < n; i++) { +111 for (int j =0; j < n; j++) { +112 if (i == j && i < p) { +113 augIData[i][j] = 1d; +114 } else { +115 augIData[i][j] = 0d; +116 } +117 } +118 } +119 +120 // Compute and return Hat matrix +121 return Q.multiply(augI).multiply(Q.transpose()); +122 } +123 +124 /** +125 * Loads new x sample data, overriding any previous sample +126 * +127 * @param x the [n,k] array representing the x sample +128 */ +129 @Override +130 protected void newXSampleData(double[][] x) { +131 this.X = new Array2DRowRealMatrix(x); +132 qr = new QRDecompositionImpl(X); +133 } +134 +135 /** +136 * Calculates regression coefficients using OLS. +137 * +138 * @return beta +139 */ +140 @Override +141 protected RealVector calculateBeta() { +142 return qr.getSolver().solve(Y); +143 } +144 +145 /** +146 * <p>Calculates the variance on the beta by OLS. +147 * </p> +148 * <p>Var(b) = (X<sup>T</sup>X)<sup>-1</sup> +149 * </p> +150 * <p>Uses QR decomposition to reduce (X<sup>T</sup>X)<sup>-1</sup> +151 * to (R<sup>T</sup>R)<sup>-1</sup>, with only the top p rows of +152 * R included, where p = the length of the beta vector.</p> +153 * +154 * @return The beta variance +155 */ +156 @Override +157 protected RealMatrix calculateBetaVariance() { +158 int p = X.getColumnDimension(); +159 RealMatrix Raug = qr.getR().getSubMatrix(0, p - 1 , 0, p - 1); +160 RealMatrix Rinv = new LUDecompositionImpl(Raug).getSolver().getInverse(); +161 return Rinv.multiply(Rinv.transpose()); +162 } +163 +164 +165 /** +166 * <p>Calculates the variance on the Y by OLS. +167 * </p> +168 * <p> Var(y) = Tr(u<sup>T</sup>u)/(n - k) +169 * </p> +170 * @return The Y variance +171 */ +172 @Override +173 protected double calculateYVariance() { +174 RealVector residuals = calculateResiduals(); +175 return residuals.dotProduct(residuals) / +176 (X.getRowDimension() - X.getColumnDimension()); +177 } +178 +179 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/regression/SimpleRegression.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/stat/regression/SimpleRegression.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,687 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.stat.regression; +019 import java.io.Serializable; +020 +021 import org.apache.commons.math.MathException; +022 import org.apache.commons.math.MathRuntimeException; +023 import org.apache.commons.math.distribution.TDistribution; +024 import org.apache.commons.math.distribution.TDistributionImpl; +025 +026 /** +027 * Estimates an ordinary least squares regression model +028 * with one independent variable. +029 * <p> +030 * <code> y = intercept + slope * x </code></p> +031 * <p> +032 * Standard errors for <code>intercept</code> and <code>slope</code> are +033 * available as well as ANOVA, r-square and Pearson's r statistics.</p> +034 * <p> +035 * Observations (x,y pairs) can be added to the model one at a time or they +036 * can be provided in a 2-dimensional array. The observations are not stored +037 * in memory, so there is no limit to the number of observations that can be +038 * added to the model.</p> +039 * <p> +040 * <strong>Usage Notes</strong>: <ul> +041 * <li> When there are fewer than two observations in the model, or when +042 * there is no variation in the x values (i.e. all x values are the same) +043 * all statistics return <code>NaN</code>. At least two observations with +044 * different x coordinates are requred to estimate a bivariate regression +045 * model. +046 * </li> +047 * <li> getters for the statistics always compute values based on the current +048 * set of observations -- i.e., you can get statistics, then add more data +049 * and get updated statistics without using a new instance. There is no +050 * "compute" method that updates all statistics. Each of the getters performs +051 * the necessary computations to return the requested statistic.</li> +052 * </ul></p> +053 * +054 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +055 */ +056 public class SimpleRegression implements Serializable { +057 +058 /** Serializable version identifier */ +059 private static final long serialVersionUID = -3004689053607543335L; +060 +061 /** the distribution used to compute inference statistics. */ +062 private TDistribution distribution; +063 +064 /** sum of x values */ +065 private double sumX = 0d; +066 +067 /** total variation in x (sum of squared deviations from xbar) */ +068 private double sumXX = 0d; +069 +070 /** sum of y values */ +071 private double sumY = 0d; +072 +073 /** total variation in y (sum of squared deviations from ybar) */ +074 private double sumYY = 0d; +075 +076 /** sum of products */ +077 private double sumXY = 0d; +078 +079 /** number of observations */ +080 private long n = 0; +081 +082 /** mean of accumulated x values, used in updating formulas */ +083 private double xbar = 0; +084 +085 /** mean of accumulated y values, used in updating formulas */ +086 private double ybar = 0; +087 +088 // ---------------------Public methods-------------------------------------- +089 +090 /** +091 * Create an empty SimpleRegression instance +092 */ +093 public SimpleRegression() { +094 this(new TDistributionImpl(1.0)); +095 } +096 +097 /** +098 * Create an empty SimpleRegression using the given distribution object to +099 * compute inference statistics. +100 * @param t the distribution used to compute inference statistics. +101 * @since 1.2 +102 */ +103 public SimpleRegression(TDistribution t) { +104 super(); +105 setDistribution(t); +106 } +107 +108 /** +109 * Adds the observation (x,y) to the regression data set. +110 * <p> +111 * Uses updating formulas for means and sums of squares defined in +112 * "Algorithms for Computing the Sample Variance: Analysis and +113 * Recommendations", Chan, T.F., Golub, G.H., and LeVeque, R.J. +114 * 1983, American Statistician, vol. 37, pp. 242-247, referenced in +115 * Weisberg, S. "Applied Linear Regression". 2nd Ed. 1985.</p> +116 * +117 * +118 * @param x independent variable value +119 * @param y dependent variable value +120 */ +121 public void addData(double x, double y) { +122 if (n == 0) { +123 xbar = x; +124 ybar = y; +125 } else { +126 double dx = x - xbar; +127 double dy = y - ybar; +128 sumXX += dx * dx * (double) n / (n + 1d); +129 sumYY += dy * dy * (double) n / (n + 1d); +130 sumXY += dx * dy * (double) n / (n + 1d); +131 xbar += dx / (n + 1.0); +132 ybar += dy / (n + 1.0); +133 } +134 sumX += x; +135 sumY += y; +136 n++; +137 +138 if (n > 2) { +139 distribution.setDegreesOfFreedom(n - 2); +140 } +141 } +142 +143 +144 /** +145 * Removes the observation (x,y) from the regression data set. +146 * <p> +147 * Mirrors the addData method. This method permits the use of +148 * SimpleRegression instances in streaming mode where the regression +149 * is applied to a sliding "window" of observations, however the caller is +150 * responsible for maintaining the set of observations in the window.</p> +151 * +152 * The method has no effect if there are no points of data (i.e. n=0) +153 * +154 * @param x independent variable value +155 * @param y dependent variable value +156 */ +157 public void removeData(double x, double y) { +158 if (n > 0) { +159 double dx = x - xbar; +160 double dy = y - ybar; +161 sumXX -= dx * dx * (double) n / (n - 1d); +162 sumYY -= dy * dy * (double) n / (n - 1d); +163 sumXY -= dx * dy * (double) n / (n - 1d); +164 xbar -= dx / (n - 1.0); +165 ybar -= dy / (n - 1.0); +166 sumX -= x; +167 sumY -= y; +168 n--; +169 +170 if (n > 2) { +171 distribution.setDegreesOfFreedom(n - 2); +172 } +173 } +174 } +175 +176 /** +177 * Adds the observations represented by the elements in +178 * <code>data</code>. +179 * <p> +180 * <code>(data[0][0],data[0][1])</code> will be the first observation, then +181 * <code>(data[1][0],data[1][1])</code>, etc.</p> +182 * <p> +183 * This method does not replace data that has already been added. The +184 * observations represented by <code>data</code> are added to the existing +185 * dataset.</p> +186 * <p> +187 * To replace all data, use <code>clear()</code> before adding the new +188 * data.</p> +189 * +190 * @param data array of observations to be added +191 */ +192 public void addData(double[][] data) { +193 for (int i = 0; i < data.length; i++) { +194 addData(data[i][0], data[i][1]); +195 } +196 } +197 +198 +199 /** +200 * Removes observations represented by the elements in <code>data</code>. +201 * <p> +202 * If the array is larger than the current n, only the first n elements are +203 * processed. This method permits the use of SimpleRegression instances in +204 * streaming mode where the regression is applied to a sliding "window" of +205 * observations, however the caller is responsible for maintaining the set +206 * of observations in the window.</p> +207 * <p> +208 * To remove all data, use <code>clear()</code>.</p> +209 * +210 * @param data array of observations to be removed +211 */ +212 public void removeData(double[][] data) { +213 for (int i = 0; i < data.length && n > 0; i++) { +214 removeData(data[i][0], data[i][1]); +215 } +216 } +217 +218 /** +219 * Clears all data from the model. +220 */ +221 public void clear() { +222 sumX = 0d; +223 sumXX = 0d; +224 sumY = 0d; +225 sumYY = 0d; +226 sumXY = 0d; +227 n = 0; +228 } +229 +230 /** +231 * Returns the number of observations that have been added to the model. +232 * +233 * @return n number of observations that have been added. +234 */ +235 public long getN() { +236 return n; +237 } +238 +239 /** +240 * Returns the "predicted" <code>y</code> value associated with the +241 * supplied <code>x</code> value, based on the data that has been +242 * added to the model when this method is activated. +243 * <p> +244 * <code> predict(x) = intercept + slope * x </code></p> +245 * <p> +246 * <strong>Preconditions</strong>: <ul> +247 * <li>At least two observations (with at least two different x values) +248 * must have been added before invoking this method. If this method is +249 * invoked before a model can be estimated, <code>Double,NaN</code> is +250 * returned. +251 * </li></ul></p> +252 * +253 * @param x input <code>x</code> value +254 * @return predicted <code>y</code> value +255 */ +256 public double predict(double x) { +257 double b1 = getSlope(); +258 return getIntercept(b1) + b1 * x; +259 } +260 +261 /** +262 * Returns the intercept of the estimated regression line. +263 * <p> +264 * The least squares estimate of the intercept is computed using the +265 * <a href="http://www.xycoon.com/estimation4.htm">normal equations</a>. +266 * The intercept is sometimes denoted b0.</p> +267 * <p> +268 * <strong>Preconditions</strong>: <ul> +269 * <li>At least two observations (with at least two different x values) +270 * must have been added before invoking this method. If this method is +271 * invoked before a model can be estimated, <code>Double,NaN</code> is +272 * returned. +273 * </li></ul></p> +274 * +275 * @return the intercept of the regression line +276 */ +277 public double getIntercept() { +278 return getIntercept(getSlope()); +279 } +280 +281 /** +282 * Returns the slope of the estimated regression line. +283 * <p> +284 * The least squares estimate of the slope is computed using the +285 * <a href="http://www.xycoon.com/estimation4.htm">normal equations</a>. +286 * The slope is sometimes denoted b1.</p> +287 * <p> +288 * <strong>Preconditions</strong>: <ul> +289 * <li>At least two observations (with at least two different x values) +290 * must have been added before invoking this method. If this method is +291 * invoked before a model can be estimated, <code>Double.NaN</code> is +292 * returned. +293 * </li></ul></p> +294 * +295 * @return the slope of the regression line +296 */ +297 public double getSlope() { +298 if (n < 2) { +299 return Double.NaN; //not enough data +300 } +301 if (Math.abs(sumXX) < 10 * Double.MIN_VALUE) { +302 return Double.NaN; //not enough variation in x +303 } +304 return sumXY / sumXX; +305 } +306 +307 /** +308 * Returns the <a href="http://www.xycoon.com/SumOfSquares.htm"> +309 * sum of squared errors</a> (SSE) associated with the regression +310 * model. +311 * <p> +312 * The sum is computed using the computational formula</p> +313 * <p> +314 * <code>SSE = SYY - (SXY * SXY / SXX)</code></p> +315 * <p> +316 * where <code>SYY</code> is the sum of the squared deviations of the y +317 * values about their mean, <code>SXX</code> is similarly defined and +318 * <code>SXY</code> is the sum of the products of x and y mean deviations. +319 * </p><p> +320 * The sums are accumulated using the updating algorithm referenced in +321 * {@link #addData}.</p> +322 * <p> +323 * The return value is constrained to be non-negative - i.e., if due to +324 * rounding errors the computational formula returns a negative result, +325 * 0 is returned.</p> +326 * <p> +327 * <strong>Preconditions</strong>: <ul> +328 * <li>At least two observations (with at least two different x values) +329 * must have been added before invoking this method. If this method is +330 * invoked before a model can be estimated, <code>Double,NaN</code> is +331 * returned. +332 * </li></ul></p> +333 * +334 * @return sum of squared errors associated with the regression model +335 */ +336 public double getSumSquaredErrors() { +337 return Math.max(0d, sumYY - sumXY * sumXY / sumXX); +338 } +339 +340 /** +341 * Returns the sum of squared deviations of the y values about their mean. +342 * <p> +343 * This is defined as SSTO +344 * <a href="http://www.xycoon.com/SumOfSquares.htm">here</a>.</p> +345 * <p> +346 * If <code>n < 2</code>, this returns <code>Double.NaN</code>.</p> +347 * +348 * @return sum of squared deviations of y values +349 */ +350 public double getTotalSumSquares() { +351 if (n < 2) { +352 return Double.NaN; +353 } +354 return sumYY; +355 } +356 +357 /** +358 * Returns the sum of squared deviations of the x values about their mean. +359 * +360 * If <code>n < 2</code>, this returns <code>Double.NaN</code>.</p> +361 * +362 * @return sum of squared deviations of x values +363 */ +364 public double getXSumSquares() { +365 if (n < 2) { +366 return Double.NaN; +367 } +368 return sumXX; +369 } +370 +371 /** +372 * Returns the sum of crossproducts, x<sub>i</sub>*y<sub>i</sub>. +373 * +374 * @return sum of cross products +375 */ +376 public double getSumOfCrossProducts() { +377 return sumXY; +378 } +379 +380 /** +381 * Returns the sum of squared deviations of the predicted y values about +382 * their mean (which equals the mean of y). +383 * <p> +384 * This is usually abbreviated SSR or SSM. It is defined as SSM +385 * <a href="http://www.xycoon.com/SumOfSquares.htm">here</a></p> +386 * <p> +387 * <strong>Preconditions</strong>: <ul> +388 * <li>At least two observations (with at least two different x values) +389 * must have been added before invoking this method. If this method is +390 * invoked before a model can be estimated, <code>Double.NaN</code> is +391 * returned. +392 * </li></ul></p> +393 * +394 * @return sum of squared deviations of predicted y values +395 */ +396 public double getRegressionSumSquares() { +397 return getRegressionSumSquares(getSlope()); +398 } +399 +400 /** +401 * Returns the sum of squared errors divided by the degrees of freedom, +402 * usually abbreviated MSE. +403 * <p> +404 * If there are fewer than <strong>three</strong> data pairs in the model, +405 * or if there is no variation in <code>x</code>, this returns +406 * <code>Double.NaN</code>.</p> +407 * +408 * @return sum of squared deviations of y values +409 */ +410 public double getMeanSquareError() { +411 if (n < 3) { +412 return Double.NaN; +413 } +414 return getSumSquaredErrors() / (n - 2); +415 } +416 +417 /** +418 * Returns <a href="http://mathworld.wolfram.com/CorrelationCoefficient.html"> +419 * Pearson's product moment correlation coefficient</a>, +420 * usually denoted r. +421 * <p> +422 * <strong>Preconditions</strong>: <ul> +423 * <li>At least two observations (with at least two different x values) +424 * must have been added before invoking this method. If this method is +425 * invoked before a model can be estimated, <code>Double,NaN</code> is +426 * returned. +427 * </li></ul></p> +428 * +429 * @return Pearson's r +430 */ +431 public double getR() { +432 double b1 = getSlope(); +433 double result = Math.sqrt(getRSquare()); +434 if (b1 < 0) { +435 result = -result; +436 } +437 return result; +438 } +439 +440 /** +441 * Returns the <a href="http://www.xycoon.com/coefficient1.htm"> +442 * coefficient of determination</a>, +443 * usually denoted r-square. +444 * <p> +445 * <strong>Preconditions</strong>: <ul> +446 * <li>At least two observations (with at least two different x values) +447 * must have been added before invoking this method. If this method is +448 * invoked before a model can be estimated, <code>Double,NaN</code> is +449 * returned. +450 * </li></ul></p> +451 * +452 * @return r-square +453 */ +454 public double getRSquare() { +455 double ssto = getTotalSumSquares(); +456 return (ssto - getSumSquaredErrors()) / ssto; +457 } +458 +459 /** +460 * Returns the <a href="http://www.xycoon.com/standarderrorb0.htm"> +461 * standard error of the intercept estimate</a>, +462 * usually denoted s(b0). +463 * <p> +464 * If there are fewer that <strong>three</strong> observations in the +465 * model, or if there is no variation in x, this returns +466 * <code>Double.NaN</code>.</p> +467 * +468 * @return standard error associated with intercept estimate +469 */ +470 public double getInterceptStdErr() { +471 return Math.sqrt( +472 getMeanSquareError() * ((1d / (double) n) + (xbar * xbar) / sumXX)); +473 } +474 +475 /** +476 * Returns the <a href="http://www.xycoon.com/standerrorb(1).htm">standard +477 * error of the slope estimate</a>, +478 * usually denoted s(b1). +479 * <p> +480 * If there are fewer that <strong>three</strong> data pairs in the model, +481 * or if there is no variation in x, this returns <code>Double.NaN</code>. +482 * </p> +483 * +484 * @return standard error associated with slope estimate +485 */ +486 public double getSlopeStdErr() { +487 return Math.sqrt(getMeanSquareError() / sumXX); +488 } +489 +490 /** +491 * Returns the half-width of a 95% confidence interval for the slope +492 * estimate. +493 * <p> +494 * The 95% confidence interval is</p> +495 * <p> +496 * <code>(getSlope() - getSlopeConfidenceInterval(), +497 * getSlope() + getSlopeConfidenceInterval())</code></p> +498 * <p> +499 * If there are fewer that <strong>three</strong> observations in the +500 * model, or if there is no variation in x, this returns +501 * <code>Double.NaN</code>.</p> +502 * <p> +503 * <strong>Usage Note</strong>:<br> +504 * The validity of this statistic depends on the assumption that the +505 * observations included in the model are drawn from a +506 * <a href="http://mathworld.wolfram.com/BivariateNormalDistribution.html"> +507 * Bivariate Normal Distribution</a>.</p> +508 * +509 * @return half-width of 95% confidence interval for the slope estimate +510 * @throws MathException if the confidence interval can not be computed. +511 */ +512 public double getSlopeConfidenceInterval() throws MathException { +513 return getSlopeConfidenceInterval(0.05d); +514 } +515 +516 /** +517 * Returns the half-width of a (100-100*alpha)% confidence interval for +518 * the slope estimate. +519 * <p> +520 * The (100-100*alpha)% confidence interval is </p> +521 * <p> +522 * <code>(getSlope() - getSlopeConfidenceInterval(), +523 * getSlope() + getSlopeConfidenceInterval())</code></p> +524 * <p> +525 * To request, for example, a 99% confidence interval, use +526 * <code>alpha = .01</code></p> +527 * <p> +528 * <strong>Usage Note</strong>:<br> +529 * The validity of this statistic depends on the assumption that the +530 * observations included in the model are drawn from a +531 * <a href="http://mathworld.wolfram.com/BivariateNormalDistribution.html"> +532 * Bivariate Normal Distribution</a>.</p> +533 * <p> +534 * <strong> Preconditions:</strong><ul> +535 * <li>If there are fewer that <strong>three</strong> observations in the +536 * model, or if there is no variation in x, this returns +537 * <code>Double.NaN</code>. +538 * </li> +539 * <li><code>(0 < alpha < 1)</code>; otherwise an +540 * <code>IllegalArgumentException</code> is thrown. +541 * </li></ul></p> +542 * +543 * @param alpha the desired significance level +544 * @return half-width of 95% confidence interval for the slope estimate +545 * @throws MathException if the confidence interval can not be computed. +546 */ +547 public double getSlopeConfidenceInterval(double alpha) +548 throws MathException { +549 if (alpha >= 1 || alpha <= 0) { +550 throw MathRuntimeException.createIllegalArgumentException( +551 "out of bounds significance level {0}, must be between {1} and {2}", +552 alpha, 0.0, 1.0); +553 } +554 return getSlopeStdErr() * +555 distribution.inverseCumulativeProbability(1d - alpha / 2d); +556 } +557 +558 /** +559 * Returns the significance level of the slope (equiv) correlation. +560 * <p> +561 * Specifically, the returned value is the smallest <code>alpha</code> +562 * such that the slope confidence interval with significance level +563 * equal to <code>alpha</code> does not include <code>0</code>. +564 * On regression output, this is often denoted <code>Prob(|t| > 0)</code> +565 * </p><p> +566 * <strong>Usage Note</strong>:<br> +567 * The validity of this statistic depends on the assumption that the +568 * observations included in the model are drawn from a +569 * <a href="http://mathworld.wolfram.com/BivariateNormalDistribution.html"> +570 * Bivariate Normal Distribution</a>.</p> +571 * <p> +572 * If there are fewer that <strong>three</strong> observations in the +573 * model, or if there is no variation in x, this returns +574 * <code>Double.NaN</code>.</p> +575 * +576 * @return significance level for slope/correlation +577 * @throws MathException if the significance level can not be computed. +578 */ +579 public double getSignificance() throws MathException { +580 return 2d * (1.0 - distribution.cumulativeProbability( +581 Math.abs(getSlope()) / getSlopeStdErr())); +582 } +583 +584 // ---------------------Private methods----------------------------------- +585 +586 /** +587 * Returns the intercept of the estimated regression line, given the slope. +588 * <p> +589 * Will return <code>NaN</code> if slope is <code>NaN</code>.</p> +590 * +591 * @param slope current slope +592 * @return the intercept of the regression line +593 */ +594 private double getIntercept(double slope) { +595 return (sumY - slope * sumX) / n; +596 } +597 +598 /** +599 * Computes SSR from b1. +600 * +601 * @param slope regression slope estimate +602 * @return sum of squared deviations of predicted y values +603 */ +604 private double getRegressionSumSquares(double slope) { +605 return slope * slope * sumXX; +606 } +607 +608 /** +609 * Modify the distribution used to compute inference statistics. +610 * @param value the new distribution +611 * @since 1.2 +612 */ +613 public void setDistribution(TDistribution value) { +614 distribution = value; +615 +616 // modify degrees of freedom +617 if (n > 2) { +618 distribution.setDegreesOfFreedom(n - 2); +619 } +620 } +621 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/transform/FastCosineTransformer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/transform/FastCosineTransformer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,328 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.transform; +018 +019 import org.apache.commons.math.FunctionEvaluationException; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.analysis.UnivariateRealFunction; +022 import org.apache.commons.math.complex.Complex; +023 +024 /** +025 * Implements the <a href="http://documents.wolfram.com/v5/Add-onsLinks/ +026 * StandardPackages/LinearAlgebra/FourierTrig.html">Fast Cosine Transform</a> +027 * for transformation of one-dimensional data sets. For reference, see +028 * <b>Fast Fourier Transforms</b>, ISBN 0849371635, chapter 3. +029 * <p> +030 * FCT is its own inverse, up to a multiplier depending on conventions. +031 * The equations are listed in the comments of the corresponding methods.</p> +032 * <p> +033 * Different from FFT and FST, FCT requires the length of data set to be +034 * power of 2 plus one. Users should especially pay attention to the +035 * function transformation on how this affects the sampling.</p> +036 * <p>As of version 2.0 this no longer implements Serializable</p> +037 * +038 * @version $Revision:670469 $ $Date:2008-06-23 10:01:38 +0200 (lun., 23 juin 2008) $ +039 * @since 1.2 +040 */ +041 public class FastCosineTransformer implements RealTransformer { +042 +043 /** +044 * Construct a default transformer. +045 */ +046 public FastCosineTransformer() { +047 super(); +048 } +049 +050 /** +051 * Transform the given real data set. +052 * <p> +053 * The formula is F<sub>n</sub> = (1/2) [f<sub>0</sub> + (-1)<sup>n</sup> f<sub>N</sub>] + +054 * ∑<sub>k=1</sub><sup>N-1</sup> f<sub>k</sub> cos(π nk/N) +055 * </p> +056 * +057 * @param f the real data array to be transformed +058 * @return the real transformed array +059 * @throws IllegalArgumentException if any parameters are invalid +060 */ +061 public double[] transform(double f[]) throws IllegalArgumentException { +062 return fct(f); +063 } +064 +065 /** +066 * Transform the given real function, sampled on the given interval. +067 * <p> +068 * The formula is F<sub>n</sub> = (1/2) [f<sub>0</sub> + (-1)<sup>n</sup> f<sub>N</sub>] + +069 * ∑<sub>k=1</sub><sup>N-1</sup> f<sub>k</sub> cos(π nk/N) +070 * </p> +071 * +072 * @param f the function to be sampled and transformed +073 * @param min the lower bound for the interval +074 * @param max the upper bound for the interval +075 * @param n the number of sample points +076 * @return the real transformed array +077 * @throws FunctionEvaluationException if function cannot be evaluated +078 * at some point +079 * @throws IllegalArgumentException if any parameters are invalid +080 */ +081 public double[] transform(UnivariateRealFunction f, +082 double min, double max, int n) +083 throws FunctionEvaluationException, IllegalArgumentException { +084 double data[] = FastFourierTransformer.sample(f, min, max, n); +085 return fct(data); +086 } +087 +088 /** +089 * Transform the given real data set. +090 * <p> +091 * The formula is F<sub>n</sub> = √(1/2N) [f<sub>0</sub> + (-1)<sup>n</sup> f<sub>N</sub>] + +092 * √(2/N) ∑<sub>k=1</sub><sup>N-1</sup> f<sub>k</sub> cos(π nk/N) +093 * </p> +094 * +095 * @param f the real data array to be transformed +096 * @return the real transformed array +097 * @throws IllegalArgumentException if any parameters are invalid +098 */ +099 public double[] transform2(double f[]) throws IllegalArgumentException { +100 +101 double scaling_coefficient = Math.sqrt(2.0 / (f.length-1)); +102 return FastFourierTransformer.scaleArray(fct(f), scaling_coefficient); +103 } +104 +105 /** +106 * Transform the given real function, sampled on the given interval. +107 * <p> +108 * The formula is F<sub>n</sub> = √(1/2N) [f<sub>0</sub> + (-1)<sup>n</sup> f<sub>N</sub>] + +109 * √(2/N) ∑<sub>k=1</sub><sup>N-1</sup> f<sub>k</sub> cos(π nk/N) +110 * +111 * </p> +112 * +113 * @param f the function to be sampled and transformed +114 * @param min the lower bound for the interval +115 * @param max the upper bound for the interval +116 * @param n the number of sample points +117 * @return the real transformed array +118 * @throws FunctionEvaluationException if function cannot be evaluated +119 * at some point +120 * @throws IllegalArgumentException if any parameters are invalid +121 */ +122 public double[] transform2(UnivariateRealFunction f, +123 double min, double max, int n) +124 throws FunctionEvaluationException, IllegalArgumentException { +125 +126 double data[] = FastFourierTransformer.sample(f, min, max, n); +127 double scaling_coefficient = Math.sqrt(2.0 / (n-1)); +128 return FastFourierTransformer.scaleArray(fct(data), scaling_coefficient); +129 } +130 +131 /** +132 * Inversely transform the given real data set. +133 * <p> +134 * The formula is f<sub>k</sub> = (1/N) [F<sub>0</sub> + (-1)<sup>k</sup> F<sub>N</sub>] + +135 * (2/N) ∑<sub>n=1</sub><sup>N-1</sup> F<sub>n</sub> cos(π nk/N) +136 * </p> +137 * +138 * @param f the real data array to be inversely transformed +139 * @return the real inversely transformed array +140 * @throws IllegalArgumentException if any parameters are invalid +141 */ +142 public double[] inversetransform(double f[]) throws IllegalArgumentException { +143 +144 double scaling_coefficient = 2.0 / (f.length - 1); +145 return FastFourierTransformer.scaleArray(fct(f), scaling_coefficient); +146 } +147 +148 /** +149 * Inversely transform the given real function, sampled on the given interval. +150 * <p> +151 * The formula is f<sub>k</sub> = (1/N) [F<sub>0</sub> + (-1)<sup>k</sup> F<sub>N</sub>] + +152 * (2/N) ∑<sub>n=1</sub><sup>N-1</sup> F<sub>n</sub> cos(π nk/N) +153 * </p> +154 * +155 * @param f the function to be sampled and inversely transformed +156 * @param min the lower bound for the interval +157 * @param max the upper bound for the interval +158 * @param n the number of sample points +159 * @return the real inversely transformed array +160 * @throws FunctionEvaluationException if function cannot be evaluated +161 * at some point +162 * @throws IllegalArgumentException if any parameters are invalid +163 */ +164 public double[] inversetransform(UnivariateRealFunction f, +165 double min, double max, int n) +166 throws FunctionEvaluationException, IllegalArgumentException { +167 +168 double data[] = FastFourierTransformer.sample(f, min, max, n); +169 double scaling_coefficient = 2.0 / (n - 1); +170 return FastFourierTransformer.scaleArray(fct(data), scaling_coefficient); +171 } +172 +173 /** +174 * Inversely transform the given real data set. +175 * <p> +176 * The formula is f<sub>k</sub> = √(1/2N) [F<sub>0</sub> + (-1)<sup>k</sup> F<sub>N</sub>] + +177 * √(2/N) ∑<sub>n=1</sub><sup>N-1</sup> F<sub>n</sub> cos(π nk/N) +178 * </p> +179 * +180 * @param f the real data array to be inversely transformed +181 * @return the real inversely transformed array +182 * @throws IllegalArgumentException if any parameters are invalid +183 */ +184 public double[] inversetransform2(double f[]) throws IllegalArgumentException { +185 return transform2(f); +186 } +187 +188 /** +189 * Inversely transform the given real function, sampled on the given interval. +190 * <p> +191 * The formula is f<sub>k</sub> = √(1/2N) [F<sub>0</sub> + (-1)<sup>k</sup> F<sub>N</sub>] + +192 * √(2/N) ∑<sub>n=1</sub><sup>N-1</sup> F<sub>n</sub> cos(π nk/N) +193 * </p> +194 * +195 * @param f the function to be sampled and inversely transformed +196 * @param min the lower bound for the interval +197 * @param max the upper bound for the interval +198 * @param n the number of sample points +199 * @return the real inversely transformed array +200 * @throws FunctionEvaluationException if function cannot be evaluated +201 * at some point +202 * @throws IllegalArgumentException if any parameters are invalid +203 */ +204 public double[] inversetransform2(UnivariateRealFunction f, +205 double min, double max, int n) +206 throws FunctionEvaluationException, IllegalArgumentException { +207 +208 return transform2(f, min, max, n); +209 } +210 +211 /** +212 * Perform the FCT algorithm (including inverse). +213 * +214 * @param f the real data array to be transformed +215 * @return the real transformed array +216 * @throws IllegalArgumentException if any parameters are invalid +217 */ +218 protected double[] fct(double f[]) +219 throws IllegalArgumentException { +220 +221 final double transformed[] = new double[f.length]; +222 +223 final int n = f.length - 1; +224 if (!FastFourierTransformer.isPowerOf2(n)) { +225 throw MathRuntimeException.createIllegalArgumentException( +226 "{0} is not a power of 2 plus one", +227 f.length); +228 } +229 if (n == 1) { // trivial case +230 transformed[0] = 0.5 * (f[0] + f[1]); +231 transformed[1] = 0.5 * (f[0] - f[1]); +232 return transformed; +233 } +234 +235 // construct a new array and perform FFT on it +236 final double[] x = new double[n]; +237 x[0] = 0.5 * (f[0] + f[n]); +238 x[n >> 1] = f[n >> 1]; +239 double t1 = 0.5 * (f[0] - f[n]); // temporary variable for transformed[1] +240 for (int i = 1; i < (n >> 1); i++) { +241 final double a = 0.5 * (f[i] + f[n-i]); +242 final double b = Math.sin(i * Math.PI / n) * (f[i] - f[n-i]); +243 final double c = Math.cos(i * Math.PI / n) * (f[i] - f[n-i]); +244 x[i] = a - b; +245 x[n-i] = a + b; +246 t1 += c; +247 } +248 FastFourierTransformer transformer = new FastFourierTransformer(); +249 Complex y[] = transformer.transform(x); +250 +251 // reconstruct the FCT result for the original array +252 transformed[0] = y[0].getReal(); +253 transformed[1] = t1; +254 for (int i = 1; i < (n >> 1); i++) { +255 transformed[2 * i] = y[i].getReal(); +256 transformed[2 * i + 1] = transformed[2 * i - 1] - y[i].getImaginary(); +257 } +258 transformed[n] = y[n >> 1].getReal(); +259 +260 return transformed; +261 } +262 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/transform/FastFourierTransformer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/transform/FastFourierTransformer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,997 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.transform; +018 +019 import java.io.Serializable; +020 import java.lang.reflect.Array; +021 +022 import org.apache.commons.math.FunctionEvaluationException; +023 import org.apache.commons.math.MathRuntimeException; +024 import org.apache.commons.math.analysis.UnivariateRealFunction; +025 import org.apache.commons.math.complex.Complex; +026 +027 /** +028 * Implements the <a href="http://mathworld.wolfram.com/FastFourierTransform.html"> +029 * Fast Fourier Transform</a> for transformation of one-dimensional data sets. +030 * For reference, see <b>Applied Numerical Linear Algebra</b>, ISBN 0898713897, +031 * chapter 6. +032 * <p> +033 * There are several conventions for the definition of FFT and inverse FFT, +034 * mainly on different coefficient and exponent. Here the equations are listed +035 * in the comments of the corresponding methods.</p> +036 * <p> +037 * We require the length of data set to be power of 2, this greatly simplifies +038 * and speeds up the code. Users can pad the data with zeros to meet this +039 * requirement. There are other flavors of FFT, for reference, see S. Winograd, +040 * <i>On computing the discrete Fourier transform</i>, Mathematics of Computation, +041 * 32 (1978), 175 - 199.</p> +042 * +043 * @version $Revision: 885278 $ $Date: 2009-11-29 16:47:51 -0500 (Sun, 29 Nov 2009) $ +044 * @since 1.2 +045 */ +046 public class FastFourierTransformer implements Serializable { +047 +048 /** Serializable version identifier. */ +049 static final long serialVersionUID = 5138259215438106000L; +050 +051 /** Message for not power of 2. */ +052 private static final String NOT_POWER_OF_TWO_MESSAGE = +053 "{0} is not a power of 2, consider padding for fix"; +054 +055 /** Message for dimension mismatch. */ +056 private static final String DIMENSION_MISMATCH_MESSAGE = +057 "some dimensions don't match: {0} != {1}"; +058 +059 /** Message for not computed roots of unity. */ +060 private static final String MISSING_ROOTS_OF_UNITY_MESSAGE = +061 "roots of unity have not been computed yet"; +062 +063 /** Message for out of range root index. */ +064 private static final String OUT_OF_RANGE_ROOT_INDEX_MESSAGE = +065 "out of range root of unity index {0} (must be in [{1};{2}])"; +066 +067 /** roots of unity */ +068 private RootsOfUnity roots = new RootsOfUnity(); +069 +070 /** +071 * Construct a default transformer. +072 */ +073 public FastFourierTransformer() { +074 super(); +075 } +076 +077 /** +078 * Transform the given real data set. +079 * <p> +080 * The formula is $ y_n = \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k $ +081 * </p> +082 * +083 * @param f the real data array to be transformed +084 * @return the complex transformed array +085 * @throws IllegalArgumentException if any parameters are invalid +086 */ +087 public Complex[] transform(double f[]) +088 throws IllegalArgumentException { +089 return fft(f, false); +090 } +091 +092 /** +093 * Transform the given real function, sampled on the given interval. +094 * <p> +095 * The formula is $ y_n = \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k $ +096 * </p> +097 * +098 * @param f the function to be sampled and transformed +099 * @param min the lower bound for the interval +100 * @param max the upper bound for the interval +101 * @param n the number of sample points +102 * @return the complex transformed array +103 * @throws FunctionEvaluationException if function cannot be evaluated +104 * at some point +105 * @throws IllegalArgumentException if any parameters are invalid +106 */ +107 public Complex[] transform(UnivariateRealFunction f, +108 double min, double max, int n) +109 throws FunctionEvaluationException, IllegalArgumentException { +110 double data[] = sample(f, min, max, n); +111 return fft(data, false); +112 } +113 +114 /** +115 * Transform the given complex data set. +116 * <p> +117 * The formula is $ y_n = \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k $ +118 * </p> +119 * +120 * @param f the complex data array to be transformed +121 * @return the complex transformed array +122 * @throws IllegalArgumentException if any parameters are invalid +123 */ +124 public Complex[] transform(Complex f[]) +125 throws IllegalArgumentException { +126 roots.computeOmega(f.length); +127 return fft(f); +128 } +129 +130 /** +131 * Transform the given real data set. +132 * <p> +133 * The formula is $y_n = (1/\sqrt{N}) \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k$ +134 * </p> +135 * +136 * @param f the real data array to be transformed +137 * @return the complex transformed array +138 * @throws IllegalArgumentException if any parameters are invalid +139 */ +140 public Complex[] transform2(double f[]) +141 throws IllegalArgumentException { +142 +143 double scaling_coefficient = 1.0 / Math.sqrt(f.length); +144 return scaleArray(fft(f, false), scaling_coefficient); +145 } +146 +147 /** +148 * Transform the given real function, sampled on the given interval. +149 * <p> +150 * The formula is $y_n = (1/\sqrt{N}) \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k$ +151 * </p> +152 * +153 * @param f the function to be sampled and transformed +154 * @param min the lower bound for the interval +155 * @param max the upper bound for the interval +156 * @param n the number of sample points +157 * @return the complex transformed array +158 * @throws FunctionEvaluationException if function cannot be evaluated +159 * at some point +160 * @throws IllegalArgumentException if any parameters are invalid +161 */ +162 public Complex[] transform2(UnivariateRealFunction f, +163 double min, double max, int n) +164 throws FunctionEvaluationException, IllegalArgumentException { +165 +166 double data[] = sample(f, min, max, n); +167 double scaling_coefficient = 1.0 / Math.sqrt(n); +168 return scaleArray(fft(data, false), scaling_coefficient); +169 } +170 +171 /** +172 * Transform the given complex data set. +173 * <p> +174 * The formula is $y_n = (1/\sqrt{N}) \Sigma_{k=0}^{N-1} e^{-2 \pi i nk/N} x_k$ +175 * </p> +176 * +177 * @param f the complex data array to be transformed +178 * @return the complex transformed array +179 * @throws IllegalArgumentException if any parameters are invalid +180 */ +181 public Complex[] transform2(Complex f[]) +182 throws IllegalArgumentException { +183 +184 roots.computeOmega(f.length); +185 double scaling_coefficient = 1.0 / Math.sqrt(f.length); +186 return scaleArray(fft(f), scaling_coefficient); +187 } +188 +189 /** +190 * Inversely transform the given real data set. +191 * <p> +192 * The formula is $ x_k = (1/N) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n $ +193 * </p> +194 * +195 * @param f the real data array to be inversely transformed +196 * @return the complex inversely transformed array +197 * @throws IllegalArgumentException if any parameters are invalid +198 */ +199 public Complex[] inversetransform(double f[]) +200 throws IllegalArgumentException { +201 +202 double scaling_coefficient = 1.0 / f.length; +203 return scaleArray(fft(f, true), scaling_coefficient); +204 } +205 +206 /** +207 * Inversely transform the given real function, sampled on the given interval. +208 * <p> +209 * The formula is $ x_k = (1/N) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n $ +210 * </p> +211 * +212 * @param f the function to be sampled and inversely transformed +213 * @param min the lower bound for the interval +214 * @param max the upper bound for the interval +215 * @param n the number of sample points +216 * @return the complex inversely transformed array +217 * @throws FunctionEvaluationException if function cannot be evaluated +218 * at some point +219 * @throws IllegalArgumentException if any parameters are invalid +220 */ +221 public Complex[] inversetransform(UnivariateRealFunction f, +222 double min, double max, int n) +223 throws FunctionEvaluationException, IllegalArgumentException { +224 +225 double data[] = sample(f, min, max, n); +226 double scaling_coefficient = 1.0 / n; +227 return scaleArray(fft(data, true), scaling_coefficient); +228 } +229 +230 /** +231 * Inversely transform the given complex data set. +232 * <p> +233 * The formula is $ x_k = (1/N) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n $ +234 * </p> +235 * +236 * @param f the complex data array to be inversely transformed +237 * @return the complex inversely transformed array +238 * @throws IllegalArgumentException if any parameters are invalid +239 */ +240 public Complex[] inversetransform(Complex f[]) +241 throws IllegalArgumentException { +242 +243 roots.computeOmega(-f.length); // pass negative argument +244 double scaling_coefficient = 1.0 / f.length; +245 return scaleArray(fft(f), scaling_coefficient); +246 } +247 +248 /** +249 * Inversely transform the given real data set. +250 * <p> +251 * The formula is $x_k = (1/\sqrt{N}) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n$ +252 * </p> +253 * +254 * @param f the real data array to be inversely transformed +255 * @return the complex inversely transformed array +256 * @throws IllegalArgumentException if any parameters are invalid +257 */ +258 public Complex[] inversetransform2(double f[]) +259 throws IllegalArgumentException { +260 +261 double scaling_coefficient = 1.0 / Math.sqrt(f.length); +262 return scaleArray(fft(f, true), scaling_coefficient); +263 } +264 +265 /** +266 * Inversely transform the given real function, sampled on the given interval. +267 * <p> +268 * The formula is $x_k = (1/\sqrt{N}) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n$ +269 * </p> +270 * +271 * @param f the function to be sampled and inversely transformed +272 * @param min the lower bound for the interval +273 * @param max the upper bound for the interval +274 * @param n the number of sample points +275 * @return the complex inversely transformed array +276 * @throws FunctionEvaluationException if function cannot be evaluated +277 * at some point +278 * @throws IllegalArgumentException if any parameters are invalid +279 */ +280 public Complex[] inversetransform2(UnivariateRealFunction f, +281 double min, double max, int n) +282 throws FunctionEvaluationException, IllegalArgumentException { +283 +284 double data[] = sample(f, min, max, n); +285 double scaling_coefficient = 1.0 / Math.sqrt(n); +286 return scaleArray(fft(data, true), scaling_coefficient); +287 } +288 +289 /** +290 * Inversely transform the given complex data set. +291 * <p> +292 * The formula is $x_k = (1/\sqrt{N}) \Sigma_{n=0}^{N-1} e^{2 \pi i nk/N} y_n$ +293 * </p> +294 * +295 * @param f the complex data array to be inversely transformed +296 * @return the complex inversely transformed array +297 * @throws IllegalArgumentException if any parameters are invalid +298 */ +299 public Complex[] inversetransform2(Complex f[]) +300 throws IllegalArgumentException { +301 +302 roots.computeOmega(-f.length); // pass negative argument +303 double scaling_coefficient = 1.0 / Math.sqrt(f.length); +304 return scaleArray(fft(f), scaling_coefficient); +305 } +306 +307 /** +308 * Perform the base-4 Cooley-Tukey FFT algorithm (including inverse). +309 * +310 * @param f the real data array to be transformed +311 * @param isInverse the indicator of forward or inverse transform +312 * @return the complex transformed array +313 * @throws IllegalArgumentException if any parameters are invalid +314 */ +315 protected Complex[] fft(double f[], boolean isInverse) +316 throws IllegalArgumentException { +317 +318 verifyDataSet(f); +319 Complex F[] = new Complex[f.length]; +320 if (f.length == 1) { +321 F[0] = new Complex(f[0], 0.0); +322 return F; +323 } +324 +325 // Rather than the naive real to complex conversion, pack 2N +326 // real numbers into N complex numbers for better performance. +327 int N = f.length >> 1; +328 Complex c[] = new Complex[N]; +329 for (int i = 0; i < N; i++) { +330 c[i] = new Complex(f[2*i], f[2*i+1]); +331 } +332 roots.computeOmega(isInverse ? -N : N); +333 Complex z[] = fft(c); +334 +335 // reconstruct the FFT result for the original array +336 roots.computeOmega(isInverse ? -2*N : 2*N); +337 F[0] = new Complex(2 * (z[0].getReal() + z[0].getImaginary()), 0.0); +338 F[N] = new Complex(2 * (z[0].getReal() - z[0].getImaginary()), 0.0); +339 for (int i = 1; i < N; i++) { +340 Complex A = z[N-i].conjugate(); +341 Complex B = z[i].add(A); +342 Complex C = z[i].subtract(A); +343 //Complex D = roots.getOmega(i).multiply(Complex.I); +344 Complex D = new Complex(-roots.getOmegaImaginary(i), +345 roots.getOmegaReal(i)); +346 F[i] = B.subtract(C.multiply(D)); +347 F[2*N-i] = F[i].conjugate(); +348 } +349 +350 return scaleArray(F, 0.5); +351 } +352 +353 /** +354 * Perform the base-4 Cooley-Tukey FFT algorithm (including inverse). +355 * +356 * @param data the complex data array to be transformed +357 * @return the complex transformed array +358 * @throws IllegalArgumentException if any parameters are invalid +359 */ +360 protected Complex[] fft(Complex data[]) +361 throws IllegalArgumentException { +362 +363 final int n = data.length; +364 final Complex f[] = new Complex[n]; +365 +366 // initial simple cases +367 verifyDataSet(data); +368 if (n == 1) { +369 f[0] = data[0]; +370 return f; +371 } +372 if (n == 2) { +373 f[0] = data[0].add(data[1]); +374 f[1] = data[0].subtract(data[1]); +375 return f; +376 } +377 +378 // permute original data array in bit-reversal order +379 int ii = 0; +380 for (int i = 0; i < n; i++) { +381 f[i] = data[ii]; +382 int k = n >> 1; +383 while (ii >= k && k > 0) { +384 ii -= k; k >>= 1; +385 } +386 ii += k; +387 } +388 +389 // the bottom base-4 round +390 for (int i = 0; i < n; i += 4) { +391 final Complex a = f[i].add(f[i+1]); +392 final Complex b = f[i+2].add(f[i+3]); +393 final Complex c = f[i].subtract(f[i+1]); +394 final Complex d = f[i+2].subtract(f[i+3]); +395 final Complex e1 = c.add(d.multiply(Complex.I)); +396 final Complex e2 = c.subtract(d.multiply(Complex.I)); +397 f[i] = a.add(b); +398 f[i+2] = a.subtract(b); +399 // omegaCount indicates forward or inverse transform +400 f[i+1] = roots.isForward() ? e2 : e1; +401 f[i+3] = roots.isForward() ? e1 : e2; +402 } +403 +404 // iterations from bottom to top take O(N*logN) time +405 for (int i = 4; i < n; i <<= 1) { +406 final int m = n / (i<<1); +407 for (int j = 0; j < n; j += i<<1) { +408 for (int k = 0; k < i; k++) { +409 //z = f[i+j+k].multiply(roots.getOmega(k*m)); +410 final int k_times_m = k*m; +411 final double omega_k_times_m_real = roots.getOmegaReal(k_times_m); +412 final double omega_k_times_m_imaginary = roots.getOmegaImaginary(k_times_m); +413 //z = f[i+j+k].multiply(omega[k*m]); +414 final Complex z = new Complex( +415 f[i+j+k].getReal() * omega_k_times_m_real - +416 f[i+j+k].getImaginary() * omega_k_times_m_imaginary, +417 f[i+j+k].getReal() * omega_k_times_m_imaginary + +418 f[i+j+k].getImaginary() * omega_k_times_m_real); +419 +420 f[i+j+k] = f[j+k].subtract(z); +421 f[j+k] = f[j+k].add(z); +422 } +423 } +424 } +425 return f; +426 } +427 +428 /** +429 * Sample the given univariate real function on the given interval. +430 * <p> +431 * The interval is divided equally into N sections and sample points +432 * are taken from min to max-(max-min)/N. Usually f(x) is periodic +433 * such that f(min) = f(max) (note max is not sampled), but we don't +434 * require that.</p> +435 * +436 * @param f the function to be sampled +437 * @param min the lower bound for the interval +438 * @param max the upper bound for the interval +439 * @param n the number of sample points +440 * @return the samples array +441 * @throws FunctionEvaluationException if function cannot be evaluated +442 * at some point +443 * @throws IllegalArgumentException if any parameters are invalid +444 */ +445 public static double[] sample(UnivariateRealFunction f, +446 double min, double max, int n) +447 throws FunctionEvaluationException, IllegalArgumentException { +448 +449 if (n <= 0) { +450 throw MathRuntimeException.createIllegalArgumentException( +451 "number of sample is not positive: {0}", +452 n); +453 } +454 verifyInterval(min, max); +455 +456 double s[] = new double[n]; +457 double h = (max - min) / n; +458 for (int i = 0; i < n; i++) { +459 s[i] = f.value(min + i * h); +460 } +461 return s; +462 } +463 +464 /** +465 * Multiply every component in the given real array by the +466 * given real number. The change is made in place. +467 * +468 * @param f the real array to be scaled +469 * @param d the real scaling coefficient +470 * @return a reference to the scaled array +471 */ +472 public static double[] scaleArray(double f[], double d) { +473 for (int i = 0; i < f.length; i++) { +474 f[i] *= d; +475 } +476 return f; +477 } +478 +479 /** +480 * Multiply every component in the given complex array by the +481 * given real number. The change is made in place. +482 * +483 * @param f the complex array to be scaled +484 * @param d the real scaling coefficient +485 * @return a reference to the scaled array +486 */ +487 public static Complex[] scaleArray(Complex f[], double d) { +488 for (int i = 0; i < f.length; i++) { +489 f[i] = new Complex(d * f[i].getReal(), d * f[i].getImaginary()); +490 } +491 return f; +492 } +493 +494 /** +495 * Returns true if the argument is power of 2. +496 * +497 * @param n the number to test +498 * @return true if the argument is power of 2 +499 */ +500 public static boolean isPowerOf2(long n) { +501 return (n > 0) && ((n & (n - 1)) == 0); +502 } +503 +504 /** +505 * Verifies that the data set has length of power of 2. +506 * +507 * @param d the data array +508 * @throws IllegalArgumentException if array length is not power of 2 +509 */ +510 public static void verifyDataSet(double d[]) throws IllegalArgumentException { +511 if (!isPowerOf2(d.length)) { +512 throw MathRuntimeException.createIllegalArgumentException( +513 NOT_POWER_OF_TWO_MESSAGE, d.length); +514 } +515 } +516 +517 /** +518 * Verifies that the data set has length of power of 2. +519 * +520 * @param o the data array +521 * @throws IllegalArgumentException if array length is not power of 2 +522 */ +523 public static void verifyDataSet(Object o[]) throws IllegalArgumentException { +524 if (!isPowerOf2(o.length)) { +525 throw MathRuntimeException.createIllegalArgumentException( +526 NOT_POWER_OF_TWO_MESSAGE, o.length); +527 } +528 } +529 +530 /** +531 * Verifies that the endpoints specify an interval. +532 * +533 * @param lower lower endpoint +534 * @param upper upper endpoint +535 * @throws IllegalArgumentException if not interval +536 */ +537 public static void verifyInterval(double lower, double upper) +538 throws IllegalArgumentException { +539 +540 if (lower >= upper) { +541 throw MathRuntimeException.createIllegalArgumentException( +542 "endpoints do not specify an interval: [{0}, {1}]", +543 lower, upper); +544 } +545 } +546 +547 /** +548 * Performs a multi-dimensional Fourier transform on a given array. +549 * Use {@link #inversetransform2(Complex[])} and +550 * {@link #transform2(Complex[])} in a row-column implementation +551 * in any number of dimensions with O(N×log(N)) complexity with +552 * N=n<sub>1</sub>×n<sub>2</sub>×n<sub>3</sub>×...×n<sub>d</sub>, +553 * n<sub>x</sub>=number of elements in dimension x, +554 * and d=total number of dimensions. +555 * +556 * @param mdca Multi-Dimensional Complex Array id est Complex[][][][] +557 * @param forward inverseTransform2 is preformed if this is false +558 * @return transform of mdca as a Multi-Dimensional Complex Array id est Complex[][][][] +559 * @throws IllegalArgumentException if any dimension is not a power of two +560 */ +561 public Object mdfft(Object mdca, boolean forward) +562 throws IllegalArgumentException { +563 MultiDimensionalComplexMatrix mdcm = (MultiDimensionalComplexMatrix) +564 new MultiDimensionalComplexMatrix(mdca).clone(); +565 int[] dimensionSize = mdcm.getDimensionSizes(); +566 //cycle through each dimension +567 for (int i = 0; i < dimensionSize.length; i++) { +568 mdfft(mdcm, forward, i, new int[0]); +569 } +570 return mdcm.getArray(); +571 } +572 +573 /** +574 * Performs one dimension of a multi-dimensional Fourier transform. +575 * +576 * @param mdcm input matrix +577 * @param forward inverseTransform2 is preformed if this is false +578 * @param d index of the dimension to process +579 * @param subVector recursion subvector +580 * @throws IllegalArgumentException if any dimension is not a power of two +581 */ +582 private void mdfft(MultiDimensionalComplexMatrix mdcm, boolean forward, +583 int d, int[] subVector) +584 throws IllegalArgumentException { +585 int[] dimensionSize = mdcm.getDimensionSizes(); +586 //if done +587 if (subVector.length == dimensionSize.length) { +588 Complex[] temp = new Complex[dimensionSize[d]]; +589 for (int i = 0; i < dimensionSize[d]; i++) { +590 //fft along dimension d +591 subVector[d] = i; +592 temp[i] = mdcm.get(subVector); +593 } +594 +595 if (forward) +596 temp = transform2(temp); +597 else +598 temp = inversetransform2(temp); +599 +600 for (int i = 0; i < dimensionSize[d]; i++) { +601 subVector[d] = i; +602 mdcm.set(temp[i], subVector); +603 } +604 } else { +605 int[] vector = new int[subVector.length + 1]; +606 System.arraycopy(subVector, 0, vector, 0, subVector.length); +607 if (subVector.length == d) { +608 //value is not important once the recursion is done. +609 //then an fft will be applied along the dimension d. +610 vector[d] = 0; +611 mdfft(mdcm, forward, d, vector); +612 } else { +613 for (int i = 0; i < dimensionSize[subVector.length]; i++) { +614 vector[subVector.length] = i; +615 //further split along the next dimension +616 mdfft(mdcm, forward, d, vector); +617 } +618 } +619 } +620 return; +621 } +622 +623 /** +624 * Complex matrix implementation. +625 * Not designed for synchronized access +626 * may eventually be replaced by jsr-83 of the java community process +627 * http://jcp.org/en/jsr/detail?id=83 +628 * may require additional exception throws for other basic requirements. +629 */ +630 private static class MultiDimensionalComplexMatrix +631 implements Cloneable { +632 +633 /** Size in all dimensions. */ +634 protected int[] dimensionSize; +635 +636 /** Storage array. */ +637 protected Object multiDimensionalComplexArray; +638 +639 /** Simple constructor. +640 * @param multiDimensionalComplexArray array containing the matrix elements +641 */ +642 public MultiDimensionalComplexMatrix(Object multiDimensionalComplexArray) { +643 +644 this.multiDimensionalComplexArray = multiDimensionalComplexArray; +645 +646 // count dimensions +647 int numOfDimensions = 0; +648 for (Object lastDimension = multiDimensionalComplexArray; +649 lastDimension instanceof Object[];) { +650 final Object[] array = (Object[]) lastDimension; +651 numOfDimensions++; +652 lastDimension = array[0]; +653 } +654 +655 // allocate array with exact count +656 dimensionSize = new int[numOfDimensions]; +657 +658 // fill array +659 numOfDimensions = 0; +660 for (Object lastDimension = multiDimensionalComplexArray; +661 lastDimension instanceof Object[];) { +662 final Object[] array = (Object[]) lastDimension; +663 dimensionSize[numOfDimensions++] = array.length; +664 lastDimension = array[0]; +665 } +666 +667 } +668 +669 /** +670 * Get a matrix element. +671 * @param vector indices of the element +672 * @return matrix element +673 * @exception IllegalArgumentException if dimensions do not match +674 */ +675 public Complex get(int... vector) +676 throws IllegalArgumentException { +677 if (vector == null) { +678 if (dimensionSize.length > 0) { +679 throw MathRuntimeException.createIllegalArgumentException( +680 DIMENSION_MISMATCH_MESSAGE, 0, dimensionSize.length); +681 } +682 return null; +683 } +684 if (vector.length != dimensionSize.length) { +685 throw MathRuntimeException.createIllegalArgumentException( +686 DIMENSION_MISMATCH_MESSAGE, vector.length, dimensionSize.length); +687 } +688 +689 Object lastDimension = multiDimensionalComplexArray; +690 +691 for (int i = 0; i < dimensionSize.length; i++) { +692 lastDimension = ((Object[]) lastDimension)[vector[i]]; +693 } +694 return (Complex) lastDimension; +695 } +696 +697 /** +698 * Set a matrix element. +699 * @param magnitude magnitude of the element +700 * @param vector indices of the element +701 * @return the previous value +702 * @exception IllegalArgumentException if dimensions do not match +703 */ +704 public Complex set(Complex magnitude, int... vector) +705 throws IllegalArgumentException { +706 if (vector == null) { +707 if (dimensionSize.length > 0) { +708 throw MathRuntimeException.createIllegalArgumentException( +709 DIMENSION_MISMATCH_MESSAGE, 0, dimensionSize.length); +710 } +711 return null; +712 } +713 if (vector.length != dimensionSize.length) { +714 throw MathRuntimeException.createIllegalArgumentException( +715 DIMENSION_MISMATCH_MESSAGE, vector.length,dimensionSize.length); +716 } +717 +718 Object[] lastDimension = (Object[]) multiDimensionalComplexArray; +719 for (int i = 0; i < dimensionSize.length - 1; i++) { +720 lastDimension = (Object[]) lastDimension[vector[i]]; +721 } +722 +723 Complex lastValue = (Complex) lastDimension[vector[dimensionSize.length - 1]]; +724 lastDimension[vector[dimensionSize.length - 1]] = magnitude; +725 +726 return lastValue; +727 } +728 +729 /** +730 * Get the size in all dimensions. +731 * @return size in all dimensions +732 */ +733 public int[] getDimensionSizes() { +734 return dimensionSize.clone(); +735 } +736 +737 /** +738 * Get the underlying storage array +739 * @return underlying storage array +740 */ +741 public Object getArray() { +742 return multiDimensionalComplexArray; +743 } +744 +745 /** {@inheritDoc} */ +746 @Override +747 public Object clone() { +748 MultiDimensionalComplexMatrix mdcm = +749 new MultiDimensionalComplexMatrix(Array.newInstance( +750 Complex.class, dimensionSize)); +751 clone(mdcm); +752 return mdcm; +753 } +754 +755 /** +756 * Copy contents of current array into mdcm. +757 * @param mdcm array where to copy data +758 */ +759 private void clone(MultiDimensionalComplexMatrix mdcm) { +760 int[] vector = new int[dimensionSize.length]; +761 int size = 1; +762 for (int i = 0; i < dimensionSize.length; i++) { +763 size *= dimensionSize[i]; +764 } +765 int[][] vectorList = new int[size][dimensionSize.length]; +766 for (int[] nextVector: vectorList) { +767 System.arraycopy(vector, 0, nextVector, 0, +768 dimensionSize.length); +769 for (int i = 0; i < dimensionSize.length; i++) { +770 vector[i]++; +771 if (vector[i] < dimensionSize[i]) { +772 break; +773 } else { +774 vector[i] = 0; +775 } +776 } +777 } +778 +779 for (int[] nextVector: vectorList) { +780 mdcm.set(get(nextVector), nextVector); +781 } +782 } +783 } +784 +785 +786 /** Computes the n<sup>th</sup> roots of unity. +787 * A cache of already computed values is maintained. +788 */ +789 private static class RootsOfUnity implements Serializable { +790 +791 /** Serializable version id. */ +792 private static final long serialVersionUID = 6404784357747329667L; +793 +794 /** Number of roots of unity. */ +795 private int omegaCount; +796 +797 /** Real part of the roots. */ +798 private double[] omegaReal; +799 +800 /** Imaginary part of the roots for forward transform. */ +801 private double[] omegaImaginaryForward; +802 +803 /** Imaginary part of the roots for reverse transform. */ +804 private double[] omegaImaginaryInverse; +805 +806 /** Forward/reverse indicator. */ +807 private boolean isForward; +808 +809 /** +810 * Build an engine for computing then <sup>th</sup> roots of unity +811 */ +812 public RootsOfUnity() { +813 +814 omegaCount = 0; +815 omegaReal = null; +816 omegaImaginaryForward = null; +817 omegaImaginaryInverse = null; +818 isForward = true; +819 +820 } +821 +822 /** +823 * Check if computation has been done for forward or reverse transform. +824 * @return true if computation has been done for forward transform +825 * @throws IllegalStateException if no roots of unity have been computed yet +826 */ +827 public synchronized boolean isForward() throws IllegalStateException { +828 +829 if (omegaCount == 0) { +830 throw MathRuntimeException.createIllegalStateException( +831 MISSING_ROOTS_OF_UNITY_MESSAGE); +832 } +833 return isForward; +834 +835 } +836 +837 /** Computes the n<sup>th</sup> roots of unity. +838 * <p>The computed omega[] = { 1, w, w<sup>2</sup>, ... w<sup>(n-1)</sup> } where +839 * w = exp(-2 π i / n), i = &sqrt;(-1).</p> +840 * <p>Note that n is positive for +841 * forward transform and negative for inverse transform.</p> +842 * @param n number of roots of unity to compute, +843 * positive for forward transform, negative for inverse transform +844 * @throws IllegalArgumentException if n = 0 +845 */ +846 public synchronized void computeOmega(int n) throws IllegalArgumentException { +847 +848 if (n == 0) { +849 throw MathRuntimeException.createIllegalArgumentException( +850 "cannot compute 0-th root of unity, indefinite result"); +851 } +852 +853 isForward = n > 0; +854 +855 // avoid repetitive calculations +856 final int absN = Math.abs(n); +857 +858 if (absN == omegaCount) { +859 return; +860 } +861 +862 // calculate everything from scratch, for both forward and inverse versions +863 final double t = 2.0 * Math.PI / absN; +864 final double cosT = Math.cos(t); +865 final double sinT = Math.sin(t); +866 omegaReal = new double[absN]; +867 omegaImaginaryForward = new double[absN]; +868 omegaImaginaryInverse = new double[absN]; +869 omegaReal[0] = 1.0; +870 omegaImaginaryForward[0] = 0.0; +871 omegaImaginaryInverse[0] = 0.0; +872 for (int i = 1; i < absN; i++) { +873 omegaReal[i] = +874 omegaReal[i-1] * cosT + omegaImaginaryForward[i-1] * sinT; +875 omegaImaginaryForward[i] = +876 omegaImaginaryForward[i-1] * cosT - omegaReal[i-1] * sinT; +877 omegaImaginaryInverse[i] = -omegaImaginaryForward[i]; +878 } +879 omegaCount = absN; +880 +881 } +882 +883 /** +884 * Get the real part of the k<sup>th</sup> n<sup>th</sup> root of unity +885 * @param k index of the n<sup>th</sup> root of unity +886 * @return real part of the k<sup>th</sup> n<sup>th</sup> root of unity +887 * @throws IllegalStateException if no roots of unity have been computed yet +888 * @throws IllegalArgumentException if k is out of range +889 */ +890 public synchronized double getOmegaReal(int k) +891 throws IllegalStateException, IllegalArgumentException { +892 +893 if (omegaCount == 0) { +894 throw MathRuntimeException.createIllegalStateException( +895 MISSING_ROOTS_OF_UNITY_MESSAGE); +896 } +897 if ((k < 0) || (k >= omegaCount)) { +898 throw MathRuntimeException.createIllegalArgumentException( +899 OUT_OF_RANGE_ROOT_INDEX_MESSAGE, k, 0, omegaCount - 1); +900 } +901 +902 return omegaReal[k]; +903 +904 } +905 +906 /** +907 * Get the imaginary part of the k<sup>th</sup> n<sup>th</sup> root of unity +908 * @param k index of the n<sup>th</sup> root of unity +909 * @return imaginary part of the k<sup>th</sup> n<sup>th</sup> root of unity +910 * @throws IllegalStateException if no roots of unity have been computed yet +911 * @throws IllegalArgumentException if k is out of range +912 */ +913 public synchronized double getOmegaImaginary(int k) +914 throws IllegalStateException, IllegalArgumentException { +915 +916 if (omegaCount == 0) { +917 throw MathRuntimeException.createIllegalStateException( +918 MISSING_ROOTS_OF_UNITY_MESSAGE); +919 } +920 if ((k < 0) || (k >= omegaCount)) { +921 throw MathRuntimeException.createIllegalArgumentException( +922 OUT_OF_RANGE_ROOT_INDEX_MESSAGE, k, 0, omegaCount - 1); +923 } +924 +925 return isForward ? omegaImaginaryForward[k] : omegaImaginaryInverse[k]; +926 +927 } +928 +929 } +930 +931 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/transform/FastHadamardTransformer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/transform/FastHadamardTransformer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,317 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.transform; +018 +019 import org.apache.commons.math.FunctionEvaluationException; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.analysis.UnivariateRealFunction; +022 +023 /** +024 * Implements the <a href="http://www.archive.chipcenter.com/dsp/DSP000517F1.html">Fast Hadamard Transform</a> (FHT). +025 * Transformation of an input vector x to the output vector y. +026 * <p>In addition to transformation of real vectors, the Hadamard transform can +027 * transform integer vectors into integer vectors. However, this integer transform +028 * cannot be inverted directly. Due to a scaling factor it may lead to rational results. +029 * As an example, the inverse transform of integer vector (0, 1, 0, 1) is rational +030 * vector (1/2, -1/2, 0, 0).</p> +031 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +032 * @since 2.0 +033 */ +034 public class FastHadamardTransformer implements RealTransformer { +035 +036 /** {@inheritDoc} */ +037 public double[] transform(double f[]) +038 throws IllegalArgumentException { +039 return fht(f); +040 } +041 +042 /** {@inheritDoc} */ +043 public double[] transform(UnivariateRealFunction f, +044 double min, double max, int n) +045 throws FunctionEvaluationException, IllegalArgumentException { +046 return fht(FastFourierTransformer.sample(f, min, max, n)); +047 } +048 +049 /** {@inheritDoc} */ +050 public double[] inversetransform(double f[]) +051 throws IllegalArgumentException { +052 return FastFourierTransformer.scaleArray(fht(f), 1.0 / f.length); +053 } +054 +055 /** {@inheritDoc} */ +056 public double[] inversetransform(UnivariateRealFunction f, +057 double min, double max, int n) +058 throws FunctionEvaluationException, IllegalArgumentException { +059 final double[] unscaled = +060 fht(FastFourierTransformer.sample(f, min, max, n)); +061 return FastFourierTransformer.scaleArray(unscaled, 1.0 / n); +062 } +063 +064 /** +065 * Transform the given real data set. +066 * <p>The integer transform cannot be inverted directly, due to a scaling +067 * factor it may lead to double results.</p> +068 * @param f the integer data array to be transformed (signal) +069 * @return the integer transformed array (spectrum) +070 * @throws IllegalArgumentException if any parameters are invalid +071 */ +072 public int[] transform(int f[]) +073 throws IllegalArgumentException { +074 return fht(f); +075 } +076 +077 /** +078 * The FHT (Fast Hadamard Transformation) which uses only subtraction and addition. +079 * <br> +080 * Requires <b>Nlog2N = n2</b><sup>n</sup> additions. +081 * <br> +082 * <br> +083 * <b><u>Short Table of manual calculation for N=8:</u></b> +084 * <ol> +085 * <li><b>x</b> is the input vector we want to transform</li> +086 * <li><b>y</b> is the output vector which is our desired result</li> +087 * <li>a and b are just helper rows</li> +088 * </ol> +089 * <pre> +090 * <code> +091 * +----+----------+---------+----------+ +092 * | <b>x</b> | <b>a</b> | <b>b</b> | <b>y</b> | +093 * +----+----------+---------+----------+ +094 * | 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> | +095 * +----+----------+---------+----------+ +096 * | 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> | +097 * +----+----------+---------+----------+ +098 * | 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> | +099 * +----+----------+---------+----------+ +100 * | 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> | +101 * +----+----------+---------+----------+ +102 * | 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> | +103 * +----+----------+---------+----------+ +104 * | 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> | +105 * +----+----------+---------+----------+ +106 * | 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> | +107 * +----+----------+---------+----------+ +108 * | 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> | +109 * +----+----------+---------+----------+ +110 * </code> +111 * </pre> +112 * +113 * <b><u>How it works</u></b> +114 * <ol> +115 * <li>Construct a matrix with N rows and n+1 columns<br> <b>hadm[n+1][N]</b> +116 * <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> +117 * <li>Place the input vector <b>x[N]</b> in the first column of the matrix <b>hadm</b></li> +118 * <li>The entries of the submatrix D<sub>top</sub> are calculated as follows. +119 * <br>D<sub>top</sub> goes from entry [0][1] to [N/2-1][n+1]. +120 * <br>The columns of D<sub>top</sub> are the pairwise mutually exclusive sums of the previous column +121 * </li> +122 * <li>The entries of the submatrix D<sub>bottom</sub> are calculated as follows. +123 * <br>D<sub>bottom</sub> goes from entry [N/2][1] to [N][n+1]. +124 * <br>The columns of D<sub>bottom</sub> are the pairwise differences of the previous column +125 * </li> +126 * <li>How D<sub>top</sub> and D<sub>bottom</sub> you can understand best with the example for N=8 above. +127 * <li>The output vector y is now in the last column of <b>hadm</b></li> +128 * <li><i>Algorithm from: http://www.archive.chipcenter.com/dsp/DSP000517F1.html</i></li> +129 * </ol> +130 * <br> +131 * <b><u>Visually</u></b> +132 * <pre> +133 * +--------+---+---+---+-----+---+ +134 * | 0 | 1 | 2 | 3 | ... |n+1| +135 * +------+--------+---+---+---+-----+---+ +136 * |0 | x<sub>0</sub> | /\ | +137 * |1 | x<sub>1</sub> | || | +138 * |2 | x<sub>2</sub> | <= D<sub>top</sub> => | +139 * |... | ... | || | +140 * |N/2-1 | x<sub>N/2-1</sub> | \/ | +141 * +------+--------+---+---+---+-----+---+ +142 * |N/2 | x<sub>N/2</sub> | /\ | +143 * |N/2+1 | x<sub>N/2+1</sub> | || | +144 * |N/2+2 | x<sub>N/2+2</sub> | <= D<sub>bottom</sub> => | which is in the last column of the matrix +145 * |... | ... | || | +146 * |N | x<sub>N/2</sub> | \/ | +147 * +------+--------+---+---+---+-----+---+ +148 * </pre> +149 * +150 * @param x input vector +151 * @return y output vector +152 * @exception IllegalArgumentException if input array is not a power of 2 +153 */ +154 protected double[] fht(double x[]) throws IllegalArgumentException { +155 +156 // n is the row count of the input vector x +157 final int n = x.length; +158 final int halfN = n / 2; +159 +160 // n has to be of the form n = 2^p !! +161 if (!FastFourierTransformer.isPowerOf2(n)) { +162 throw MathRuntimeException.createIllegalArgumentException( +163 "{0} is not a power of 2", +164 n); +165 } +166 +167 // Instead of creating a matrix with p+1 columns and n rows +168 // we will use two single dimension arrays which we will use in an alternating way. +169 double[] yPrevious = new double[n]; +170 double[] yCurrent = x.clone(); +171 +172 // iterate from left to right (column) +173 for (int j = 1; j < n; j <<= 1) { +174 +175 // switch columns +176 final double[] yTmp = yCurrent; +177 yCurrent = yPrevious; +178 yPrevious = yTmp; +179 +180 // iterate from top to bottom (row) +181 for (int i = 0; i < halfN; ++i) { +182 // D<sub>top</sub> +183 // The top part works with addition +184 final int twoI = 2 * i; +185 yCurrent[i] = yPrevious[twoI] + yPrevious[twoI + 1]; +186 } +187 for (int i = halfN; i < n; ++i) { +188 // D<sub>bottom</sub> +189 // The bottom part works with subtraction +190 final int twoI = 2 * i; +191 yCurrent[i] = yPrevious[twoI - n] - yPrevious[twoI - n + 1]; +192 } +193 } +194 +195 // return the last computed output vector y +196 return yCurrent; +197 +198 } +199 /** +200 * The FHT (Fast Hadamard Transformation) which uses only subtraction and addition. +201 * @param x input vector +202 * @return y output vector +203 * @exception IllegalArgumentException if input array is not a power of 2 +204 */ +205 protected int[] fht(int x[]) throws IllegalArgumentException { +206 +207 // n is the row count of the input vector x +208 final int n = x.length; +209 final int halfN = n / 2; +210 +211 // n has to be of the form n = 2^p !! +212 if (!FastFourierTransformer.isPowerOf2(n)) { +213 throw MathRuntimeException.createIllegalArgumentException( +214 "{0} is not a power of 2", +215 n); +216 } +217 +218 // Instead of creating a matrix with p+1 columns and n rows +219 // we will use two single dimension arrays which we will use in an alternating way. +220 int[] yPrevious = new int[n]; +221 int[] yCurrent = x.clone(); +222 +223 // iterate from left to right (column) +224 for (int j = 1; j < n; j <<= 1) { +225 +226 // switch columns +227 final int[] yTmp = yCurrent; +228 yCurrent = yPrevious; +229 yPrevious = yTmp; +230 +231 // iterate from top to bottom (row) +232 for (int i = 0; i < halfN; ++i) { +233 // D<sub>top</sub> +234 // The top part works with addition +235 final int twoI = 2 * i; +236 yCurrent[i] = yPrevious[twoI] + yPrevious[twoI + 1]; +237 } +238 for (int i = halfN; i < n; ++i) { +239 // D<sub>bottom</sub> +240 // The bottom part works with subtraction +241 final int twoI = 2 * i; +242 yCurrent[i] = yPrevious[twoI - n] - yPrevious[twoI - n + 1]; +243 } +244 } +245 +246 // return the last computed output vector y +247 return yCurrent; +248 +249 } +250 +251 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/transform/FastSineTransformer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/transform/FastSineTransformer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,318 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.transform; +018 +019 import org.apache.commons.math.FunctionEvaluationException; +020 import org.apache.commons.math.MathRuntimeException; +021 import org.apache.commons.math.analysis.UnivariateRealFunction; +022 import org.apache.commons.math.complex.Complex; +023 +024 /** +025 * Implements the <a href="http://documents.wolfram.com/v5/Add-onsLinks/ +026 * StandardPackages/LinearAlgebra/FourierTrig.html">Fast Sine Transform</a> +027 * for transformation of one-dimensional data sets. For reference, see +028 * <b>Fast Fourier Transforms</b>, ISBN 0849371635, chapter 3. +029 * <p> +030 * FST is its own inverse, up to a multiplier depending on conventions. +031 * The equations are listed in the comments of the corresponding methods.</p> +032 * <p> +033 * Similar to FFT, we also require the length of data set to be power of 2. +034 * In addition, the first element must be 0 and it's enforced in function +035 * transformation after sampling.</p> +036 * <p>As of version 2.0 this no longer implements Serializable</p> +037 * +038 * @version $Revision: 825919 $ $Date: 2009-10-16 10:51:55 -0400 (Fri, 16 Oct 2009) $ +039 * @since 1.2 +040 */ +041 public class FastSineTransformer implements RealTransformer { +042 +043 /** +044 * Construct a default transformer. +045 */ +046 public FastSineTransformer() { +047 super(); +048 } +049 +050 /** +051 * Transform the given real data set. +052 * <p> +053 * The formula is F<sub>n</sub> = ∑<sub>k=0</sub><sup>N-1</sup> f<sub>k</sub> sin(π nk/N) +054 * </p> +055 * +056 * @param f the real data array to be transformed +057 * @return the real transformed array +058 * @throws IllegalArgumentException if any parameters are invalid +059 */ +060 public double[] transform(double f[]) +061 throws IllegalArgumentException { +062 return fst(f); +063 } +064 +065 /** +066 * Transform the given real function, sampled on the given interval. +067 * <p> +068 * The formula is F<sub>n</sub> = ∑<sub>k=0</sub><sup>N-1</sup> f<sub>k</sub> sin(π nk/N) +069 * </p> +070 * +071 * @param f the function to be sampled and transformed +072 * @param min the lower bound for the interval +073 * @param max the upper bound for the interval +074 * @param n the number of sample points +075 * @return the real transformed array +076 * @throws FunctionEvaluationException if function cannot be evaluated +077 * at some point +078 * @throws IllegalArgumentException if any parameters are invalid +079 */ +080 public double[] transform(UnivariateRealFunction f, +081 double min, double max, int n) +082 throws FunctionEvaluationException, IllegalArgumentException { +083 +084 double data[] = FastFourierTransformer.sample(f, min, max, n); +085 data[0] = 0.0; +086 return fst(data); +087 } +088 +089 /** +090 * Transform the given real data set. +091 * <p> +092 * The formula is F<sub>n</sub> = √(2/N) ∑<sub>k=0</sub><sup>N-1</sup> f<sub>k</sub> sin(π nk/N) +093 * </p> +094 * +095 * @param f the real data array to be transformed +096 * @return the real transformed array +097 * @throws IllegalArgumentException if any parameters are invalid +098 */ +099 public double[] transform2(double f[]) throws IllegalArgumentException { +100 +101 double scaling_coefficient = Math.sqrt(2.0 / f.length); +102 return FastFourierTransformer.scaleArray(fst(f), scaling_coefficient); +103 } +104 +105 /** +106 * Transform the given real function, sampled on the given interval. +107 * <p> +108 * The formula is F<sub>n</sub> = √(2/N) ∑<sub>k=0</sub><sup>N-1</sup> f<sub>k</sub> sin(π nk/N) +109 * </p> +110 * +111 * @param f the function to be sampled and transformed +112 * @param min the lower bound for the interval +113 * @param max the upper bound for the interval +114 * @param n the number of sample points +115 * @return the real transformed array +116 * @throws FunctionEvaluationException if function cannot be evaluated +117 * at some point +118 * @throws IllegalArgumentException if any parameters are invalid +119 */ +120 public double[] transform2( +121 UnivariateRealFunction f, double min, double max, int n) +122 throws FunctionEvaluationException, IllegalArgumentException { +123 +124 double data[] = FastFourierTransformer.sample(f, min, max, n); +125 data[0] = 0.0; +126 double scaling_coefficient = Math.sqrt(2.0 / n); +127 return FastFourierTransformer.scaleArray(fst(data), scaling_coefficient); +128 } +129 +130 /** +131 * Inversely transform the given real data set. +132 * <p> +133 * The formula is f<sub>k</sub> = (2/N) ∑<sub>n=0</sub><sup>N-1</sup> F<sub>n</sub> sin(π nk/N) +134 * </p> +135 * +136 * @param f the real data array to be inversely transformed +137 * @return the real inversely transformed array +138 * @throws IllegalArgumentException if any parameters are invalid +139 */ +140 public double[] inversetransform(double f[]) throws IllegalArgumentException { +141 +142 double scaling_coefficient = 2.0 / f.length; +143 return FastFourierTransformer.scaleArray(fst(f), scaling_coefficient); +144 } +145 +146 /** +147 * Inversely transform the given real function, sampled on the given interval. +148 * <p> +149 * The formula is f<sub>k</sub> = (2/N) ∑<sub>n=0</sub><sup>N-1</sup> F<sub>n</sub> sin(π nk/N) +150 * </p> +151 * +152 * @param f the function to be sampled and inversely transformed +153 * @param min the lower bound for the interval +154 * @param max the upper bound for the interval +155 * @param n the number of sample points +156 * @return the real inversely transformed array +157 * @throws FunctionEvaluationException if function cannot be evaluated +158 * at some point +159 * @throws IllegalArgumentException if any parameters are invalid +160 */ +161 public double[] inversetransform(UnivariateRealFunction f, double min, double max, int n) +162 throws FunctionEvaluationException, IllegalArgumentException { +163 +164 double data[] = FastFourierTransformer.sample(f, min, max, n); +165 data[0] = 0.0; +166 double scaling_coefficient = 2.0 / n; +167 return FastFourierTransformer.scaleArray(fst(data), scaling_coefficient); +168 } +169 +170 /** +171 * Inversely transform the given real data set. +172 * <p> +173 * The formula is f<sub>k</sub> = √(2/N) ∑<sub>n=0</sub><sup>N-1</sup> F<sub>n</sub> sin(π nk/N) +174 * </p> +175 * +176 * @param f the real data array to be inversely transformed +177 * @return the real inversely transformed array +178 * @throws IllegalArgumentException if any parameters are invalid +179 */ +180 public double[] inversetransform2(double f[]) throws IllegalArgumentException { +181 +182 return transform2(f); +183 } +184 +185 /** +186 * Inversely transform the given real function, sampled on the given interval. +187 * <p> +188 * The formula is f<sub>k</sub> = √(2/N) ∑<sub>n=0</sub><sup>N-1</sup> F<sub>n</sub> sin(π nk/N) +189 * </p> +190 * +191 * @param f the function to be sampled and inversely transformed +192 * @param min the lower bound for the interval +193 * @param max the upper bound for the interval +194 * @param n the number of sample points +195 * @return the real inversely transformed array +196 * @throws FunctionEvaluationException if function cannot be evaluated +197 * at some point +198 * @throws IllegalArgumentException if any parameters are invalid +199 */ +200 public double[] inversetransform2(UnivariateRealFunction f, double min, double max, int n) +201 throws FunctionEvaluationException, IllegalArgumentException { +202 +203 return transform2(f, min, max, n); +204 } +205 +206 /** +207 * Perform the FST algorithm (including inverse). +208 * +209 * @param f the real data array to be transformed +210 * @return the real transformed array +211 * @throws IllegalArgumentException if any parameters are invalid +212 */ +213 protected double[] fst(double f[]) throws IllegalArgumentException { +214 +215 final double transformed[] = new double[f.length]; +216 +217 FastFourierTransformer.verifyDataSet(f); +218 if (f[0] != 0.0) { +219 throw MathRuntimeException.createIllegalArgumentException( +220 "first element is not 0: {0}", +221 f[0]); +222 } +223 final int n = f.length; +224 if (n == 1) { // trivial case +225 transformed[0] = 0.0; +226 return transformed; +227 } +228 +229 // construct a new array and perform FFT on it +230 final double[] x = new double[n]; +231 x[0] = 0.0; +232 x[n >> 1] = 2.0 * f[n >> 1]; +233 for (int i = 1; i < (n >> 1); i++) { +234 final double a = Math.sin(i * Math.PI / n) * (f[i] + f[n-i]); +235 final double b = 0.5 * (f[i] - f[n-i]); +236 x[i] = a + b; +237 x[n - i] = a - b; +238 } +239 FastFourierTransformer transformer = new FastFourierTransformer(); +240 Complex y[] = transformer.transform(x); +241 +242 // reconstruct the FST result for the original array +243 transformed[0] = 0.0; +244 transformed[1] = 0.5 * y[0].getReal(); +245 for (int i = 1; i < (n >> 1); i++) { +246 transformed[2 * i] = -y[i].getImaginary(); +247 transformed[2 * i + 1] = y[i].getReal() + transformed[2 * i - 1]; +248 } +249 +250 return transformed; +251 } +252 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/transform/RealTransformer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/transform/RealTransformer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,148 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.transform; +018 +019 import org.apache.commons.math.FunctionEvaluationException; +020 import org.apache.commons.math.analysis.UnivariateRealFunction; +021 +022 /** +023 * Interface for one-dimensional data sets transformations producing real results. +024 * <p>Such transforms include {@link FastSineTransformer sine transform}, +025 * {@link FastCosineTransformer cosine transform} or {@link +026 * FastHadamardTransformer Hadamard transform}. {@link FastFourierTransformer +027 * Fourier transform} is of a different kind and does not implement this +028 * interface since it produces {@link org.apache.commons.math.complex.Complex complex} +029 * results instead of real ones. +030 * </p> +031 * @version $Revision: 811786 $ $Date: 2009-09-06 05:36:08 -0400 (Sun, 06 Sep 2009) $ +032 * @since 2.0 +033 */ +034 public interface RealTransformer { +035 +036 /** +037 * Transform the given real data set. +038 * @param f the real data array to be transformed (signal) +039 * @return the real transformed array (spectrum) +040 * @throws IllegalArgumentException if any parameters are invalid +041 */ +042 double[] transform(double f[]) +043 throws IllegalArgumentException; +044 +045 /** +046 * Transform the given real function, sampled on the given interval. +047 * @param f the function to be sampled and transformed +048 * @param min the lower bound for the interval +049 * @param max the upper bound for the interval +050 * @param n the number of sample points +051 * @return the real transformed array +052 * @throws FunctionEvaluationException if function cannot be evaluated +053 * at some point +054 * @throws IllegalArgumentException if any parameters are invalid +055 */ +056 double[] transform(UnivariateRealFunction f, double min, double max, int n) +057 throws FunctionEvaluationException, IllegalArgumentException; +058 +059 /** +060 * Inversely transform the given real data set. +061 * @param f the real data array to be inversely transformed (spectrum) +062 * @return the real inversely transformed array (signal) +063 * @throws IllegalArgumentException if any parameters are invalid +064 */ +065 double[] inversetransform(double f[]) +066 throws IllegalArgumentException; +067 +068 /** +069 * Inversely transform the given real function, sampled on the given interval. +070 * @param f the function to be sampled and inversely transformed +071 * @param min the lower bound for the interval +072 * @param max the upper bound for the interval +073 * @param n the number of sample points +074 * @return the real inversely transformed array +075 * @throws FunctionEvaluationException if function cannot be evaluated +076 * at some point +077 * @throws IllegalArgumentException if any parameters are invalid +078 */ +079 double[] inversetransform(UnivariateRealFunction f, double min, double max, int n) +080 throws FunctionEvaluationException, IllegalArgumentException; +081 +082 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/BigReal.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/BigReal.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,358 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.util; +018 +019 +020 import java.io.Serializable; +021 import java.math.BigDecimal; +022 import java.math.BigInteger; +023 import java.math.MathContext; +024 import java.math.RoundingMode; +025 +026 import org.apache.commons.math.Field; +027 import org.apache.commons.math.FieldElement; +028 +029 /** +030 * Arbitrary precision decimal number. +031 * <p> +032 * This class is a simple wrapper around the standard <code>BigDecimal</code> +033 * in order to implement the {@link FieldElement} interface. +034 * </p> +035 * @since 2.0 +036 * @version $Revision: 925812 $ $Date: 2010-03-21 11:49:31 -0400 (Sun, 21 Mar 2010) $ +037 */ +038 public class BigReal implements FieldElement<BigReal>, Comparable<BigReal>, Serializable { +039 +040 /** A big real representing 0. */ +041 public static final BigReal ZERO = new BigReal(BigDecimal.ZERO); +042 +043 /** A big real representing 1. */ +044 public static final BigReal ONE = new BigReal(BigDecimal.ONE); +045 +046 /** Serializable version identifier. */ +047 private static final long serialVersionUID = 4984534880991310382L; +048 +049 /** Underlying BigDecimal. */ +050 private final BigDecimal d; +051 +052 /** Rounding mode for divisions. **/ +053 private RoundingMode roundingMode = RoundingMode.HALF_UP; +054 +055 /*** BigDecimal scale ***/ +056 private int scale = 64; +057 +058 /** Build an instance from a BigDecimal. +059 * @param val value of the instance +060 */ +061 public BigReal(BigDecimal val) { +062 d = val; +063 } +064 +065 /** Build an instance from a BigInteger. +066 * @param val value of the instance +067 */ +068 public BigReal(BigInteger val) { +069 d = new BigDecimal(val); +070 } +071 +072 /** Build an instance from an unscaled BigInteger. +073 * @param unscaledVal unscaled value +074 * @param scale scale to use +075 */ +076 public BigReal(BigInteger unscaledVal, int scale) { +077 d = new BigDecimal(unscaledVal, scale); +078 } +079 +080 /** Build an instance from an unscaled BigInteger. +081 * @param unscaledVal unscaled value +082 * @param scale scale to use +083 * @param mc to used +084 */ +085 public BigReal(BigInteger unscaledVal, int scale, MathContext mc) { +086 d = new BigDecimal(unscaledVal, scale, mc); +087 } +088 +089 /** Build an instance from a BigInteger. +090 * @param val value of the instance +091 * @param mc context to use +092 */ +093 public BigReal(BigInteger val, MathContext mc) { +094 d = new BigDecimal(val, mc); +095 } +096 +097 /** Build an instance from a characters representation. +098 * @param in character representation of the value +099 */ +100 public BigReal(char[] in) { +101 d = new BigDecimal(in); +102 } +103 +104 /** Build an instance from a characters representation. +105 * @param in character representation of the value +106 * @param offset offset of the first character to analyze +107 * @param len length of the array slice to analyze +108 */ +109 public BigReal(char[] in, int offset, int len) { +110 d = new BigDecimal(in, offset, len); +111 } +112 +113 /** Build an instance from a characters representation. +114 * @param in character representation of the value +115 * @param offset offset of the first character to analyze +116 * @param len length of the array slice to analyze +117 * @param mc context to use +118 */ +119 public BigReal(char[] in, int offset, int len, MathContext mc) { +120 d = new BigDecimal(in, offset, len, mc); +121 } +122 +123 /** Build an instance from a characters representation. +124 * @param in character representation of the value +125 * @param mc context to use +126 */ +127 public BigReal(char[] in, MathContext mc) { +128 d = new BigDecimal(in, mc); +129 } +130 +131 /** Build an instance from a double. +132 * @param val value of the instance +133 */ +134 public BigReal(double val) { +135 d = new BigDecimal(val); +136 } +137 +138 /** Build an instance from a double. +139 * @param val value of the instance +140 * @param mc context to use +141 */ +142 public BigReal(double val, MathContext mc) { +143 d = new BigDecimal(val, mc); +144 } +145 +146 /** Build an instance from an int. +147 * @param val value of the instance +148 */ +149 public BigReal(int val) { +150 d = new BigDecimal(val); +151 } +152 +153 /** Build an instance from an int. +154 * @param val value of the instance +155 * @param mc context to use +156 */ +157 public BigReal(int val, MathContext mc) { +158 d = new BigDecimal(val, mc); +159 } +160 +161 /** Build an instance from a long. +162 * @param val value of the instance +163 */ +164 public BigReal(long val) { +165 d = new BigDecimal(val); +166 } +167 +168 /** Build an instance from a long. +169 * @param val value of the instance +170 * @param mc context to use +171 */ +172 public BigReal(long val, MathContext mc) { +173 d = new BigDecimal(val, mc); +174 } +175 +176 /** Build an instance from a String representation. +177 * @param val character representation of the value +178 */ +179 public BigReal(String val) { +180 d = new BigDecimal(val); +181 } +182 +183 /** Build an instance from a String representation. +184 * @param val character representation of the value +185 * @param mc context to use +186 */ +187 public BigReal(String val, MathContext mc) { +188 d = new BigDecimal(val, mc); +189 } +190 +191 /*** +192 * Gets the rounding mode for division operations +193 * The default is {@code RoundingMode.HALF_UP} +194 * @return the rounding mode. +195 * @since 2.1 +196 */ +197 public RoundingMode getRoundingMode() { +198 return roundingMode; +199 } +200 +201 /*** +202 * Sets the rounding mode for decimal divisions. +203 * @param roundingMode rounding mode for decimal divisions +204 * @since 2.1 +205 */ +206 public void setRoundingMode(RoundingMode roundingMode) { +207 this.roundingMode = roundingMode; +208 } +209 +210 /*** +211 * Sets the scale for division operations. +212 * The default is 64 +213 * @return the scale +214 * @since 2.1 +215 */ +216 public int getScale() { +217 return scale; +218 } +219 +220 /*** +221 * Sets the scale for division operations. +222 * @param scale scale for division operations +223 * @since 2.1 +224 */ +225 public void setScale(int scale) { +226 this.scale = scale; +227 } +228 +229 /** {@inheritDoc} */ +230 public BigReal add(BigReal a) { +231 return new BigReal(d.add(a.d)); +232 } +233 +234 /** {@inheritDoc} */ +235 public BigReal subtract(BigReal a) { +236 return new BigReal(d.subtract(a.d)); +237 } +238 +239 /** {@inheritDoc} */ +240 public BigReal divide(BigReal a) throws ArithmeticException { +241 return new BigReal(d.divide(a.d, scale, roundingMode)); +242 } +243 +244 /** {@inheritDoc} */ +245 public BigReal multiply(BigReal a) { +246 return new BigReal(d.multiply(a.d)); +247 } +248 +249 /** {@inheritDoc} */ +250 public int compareTo(BigReal a) { +251 return d.compareTo(a.d); +252 } +253 +254 /** Get the double value corresponding to the instance. +255 * @return double value corresponding to the instance +256 */ +257 public double doubleValue() { +258 return d.doubleValue(); +259 } +260 +261 /** Get the BigDecimal value corresponding to the instance. +262 * @return BigDecimal value corresponding to the instance +263 */ +264 public BigDecimal bigDecimalValue() { +265 return d; +266 } +267 +268 /** {@inheritDoc} */ +269 @Override +270 public boolean equals(Object other) { +271 if (this == other){ +272 return true; +273 } +274 +275 if (other instanceof BigReal){ +276 return d.equals(((BigReal) other).d); +277 } +278 return false; +279 } +280 +281 /** {@inheritDoc} */ +282 @Override +283 public int hashCode() { +284 return d.hashCode(); +285 } +286 +287 /** {@inheritDoc} */ +288 public Field<BigReal> getField() { +289 return BigRealField.getInstance(); +290 } +291 +292 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/BigRealField.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/BigRealField.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,144 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.util; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.Field; +023 +024 /** +025 * Representation of real numbers with arbitrary precision field. +026 * <p> +027 * This class is a singleton. +028 * </p> +029 * @see BigReal +030 * @version $Revision: 811827 $ $Date: 2009-09-06 11:32:50 -0400 (Sun, 06 Sep 2009) $ +031 * @since 2.0 +032 */ +033 public class BigRealField implements Field<BigReal>, Serializable { +034 +035 /** Serializable version identifier */ +036 private static final long serialVersionUID = 4756431066541037559L; +037 +038 /** Private constructor for the singleton. +039 */ +040 private BigRealField() { +041 } +042 +043 /** Get the unique instance. +044 * @return the unique instance +045 */ +046 public static BigRealField getInstance() { +047 return LazyHolder.INSTANCE; +048 } +049 +050 /** {@inheritDoc} */ +051 public BigReal getOne() { +052 return BigReal.ONE; +053 } +054 +055 /** {@inheritDoc} */ +056 public BigReal getZero() { +057 return BigReal.ZERO; +058 } +059 +060 // CHECKSTYLE: stop HideUtilityClassConstructor +061 /** Holder for the instance. +062 * <p>We use here the Initialization On Demand Holder Idiom.</p> +063 */ +064 private static class LazyHolder { +065 /** Cached field instance. */ +066 private static final BigRealField INSTANCE = new BigRealField(); +067 } +068 // CHECKSTYLE: resume HideUtilityClassConstructor +069 +070 /** Handle deserialization of the singleton. +071 * @return the singleton instance +072 */ +073 private Object readResolve() { +074 // return the singleton instance +075 return LazyHolder.INSTANCE; +076 } +077 +078 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/CompositeFormat.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/CompositeFormat.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,286 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.util; +018 +019 import java.text.FieldPosition; +020 import java.text.Format; +021 import java.text.NumberFormat; +022 import java.text.ParsePosition; +023 import java.util.Locale; +024 +025 /** +026 * Base class for formatters of composite objects (complex numbers, vectors ...). +027 * +028 * @version $Revision: 811783 $ $Date: 2009-09-06 04:56:58 -0400 (Sun, 06 Sep 2009) $ +029 */ +030 public abstract class CompositeFormat extends Format { +031 +032 /** Serializable version identifier. */ +033 private static final long serialVersionUID = 5358685519349262494L; +034 +035 /** +036 * Create a default number format. The default number format is based on +037 * {@link NumberFormat#getInstance()} with the only customizing that the +038 * maximum number of fraction digits is set to 2. +039 * @return the default number format. +040 */ +041 protected static NumberFormat getDefaultNumberFormat() { +042 return getDefaultNumberFormat(Locale.getDefault()); +043 } +044 +045 /** +046 * Create a default number format. The default number format is based on +047 * {@link NumberFormat#getInstance(java.util.Locale)} with the only +048 * customizing that the maximum number of fraction digits is set to 2. +049 * @param locale the specific locale used by the format. +050 * @return the default number format specific to the given locale. +051 */ +052 protected static NumberFormat getDefaultNumberFormat(final Locale locale) { +053 final NumberFormat nf = NumberFormat.getInstance(locale); +054 nf.setMaximumFractionDigits(2); +055 return nf; +056 } +057 +058 /** +059 * Parses <code>source</code> until a non-whitespace character is found. +060 * +061 * @param source the string to parse +062 * @param pos input/ouput parsing parameter. On output, <code>pos</code> +063 * holds the index of the next non-whitespace character. +064 */ +065 protected void parseAndIgnoreWhitespace(final String source, +066 final ParsePosition pos) { +067 parseNextCharacter(source, pos); +068 pos.setIndex(pos.getIndex() - 1); +069 } +070 +071 /** +072 * Parses <code>source</code> until a non-whitespace character is found. +073 * +074 * @param source the string to parse +075 * @param pos input/ouput parsing parameter. +076 * @return the first non-whitespace character. +077 */ +078 protected char parseNextCharacter(final String source, +079 final ParsePosition pos) { +080 int index = pos.getIndex(); +081 final int n = source.length(); +082 char ret = 0; +083 +084 if (index < n) { +085 char c; +086 do { +087 c = source.charAt(index++); +088 } while (Character.isWhitespace(c) && index < n); +089 pos.setIndex(index); +090 +091 if (index < n) { +092 ret = c; +093 } +094 } +095 +096 return ret; +097 } +098 +099 /** +100 * Parses <code>source</code> for special double values. These values +101 * include Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY. +102 * +103 * @param source the string to parse +104 * @param value the special value to parse. +105 * @param pos input/ouput parsing parameter. +106 * @return the special number. +107 */ +108 private Number parseNumber(final String source, final double value, +109 final ParsePosition pos) { +110 Number ret = null; +111 +112 StringBuffer sb = new StringBuffer(); +113 sb.append('('); +114 sb.append(value); +115 sb.append(')'); +116 +117 final int n = sb.length(); +118 final int startIndex = pos.getIndex(); +119 final int endIndex = startIndex + n; +120 if (endIndex < source.length()) { +121 if (source.substring(startIndex, endIndex).compareTo(sb.toString()) == 0) { +122 ret = Double.valueOf(value); +123 pos.setIndex(endIndex); +124 } +125 } +126 +127 return ret; +128 } +129 +130 /** +131 * Parses <code>source</code> for a number. This method can parse normal, +132 * numeric values as well as special values. These special values include +133 * Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY. +134 * +135 * @param source the string to parse +136 * @param format the number format used to parse normal, numeric values. +137 * @param pos input/ouput parsing parameter. +138 * @return the parsed number. +139 */ +140 protected Number parseNumber(final String source, final NumberFormat format, +141 final ParsePosition pos) { +142 final int startIndex = pos.getIndex(); +143 Number number = format.parse(source, pos); +144 final int endIndex = pos.getIndex(); +145 +146 // check for error parsing number +147 if (startIndex == endIndex) { +148 // try parsing special numbers +149 final double[] special = { +150 Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY +151 }; +152 for (int i = 0; i < special.length; ++i) { +153 number = parseNumber(source, special[i], pos); +154 if (number != null) { +155 break; +156 } +157 } +158 } +159 +160 return number; +161 } +162 +163 /** +164 * Parse <code>source</code> for an expected fixed string. +165 * @param source the string to parse +166 * @param expected expected string +167 * @param pos input/ouput parsing parameter. +168 * @return true if the expected string was there +169 */ +170 protected boolean parseFixedstring(final String source, final String expected, +171 final ParsePosition pos) { +172 +173 final int startIndex = pos.getIndex(); +174 final int endIndex = startIndex + expected.length(); +175 if ((startIndex >= source.length()) || +176 (endIndex > source.length()) || +177 (source.substring(startIndex, endIndex).compareTo(expected) != 0)) { +178 // set index back to start, error index should be the start index +179 pos.setIndex(startIndex); +180 pos.setErrorIndex(startIndex); +181 return false; +182 } +183 +184 // the string was here +185 pos.setIndex(endIndex); +186 return true; +187 +188 } +189 +190 /** +191 * Formats a double value to produce a string. In general, the value is +192 * formatted using the formatting rules of <code>format</code>. There are +193 * three exceptions to this: +194 * <ol> +195 * <li>NaN is formatted as '(NaN)'</li> +196 * <li>Positive infinity is formatted as '(Infinity)'</li> +197 * <li>Negative infinity is formatted as '(-Infinity)'</li> +198 * </ol> +199 * +200 * @param value the double to format. +201 * @param format the format used. +202 * @param toAppendTo where the text is to be appended +203 * @param pos On input: an alignment field, if desired. On output: the +204 * offsets of the alignment field +205 * @return the value passed in as toAppendTo. +206 */ +207 protected StringBuffer formatDouble(final double value, final NumberFormat format, +208 final StringBuffer toAppendTo, +209 final FieldPosition pos) { +210 if( Double.isNaN(value) || Double.isInfinite(value) ) { +211 toAppendTo.append('('); +212 toAppendTo.append(value); +213 toAppendTo.append(')'); +214 } else { +215 format.format(value, toAppendTo, pos); +216 } +217 return toAppendTo; +218 } +219 +220 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/ContinuedFraction.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/ContinuedFraction.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,273 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.util; +018 +019 import org.apache.commons.math.ConvergenceException; +020 import org.apache.commons.math.MathException; +021 import org.apache.commons.math.MaxIterationsExceededException; +022 +023 /** +024 * Provides a generic means to evaluate continued fractions. Subclasses simply +025 * provided the a and b coefficients to evaluate the continued fraction. +026 * +027 * <p> +028 * References: +029 * <ul> +030 * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html"> +031 * Continued Fraction</a></li> +032 * </ul> +033 * </p> +034 * +035 * @version $Revision: 920558 $ $Date: 2010-03-08 17:57:32 -0500 (Mon, 08 Mar 2010) $ +036 */ +037 public abstract class ContinuedFraction { +038 +039 /** Maximum allowed numerical error. */ +040 private static final double DEFAULT_EPSILON = 10e-9; +041 +042 /** +043 * Default constructor. +044 */ +045 protected ContinuedFraction() { +046 super(); +047 } +048 +049 /** +050 * Access the n-th a coefficient of the continued fraction. Since a can be +051 * a function of the evaluation point, x, that is passed in as well. +052 * @param n the coefficient index to retrieve. +053 * @param x the evaluation point. +054 * @return the n-th a coefficient. +055 */ +056 protected abstract double getA(int n, double x); +057 +058 /** +059 * Access the n-th b coefficient of the continued fraction. Since b can be +060 * a function of the evaluation point, x, that is passed in as well. +061 * @param n the coefficient index to retrieve. +062 * @param x the evaluation point. +063 * @return the n-th b coefficient. +064 */ +065 protected abstract double getB(int n, double x); +066 +067 /** +068 * Evaluates the continued fraction at the value x. +069 * @param x the evaluation point. +070 * @return the value of the continued fraction evaluated at x. +071 * @throws MathException if the algorithm fails to converge. +072 */ +073 public double evaluate(double x) throws MathException { +074 return evaluate(x, DEFAULT_EPSILON, Integer.MAX_VALUE); +075 } +076 +077 /** +078 * Evaluates the continued fraction at the value x. +079 * @param x the evaluation point. +080 * @param epsilon maximum error allowed. +081 * @return the value of the continued fraction evaluated at x. +082 * @throws MathException if the algorithm fails to converge. +083 */ +084 public double evaluate(double x, double epsilon) throws MathException { +085 return evaluate(x, epsilon, Integer.MAX_VALUE); +086 } +087 +088 /** +089 * Evaluates the continued fraction at the value x. +090 * @param x the evaluation point. +091 * @param maxIterations maximum number of convergents +092 * @return the value of the continued fraction evaluated at x. +093 * @throws MathException if the algorithm fails to converge. +094 */ +095 public double evaluate(double x, int maxIterations) throws MathException { +096 return evaluate(x, DEFAULT_EPSILON, maxIterations); +097 } +098 +099 /** +100 * <p> +101 * Evaluates the continued fraction at the value x. +102 * </p> +103 * +104 * <p> +105 * The implementation of this method is based on equations 14-17 of: +106 * <ul> +107 * <li> +108 * Eric W. Weisstein. "Continued Fraction." From MathWorld--A Wolfram Web +109 * Resource. <a target="_blank" +110 * href="http://mathworld.wolfram.com/ContinuedFraction.html"> +111 * http://mathworld.wolfram.com/ContinuedFraction.html</a> +112 * </li> +113 * </ul> +114 * The recurrence relationship defined in those equations can result in +115 * very large intermediate results which can result in numerical overflow. +116 * As a means to combat these overflow conditions, the intermediate results +117 * are scaled whenever they threaten to become numerically unstable.</p> +118 * +119 * @param x the evaluation point. +120 * @param epsilon maximum error allowed. +121 * @param maxIterations maximum number of convergents +122 * @return the value of the continued fraction evaluated at x. +123 * @throws MathException if the algorithm fails to converge. +124 */ +125 public double evaluate(double x, double epsilon, int maxIterations) +126 throws MathException +127 { +128 double p0 = 1.0; +129 double p1 = getA(0, x); +130 double q0 = 0.0; +131 double q1 = 1.0; +132 double c = p1 / q1; +133 int n = 0; +134 double relativeError = Double.MAX_VALUE; +135 while (n < maxIterations && relativeError > epsilon) { +136 ++n; +137 double a = getA(n, x); +138 double b = getB(n, x); +139 double p2 = a * p1 + b * p0; +140 double q2 = a * q1 + b * q0; +141 boolean infinite = false; +142 if (Double.isInfinite(p2) || Double.isInfinite(q2)) { +143 /* +144 * Need to scale. Try successive powers of the larger of a or b +145 * up to 5th power. Throw ConvergenceException if one or both +146 * of p2, q2 still overflow. +147 */ +148 double scaleFactor = 1d; +149 double lastScaleFactor = 1d; +150 final int maxPower = 5; +151 final double scale = Math.max(a,b); +152 if (scale <= 0) { // Can't scale +153 throw new ConvergenceException( +154 "Continued fraction convergents diverged to +/- infinity for value {0}", +155 x); +156 } +157 infinite = true; +158 for (int i = 0; i < maxPower; i++) { +159 lastScaleFactor = scaleFactor; +160 scaleFactor *= scale; +161 if (a != 0.0 && a > b) { +162 p2 = p1 / lastScaleFactor + (b / scaleFactor * p0); +163 q2 = q1 / lastScaleFactor + (b / scaleFactor * q0); +164 } else if (b != 0) { +165 p2 = (a / scaleFactor * p1) + p0 / lastScaleFactor; +166 q2 = (a / scaleFactor * q1) + q0 / lastScaleFactor; +167 } +168 infinite = Double.isInfinite(p2) || Double.isInfinite(q2); +169 if (!infinite) { +170 break; +171 } +172 } +173 } +174 +175 if (infinite) { +176 // Scaling failed +177 throw new ConvergenceException( +178 "Continued fraction convergents diverged to +/- infinity for value {0}", +179 x); +180 } +181 +182 double r = p2 / q2; +183 +184 if (Double.isNaN(r)) { +185 throw new ConvergenceException( +186 "Continued fraction diverged to NaN for value {0}", +187 x); +188 } +189 relativeError = Math.abs(r / c - 1.0); +190 +191 // prepare for next iteration +192 c = p2 / q2; +193 p0 = p1; +194 p1 = p2; +195 q0 = q1; +196 q1 = q2; +197 } +198 +199 if (n >= maxIterations) { +200 throw new MaxIterationsExceededException(maxIterations, +201 "Continued fraction convergents failed to converge for value {0}", +202 x); +203 } +204 +205 return c; +206 } +207 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/DefaultTransformer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/DefaultTransformer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,147 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.util; +019 +020 import java.io.Serializable; +021 +022 import org.apache.commons.math.MathException; +023 +024 /** +025 * A Default NumberTransformer for java.lang.Numbers and Numeric Strings. This +026 * provides some simple conversion capabilities to turn any java.lang.Number +027 * into a primitive double or to turn a String representation of a Number into +028 * a double. +029 * +030 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +031 */ +032 public class DefaultTransformer implements NumberTransformer, Serializable { +033 +034 /** Serializable version identifier */ +035 private static final long serialVersionUID = 4019938025047800455L; +036 +037 /** +038 * @param o the object that gets transformed. +039 * @return a double primitive representation of the Object o. +040 * @throws org.apache.commons.math.MathException If it cannot successfully +041 * be transformed or is null. +042 * @see <a href="http://commons.apache.org/collections/api-release/org/apache/commons/collections/Transformer.html"/> +043 */ +044 public double transform(Object o) throws MathException{ +045 +046 if (o == null) { +047 throw new MathException("Conversion Exception in Transformation, Object is null"); +048 } +049 +050 if (o instanceof Number) { +051 return ((Number)o).doubleValue(); +052 } +053 +054 try { +055 return Double.valueOf(o.toString()).doubleValue(); +056 } catch (NumberFormatException e) { +057 throw new MathException(e, +058 "Conversion Exception in Transformation: {0}", e.getMessage()); +059 } +060 } +061 +062 /** {@inheritDoc} */ +063 @Override +064 public boolean equals(Object other) { +065 if (this == other) { +066 return true; +067 } +068 if (other == null) { +069 return false; +070 } +071 return other instanceof DefaultTransformer; +072 } +073 +074 /** {@inheritDoc} */ +075 @Override +076 public int hashCode() { +077 // some arbitrary number ... +078 return 401993047; +079 } +080 +081 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/DoubleArray.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/DoubleArray.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,170 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.util; +018 +019 +020 /** +021 * Provides a standard interface for double arrays. Allows different +022 * array implementations to support various storage mechanisms +023 * such as automatic expansion, contraction, and array "rolling". +024 * +025 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +026 */ +027 public interface DoubleArray { +028 +029 /** +030 * Returns the number of elements currently in the array. Please note +031 * that this may be different from the length of the internal storage array. +032 * +033 * @return number of elements +034 */ +035 int getNumElements(); +036 +037 /** +038 * Returns the element at the specified index. Note that if an +039 * out of bounds index is supplied a ArrayIndexOutOfBoundsException +040 * will be thrown. +041 * +042 * @param index index to fetch a value from +043 * @return value stored at the specified index +044 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is less than +045 * zero or is greater than <code>getNumElements() - 1</code>. +046 */ +047 double getElement(int index); +048 +049 /** +050 * Sets the element at the specified index. If the specified index is greater than +051 * <code>getNumElements() - 1</code>, the <code>numElements</code> property +052 * is increased to <code>index +1</code> and additional storage is allocated +053 * (if necessary) for the new element and all (uninitialized) elements +054 * between the new element and the previous end of the array). +055 * +056 * @param index index to store a value in +057 * @param value value to store at the specified index +058 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is less than +059 * zero. +060 */ +061 void setElement(int index, double value); +062 +063 /** +064 * Adds an element to the end of this expandable array +065 * +066 * @param value to be added to end of array +067 */ +068 void addElement(double value); +069 +070 /** +071 * <p> +072 * Adds an element to the end of the array and removes the first +073 * element in the array. Returns the discarded first element. +074 * The effect is similar to a push operation in a FIFO queue. +075 * </p> +076 * <p> +077 * Example: If the array contains the elements 1, 2, 3, 4 (in that order) +078 * and addElementRolling(5) is invoked, the result is an array containing +079 * the entries 2, 3, 4, 5 and the value returned is 1. +080 * </p> +081 * +082 * @param value the value to be added to the array +083 * @return the value which has been discarded or "pushed" out of the array +084 * by this rolling insert +085 */ +086 double addElementRolling(double value); +087 +088 /** +089 * Returns a double[] array containing the elements of this +090 * <code>DoubleArray</code>. If the underlying implementation is +091 * array-based, this method should always return a copy, rather than a +092 * reference to the underlying array so that changes made to the returned +093 * array have no effect on the <code>DoubleArray.</code> +094 * +095 * @return all elements added to the array +096 */ +097 double[] getElements(); +098 +099 /** +100 * Clear the double array +101 */ +102 void clear(); +103 +104 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/MathUtils.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/MathUtils.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,1899 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.util; +019 +020 import java.math.BigDecimal; +021 import java.math.BigInteger; +022 import java.util.Arrays; +023 +024 import org.apache.commons.math.MathRuntimeException; +025 +026 /** +027 * Some useful additions to the built-in functions in {@link Math}. +028 * @version $Revision: 927249 $ $Date: 2010-03-24 21:06:51 -0400 (Wed, 24 Mar 2010) $ +029 */ +030 public final class MathUtils { +031 +032 /** Smallest positive number such that 1 - EPSILON is not numerically equal to 1. */ +033 public static final double EPSILON = 0x1.0p-53; +034 +035 /** Safe minimum, such that 1 / SAFE_MIN does not overflow. +036 * <p>In IEEE 754 arithmetic, this is also the smallest normalized +037 * number 2<sup>-1022</sup>.</p> +038 */ +039 public static final double SAFE_MIN = 0x1.0p-1022; +040 +041 /** +042 * 2 π. +043 * @since 2.1 +044 */ +045 public static final double TWO_PI = 2 * Math.PI; +046 +047 /** -1.0 cast as a byte. */ +048 private static final byte NB = (byte)-1; +049 +050 /** -1.0 cast as a short. */ +051 private static final short NS = (short)-1; +052 +053 /** 1.0 cast as a byte. */ +054 private static final byte PB = (byte)1; +055 +056 /** 1.0 cast as a short. */ +057 private static final short PS = (short)1; +058 +059 /** 0.0 cast as a byte. */ +060 private static final byte ZB = (byte)0; +061 +062 /** 0.0 cast as a short. */ +063 private static final short ZS = (short)0; +064 +065 /** Gap between NaN and regular numbers. */ +066 private static final int NAN_GAP = 4 * 1024 * 1024; +067 +068 /** Offset to order signed double numbers lexicographically. */ +069 private static final long SGN_MASK = 0x8000000000000000L; +070 +071 /** All long-representable factorials */ +072 private static final long[] FACTORIALS = new long[] { +073 1l, 1l, 2l, +074 6l, 24l, 120l, +075 720l, 5040l, 40320l, +076 362880l, 3628800l, 39916800l, +077 479001600l, 6227020800l, 87178291200l, +078 1307674368000l, 20922789888000l, 355687428096000l, +079 6402373705728000l, 121645100408832000l, 2432902008176640000l }; +080 +081 /** +082 * Private Constructor +083 */ +084 private MathUtils() { +085 super(); +086 } +087 +088 /** +089 * Add two integers, checking for overflow. +090 * +091 * @param x an addend +092 * @param y an addend +093 * @return the sum <code>x+y</code> +094 * @throws ArithmeticException if the result can not be represented as an +095 * int +096 * @since 1.1 +097 */ +098 public static int addAndCheck(int x, int y) { +099 long s = (long)x + (long)y; +100 if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) { +101 throw new ArithmeticException("overflow: add"); +102 } +103 return (int)s; +104 } +105 +106 /** +107 * Add two long integers, checking for overflow. +108 * +109 * @param a an addend +110 * @param b an addend +111 * @return the sum <code>a+b</code> +112 * @throws ArithmeticException if the result can not be represented as an +113 * long +114 * @since 1.2 +115 */ +116 public static long addAndCheck(long a, long b) { +117 return addAndCheck(a, b, "overflow: add"); +118 } +119 +120 /** +121 * Add two long integers, checking for overflow. +122 * +123 * @param a an addend +124 * @param b an addend +125 * @param msg the message to use for any thrown exception. +126 * @return the sum <code>a+b</code> +127 * @throws ArithmeticException if the result can not be represented as an +128 * long +129 * @since 1.2 +130 */ +131 private static long addAndCheck(long a, long b, String msg) { +132 long ret; +133 if (a > b) { +134 // use symmetry to reduce boundary cases +135 ret = addAndCheck(b, a, msg); +136 } else { +137 // assert a <= b +138 +139 if (a < 0) { +140 if (b < 0) { +141 // check for negative overflow +142 if (Long.MIN_VALUE - b <= a) { +143 ret = a + b; +144 } else { +145 throw new ArithmeticException(msg); +146 } +147 } else { +148 // opposite sign addition is always safe +149 ret = a + b; +150 } +151 } else { +152 // assert a >= 0 +153 // assert b >= 0 +154 +155 // check for positive overflow +156 if (a <= Long.MAX_VALUE - b) { +157 ret = a + b; +158 } else { +159 throw new ArithmeticException(msg); +160 } +161 } +162 } +163 return ret; +164 } +165 +166 /** +167 * Returns an exact representation of the <a +168 * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial +169 * Coefficient</a>, "<code>n choose k</code>", the number of +170 * <code>k</code>-element subsets that can be selected from an +171 * <code>n</code>-element set. +172 * <p> +173 * <Strong>Preconditions</strong>: +174 * <ul> +175 * <li> <code>0 <= k <= n </code> (otherwise +176 * <code>IllegalArgumentException</code> is thrown)</li> +177 * <li> The result is small enough to fit into a <code>long</code>. The +178 * largest value of <code>n</code> for which all coefficients are +179 * <code> < Long.MAX_VALUE</code> is 66. If the computed value exceeds +180 * <code>Long.MAX_VALUE</code> an <code>ArithMeticException</code> is +181 * thrown.</li> +182 * </ul></p> +183 * +184 * @param n the size of the set +185 * @param k the size of the subsets to be counted +186 * @return <code>n choose k</code> +187 * @throws IllegalArgumentException if preconditions are not met. +188 * @throws ArithmeticException if the result is too large to be represented +189 * by a long integer. +190 */ +191 public static long binomialCoefficient(final int n, final int k) { +192 checkBinomial(n, k); +193 if ((n == k) || (k == 0)) { +194 return 1; +195 } +196 if ((k == 1) || (k == n - 1)) { +197 return n; +198 } +199 // Use symmetry for large k +200 if (k > n / 2) +201 return binomialCoefficient(n, n - k); +202 +203 // We use the formula +204 // (n choose k) = n! / (n-k)! / k! +205 // (n choose k) == ((n-k+1)*...*n) / (1*...*k) +206 // which could be written +207 // (n choose k) == (n-1 choose k-1) * n / k +208 long result = 1; +209 if (n <= 61) { +210 // For n <= 61, the naive implementation cannot overflow. +211 int i = n - k + 1; +212 for (int j = 1; j <= k; j++) { +213 result = result * i / j; +214 i++; +215 } +216 } else if (n <= 66) { +217 // For n > 61 but n <= 66, the result cannot overflow, +218 // but we must take care not to overflow intermediate values. +219 int i = n - k + 1; +220 for (int j = 1; j <= k; j++) { +221 // We know that (result * i) is divisible by j, +222 // but (result * i) may overflow, so we split j: +223 // Filter out the gcd, d, so j/d and i/d are integer. +224 // result is divisible by (j/d) because (j/d) +225 // is relative prime to (i/d) and is a divisor of +226 // result * (i/d). +227 final long d = gcd(i, j); +228 result = (result / (j / d)) * (i / d); +229 i++; +230 } +231 } else { +232 // For n > 66, a result overflow might occur, so we check +233 // the multiplication, taking care to not overflow +234 // unnecessary. +235 int i = n - k + 1; +236 for (int j = 1; j <= k; j++) { +237 final long d = gcd(i, j); +238 result = mulAndCheck(result / (j / d), i / d); +239 i++; +240 } +241 } +242 return result; +243 } +244 +245 /** +246 * Returns a <code>double</code> representation of the <a +247 * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial +248 * Coefficient</a>, "<code>n choose k</code>", the number of +249 * <code>k</code>-element subsets that can be selected from an +250 * <code>n</code>-element set. +251 * <p> +252 * <Strong>Preconditions</strong>: +253 * <ul> +254 * <li> <code>0 <= k <= n </code> (otherwise +255 * <code>IllegalArgumentException</code> is thrown)</li> +256 * <li> The result is small enough to fit into a <code>double</code>. The +257 * largest value of <code>n</code> for which all coefficients are < +258 * Double.MAX_VALUE is 1029. If the computed value exceeds Double.MAX_VALUE, +259 * Double.POSITIVE_INFINITY is returned</li> +260 * </ul></p> +261 * +262 * @param n the size of the set +263 * @param k the size of the subsets to be counted +264 * @return <code>n choose k</code> +265 * @throws IllegalArgumentException if preconditions are not met. +266 */ +267 public static double binomialCoefficientDouble(final int n, final int k) { +268 checkBinomial(n, k); +269 if ((n == k) || (k == 0)) { +270 return 1d; +271 } +272 if ((k == 1) || (k == n - 1)) { +273 return n; +274 } +275 if (k > n/2) { +276 return binomialCoefficientDouble(n, n - k); +277 } +278 if (n < 67) { +279 return binomialCoefficient(n,k); +280 } +281 +282 double result = 1d; +283 for (int i = 1; i <= k; i++) { +284 result *= (double)(n - k + i) / (double)i; +285 } +286 +287 return Math.floor(result + 0.5); +288 } +289 +290 /** +291 * Returns the natural <code>log</code> of the <a +292 * href="http://mathworld.wolfram.com/BinomialCoefficient.html"> Binomial +293 * Coefficient</a>, "<code>n choose k</code>", the number of +294 * <code>k</code>-element subsets that can be selected from an +295 * <code>n</code>-element set. +296 * <p> +297 * <Strong>Preconditions</strong>: +298 * <ul> +299 * <li> <code>0 <= k <= n </code> (otherwise +300 * <code>IllegalArgumentException</code> is thrown)</li> +301 * </ul></p> +302 * +303 * @param n the size of the set +304 * @param k the size of the subsets to be counted +305 * @return <code>n choose k</code> +306 * @throws IllegalArgumentException if preconditions are not met. +307 */ +308 public static double binomialCoefficientLog(final int n, final int k) { +309 checkBinomial(n, k); +310 if ((n == k) || (k == 0)) { +311 return 0; +312 } +313 if ((k == 1) || (k == n - 1)) { +314 return Math.log(n); +315 } +316 +317 /* +318 * For values small enough to do exact integer computation, +319 * return the log of the exact value +320 */ +321 if (n < 67) { +322 return Math.log(binomialCoefficient(n,k)); +323 } +324 +325 /* +326 * Return the log of binomialCoefficientDouble for values that will not +327 * overflow binomialCoefficientDouble +328 */ +329 if (n < 1030) { +330 return Math.log(binomialCoefficientDouble(n, k)); +331 } +332 +333 if (k > n / 2) { +334 return binomialCoefficientLog(n, n - k); +335 } +336 +337 /* +338 * Sum logs for values that could overflow +339 */ +340 double logSum = 0; +341 +342 // n!/(n-k)! +343 for (int i = n - k + 1; i <= n; i++) { +344 logSum += Math.log(i); +345 } +346 +347 // divide by k! +348 for (int i = 2; i <= k; i++) { +349 logSum -= Math.log(i); +350 } +351 +352 return logSum; +353 } +354 +355 /** +356 * Check binomial preconditions. +357 * @param n the size of the set +358 * @param k the size of the subsets to be counted +359 * @exception IllegalArgumentException if preconditions are not met. +360 */ +361 private static void checkBinomial(final int n, final int k) +362 throws IllegalArgumentException { +363 if (n < k) { +364 throw MathRuntimeException.createIllegalArgumentException( +365 "must have n >= k for binomial coefficient (n,k), got n = {0}, k = {1}", +366 n, k); +367 } +368 if (n < 0) { +369 throw MathRuntimeException.createIllegalArgumentException( +370 "must have n >= 0 for binomial coefficient (n,k), got n = {0}", +371 n); +372 } +373 } +374 +375 /** +376 * Compares two numbers given some amount of allowed error. +377 * +378 * @param x the first number +379 * @param y the second number +380 * @param eps the amount of error to allow when checking for equality +381 * @return <ul><li>0 if {@link #equals(double, double, double) equals(x, y, eps)}</li> +382 * <li>< 0 if !{@link #equals(double, double, double) equals(x, y, eps)} && x < y</li> +383 * <li>> 0 if !{@link #equals(double, double, double) equals(x, y, eps)} && x > y</li></ul> +384 */ +385 public static int compareTo(double x, double y, double eps) { +386 if (equals(x, y, eps)) { +387 return 0; +388 } else if (x < y) { +389 return -1; +390 } +391 return 1; +392 } +393 +394 /** +395 * Returns the <a href="http://mathworld.wolfram.com/HyperbolicCosine.html"> +396 * hyperbolic cosine</a> of x. +397 * +398 * @param x double value for which to find the hyperbolic cosine +399 * @return hyperbolic cosine of x +400 */ +401 public static double cosh(double x) { +402 return (Math.exp(x) + Math.exp(-x)) / 2.0; +403 } +404 +405 /** +406 * Returns true iff both arguments are NaN or neither is NaN and they are +407 * equal +408 * +409 * @param x first value +410 * @param y second value +411 * @return true if the values are equal or both are NaN +412 */ +413 public static boolean equals(double x, double y) { +414 return (Double.isNaN(x) && Double.isNaN(y)) || x == y; +415 } +416 +417 /** +418 * Returns true iff both arguments are equal or within the range of allowed +419 * error (inclusive). +420 * <p> +421 * Two NaNs are considered equals, as are two infinities with same sign. +422 * </p> +423 * +424 * @param x first value +425 * @param y second value +426 * @param eps the amount of absolute error to allow +427 * @return true if the values are equal or within range of each other +428 */ +429 public static boolean equals(double x, double y, double eps) { +430 return equals(x, y) || (Math.abs(y - x) <= eps); +431 } +432 +433 /** +434 * Returns true iff both arguments are equal or within the range of allowed +435 * error (inclusive). +436 * Adapted from <a +437 * href="http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm"> +438 * Bruce Dawson</a> +439 * +440 * @param x first value +441 * @param y second value +442 * @param maxUlps {@code (maxUlps - 1)} is the number of floating point +443 * values between {@code x} and {@code y}. +444 * @return {@code true} if there are less than {@code maxUlps} floating +445 * point values between {@code x} and {@code y} +446 */ +447 public static boolean equals(double x, double y, int maxUlps) { +448 // Check that "maxUlps" is non-negative and small enough so that the +449 // default NAN won't compare as equal to anything. +450 assert maxUlps > 0 && maxUlps < NAN_GAP; +451 +452 long xInt = Double.doubleToLongBits(x); +453 long yInt = Double.doubleToLongBits(y); +454 +455 // Make lexicographically ordered as a two's-complement integer. +456 if (xInt < 0) { +457 xInt = SGN_MASK - xInt; +458 } +459 if (yInt < 0) { +460 yInt = SGN_MASK - yInt; +461 } +462 +463 return Math.abs(xInt - yInt) <= maxUlps; +464 } +465 +466 /** +467 * Returns true iff both arguments are null or have same dimensions +468 * and all their elements are {@link #equals(double,double) equals} +469 * +470 * @param x first array +471 * @param y second array +472 * @return true if the values are both null or have same dimension +473 * and equal elements +474 * @since 1.2 +475 */ +476 public static boolean equals(double[] x, double[] y) { +477 if ((x == null) || (y == null)) { +478 return !((x == null) ^ (y == null)); +479 } +480 if (x.length != y.length) { +481 return false; +482 } +483 for (int i = 0; i < x.length; ++i) { +484 if (!equals(x[i], y[i])) { +485 return false; +486 } +487 } +488 return true; +489 } +490 +491 /** +492 * Returns n!. Shorthand for <code>n</code> <a +493 * href="http://mathworld.wolfram.com/Factorial.html"> Factorial</a>, the +494 * product of the numbers <code>1,...,n</code>. +495 * <p> +496 * <Strong>Preconditions</strong>: +497 * <ul> +498 * <li> <code>n >= 0</code> (otherwise +499 * <code>IllegalArgumentException</code> is thrown)</li> +500 * <li> The result is small enough to fit into a <code>long</code>. The +501 * largest value of <code>n</code> for which <code>n!</code> < +502 * Long.MAX_VALUE</code> is 20. If the computed value exceeds <code>Long.MAX_VALUE</code> +503 * an <code>ArithMeticException </code> is thrown.</li> +504 * </ul> +505 * </p> +506 * +507 * @param n argument +508 * @return <code>n!</code> +509 * @throws ArithmeticException if the result is too large to be represented +510 * by a long integer. +511 * @throws IllegalArgumentException if n < 0 +512 */ +513 public static long factorial(final int n) { +514 if (n < 0) { +515 throw MathRuntimeException.createIllegalArgumentException( +516 "must have n >= 0 for n!, got n = {0}", +517 n); +518 } +519 if (n > 20) { +520 throw new ArithmeticException( +521 "factorial value is too large to fit in a long"); +522 } +523 return FACTORIALS[n]; +524 } +525 +526 /** +527 * Returns n!. Shorthand for <code>n</code> <a +528 * href="http://mathworld.wolfram.com/Factorial.html"> Factorial</a>, the +529 * product of the numbers <code>1,...,n</code> as a <code>double</code>. +530 * <p> +531 * <Strong>Preconditions</strong>: +532 * <ul> +533 * <li> <code>n >= 0</code> (otherwise +534 * <code>IllegalArgumentException</code> is thrown)</li> +535 * <li> The result is small enough to fit into a <code>double</code>. The +536 * largest value of <code>n</code> for which <code>n!</code> < +537 * Double.MAX_VALUE</code> is 170. If the computed value exceeds +538 * Double.MAX_VALUE, Double.POSITIVE_INFINITY is returned</li> +539 * </ul> +540 * </p> +541 * +542 * @param n argument +543 * @return <code>n!</code> +544 * @throws IllegalArgumentException if n < 0 +545 */ +546 public static double factorialDouble(final int n) { +547 if (n < 0) { +548 throw MathRuntimeException.createIllegalArgumentException( +549 "must have n >= 0 for n!, got n = {0}", +550 n); +551 } +552 if (n < 21) { +553 return factorial(n); +554 } +555 return Math.floor(Math.exp(factorialLog(n)) + 0.5); +556 } +557 +558 /** +559 * Returns the natural logarithm of n!. +560 * <p> +561 * <Strong>Preconditions</strong>: +562 * <ul> +563 * <li> <code>n >= 0</code> (otherwise +564 * <code>IllegalArgumentException</code> is thrown)</li> +565 * </ul></p> +566 * +567 * @param n argument +568 * @return <code>n!</code> +569 * @throws IllegalArgumentException if preconditions are not met. +570 */ +571 public static double factorialLog(final int n) { +572 if (n < 0) { +573 throw MathRuntimeException.createIllegalArgumentException( +574 "must have n >= 0 for n!, got n = {0}", +575 n); +576 } +577 if (n < 21) { +578 return Math.log(factorial(n)); +579 } +580 double logSum = 0; +581 for (int i = 2; i <= n; i++) { +582 logSum += Math.log(i); +583 } +584 return logSum; +585 } +586 +587 /** +588 * <p> +589 * Gets the greatest common divisor of the absolute value of two numbers, +590 * using the "binary gcd" method which avoids division and modulo +591 * operations. See Knuth 4.5.2 algorithm B. This algorithm is due to Josef +592 * Stein (1961). +593 * </p> +594 * Special cases: +595 * <ul> +596 * <li>The invocations +597 * <code>gcd(Integer.MIN_VALUE, Integer.MIN_VALUE)</code>, +598 * <code>gcd(Integer.MIN_VALUE, 0)</code> and +599 * <code>gcd(0, Integer.MIN_VALUE)</code> throw an +600 * <code>ArithmeticException</code>, because the result would be 2^31, which +601 * is too large for an int value.</li> +602 * <li>The result of <code>gcd(x, x)</code>, <code>gcd(0, x)</code> and +603 * <code>gcd(x, 0)</code> is the absolute value of <code>x</code>, except +604 * for the special cases above. +605 * <li>The invocation <code>gcd(0, 0)</code> is the only one which returns +606 * <code>0</code>.</li> +607 * </ul> +608 * +609 * @param p any number +610 * @param q any number +611 * @return the greatest common divisor, never negative +612 * @throws ArithmeticException if the result cannot be represented as a +613 * nonnegative int value +614 * @since 1.1 +615 */ +616 public static int gcd(final int p, final int q) { +617 int u = p; +618 int v = q; +619 if ((u == 0) || (v == 0)) { +620 if ((u == Integer.MIN_VALUE) || (v == Integer.MIN_VALUE)) { +621 throw MathRuntimeException.createArithmeticException( +622 "overflow: gcd({0}, {1}) is 2^31", +623 p, q); +624 } +625 return Math.abs(u) + Math.abs(v); +626 } +627 // keep u and v negative, as negative integers range down to +628 // -2^31, while positive numbers can only be as large as 2^31-1 +629 // (i.e. we can't necessarily negate a negative number without +630 // overflow) +631 /* assert u!=0 && v!=0; */ +632 if (u > 0) { +633 u = -u; +634 } // make u negative +635 if (v > 0) { +636 v = -v; +637 } // make v negative +638 // B1. [Find power of 2] +639 int k = 0; +640 while ((u & 1) == 0 && (v & 1) == 0 && k < 31) { // while u and v are +641 // both even... +642 u /= 2; +643 v /= 2; +644 k++; // cast out twos. +645 } +646 if (k == 31) { +647 throw MathRuntimeException.createArithmeticException( +648 "overflow: gcd({0}, {1}) is 2^31", +649 p, q); +650 } +651 // B2. Initialize: u and v have been divided by 2^k and at least +652 // one is odd. +653 int t = ((u & 1) == 1) ? v : -(u / 2)/* B3 */; +654 // t negative: u was odd, v may be even (t replaces v) +655 // t positive: u was even, v is odd (t replaces u) +656 do { +657 /* assert u<0 && v<0; */ +658 // B4/B3: cast out twos from t. +659 while ((t & 1) == 0) { // while t is even.. +660 t /= 2; // cast out twos +661 } +662 // B5 [reset max(u,v)] +663 if (t > 0) { +664 u = -t; +665 } else { +666 v = t; +667 } +668 // B6/B3. at this point both u and v should be odd. +669 t = (v - u) / 2; +670 // |u| larger: t positive (replace u) +671 // |v| larger: t negative (replace v) +672 } while (t != 0); +673 return -u * (1 << k); // gcd is u*2^k +674 } +675 +676 /** +677 * <p> +678 * Gets the greatest common divisor of the absolute value of two numbers, +679 * using the "binary gcd" method which avoids division and modulo +680 * operations. See Knuth 4.5.2 algorithm B. This algorithm is due to Josef +681 * Stein (1961). +682 * </p> +683 * Special cases: +684 * <ul> +685 * <li>The invocations +686 * <code>gcd(Long.MIN_VALUE, Long.MIN_VALUE)</code>, +687 * <code>gcd(Long.MIN_VALUE, 0L)</code> and +688 * <code>gcd(0L, Long.MIN_VALUE)</code> throw an +689 * <code>ArithmeticException</code>, because the result would be 2^63, which +690 * is too large for a long value.</li> +691 * <li>The result of <code>gcd(x, x)</code>, <code>gcd(0L, x)</code> and +692 * <code>gcd(x, 0L)</code> is the absolute value of <code>x</code>, except +693 * for the special cases above. +694 * <li>The invocation <code>gcd(0L, 0L)</code> is the only one which returns +695 * <code>0L</code>.</li> +696 * </ul> +697 * +698 * @param p any number +699 * @param q any number +700 * @return the greatest common divisor, never negative +701 * @throws ArithmeticException if the result cannot be represented as a nonnegative long +702 * value +703 * @since 2.1 +704 */ +705 public static long gcd(final long p, final long q) { +706 long u = p; +707 long v = q; +708 if ((u == 0) || (v == 0)) { +709 if ((u == Long.MIN_VALUE) || (v == Long.MIN_VALUE)){ +710 throw MathRuntimeException.createArithmeticException( +711 "overflow: gcd({0}, {1}) is 2^63", +712 p, q); +713 } +714 return Math.abs(u) + Math.abs(v); +715 } +716 // keep u and v negative, as negative integers range down to +717 // -2^63, while positive numbers can only be as large as 2^63-1 +718 // (i.e. we can't necessarily negate a negative number without +719 // overflow) +720 /* assert u!=0 && v!=0; */ +721 if (u > 0) { +722 u = -u; +723 } // make u negative +724 if (v > 0) { +725 v = -v; +726 } // make v negative +727 // B1. [Find power of 2] +728 int k = 0; +729 while ((u & 1) == 0 && (v & 1) == 0 && k < 63) { // while u and v are +730 // both even... +731 u /= 2; +732 v /= 2; +733 k++; // cast out twos. +734 } +735 if (k == 63) { +736 throw MathRuntimeException.createArithmeticException( +737 "overflow: gcd({0}, {1}) is 2^63", +738 p, q); +739 } +740 // B2. Initialize: u and v have been divided by 2^k and at least +741 // one is odd. +742 long t = ((u & 1) == 1) ? v : -(u / 2)/* B3 */; +743 // t negative: u was odd, v may be even (t replaces v) +744 // t positive: u was even, v is odd (t replaces u) +745 do { +746 /* assert u<0 && v<0; */ +747 // B4/B3: cast out twos from t. +748 while ((t & 1) == 0) { // while t is even.. +749 t /= 2; // cast out twos +750 } +751 // B5 [reset max(u,v)] +752 if (t > 0) { +753 u = -t; +754 } else { +755 v = t; +756 } +757 // B6/B3. at this point both u and v should be odd. +758 t = (v - u) / 2; +759 // |u| larger: t positive (replace u) +760 // |v| larger: t negative (replace v) +761 } while (t != 0); +762 return -u * (1L << k); // gcd is u*2^k +763 } +764 +765 /** +766 * Returns an integer hash code representing the given double value. +767 * +768 * @param value the value to be hashed +769 * @return the hash code +770 */ +771 public static int hash(double value) { +772 return new Double(value).hashCode(); +773 } +774 +775 /** +776 * Returns an integer hash code representing the given double array. +777 * +778 * @param value the value to be hashed (may be null) +779 * @return the hash code +780 * @since 1.2 +781 */ +782 public static int hash(double[] value) { +783 return Arrays.hashCode(value); +784 } +785 +786 /** +787 * For a byte value x, this method returns (byte)(+1) if x >= 0 and +788 * (byte)(-1) if x < 0. +789 * +790 * @param x the value, a byte +791 * @return (byte)(+1) or (byte)(-1), depending on the sign of x +792 */ +793 public static byte indicator(final byte x) { +794 return (x >= ZB) ? PB : NB; +795 } +796 +797 /** +798 * For a double precision value x, this method returns +1.0 if x >= 0 and +799 * -1.0 if x < 0. Returns <code>NaN</code> if <code>x</code> is +800 * <code>NaN</code>. +801 * +802 * @param x the value, a double +803 * @return +1.0 or -1.0, depending on the sign of x +804 */ +805 public static double indicator(final double x) { +806 if (Double.isNaN(x)) { +807 return Double.NaN; +808 } +809 return (x >= 0.0) ? 1.0 : -1.0; +810 } +811 +812 /** +813 * For a float value x, this method returns +1.0F if x >= 0 and -1.0F if x < +814 * 0. Returns <code>NaN</code> if <code>x</code> is <code>NaN</code>. +815 * +816 * @param x the value, a float +817 * @return +1.0F or -1.0F, depending on the sign of x +818 */ +819 public static float indicator(final float x) { +820 if (Float.isNaN(x)) { +821 return Float.NaN; +822 } +823 return (x >= 0.0F) ? 1.0F : -1.0F; +824 } +825 +826 /** +827 * For an int value x, this method returns +1 if x >= 0 and -1 if x < 0. +828 * +829 * @param x the value, an int +830 * @return +1 or -1, depending on the sign of x +831 */ +832 public static int indicator(final int x) { +833 return (x >= 0) ? 1 : -1; +834 } +835 +836 /** +837 * For a long value x, this method returns +1L if x >= 0 and -1L if x < 0. +838 * +839 * @param x the value, a long +840 * @return +1L or -1L, depending on the sign of x +841 */ +842 public static long indicator(final long x) { +843 return (x >= 0L) ? 1L : -1L; +844 } +845 +846 /** +847 * For a short value x, this method returns (short)(+1) if x >= 0 and +848 * (short)(-1) if x < 0. +849 * +850 * @param x the value, a short +851 * @return (short)(+1) or (short)(-1), depending on the sign of x +852 */ +853 public static short indicator(final short x) { +854 return (x >= ZS) ? PS : NS; +855 } +856 +857 /** +858 * <p> +859 * Returns the least common multiple of the absolute value of two numbers, +860 * using the formula <code>lcm(a,b) = (a / gcd(a,b)) * b</code>. +861 * </p> +862 * Special cases: +863 * <ul> +864 * <li>The invocations <code>lcm(Integer.MIN_VALUE, n)</code> and +865 * <code>lcm(n, Integer.MIN_VALUE)</code>, where <code>abs(n)</code> is a +866 * power of 2, throw an <code>ArithmeticException</code>, because the result +867 * would be 2^31, which is too large for an int value.</li> +868 * <li>The result of <code>lcm(0, x)</code> and <code>lcm(x, 0)</code> is +869 * <code>0</code> for any <code>x</code>. +870 * </ul> +871 * +872 * @param a any number +873 * @param b any number +874 * @return the least common multiple, never negative +875 * @throws ArithmeticException +876 * if the result cannot be represented as a nonnegative int +877 * value +878 * @since 1.1 +879 */ +880 public static int lcm(int a, int b) { +881 if (a==0 || b==0){ +882 return 0; +883 } +884 int lcm = Math.abs(mulAndCheck(a / gcd(a, b), b)); +885 if (lcm == Integer.MIN_VALUE) { +886 throw MathRuntimeException.createArithmeticException( +887 "overflow: lcm({0}, {1}) is 2^31", +888 a, b); +889 } +890 return lcm; +891 } +892 +893 /** +894 * <p> +895 * Returns the least common multiple of the absolute value of two numbers, +896 * using the formula <code>lcm(a,b) = (a / gcd(a,b)) * b</code>. +897 * </p> +898 * Special cases: +899 * <ul> +900 * <li>The invocations <code>lcm(Long.MIN_VALUE, n)</code> and +901 * <code>lcm(n, Long.MIN_VALUE)</code>, where <code>abs(n)</code> is a +902 * power of 2, throw an <code>ArithmeticException</code>, because the result +903 * would be 2^63, which is too large for an int value.</li> +904 * <li>The result of <code>lcm(0L, x)</code> and <code>lcm(x, 0L)</code> is +905 * <code>0L</code> for any <code>x</code>. +906 * </ul> +907 * +908 * @param a any number +909 * @param b any number +910 * @return the least common multiple, never negative +911 * @throws ArithmeticException if the result cannot be represented as a nonnegative long +912 * value +913 * @since 2.1 +914 */ +915 public static long lcm(long a, long b) { +916 if (a==0 || b==0){ +917 return 0; +918 } +919 long lcm = Math.abs(mulAndCheck(a / gcd(a, b), b)); +920 if (lcm == Long.MIN_VALUE){ +921 throw MathRuntimeException.createArithmeticException( +922 "overflow: lcm({0}, {1}) is 2^63", +923 a, b); +924 } +925 return lcm; +926 } +927 +928 /** +929 * <p>Returns the +930 * <a href="http://mathworld.wolfram.com/Logarithm.html">logarithm</a> +931 * for base <code>b</code> of <code>x</code>. +932 * </p> +933 * <p>Returns <code>NaN<code> if either argument is negative. If +934 * <code>base</code> is 0 and <code>x</code> is positive, 0 is returned. +935 * If <code>base</code> is positive and <code>x</code> is 0, +936 * <code>Double.NEGATIVE_INFINITY</code> is returned. If both arguments +937 * are 0, the result is <code>NaN</code>.</p> +938 * +939 * @param base the base of the logarithm, must be greater than 0 +940 * @param x argument, must be greater than 0 +941 * @return the value of the logarithm - the number y such that base^y = x. +942 * @since 1.2 +943 */ +944 public static double log(double base, double x) { +945 return Math.log(x)/Math.log(base); +946 } +947 +948 /** +949 * Multiply two integers, checking for overflow. +950 * +951 * @param x a factor +952 * @param y a factor +953 * @return the product <code>x*y</code> +954 * @throws ArithmeticException if the result can not be represented as an +955 * int +956 * @since 1.1 +957 */ +958 public static int mulAndCheck(int x, int y) { +959 long m = ((long)x) * ((long)y); +960 if (m < Integer.MIN_VALUE || m > Integer.MAX_VALUE) { +961 throw new ArithmeticException("overflow: mul"); +962 } +963 return (int)m; +964 } +965 +966 /** +967 * Multiply two long integers, checking for overflow. +968 * +969 * @param a first value +970 * @param b second value +971 * @return the product <code>a * b</code> +972 * @throws ArithmeticException if the result can not be represented as an +973 * long +974 * @since 1.2 +975 */ +976 public static long mulAndCheck(long a, long b) { +977 long ret; +978 String msg = "overflow: multiply"; +979 if (a > b) { +980 // use symmetry to reduce boundary cases +981 ret = mulAndCheck(b, a); +982 } else { +983 if (a < 0) { +984 if (b < 0) { +985 // check for positive overflow with negative a, negative b +986 if (a >= Long.MAX_VALUE / b) { +987 ret = a * b; +988 } else { +989 throw new ArithmeticException(msg); +990 } +991 } else if (b > 0) { +992 // check for negative overflow with negative a, positive b +993 if (Long.MIN_VALUE / b <= a) { +994 ret = a * b; +995 } else { +996 throw new ArithmeticException(msg); +997 +998 } +999 } else { +1000 // assert b == 0 +1001 ret = 0; +1002 } +1003 } else if (a > 0) { +1004 // assert a > 0 +1005 // assert b > 0 +1006 +1007 // check for positive overflow with positive a, positive b +1008 if (a <= Long.MAX_VALUE / b) { +1009 ret = a * b; +1010 } else { +1011 throw new ArithmeticException(msg); +1012 } +1013 } else { +1014 // assert a == 0 +1015 ret = 0; +1016 } +1017 } +1018 return ret; +1019 } +1020 +1021 /** +1022 * Get the next machine representable number after a number, moving +1023 * in the direction of another number. +1024 * <p> +1025 * If <code>direction</code> is greater than or equal to<code>d</code>, +1026 * the smallest machine representable number strictly greater than +1027 * <code>d</code> is returned; otherwise the largest representable number +1028 * strictly less than <code>d</code> is returned.</p> +1029 * <p> +1030 * If <code>d</code> is NaN or Infinite, it is returned unchanged.</p> +1031 * +1032 * @param d base number +1033 * @param direction (the only important thing is whether +1034 * direction is greater or smaller than d) +1035 * @return the next machine representable number in the specified direction +1036 * @since 1.2 +1037 */ +1038 public static double nextAfter(double d, double direction) { +1039 +1040 // handling of some important special cases +1041 if (Double.isNaN(d) || Double.isInfinite(d)) { +1042 return d; +1043 } else if (d == 0) { +1044 return (direction < 0) ? -Double.MIN_VALUE : Double.MIN_VALUE; +1045 } +1046 // special cases MAX_VALUE to infinity and MIN_VALUE to 0 +1047 // are handled just as normal numbers +1048 +1049 // split the double in raw components +1050 long bits = Double.doubleToLongBits(d); +1051 long sign = bits & 0x8000000000000000L; +1052 long exponent = bits & 0x7ff0000000000000L; +1053 long mantissa = bits & 0x000fffffffffffffL; +1054 +1055 if (d * (direction - d) >= 0) { +1056 // we should increase the mantissa +1057 if (mantissa == 0x000fffffffffffffL) { +1058 return Double.longBitsToDouble(sign | +1059 (exponent + 0x0010000000000000L)); +1060 } else { +1061 return Double.longBitsToDouble(sign | +1062 exponent | (mantissa + 1)); +1063 } +1064 } else { +1065 // we should decrease the mantissa +1066 if (mantissa == 0L) { +1067 return Double.longBitsToDouble(sign | +1068 (exponent - 0x0010000000000000L) | +1069 0x000fffffffffffffL); +1070 } else { +1071 return Double.longBitsToDouble(sign | +1072 exponent | (mantissa - 1)); +1073 } +1074 } +1075 +1076 } +1077 +1078 /** +1079 * Scale a number by 2<sup>scaleFactor</sup>. +1080 * <p>If <code>d</code> is 0 or NaN or Infinite, it is returned unchanged.</p> +1081 * +1082 * @param d base number +1083 * @param scaleFactor power of two by which d sould be multiplied +1084 * @return d × 2<sup>scaleFactor</sup> +1085 * @since 2.0 +1086 */ +1087 public static double scalb(final double d, final int scaleFactor) { +1088 +1089 // handling of some important special cases +1090 if ((d == 0) || Double.isNaN(d) || Double.isInfinite(d)) { +1091 return d; +1092 } +1093 +1094 // split the double in raw components +1095 final long bits = Double.doubleToLongBits(d); +1096 final long exponent = bits & 0x7ff0000000000000L; +1097 final long rest = bits & 0x800fffffffffffffL; +1098 +1099 // shift the exponent +1100 final long newBits = rest | (exponent + (((long) scaleFactor) << 52)); +1101 return Double.longBitsToDouble(newBits); +1102 +1103 } +1104 +1105 /** +1106 * Normalize an angle in a 2&pi wide interval around a center value. +1107 * <p>This method has three main uses:</p> +1108 * <ul> +1109 * <li>normalize an angle between 0 and 2π:<br/> +1110 * <code>a = MathUtils.normalizeAngle(a, Math.PI);</code></li> +1111 * <li>normalize an angle between -π and +π<br/> +1112 * <code>a = MathUtils.normalizeAngle(a, 0.0);</code></li> +1113 * <li>compute the angle between two defining angular positions:<br> +1114 * <code>angle = MathUtils.normalizeAngle(end, start) - start;</code></li> +1115 * </ul> +1116 * <p>Note that due to numerical accuracy and since π cannot be represented +1117 * exactly, the result interval is <em>closed</em>, it cannot be half-closed +1118 * as would be more satisfactory in a purely mathematical view.</p> +1119 * @param a angle to normalize +1120 * @param center center of the desired 2π interval for the result +1121 * @return a-2kπ with integer k and center-π <= a-2kπ <= center+π +1122 * @since 1.2 +1123 */ +1124 public static double normalizeAngle(double a, double center) { +1125 return a - TWO_PI * Math.floor((a + Math.PI - center) / TWO_PI); +1126 } +1127 +1128 /** +1129 * <p>Normalizes an array to make it sum to a specified value. +1130 * Returns the result of the transformation <pre> +1131 * x |-> x * normalizedSum / sum +1132 * </pre> +1133 * applied to each non-NaN element x of the input array, where sum is the +1134 * sum of the non-NaN entries in the input array.</p> +1135 * +1136 * <p>Throws IllegalArgumentException if <code>normalizedSum</code> is infinite +1137 * or NaN and ArithmeticException if the input array contains any infinite elements +1138 * or sums to 0</p> +1139 * +1140 * <p>Ignores (i.e., copies unchanged to the output array) NaNs in the input array.</p> +1141 * +1142 * @param values input array to be normalized +1143 * @param normalizedSum target sum for the normalized array +1144 * @return normalized array +1145 * @throws ArithmeticException if the input array contains infinite elements or sums to zero +1146 * @throws IllegalArgumentException if the target sum is infinite or NaN +1147 * @since 2.1 +1148 */ +1149 public static double[] normalizeArray(double[] values, double normalizedSum) +1150 throws ArithmeticException, IllegalArgumentException { +1151 if (Double.isInfinite(normalizedSum)) { +1152 throw MathRuntimeException.createIllegalArgumentException( +1153 "Cannot normalize to an infinite value"); +1154 } +1155 if (Double.isNaN(normalizedSum)) { +1156 throw MathRuntimeException.createIllegalArgumentException( +1157 "Cannot normalize to NaN"); +1158 } +1159 double sum = 0d; +1160 final int len = values.length; +1161 double[] out = new double[len]; +1162 for (int i = 0; i < len; i++) { +1163 if (Double.isInfinite(values[i])) { +1164 throw MathRuntimeException.createArithmeticException( +1165 "Array contains an infinite element, {0} at index {1}", values[i], i); +1166 } +1167 if (!Double.isNaN(values[i])) { +1168 sum += values[i]; +1169 } +1170 } +1171 if (sum == 0) { +1172 throw MathRuntimeException.createArithmeticException( +1173 "Array sums to zero"); +1174 } +1175 for (int i = 0; i < len; i++) { +1176 if (Double.isNaN(values[i])) { +1177 out[i] = Double.NaN; +1178 } else { +1179 out[i] = values[i] * normalizedSum / sum; +1180 } +1181 } +1182 return out; +1183 } +1184 +1185 /** +1186 * Round the given value to the specified number of decimal places. The +1187 * value is rounded using the {@link BigDecimal#ROUND_HALF_UP} method. +1188 * +1189 * @param x the value to round. +1190 * @param scale the number of digits to the right of the decimal point. +1191 * @return the rounded value. +1192 * @since 1.1 +1193 */ +1194 public static double round(double x, int scale) { +1195 return round(x, scale, BigDecimal.ROUND_HALF_UP); +1196 } +1197 +1198 /** +1199 * Round the given value to the specified number of decimal places. The +1200 * value is rounded using the given method which is any method defined in +1201 * {@link BigDecimal}. +1202 * +1203 * @param x the value to round. +1204 * @param scale the number of digits to the right of the decimal point. +1205 * @param roundingMethod the rounding method as defined in +1206 * {@link BigDecimal}. +1207 * @return the rounded value. +1208 * @since 1.1 +1209 */ +1210 public static double round(double x, int scale, int roundingMethod) { +1211 try { +1212 return (new BigDecimal +1213 (Double.toString(x)) +1214 .setScale(scale, roundingMethod)) +1215 .doubleValue(); +1216 } catch (NumberFormatException ex) { +1217 if (Double.isInfinite(x)) { +1218 return x; +1219 } else { +1220 return Double.NaN; +1221 } +1222 } +1223 } +1224 +1225 /** +1226 * Round the given value to the specified number of decimal places. The +1227 * value is rounding using the {@link BigDecimal#ROUND_HALF_UP} method. +1228 * +1229 * @param x the value to round. +1230 * @param scale the number of digits to the right of the decimal point. +1231 * @return the rounded value. +1232 * @since 1.1 +1233 */ +1234 public static float round(float x, int scale) { +1235 return round(x, scale, BigDecimal.ROUND_HALF_UP); +1236 } +1237 +1238 /** +1239 * Round the given value to the specified number of decimal places. The +1240 * value is rounded using the given method which is any method defined in +1241 * {@link BigDecimal}. +1242 * +1243 * @param x the value to round. +1244 * @param scale the number of digits to the right of the decimal point. +1245 * @param roundingMethod the rounding method as defined in +1246 * {@link BigDecimal}. +1247 * @return the rounded value. +1248 * @since 1.1 +1249 */ +1250 public static float round(float x, int scale, int roundingMethod) { +1251 float sign = indicator(x); +1252 float factor = (float)Math.pow(10.0f, scale) * sign; +1253 return (float)roundUnscaled(x * factor, sign, roundingMethod) / factor; +1254 } +1255 +1256 /** +1257 * Round the given non-negative, value to the "nearest" integer. Nearest is +1258 * determined by the rounding method specified. Rounding methods are defined +1259 * in {@link BigDecimal}. +1260 * +1261 * @param unscaled the value to round. +1262 * @param sign the sign of the original, scaled value. +1263 * @param roundingMethod the rounding method as defined in +1264 * {@link BigDecimal}. +1265 * @return the rounded value. +1266 * @since 1.1 +1267 */ +1268 private static double roundUnscaled(double unscaled, double sign, +1269 int roundingMethod) { +1270 switch (roundingMethod) { +1271 case BigDecimal.ROUND_CEILING : +1272 if (sign == -1) { +1273 unscaled = Math.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY)); +1274 } else { +1275 unscaled = Math.ceil(nextAfter(unscaled, Double.POSITIVE_INFINITY)); +1276 } +1277 break; +1278 case BigDecimal.ROUND_DOWN : +1279 unscaled = Math.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY)); +1280 break; +1281 case BigDecimal.ROUND_FLOOR : +1282 if (sign == -1) { +1283 unscaled = Math.ceil(nextAfter(unscaled, Double.POSITIVE_INFINITY)); +1284 } else { +1285 unscaled = Math.floor(nextAfter(unscaled, Double.NEGATIVE_INFINITY)); +1286 } +1287 break; +1288 case BigDecimal.ROUND_HALF_DOWN : { +1289 unscaled = nextAfter(unscaled, Double.NEGATIVE_INFINITY); +1290 double fraction = unscaled - Math.floor(unscaled); +1291 if (fraction > 0.5) { +1292 unscaled = Math.ceil(unscaled); +1293 } else { +1294 unscaled = Math.floor(unscaled); +1295 } +1296 break; +1297 } +1298 case BigDecimal.ROUND_HALF_EVEN : { +1299 double fraction = unscaled - Math.floor(unscaled); +1300 if (fraction > 0.5) { +1301 unscaled = Math.ceil(unscaled); +1302 } else if (fraction < 0.5) { +1303 unscaled = Math.floor(unscaled); +1304 } else { +1305 // The following equality test is intentional and needed for rounding purposes +1306 if (Math.floor(unscaled) / 2.0 == Math.floor(Math +1307 .floor(unscaled) / 2.0)) { // even +1308 unscaled = Math.floor(unscaled); +1309 } else { // odd +1310 unscaled = Math.ceil(unscaled); +1311 } +1312 } +1313 break; +1314 } +1315 case BigDecimal.ROUND_HALF_UP : { +1316 unscaled = nextAfter(unscaled, Double.POSITIVE_INFINITY); +1317 double fraction = unscaled - Math.floor(unscaled); +1318 if (fraction >= 0.5) { +1319 unscaled = Math.ceil(unscaled); +1320 } else { +1321 unscaled = Math.floor(unscaled); +1322 } +1323 break; +1324 } +1325 case BigDecimal.ROUND_UNNECESSARY : +1326 if (unscaled != Math.floor(unscaled)) { +1327 throw new ArithmeticException("Inexact result from rounding"); +1328 } +1329 break; +1330 case BigDecimal.ROUND_UP : +1331 unscaled = Math.ceil(nextAfter(unscaled, Double.POSITIVE_INFINITY)); +1332 break; +1333 default : +1334 throw MathRuntimeException.createIllegalArgumentException( +1335 "invalid rounding method {0}, valid methods: {1} ({2}), {3} ({4})," + +1336 " {5} ({6}), {7} ({8}), {9} ({10}), {11} ({12}), {13} ({14}), {15} ({16})", +1337 roundingMethod, +1338 "ROUND_CEILING", BigDecimal.ROUND_CEILING, +1339 "ROUND_DOWN", BigDecimal.ROUND_DOWN, +1340 "ROUND_FLOOR", BigDecimal.ROUND_FLOOR, +1341 "ROUND_HALF_DOWN", BigDecimal.ROUND_HALF_DOWN, +1342 "ROUND_HALF_EVEN", BigDecimal.ROUND_HALF_EVEN, +1343 "ROUND_HALF_UP", BigDecimal.ROUND_HALF_UP, +1344 "ROUND_UNNECESSARY", BigDecimal.ROUND_UNNECESSARY, +1345 "ROUND_UP", BigDecimal.ROUND_UP); +1346 } +1347 return unscaled; +1348 } +1349 +1350 /** +1351 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> +1352 * for byte value <code>x</code>. +1353 * <p> +1354 * For a byte value x, this method returns (byte)(+1) if x > 0, (byte)(0) if +1355 * x = 0, and (byte)(-1) if x < 0.</p> +1356 * +1357 * @param x the value, a byte +1358 * @return (byte)(+1), (byte)(0), or (byte)(-1), depending on the sign of x +1359 */ +1360 public static byte sign(final byte x) { +1361 return (x == ZB) ? ZB : (x > ZB) ? PB : NB; +1362 } +1363 +1364 /** +1365 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> +1366 * for double precision <code>x</code>. +1367 * <p> +1368 * For a double value <code>x</code>, this method returns +1369 * <code>+1.0</code> if <code>x > 0</code>, <code>0.0</code> if +1370 * <code>x = 0.0</code>, and <code>-1.0</code> if <code>x < 0</code>. +1371 * Returns <code>NaN</code> if <code>x</code> is <code>NaN</code>.</p> +1372 * +1373 * @param x the value, a double +1374 * @return +1.0, 0.0, or -1.0, depending on the sign of x +1375 */ +1376 public static double sign(final double x) { +1377 if (Double.isNaN(x)) { +1378 return Double.NaN; +1379 } +1380 return (x == 0.0) ? 0.0 : (x > 0.0) ? 1.0 : -1.0; +1381 } +1382 +1383 /** +1384 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> +1385 * for float value <code>x</code>. +1386 * <p> +1387 * For a float value x, this method returns +1.0F if x > 0, 0.0F if x = +1388 * 0.0F, and -1.0F if x < 0. Returns <code>NaN</code> if <code>x</code> +1389 * is <code>NaN</code>.</p> +1390 * +1391 * @param x the value, a float +1392 * @return +1.0F, 0.0F, or -1.0F, depending on the sign of x +1393 */ +1394 public static float sign(final float x) { +1395 if (Float.isNaN(x)) { +1396 return Float.NaN; +1397 } +1398 return (x == 0.0F) ? 0.0F : (x > 0.0F) ? 1.0F : -1.0F; +1399 } +1400 +1401 /** +1402 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> +1403 * for int value <code>x</code>. +1404 * <p> +1405 * For an int value x, this method returns +1 if x > 0, 0 if x = 0, and -1 +1406 * if x < 0.</p> +1407 * +1408 * @param x the value, an int +1409 * @return +1, 0, or -1, depending on the sign of x +1410 */ +1411 public static int sign(final int x) { +1412 return (x == 0) ? 0 : (x > 0) ? 1 : -1; +1413 } +1414 +1415 /** +1416 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> +1417 * for long value <code>x</code>. +1418 * <p> +1419 * For a long value x, this method returns +1L if x > 0, 0L if x = 0, and +1420 * -1L if x < 0.</p> +1421 * +1422 * @param x the value, a long +1423 * @return +1L, 0L, or -1L, depending on the sign of x +1424 */ +1425 public static long sign(final long x) { +1426 return (x == 0L) ? 0L : (x > 0L) ? 1L : -1L; +1427 } +1428 +1429 /** +1430 * Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a> +1431 * for short value <code>x</code>. +1432 * <p> +1433 * For a short value x, this method returns (short)(+1) if x > 0, (short)(0) +1434 * if x = 0, and (short)(-1) if x < 0.</p> +1435 * +1436 * @param x the value, a short +1437 * @return (short)(+1), (short)(0), or (short)(-1), depending on the sign of +1438 * x +1439 */ +1440 public static short sign(final short x) { +1441 return (x == ZS) ? ZS : (x > ZS) ? PS : NS; +1442 } +1443 +1444 /** +1445 * Returns the <a href="http://mathworld.wolfram.com/HyperbolicSine.html"> +1446 * hyperbolic sine</a> of x. +1447 * +1448 * @param x double value for which to find the hyperbolic sine +1449 * @return hyperbolic sine of x +1450 */ +1451 public static double sinh(double x) { +1452 return (Math.exp(x) - Math.exp(-x)) / 2.0; +1453 } +1454 +1455 /** +1456 * Subtract two integers, checking for overflow. +1457 * +1458 * @param x the minuend +1459 * @param y the subtrahend +1460 * @return the difference <code>x-y</code> +1461 * @throws ArithmeticException if the result can not be represented as an +1462 * int +1463 * @since 1.1 +1464 */ +1465 public static int subAndCheck(int x, int y) { +1466 long s = (long)x - (long)y; +1467 if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) { +1468 throw new ArithmeticException("overflow: subtract"); +1469 } +1470 return (int)s; +1471 } +1472 +1473 /** +1474 * Subtract two long integers, checking for overflow. +1475 * +1476 * @param a first value +1477 * @param b second value +1478 * @return the difference <code>a-b</code> +1479 * @throws ArithmeticException if the result can not be represented as an +1480 * long +1481 * @since 1.2 +1482 */ +1483 public static long subAndCheck(long a, long b) { +1484 long ret; +1485 String msg = "overflow: subtract"; +1486 if (b == Long.MIN_VALUE) { +1487 if (a < 0) { +1488 ret = a - b; +1489 } else { +1490 throw new ArithmeticException(msg); +1491 } +1492 } else { +1493 // use additive inverse +1494 ret = addAndCheck(a, -b, msg); +1495 } +1496 return ret; +1497 } +1498 +1499 /** +1500 * Raise an int to an int power. +1501 * @param k number to raise +1502 * @param e exponent (must be positive or null) +1503 * @return k<sup>e</sup> +1504 * @exception IllegalArgumentException if e is negative +1505 */ +1506 public static int pow(final int k, int e) +1507 throws IllegalArgumentException { +1508 +1509 if (e < 0) { +1510 throw MathRuntimeException.createIllegalArgumentException( +1511 "cannot raise an integral value to a negative power ({0}^{1})", +1512 k, e); +1513 } +1514 +1515 int result = 1; +1516 int k2p = k; +1517 while (e != 0) { +1518 if ((e & 0x1) != 0) { +1519 result *= k2p; +1520 } +1521 k2p *= k2p; +1522 e = e >> 1; +1523 } +1524 +1525 return result; +1526 +1527 } +1528 +1529 /** +1530 * Raise an int to a long power. +1531 * @param k number to raise +1532 * @param e exponent (must be positive or null) +1533 * @return k<sup>e</sup> +1534 * @exception IllegalArgumentException if e is negative +1535 */ +1536 public static int pow(final int k, long e) +1537 throws IllegalArgumentException { +1538 +1539 if (e < 0) { +1540 throw MathRuntimeException.createIllegalArgumentException( +1541 "cannot raise an integral value to a negative power ({0}^{1})", +1542 k, e); +1543 } +1544 +1545 int result = 1; +1546 int k2p = k; +1547 while (e != 0) { +1548 if ((e & 0x1) != 0) { +1549 result *= k2p; +1550 } +1551 k2p *= k2p; +1552 e = e >> 1; +1553 } +1554 +1555 return result; +1556 +1557 } +1558 +1559 /** +1560 * Raise a long to an int power. +1561 * @param k number to raise +1562 * @param e exponent (must be positive or null) +1563 * @return k<sup>e</sup> +1564 * @exception IllegalArgumentException if e is negative +1565 */ +1566 public static long pow(final long k, int e) +1567 throws IllegalArgumentException { +1568 +1569 if (e < 0) { +1570 throw MathRuntimeException.createIllegalArgumentException( +1571 "cannot raise an integral value to a negative power ({0}^{1})", +1572 k, e); +1573 } +1574 +1575 long result = 1l; +1576 long k2p = k; +1577 while (e != 0) { +1578 if ((e & 0x1) != 0) { +1579 result *= k2p; +1580 } +1581 k2p *= k2p; +1582 e = e >> 1; +1583 } +1584 +1585 return result; +1586 +1587 } +1588 +1589 /** +1590 * Raise a long to a long power. +1591 * @param k number to raise +1592 * @param e exponent (must be positive or null) +1593 * @return k<sup>e</sup> +1594 * @exception IllegalArgumentException if e is negative +1595 */ +1596 public static long pow(final long k, long e) +1597 throws IllegalArgumentException { +1598 +1599 if (e < 0) { +1600 throw MathRuntimeException.createIllegalArgumentException( +1601 "cannot raise an integral value to a negative power ({0}^{1})", +1602 k, e); +1603 } +1604 +1605 long result = 1l; +1606 long k2p = k; +1607 while (e != 0) { +1608 if ((e & 0x1) != 0) { +1609 result *= k2p; +1610 } +1611 k2p *= k2p; +1612 e = e >> 1; +1613 } +1614 +1615 return result; +1616 +1617 } +1618 +1619 /** +1620 * Raise a BigInteger to an int power. +1621 * @param k number to raise +1622 * @param e exponent (must be positive or null) +1623 * @return k<sup>e</sup> +1624 * @exception IllegalArgumentException if e is negative +1625 */ +1626 public static BigInteger pow(final BigInteger k, int e) +1627 throws IllegalArgumentException { +1628 +1629 if (e < 0) { +1630 throw MathRuntimeException.createIllegalArgumentException( +1631 "cannot raise an integral value to a negative power ({0}^{1})", +1632 k, e); +1633 } +1634 +1635 return k.pow(e); +1636 +1637 } +1638 +1639 /** +1640 * Raise a BigInteger to a long power. +1641 * @param k number to raise +1642 * @param e exponent (must be positive or null) +1643 * @return k<sup>e</sup> +1644 * @exception IllegalArgumentException if e is negative +1645 */ +1646 public static BigInteger pow(final BigInteger k, long e) +1647 throws IllegalArgumentException { +1648 +1649 if (e < 0) { +1650 throw MathRuntimeException.createIllegalArgumentException( +1651 "cannot raise an integral value to a negative power ({0}^{1})", +1652 k, e); +1653 } +1654 +1655 BigInteger result = BigInteger.ONE; +1656 BigInteger k2p = k; +1657 while (e != 0) { +1658 if ((e & 0x1) != 0) { +1659 result = result.multiply(k2p); +1660 } +1661 k2p = k2p.multiply(k2p); +1662 e = e >> 1; +1663 } +1664 +1665 return result; +1666 +1667 } +1668 +1669 /** +1670 * Raise a BigInteger to a BigInteger power. +1671 * @param k number to raise +1672 * @param e exponent (must be positive or null) +1673 * @return k<sup>e</sup> +1674 * @exception IllegalArgumentException if e is negative +1675 */ +1676 public static BigInteger pow(final BigInteger k, BigInteger e) +1677 throws IllegalArgumentException { +1678 +1679 if (e.compareTo(BigInteger.ZERO) < 0) { +1680 throw MathRuntimeException.createIllegalArgumentException( +1681 "cannot raise an integral value to a negative power ({0}^{1})", +1682 k, e); +1683 } +1684 +1685 BigInteger result = BigInteger.ONE; +1686 BigInteger k2p = k; +1687 while (!BigInteger.ZERO.equals(e)) { +1688 if (e.testBit(0)) { +1689 result = result.multiply(k2p); +1690 } +1691 k2p = k2p.multiply(k2p); +1692 e = e.shiftRight(1); +1693 } +1694 +1695 return result; +1696 +1697 } +1698 +1699 /** +1700 * Calculates the L<sub>1</sub> (sum of abs) distance between two points. +1701 * +1702 * @param p1 the first point +1703 * @param p2 the second point +1704 * @return the L<sub>1</sub> distance between the two points +1705 */ +1706 public static double distance1(double[] p1, double[] p2) { +1707 double sum = 0; +1708 for (int i = 0; i < p1.length; i++) { +1709 sum += Math.abs(p1[i] - p2[i]); +1710 } +1711 return sum; +1712 } +1713 +1714 /** +1715 * Calculates the L<sub>1</sub> (sum of abs) distance between two points. +1716 * +1717 * @param p1 the first point +1718 * @param p2 the second point +1719 * @return the L<sub>1</sub> distance between the two points +1720 */ +1721 public static int distance1(int[] p1, int[] p2) { +1722 int sum = 0; +1723 for (int i = 0; i < p1.length; i++) { +1724 sum += Math.abs(p1[i] - p2[i]); +1725 } +1726 return sum; +1727 } +1728 +1729 /** +1730 * Calculates the L<sub>2</sub> (Euclidean) distance between two points. +1731 * +1732 * @param p1 the first point +1733 * @param p2 the second point +1734 * @return the L<sub>2</sub> distance between the two points +1735 */ +1736 public static double distance(double[] p1, double[] p2) { +1737 double sum = 0; +1738 for (int i = 0; i < p1.length; i++) { +1739 final double dp = p1[i] - p2[i]; +1740 sum += dp * dp; +1741 } +1742 return Math.sqrt(sum); +1743 } +1744 +1745 /** +1746 * Calculates the L<sub>2</sub> (Euclidean) distance between two points. +1747 * +1748 * @param p1 the first point +1749 * @param p2 the second point +1750 * @return the L<sub>2</sub> distance between the two points +1751 */ +1752 public static double distance(int[] p1, int[] p2) { +1753 double sum = 0; +1754 for (int i = 0; i < p1.length; i++) { +1755 final double dp = p1[i] - p2[i]; +1756 sum += dp * dp; +1757 } +1758 return Math.sqrt(sum); +1759 } +1760 +1761 /** +1762 * Calculates the L<sub>∞</sub> (max of abs) distance between two points. +1763 * +1764 * @param p1 the first point +1765 * @param p2 the second point +1766 * @return the L<sub>∞</sub> distance between the two points +1767 */ +1768 public static double distanceInf(double[] p1, double[] p2) { +1769 double max = 0; +1770 for (int i = 0; i < p1.length; i++) { +1771 max = Math.max(max, Math.abs(p1[i] - p2[i])); +1772 } +1773 return max; +1774 } +1775 +1776 /** +1777 * Calculates the L<sub>∞</sub> (max of abs) distance between two points. +1778 * +1779 * @param p1 the first point +1780 * @param p2 the second point +1781 * @return the L<sub>∞</sub> distance between the two points +1782 */ +1783 public static int distanceInf(int[] p1, int[] p2) { +1784 int max = 0; +1785 for (int i = 0; i < p1.length; i++) { +1786 max = Math.max(max, Math.abs(p1[i] - p2[i])); +1787 } +1788 return max; +1789 } +1790 +1791 /** +1792 * Checks that the given array is sorted. +1793 * +1794 * @param val Values +1795 * @param dir Order direction (-1 for decreasing, 1 for increasing) +1796 * @param strict Whether the order should be strict +1797 * @throws IllegalArgumentException if the array is not sorted. +1798 */ +1799 public static void checkOrder(double[] val, int dir, boolean strict) { +1800 double previous = val[0]; +1801 +1802 int max = val.length; +1803 for (int i = 1; i < max; i++) { +1804 if (dir > 0) { +1805 if (strict) { +1806 if (val[i] <= previous) { +1807 throw MathRuntimeException.createIllegalArgumentException("points {0} and {1} are not strictly increasing ({2} >= {3})", +1808 i - 1, i, previous, val[i]); +1809 } +1810 } else { +1811 if (val[i] < previous) { +1812 throw MathRuntimeException.createIllegalArgumentException("points {0} and {1} are not increasing ({2} > {3})", +1813 i - 1, i, previous, val[i]); +1814 } +1815 } +1816 } else { +1817 if (strict) { +1818 if (val[i] >= previous) { +1819 throw MathRuntimeException.createIllegalArgumentException("points {0} and {1} are not strictly decreasing ({2} <= {3})", +1820 i - 1, i, previous, val[i]); +1821 } +1822 } else { +1823 if (val[i] > previous) { +1824 throw MathRuntimeException.createIllegalArgumentException("points {0} and {1} are not decreasing ({2} < {3})", +1825 i - 1, i, previous, val[i]); +1826 } +1827 } +1828 } +1829 +1830 previous = val[i]; +1831 } +1832 } +1833 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/NumberTransformer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/NumberTransformer.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,105 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.util; +018 +019 import org.apache.commons.math.MathException; +020 +021 /** +022 * Subclasses implementing this interface can transform Objects to doubles. +023 * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $ +024 * +025 * No longer extends Serializable since 2.0 +026 * +027 */ +028 public interface NumberTransformer { +029 +030 /** +031 * Implementing this interface provides a facility to transform +032 * from Object to Double. +033 * +034 * @param o the Object to be transformed. +035 * @return the double value of the Object. +036 * @throws MathException if the Object can not be transformed into a Double. +037 */ +038 double transform(Object o) throws MathException; +039 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/OpenIntToDoubleHashMap.Iterator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/OpenIntToDoubleHashMap.Iterator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,676 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.util; +019 +020 import java.io.IOException; +021 import java.io.ObjectInputStream; +022 import java.io.Serializable; +023 import java.util.ConcurrentModificationException; +024 import java.util.NoSuchElementException; +025 +026 import org.apache.commons.math.MathRuntimeException; +027 +028 /** +029 * Open addressed map from int to double. +030 * <p>This class provides a dedicated map from integers to doubles with a +031 * much smaller memory overhead than standard <code>java.util.Map</code>.</p> +032 * <p>This class is not synchronized. The specialized iterators returned by +033 * {@link #iterator()} are fail-fast: they throw a +034 * <code>ConcurrentModificationException</code> when they detect the map has been +035 * modified during iteration.</p> +036 * @version $Revision: 885278 $ $Date: 2009-11-29 16:47:51 -0500 (Sun, 29 Nov 2009) $ +037 * @since 2.0 +038 */ +039 public class OpenIntToDoubleHashMap implements Serializable { +040 +041 /** Status indicator for free table entries. */ +042 protected static final byte FREE = 0; +043 +044 /** Status indicator for full table entries. */ +045 protected static final byte FULL = 1; +046 +047 /** Status indicator for removed table entries. */ +048 protected static final byte REMOVED = 2; +049 +050 /** Serializable version identifier */ +051 private static final long serialVersionUID = -3646337053166149105L; +052 +053 /** Message for map modification during iteration. */ +054 private static final String CONCURRENT_MODIFICATION_MESSAGE = +055 "map has been modified while iterating"; +056 +057 /** Message for exhausted iterator. */ +058 private static final String EXHAUSTED_ITERATOR_MESSAGE = +059 "iterator exhausted"; +060 +061 /** Load factor for the map. */ +062 private static final float LOAD_FACTOR = 0.5f; +063 +064 /** Default starting size. +065 * <p>This must be a power of two for bit mask to work properly. </p> +066 */ +067 private static final int DEFAULT_EXPECTED_SIZE = 16; +068 +069 /** Multiplier for size growth when map fills up. +070 * <p>This must be a power of two for bit mask to work properly. </p> +071 */ +072 private static final int RESIZE_MULTIPLIER = 2; +073 +074 /** Number of bits to perturb the index when probing for collision resolution. */ +075 private static final int PERTURB_SHIFT = 5; +076 +077 /** Keys table. */ +078 private int[] keys; +079 +080 /** Values table. */ +081 private double[] values; +082 +083 /** States table. */ +084 private byte[] states; +085 +086 /** Return value for missing entries. */ +087 private final double missingEntries; +088 +089 /** Current size of the map. */ +090 private int size; +091 +092 /** Bit mask for hash values. */ +093 private int mask; +094 +095 /** Modifications count. */ +096 private transient int count; +097 +098 /** +099 * Build an empty map with default size and using NaN for missing entries. +100 */ +101 public OpenIntToDoubleHashMap() { +102 this(DEFAULT_EXPECTED_SIZE, Double.NaN); +103 } +104 +105 /** +106 * Build an empty map with default size +107 * @param missingEntries value to return when a missing entry is fetched +108 */ +109 public OpenIntToDoubleHashMap(final double missingEntries) { +110 this(DEFAULT_EXPECTED_SIZE, missingEntries); +111 } +112 +113 /** +114 * Build an empty map with specified size and using NaN for missing entries. +115 * @param expectedSize expected number of elements in the map +116 */ +117 public OpenIntToDoubleHashMap(final int expectedSize) { +118 this(expectedSize, Double.NaN); +119 } +120 +121 /** +122 * Build an empty map with specified size. +123 * @param expectedSize expected number of elements in the map +124 * @param missingEntries value to return when a missing entry is fetched +125 */ +126 public OpenIntToDoubleHashMap(final int expectedSize, +127 final double missingEntries) { +128 final int capacity = computeCapacity(expectedSize); +129 keys = new int[capacity]; +130 values = new double[capacity]; +131 states = new byte[capacity]; +132 this.missingEntries = missingEntries; +133 mask = capacity - 1; +134 } +135 +136 /** +137 * Copy constructor. +138 * @param source map to copy +139 */ +140 public OpenIntToDoubleHashMap(final OpenIntToDoubleHashMap source) { +141 final int length = source.keys.length; +142 keys = new int[length]; +143 System.arraycopy(source.keys, 0, keys, 0, length); +144 values = new double[length]; +145 System.arraycopy(source.values, 0, values, 0, length); +146 states = new byte[length]; +147 System.arraycopy(source.states, 0, states, 0, length); +148 missingEntries = source.missingEntries; +149 size = source.size; +150 mask = source.mask; +151 count = source.count; +152 } +153 +154 /** +155 * Compute the capacity needed for a given size. +156 * @param expectedSize expected size of the map +157 * @return capacity to use for the specified size +158 */ +159 private static int computeCapacity(final int expectedSize) { +160 if (expectedSize == 0) { +161 return 1; +162 } +163 final int capacity = (int) Math.ceil(expectedSize / LOAD_FACTOR); +164 final int powerOfTwo = Integer.highestOneBit(capacity); +165 if (powerOfTwo == capacity) { +166 return capacity; +167 } +168 return nextPowerOfTwo(capacity); +169 } +170 +171 /** +172 * Find the smallest power of two greater than the input value +173 * @param i input value +174 * @return smallest power of two greater than the input value +175 */ +176 private static int nextPowerOfTwo(final int i) { +177 return Integer.highestOneBit(i) << 1; +178 } +179 +180 /** +181 * Get the stored value associated with the given key +182 * @param key key associated with the data +183 * @return data associated with the key +184 */ +185 public double get(final int key) { +186 +187 final int hash = hashOf(key); +188 int index = hash & mask; +189 if (containsKey(key, index)) { +190 return values[index]; +191 } +192 +193 if (states[index] == FREE) { +194 return missingEntries; +195 } +196 +197 int j = index; +198 for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { +199 j = probe(perturb, j); +200 index = j & mask; +201 if (containsKey(key, index)) { +202 return values[index]; +203 } +204 } +205 +206 return missingEntries; +207 +208 } +209 +210 /** +211 * Check if a value is associated with a key. +212 * @param key key to check +213 * @return true if a value is associated with key +214 */ +215 public boolean containsKey(final int key) { +216 +217 final int hash = hashOf(key); +218 int index = hash & mask; +219 if (containsKey(key, index)) { +220 return true; +221 } +222 +223 if (states[index] == FREE) { +224 return false; +225 } +226 +227 int j = index; +228 for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { +229 j = probe(perturb, j); +230 index = j & mask; +231 if (containsKey(key, index)) { +232 return true; +233 } +234 } +235 +236 return false; +237 +238 } +239 +240 /** +241 * Get an iterator over map elements. +242 * <p>The specialized iterators returned are fail-fast: they throw a +243 * <code>ConcurrentModificationException</code> when they detect the map +244 * has been modified during iteration.</p> +245 * @return iterator over the map elements +246 */ +247 public Iterator iterator() { +248 return new Iterator(); +249 } +250 +251 /** +252 * Perturb the hash for starting probing. +253 * @param hash initial hash +254 * @return perturbed hash +255 */ +256 private static int perturb(final int hash) { +257 return hash & 0x7fffffff; +258 } +259 +260 /** +261 * Find the index at which a key should be inserted +262 * @param key key to lookup +263 * @return index at which key should be inserted +264 */ +265 private int findInsertionIndex(final int key) { +266 return findInsertionIndex(keys, states, key, mask); +267 } +268 +269 /** +270 * Find the index at which a key should be inserted +271 * @param keys keys table +272 * @param states states table +273 * @param key key to lookup +274 * @param mask bit mask for hash values +275 * @return index at which key should be inserted +276 */ +277 private static int findInsertionIndex(final int[] keys, final byte[] states, +278 final int key, final int mask) { +279 final int hash = hashOf(key); +280 int index = hash & mask; +281 if (states[index] == FREE) { +282 return index; +283 } else if (states[index] == FULL && keys[index] == key) { +284 return changeIndexSign(index); +285 } +286 +287 int perturb = perturb(hash); +288 int j = index; +289 if (states[index] == FULL) { +290 while (true) { +291 j = probe(perturb, j); +292 index = j & mask; +293 perturb >>= PERTURB_SHIFT; +294 +295 if (states[index] != FULL || keys[index] == key) { +296 break; +297 } +298 } +299 } +300 +301 if (states[index] == FREE) { +302 return index; +303 } else if (states[index] == FULL) { +304 // due to the loop exit condition, +305 // if (states[index] == FULL) then keys[index] == key +306 return changeIndexSign(index); +307 } +308 +309 final int firstRemoved = index; +310 while (true) { +311 j = probe(perturb, j); +312 index = j & mask; +313 +314 if (states[index] == FREE) { +315 return firstRemoved; +316 } else if (states[index] == FULL && keys[index] == key) { +317 return changeIndexSign(index); +318 } +319 +320 perturb >>= PERTURB_SHIFT; +321 +322 } +323 +324 } +325 +326 /** +327 * Compute next probe for collision resolution +328 * @param perturb perturbed hash +329 * @param j previous probe +330 * @return next probe +331 */ +332 private static int probe(final int perturb, final int j) { +333 return (j << 2) + j + perturb + 1; +334 } +335 +336 /** +337 * Change the index sign +338 * @param index initial index +339 * @return changed index +340 */ +341 private static int changeIndexSign(final int index) { +342 return -index - 1; +343 } +344 +345 /** +346 * Get the number of elements stored in the map. +347 * @return number of elements stored in the map +348 */ +349 public int size() { +350 return size; +351 } +352 +353 +354 /** +355 * Remove the value associated with a key. +356 * @param key key to which the value is associated +357 * @return removed value +358 */ +359 public double remove(final int key) { +360 +361 final int hash = hashOf(key); +362 int index = hash & mask; +363 if (containsKey(key, index)) { +364 return doRemove(index); +365 } +366 +367 if (states[index] == FREE) { +368 return missingEntries; +369 } +370 +371 int j = index; +372 for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { +373 j = probe(perturb, j); +374 index = j & mask; +375 if (containsKey(key, index)) { +376 return doRemove(index); +377 } +378 } +379 +380 return missingEntries; +381 +382 } +383 +384 /** +385 * Check if the tables contain an element associated with specified key +386 * at specified index. +387 * @param key key to check +388 * @param index index to check +389 * @return true if an element is associated with key at index +390 */ +391 private boolean containsKey(final int key, final int index) { +392 return (key != 0 || states[index] == FULL) && keys[index] == key; +393 } +394 +395 /** +396 * Remove an element at specified index. +397 * @param index index of the element to remove +398 * @return removed value +399 */ +400 private double doRemove(int index) { +401 keys[index] = 0; +402 states[index] = REMOVED; +403 final double previous = values[index]; +404 values[index] = missingEntries; +405 --size; +406 ++count; +407 return previous; +408 } +409 +410 /** +411 * Put a value associated with a key in the map. +412 * @param key key to which value is associated +413 * @param value value to put in the map +414 * @return previous value associated with the key +415 */ +416 public double put(final int key, final double value) { +417 int index = findInsertionIndex(key); +418 double previous = missingEntries; +419 boolean newMapping = true; +420 if (index < 0) { +421 index = changeIndexSign(index); +422 previous = values[index]; +423 newMapping = false; +424 } +425 keys[index] = key; +426 states[index] = FULL; +427 values[index] = value; +428 if (newMapping) { +429 ++size; +430 if (shouldGrowTable()) { +431 growTable(); +432 } +433 ++count; +434 } +435 return previous; +436 +437 } +438 +439 /** +440 * Grow the tables. +441 */ +442 private void growTable() { +443 +444 final int oldLength = states.length; +445 final int[] oldKeys = keys; +446 final double[] oldValues = values; +447 final byte[] oldStates = states; +448 +449 final int newLength = RESIZE_MULTIPLIER * oldLength; +450 final int[] newKeys = new int[newLength]; +451 final double[] newValues = new double[newLength]; +452 final byte[] newStates = new byte[newLength]; +453 final int newMask = newLength - 1; +454 for (int i = 0; i < oldLength; ++i) { +455 if (oldStates[i] == FULL) { +456 final int key = oldKeys[i]; +457 final int index = findInsertionIndex(newKeys, newStates, key, newMask); +458 newKeys[index] = key; +459 newValues[index] = oldValues[i]; +460 newStates[index] = FULL; +461 } +462 } +463 +464 mask = newMask; +465 keys = newKeys; +466 values = newValues; +467 states = newStates; +468 +469 } +470 +471 /** +472 * Check if tables should grow due to increased size. +473 * @return true if tables should grow +474 */ +475 private boolean shouldGrowTable() { +476 return size > (mask + 1) * LOAD_FACTOR; +477 } +478 +479 /** +480 * Compute the hash value of a key +481 * @param key key to hash +482 * @return hash value of the key +483 */ +484 private static int hashOf(final int key) { +485 final int h = key ^ ((key >>> 20) ^ (key >>> 12)); +486 return h ^ (h >>> 7) ^ (h >>> 4); +487 } +488 +489 +490 /** Iterator class for the map. */ +491 public class Iterator { +492 +493 /** Reference modification count. */ +494 private final int referenceCount; +495 +496 /** Index of current element. */ +497 private int current; +498 +499 /** Index of next element. */ +500 private int next; +501 +502 /** +503 * Simple constructor. +504 */ +505 private Iterator() { +506 +507 // preserve the modification count of the map to detect concurrent modifications later +508 referenceCount = count; +509 +510 // initialize current index +511 next = -1; +512 try { +513 advance(); +514 } catch (NoSuchElementException nsee) { +515 // ignored +516 } +517 +518 } +519 +520 /** +521 * Check if there is a next element in the map. +522 * @return true if there is a next element +523 */ +524 public boolean hasNext() { +525 return next >= 0; +526 } +527 +528 /** +529 * Get the key of current entry. +530 * @return key of current entry +531 * @exception ConcurrentModificationException if the map is modified during iteration +532 * @exception NoSuchElementException if there is no element left in the map +533 */ +534 public int key() +535 throws ConcurrentModificationException, NoSuchElementException { +536 if (referenceCount != count) { +537 throw MathRuntimeException.createConcurrentModificationException( +538 CONCURRENT_MODIFICATION_MESSAGE); +539 } +540 if (current < 0) { +541 throw MathRuntimeException.createNoSuchElementException(EXHAUSTED_ITERATOR_MESSAGE); +542 } +543 return keys[current]; +544 } +545 +546 /** +547 * Get the value of current entry. +548 * @return value of current entry +549 * @exception ConcurrentModificationException if the map is modified during iteration +550 * @exception NoSuchElementException if there is no element left in the map +551 */ +552 public double value() +553 throws ConcurrentModificationException, NoSuchElementException { +554 if (referenceCount != count) { +555 throw MathRuntimeException.createConcurrentModificationException( +556 CONCURRENT_MODIFICATION_MESSAGE); +557 } +558 if (current < 0) { +559 throw MathRuntimeException.createNoSuchElementException(EXHAUSTED_ITERATOR_MESSAGE); +560 } +561 return values[current]; +562 } +563 +564 /** +565 * Advance iterator one step further. +566 * @exception ConcurrentModificationException if the map is modified during iteration +567 * @exception NoSuchElementException if there is no element left in the map +568 */ +569 public void advance() +570 throws ConcurrentModificationException, NoSuchElementException { +571 +572 if (referenceCount != count) { +573 throw MathRuntimeException.createConcurrentModificationException( +574 CONCURRENT_MODIFICATION_MESSAGE); +575 } +576 +577 // advance on step +578 current = next; +579 +580 // prepare next step +581 try { +582 while (states[++next] != FULL) { +583 // nothing to do +584 } +585 } catch (ArrayIndexOutOfBoundsException e) { +586 next = -2; +587 if (current < 0) { +588 throw MathRuntimeException.createNoSuchElementException(EXHAUSTED_ITERATOR_MESSAGE); +589 } +590 } +591 +592 } +593 +594 } +595 +596 /** +597 * Read a serialized object. +598 * @param stream input stream +599 * @throws IOException if object cannot be read +600 * @throws ClassNotFoundException if the class corresponding +601 * to the serialized object cannot be found +602 */ +603 private void readObject(final ObjectInputStream stream) +604 throws IOException, ClassNotFoundException { +605 stream.defaultReadObject(); +606 count = 0; +607 } +608 +609 +610 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/OpenIntToDoubleHashMap.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/OpenIntToDoubleHashMap.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,676 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 +018 package org.apache.commons.math.util; +019 +020 import java.io.IOException; +021 import java.io.ObjectInputStream; +022 import java.io.Serializable; +023 import java.util.ConcurrentModificationException; +024 import java.util.NoSuchElementException; +025 +026 import org.apache.commons.math.MathRuntimeException; +027 +028 /** +029 * Open addressed map from int to double. +030 * <p>This class provides a dedicated map from integers to doubles with a +031 * much smaller memory overhead than standard <code>java.util.Map</code>.</p> +032 * <p>This class is not synchronized. The specialized iterators returned by +033 * {@link #iterator()} are fail-fast: they throw a +034 * <code>ConcurrentModificationException</code> when they detect the map has been +035 * modified during iteration.</p> +036 * @version $Revision: 885278 $ $Date: 2009-11-29 16:47:51 -0500 (Sun, 29 Nov 2009) $ +037 * @since 2.0 +038 */ +039 public class OpenIntToDoubleHashMap implements Serializable { +040 +041 /** Status indicator for free table entries. */ +042 protected static final byte FREE = 0; +043 +044 /** Status indicator for full table entries. */ +045 protected static final byte FULL = 1; +046 +047 /** Status indicator for removed table entries. */ +048 protected static final byte REMOVED = 2; +049 +050 /** Serializable version identifier */ +051 private static final long serialVersionUID = -3646337053166149105L; +052 +053 /** Message for map modification during iteration. */ +054 private static final String CONCURRENT_MODIFICATION_MESSAGE = +055 "map has been modified while iterating"; +056 +057 /** Message for exhausted iterator. */ +058 private static final String EXHAUSTED_ITERATOR_MESSAGE = +059 "iterator exhausted"; +060 +061 /** Load factor for the map. */ +062 private static final float LOAD_FACTOR = 0.5f; +063 +064 /** Default starting size. +065 * <p>This must be a power of two for bit mask to work properly. </p> +066 */ +067 private static final int DEFAULT_EXPECTED_SIZE = 16; +068 +069 /** Multiplier for size growth when map fills up. +070 * <p>This must be a power of two for bit mask to work properly. </p> +071 */ +072 private static final int RESIZE_MULTIPLIER = 2; +073 +074 /** Number of bits to perturb the index when probing for collision resolution. */ +075 private static final int PERTURB_SHIFT = 5; +076 +077 /** Keys table. */ +078 private int[] keys; +079 +080 /** Values table. */ +081 private double[] values; +082 +083 /** States table. */ +084 private byte[] states; +085 +086 /** Return value for missing entries. */ +087 private final double missingEntries; +088 +089 /** Current size of the map. */ +090 private int size; +091 +092 /** Bit mask for hash values. */ +093 private int mask; +094 +095 /** Modifications count. */ +096 private transient int count; +097 +098 /** +099 * Build an empty map with default size and using NaN for missing entries. +100 */ +101 public OpenIntToDoubleHashMap() { +102 this(DEFAULT_EXPECTED_SIZE, Double.NaN); +103 } +104 +105 /** +106 * Build an empty map with default size +107 * @param missingEntries value to return when a missing entry is fetched +108 */ +109 public OpenIntToDoubleHashMap(final double missingEntries) { +110 this(DEFAULT_EXPECTED_SIZE, missingEntries); +111 } +112 +113 /** +114 * Build an empty map with specified size and using NaN for missing entries. +115 * @param expectedSize expected number of elements in the map +116 */ +117 public OpenIntToDoubleHashMap(final int expectedSize) { +118 this(expectedSize, Double.NaN); +119 } +120 +121 /** +122 * Build an empty map with specified size. +123 * @param expectedSize expected number of elements in the map +124 * @param missingEntries value to return when a missing entry is fetched +125 */ +126 public OpenIntToDoubleHashMap(final int expectedSize, +127 final double missingEntries) { +128 final int capacity = computeCapacity(expectedSize); +129 keys = new int[capacity]; +130 values = new double[capacity]; +131 states = new byte[capacity]; +132 this.missingEntries = missingEntries; +133 mask = capacity - 1; +134 } +135 +136 /** +137 * Copy constructor. +138 * @param source map to copy +139 */ +140 public OpenIntToDoubleHashMap(final OpenIntToDoubleHashMap source) { +141 final int length = source.keys.length; +142 keys = new int[length]; +143 System.arraycopy(source.keys, 0, keys, 0, length); +144 values = new double[length]; +145 System.arraycopy(source.values, 0, values, 0, length); +146 states = new byte[length]; +147 System.arraycopy(source.states, 0, states, 0, length); +148 missingEntries = source.missingEntries; +149 size = source.size; +150 mask = source.mask; +151 count = source.count; +152 } +153 +154 /** +155 * Compute the capacity needed for a given size. +156 * @param expectedSize expected size of the map +157 * @return capacity to use for the specified size +158 */ +159 private static int computeCapacity(final int expectedSize) { +160 if (expectedSize == 0) { +161 return 1; +162 } +163 final int capacity = (int) Math.ceil(expectedSize / LOAD_FACTOR); +164 final int powerOfTwo = Integer.highestOneBit(capacity); +165 if (powerOfTwo == capacity) { +166 return capacity; +167 } +168 return nextPowerOfTwo(capacity); +169 } +170 +171 /** +172 * Find the smallest power of two greater than the input value +173 * @param i input value +174 * @return smallest power of two greater than the input value +175 */ +176 private static int nextPowerOfTwo(final int i) { +177 return Integer.highestOneBit(i) << 1; +178 } +179 +180 /** +181 * Get the stored value associated with the given key +182 * @param key key associated with the data +183 * @return data associated with the key +184 */ +185 public double get(final int key) { +186 +187 final int hash = hashOf(key); +188 int index = hash & mask; +189 if (containsKey(key, index)) { +190 return values[index]; +191 } +192 +193 if (states[index] == FREE) { +194 return missingEntries; +195 } +196 +197 int j = index; +198 for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { +199 j = probe(perturb, j); +200 index = j & mask; +201 if (containsKey(key, index)) { +202 return values[index]; +203 } +204 } +205 +206 return missingEntries; +207 +208 } +209 +210 /** +211 * Check if a value is associated with a key. +212 * @param key key to check +213 * @return true if a value is associated with key +214 */ +215 public boolean containsKey(final int key) { +216 +217 final int hash = hashOf(key); +218 int index = hash & mask; +219 if (containsKey(key, index)) { +220 return true; +221 } +222 +223 if (states[index] == FREE) { +224 return false; +225 } +226 +227 int j = index; +228 for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { +229 j = probe(perturb, j); +230 index = j & mask; +231 if (containsKey(key, index)) { +232 return true; +233 } +234 } +235 +236 return false; +237 +238 } +239 +240 /** +241 * Get an iterator over map elements. +242 * <p>The specialized iterators returned are fail-fast: they throw a +243 * <code>ConcurrentModificationException</code> when they detect the map +244 * has been modified during iteration.</p> +245 * @return iterator over the map elements +246 */ +247 public Iterator iterator() { +248 return new Iterator(); +249 } +250 +251 /** +252 * Perturb the hash for starting probing. +253 * @param hash initial hash +254 * @return perturbed hash +255 */ +256 private static int perturb(final int hash) { +257 return hash & 0x7fffffff; +258 } +259 +260 /** +261 * Find the index at which a key should be inserted +262 * @param key key to lookup +263 * @return index at which key should be inserted +264 */ +265 private int findInsertionIndex(final int key) { +266 return findInsertionIndex(keys, states, key, mask); +267 } +268 +269 /** +270 * Find the index at which a key should be inserted +271 * @param keys keys table +272 * @param states states table +273 * @param key key to lookup +274 * @param mask bit mask for hash values +275 * @return index at which key should be inserted +276 */ +277 private static int findInsertionIndex(final int[] keys, final byte[] states, +278 final int key, final int mask) { +279 final int hash = hashOf(key); +280 int index = hash & mask; +281 if (states[index] == FREE) { +282 return index; +283 } else if (states[index] == FULL && keys[index] == key) { +284 return changeIndexSign(index); +285 } +286 +287 int perturb = perturb(hash); +288 int j = index; +289 if (states[index] == FULL) { +290 while (true) { +291 j = probe(perturb, j); +292 index = j & mask; +293 perturb >>= PERTURB_SHIFT; +294 +295 if (states[index] != FULL || keys[index] == key) { +296 break; +297 } +298 } +299 } +300 +301 if (states[index] == FREE) { +302 return index; +303 } else if (states[index] == FULL) { +304 // due to the loop exit condition, +305 // if (states[index] == FULL) then keys[index] == key +306 return changeIndexSign(index); +307 } +308 +309 final int firstRemoved = index; +310 while (true) { +311 j = probe(perturb, j); +312 index = j & mask; +313 +314 if (states[index] == FREE) { +315 return firstRemoved; +316 } else if (states[index] == FULL && keys[index] == key) { +317 return changeIndexSign(index); +318 } +319 +320 perturb >>= PERTURB_SHIFT; +321 +322 } +323 +324 } +325 +326 /** +327 * Compute next probe for collision resolution +328 * @param perturb perturbed hash +329 * @param j previous probe +330 * @return next probe +331 */ +332 private static int probe(final int perturb, final int j) { +333 return (j << 2) + j + perturb + 1; +334 } +335 +336 /** +337 * Change the index sign +338 * @param index initial index +339 * @return changed index +340 */ +341 private static int changeIndexSign(final int index) { +342 return -index - 1; +343 } +344 +345 /** +346 * Get the number of elements stored in the map. +347 * @return number of elements stored in the map +348 */ +349 public int size() { +350 return size; +351 } +352 +353 +354 /** +355 * Remove the value associated with a key. +356 * @param key key to which the value is associated +357 * @return removed value +358 */ +359 public double remove(final int key) { +360 +361 final int hash = hashOf(key); +362 int index = hash & mask; +363 if (containsKey(key, index)) { +364 return doRemove(index); +365 } +366 +367 if (states[index] == FREE) { +368 return missingEntries; +369 } +370 +371 int j = index; +372 for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { +373 j = probe(perturb, j); +374 index = j & mask; +375 if (containsKey(key, index)) { +376 return doRemove(index); +377 } +378 } +379 +380 return missingEntries; +381 +382 } +383 +384 /** +385 * Check if the tables contain an element associated with specified key +386 * at specified index. +387 * @param key key to check +388 * @param index index to check +389 * @return true if an element is associated with key at index +390 */ +391 private boolean containsKey(final int key, final int index) { +392 return (key != 0 || states[index] == FULL) && keys[index] == key; +393 } +394 +395 /** +396 * Remove an element at specified index. +397 * @param index index of the element to remove +398 * @return removed value +399 */ +400 private double doRemove(int index) { +401 keys[index] = 0; +402 states[index] = REMOVED; +403 final double previous = values[index]; +404 values[index] = missingEntries; +405 --size; +406 ++count; +407 return previous; +408 } +409 +410 /** +411 * Put a value associated with a key in the map. +412 * @param key key to which value is associated +413 * @param value value to put in the map +414 * @return previous value associated with the key +415 */ +416 public double put(final int key, final double value) { +417 int index = findInsertionIndex(key); +418 double previous = missingEntries; +419 boolean newMapping = true; +420 if (index < 0) { +421 index = changeIndexSign(index); +422 previous = values[index]; +423 newMapping = false; +424 } +425 keys[index] = key; +426 states[index] = FULL; +427 values[index] = value; +428 if (newMapping) { +429 ++size; +430 if (shouldGrowTable()) { +431 growTable(); +432 } +433 ++count; +434 } +435 return previous; +436 +437 } +438 +439 /** +440 * Grow the tables. +441 */ +442 private void growTable() { +443 +444 final int oldLength = states.length; +445 final int[] oldKeys = keys; +446 final double[] oldValues = values; +447 final byte[] oldStates = states; +448 +449 final int newLength = RESIZE_MULTIPLIER * oldLength; +450 final int[] newKeys = new int[newLength]; +451 final double[] newValues = new double[newLength]; +452 final byte[] newStates = new byte[newLength]; +453 final int newMask = newLength - 1; +454 for (int i = 0; i < oldLength; ++i) { +455 if (oldStates[i] == FULL) { +456 final int key = oldKeys[i]; +457 final int index = findInsertionIndex(newKeys, newStates, key, newMask); +458 newKeys[index] = key; +459 newValues[index] = oldValues[i]; +460 newStates[index] = FULL; +461 } +462 } +463 +464 mask = newMask; +465 keys = newKeys; +466 values = newValues; +467 states = newStates; +468 +469 } +470 +471 /** +472 * Check if tables should grow due to increased size. +473 * @return true if tables should grow +474 */ +475 private boolean shouldGrowTable() { +476 return size > (mask + 1) * LOAD_FACTOR; +477 } +478 +479 /** +480 * Compute the hash value of a key +481 * @param key key to hash +482 * @return hash value of the key +483 */ +484 private static int hashOf(final int key) { +485 final int h = key ^ ((key >>> 20) ^ (key >>> 12)); +486 return h ^ (h >>> 7) ^ (h >>> 4); +487 } +488 +489 +490 /** Iterator class for the map. */ +491 public class Iterator { +492 +493 /** Reference modification count. */ +494 private final int referenceCount; +495 +496 /** Index of current element. */ +497 private int current; +498 +499 /** Index of next element. */ +500 private int next; +501 +502 /** +503 * Simple constructor. +504 */ +505 private Iterator() { +506 +507 // preserve the modification count of the map to detect concurrent modifications later +508 referenceCount = count; +509 +510 // initialize current index +511 next = -1; +512 try { +513 advance(); +514 } catch (NoSuchElementException nsee) { +515 // ignored +516 } +517 +518 } +519 +520 /** +521 * Check if there is a next element in the map. +522 * @return true if there is a next element +523 */ +524 public boolean hasNext() { +525 return next >= 0; +526 } +527 +528 /** +529 * Get the key of current entry. +530 * @return key of current entry +531 * @exception ConcurrentModificationException if the map is modified during iteration +532 * @exception NoSuchElementException if there is no element left in the map +533 */ +534 public int key() +535 throws ConcurrentModificationException, NoSuchElementException { +536 if (referenceCount != count) { +537 throw MathRuntimeException.createConcurrentModificationException( +538 CONCURRENT_MODIFICATION_MESSAGE); +539 } +540 if (current < 0) { +541 throw MathRuntimeException.createNoSuchElementException(EXHAUSTED_ITERATOR_MESSAGE); +542 } +543 return keys[current]; +544 } +545 +546 /** +547 * Get the value of current entry. +548 * @return value of current entry +549 * @exception ConcurrentModificationException if the map is modified during iteration +550 * @exception NoSuchElementException if there is no element left in the map +551 */ +552 public double value() +553 throws ConcurrentModificationException, NoSuchElementException { +554 if (referenceCount != count) { +555 throw MathRuntimeException.createConcurrentModificationException( +556 CONCURRENT_MODIFICATION_MESSAGE); +557 } +558 if (current < 0) { +559 throw MathRuntimeException.createNoSuchElementException(EXHAUSTED_ITERATOR_MESSAGE); +560 } +561 return values[current]; +562 } +563 +564 /** +565 * Advance iterator one step further. +566 * @exception ConcurrentModificationException if the map is modified during iteration +567 * @exception NoSuchElementException if there is no element left in the map +568 */ +569 public void advance() +570 throws ConcurrentModificationException, NoSuchElementException { +571 +572 if (referenceCount != count) { +573 throw MathRuntimeException.createConcurrentModificationException( +574 CONCURRENT_MODIFICATION_MESSAGE); +575 } +576 +577 // advance on step +578 current = next; +579 +580 // prepare next step +581 try { +582 while (states[++next] != FULL) { +583 // nothing to do +584 } +585 } catch (ArrayIndexOutOfBoundsException e) { +586 next = -2; +587 if (current < 0) { +588 throw MathRuntimeException.createNoSuchElementException(EXHAUSTED_ITERATOR_MESSAGE); +589 } +590 } +591 +592 } +593 +594 } +595 +596 /** +597 * Read a serialized object. +598 * @param stream input stream +599 * @throws IOException if object cannot be read +600 * @throws ClassNotFoundException if the class corresponding +601 * to the serialized object cannot be found +602 */ +603 private void readObject(final ObjectInputStream stream) +604 throws IOException, ClassNotFoundException { +605 stream.defaultReadObject(); +606 count = 0; +607 } +608 +609 +610 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/OpenIntToFieldHashMap.Iterator.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/OpenIntToFieldHashMap.Iterator.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,696 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.util; +018 +019 import java.io.IOException; +020 import java.io.ObjectInputStream; +021 import java.io.Serializable; +022 import java.lang.reflect.Array; +023 import java.util.ConcurrentModificationException; +024 import java.util.NoSuchElementException; +025 +026 import org.apache.commons.math.Field; +027 import org.apache.commons.math.FieldElement; +028 import org.apache.commons.math.MathRuntimeException; +029 +030 /** +031 * Open addressed map from int to FieldElement. +032 * <p>This class provides a dedicated map from integers to FieldElements with a +033 * much smaller memory overhead than standard <code>java.util.Map</code>.</p> +034 * <p>This class is not synchronized. The specialized iterators returned by +035 * {@link #iterator()} are fail-fast: they throw a +036 * <code>ConcurrentModificationException</code> when they detect the map has been +037 * modified during iteration.</p> +038 * @param <T> the type of the field elements +039 * @version $Revision: 903047 $ $Date: 2010-01-25 21:07:42 -0500 (Mon, 25 Jan 2010) $ +040 * @since 2.0 +041 */ +042 public class OpenIntToFieldHashMap<T extends FieldElement<T>> implements Serializable { +043 +044 /** Status indicator for free table entries. */ +045 protected static final byte FREE = 0; +046 +047 /** Status indicator for full table entries. */ +048 protected static final byte FULL = 1; +049 +050 /** Status indicator for removed table entries. */ +051 protected static final byte REMOVED = 2; +052 +053 /** Serializable version identifier. */ +054 private static final long serialVersionUID = -9179080286849120720L; +055 +056 /** Message for map modification during iteration. */ +057 private static final String CONCURRENT_MODIFICATION_MESSAGE = +058 "map has been modified while iterating"; +059 +060 /** Message for exhausted iterator. */ +061 private static final String EXHAUSTED_ITERATOR_MESSAGE = +062 "iterator exhausted"; +063 +064 /** Load factor for the map. */ +065 private static final float LOAD_FACTOR = 0.5f; +066 +067 /** Default starting size. +068 * <p>This must be a power of two for bit mask to work properly. </p> +069 */ +070 private static final int DEFAULT_EXPECTED_SIZE = 16; +071 +072 /** Multiplier for size growth when map fills up. +073 * <p>This must be a power of two for bit mask to work properly. </p> +074 */ +075 private static final int RESIZE_MULTIPLIER = 2; +076 +077 /** Number of bits to perturb the index when probing for collision resolution. */ +078 private static final int PERTURB_SHIFT = 5; +079 +080 /** Field to which the elements belong. */ +081 private final Field<T> field; +082 +083 /** Keys table. */ +084 private int[] keys; +085 +086 /** Values table. */ +087 private T[] values; +088 +089 /** States table. */ +090 private byte[] states; +091 +092 /** Return value for missing entries. */ +093 private final T missingEntries; +094 +095 /** Current size of the map. */ +096 private int size; +097 +098 /** Bit mask for hash values. */ +099 private int mask; +100 +101 /** Modifications count. */ +102 private transient int count; +103 +104 /** +105 * Build an empty map with default size and using zero for missing entries. +106 * @param field field to which the elements belong +107 */ +108 public OpenIntToFieldHashMap(final Field<T>field) { +109 this(field, DEFAULT_EXPECTED_SIZE, field.getZero()); +110 } +111 +112 /** +113 * Build an empty map with default size +114 * @param field field to which the elements belong +115 * @param missingEntries value to return when a missing entry is fetched +116 */ +117 public OpenIntToFieldHashMap(final Field<T>field, final T missingEntries) { +118 this(field,DEFAULT_EXPECTED_SIZE, missingEntries); +119 } +120 +121 /** +122 * Build an empty map with specified size and using zero for missing entries. +123 * @param field field to which the elements belong +124 * @param expectedSize expected number of elements in the map +125 */ +126 public OpenIntToFieldHashMap(final Field<T> field,final int expectedSize) { +127 this(field,expectedSize, field.getZero()); +128 } +129 +130 /** +131 * Build an empty map with specified size. +132 * @param field field to which the elements belong +133 * @param expectedSize expected number of elements in the map +134 * @param missingEntries value to return when a missing entry is fetched +135 */ +136 public OpenIntToFieldHashMap(final Field<T> field,final int expectedSize, +137 final T missingEntries) { +138 this.field = field; +139 final int capacity = computeCapacity(expectedSize); +140 keys = new int[capacity]; +141 values = buildArray(capacity); +142 states = new byte[capacity]; +143 this.missingEntries = missingEntries; +144 mask = capacity - 1; +145 } +146 +147 /** +148 * Copy constructor. +149 * @param source map to copy +150 */ +151 public OpenIntToFieldHashMap(final OpenIntToFieldHashMap<T> source) { +152 field = source.field; +153 final int length = source.keys.length; +154 keys = new int[length]; +155 System.arraycopy(source.keys, 0, keys, 0, length); +156 values = buildArray(length); +157 System.arraycopy(source.values, 0, values, 0, length); +158 states = new byte[length]; +159 System.arraycopy(source.states, 0, states, 0, length); +160 missingEntries = source.missingEntries; +161 size = source.size; +162 mask = source.mask; +163 count = source.count; +164 } +165 +166 /** +167 * Compute the capacity needed for a given size. +168 * @param expectedSize expected size of the map +169 * @return capacity to use for the specified size +170 */ +171 private static int computeCapacity(final int expectedSize) { +172 if (expectedSize == 0) { +173 return 1; +174 } +175 final int capacity = (int) Math.ceil(expectedSize / LOAD_FACTOR); +176 final int powerOfTwo = Integer.highestOneBit(capacity); +177 if (powerOfTwo == capacity) { +178 return capacity; +179 } +180 return nextPowerOfTwo(capacity); +181 } +182 +183 /** +184 * Find the smallest power of two greater than the input value +185 * @param i input value +186 * @return smallest power of two greater than the input value +187 */ +188 private static int nextPowerOfTwo(final int i) { +189 return Integer.highestOneBit(i) << 1; +190 } +191 +192 /** +193 * Get the stored value associated with the given key +194 * @param key key associated with the data +195 * @return data associated with the key +196 */ +197 public T get(final int key) { +198 +199 final int hash = hashOf(key); +200 int index = hash & mask; +201 if (containsKey(key, index)) { +202 return values[index]; +203 } +204 +205 if (states[index] == FREE) { +206 return missingEntries; +207 } +208 +209 int j = index; +210 for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { +211 j = probe(perturb, j); +212 index = j & mask; +213 if (containsKey(key, index)) { +214 return values[index]; +215 } +216 } +217 +218 return missingEntries; +219 +220 } +221 +222 /** +223 * Check if a value is associated with a key. +224 * @param key key to check +225 * @return true if a value is associated with key +226 */ +227 public boolean containsKey(final int key) { +228 +229 final int hash = hashOf(key); +230 int index = hash & mask; +231 if (containsKey(key, index)) { +232 return true; +233 } +234 +235 if (states[index] == FREE) { +236 return false; +237 } +238 +239 int j = index; +240 for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { +241 j = probe(perturb, j); +242 index = j & mask; +243 if (containsKey(key, index)) { +244 return true; +245 } +246 } +247 +248 return false; +249 +250 } +251 +252 /** +253 * Get an iterator over map elements. +254 * <p>The specialized iterators returned are fail-fast: they throw a +255 * <code>ConcurrentModificationException</code> when they detect the map +256 * has been modified during iteration.</p> +257 * @return iterator over the map elements +258 */ +259 public Iterator iterator() { +260 return new Iterator(); +261 } +262 +263 /** +264 * Perturb the hash for starting probing. +265 * @param hash initial hash +266 * @return perturbed hash +267 */ +268 private static int perturb(final int hash) { +269 return hash & 0x7fffffff; +270 } +271 +272 /** +273 * Find the index at which a key should be inserted +274 * @param key key to lookup +275 * @return index at which key should be inserted +276 */ +277 private int findInsertionIndex(final int key) { +278 return findInsertionIndex(keys, states, key, mask); +279 } +280 +281 /** +282 * Find the index at which a key should be inserted +283 * @param keys keys table +284 * @param states states table +285 * @param key key to lookup +286 * @param mask bit mask for hash values +287 * @return index at which key should be inserted +288 */ +289 private static int findInsertionIndex(final int[] keys, final byte[] states, +290 final int key, final int mask) { +291 final int hash = hashOf(key); +292 int index = hash & mask; +293 if (states[index] == FREE) { +294 return index; +295 } else if (states[index] == FULL && keys[index] == key) { +296 return changeIndexSign(index); +297 } +298 +299 int perturb = perturb(hash); +300 int j = index; +301 if (states[index] == FULL) { +302 while (true) { +303 j = probe(perturb, j); +304 index = j & mask; +305 perturb >>= PERTURB_SHIFT; +306 +307 if (states[index] != FULL || keys[index] == key) { +308 break; +309 } +310 } +311 } +312 +313 if (states[index] == FREE) { +314 return index; +315 } else if (states[index] == FULL) { +316 // due to the loop exit condition, +317 // if (states[index] == FULL) then keys[index] == key +318 return changeIndexSign(index); +319 } +320 +321 final int firstRemoved = index; +322 while (true) { +323 j = probe(perturb, j); +324 index = j & mask; +325 +326 if (states[index] == FREE) { +327 return firstRemoved; +328 } else if (states[index] == FULL && keys[index] == key) { +329 return changeIndexSign(index); +330 } +331 +332 perturb >>= PERTURB_SHIFT; +333 +334 } +335 +336 } +337 +338 /** +339 * Compute next probe for collision resolution +340 * @param perturb perturbed hash +341 * @param j previous probe +342 * @return next probe +343 */ +344 private static int probe(final int perturb, final int j) { +345 return (j << 2) + j + perturb + 1; +346 } +347 +348 /** +349 * Change the index sign +350 * @param index initial index +351 * @return changed index +352 */ +353 private static int changeIndexSign(final int index) { +354 return -index - 1; +355 } +356 +357 /** +358 * Get the number of elements stored in the map. +359 * @return number of elements stored in the map +360 */ +361 public int size() { +362 return size; +363 } +364 +365 +366 /** +367 * Remove the value associated with a key. +368 * @param key key to which the value is associated +369 * @return removed value +370 */ +371 public T remove(final int key) { +372 +373 final int hash = hashOf(key); +374 int index = hash & mask; +375 if (containsKey(key, index)) { +376 return doRemove(index); +377 } +378 +379 if (states[index] == FREE) { +380 return missingEntries; +381 } +382 +383 int j = index; +384 for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { +385 j = probe(perturb, j); +386 index = j & mask; +387 if (containsKey(key, index)) { +388 return doRemove(index); +389 } +390 } +391 +392 return missingEntries; +393 +394 } +395 +396 /** +397 * Check if the tables contain an element associated with specified key +398 * at specified index. +399 * @param key key to check +400 * @param index index to check +401 * @return true if an element is associated with key at index +402 */ +403 private boolean containsKey(final int key, final int index) { +404 return (key != 0 || states[index] == FULL) && keys[index] == key; +405 } +406 +407 /** +408 * Remove an element at specified index. +409 * @param index index of the element to remove +410 * @return removed value +411 */ +412 private T doRemove(int index) { +413 keys[index] = 0; +414 states[index] = REMOVED; +415 final T previous = values[index]; +416 values[index] = missingEntries; +417 --size; +418 ++count; +419 return previous; +420 } +421 +422 /** +423 * Put a value associated with a key in the map. +424 * @param key key to which value is associated +425 * @param value value to put in the map +426 * @return previous value associated with the key +427 */ +428 public T put(final int key, final T value) { +429 int index = findInsertionIndex(key); +430 T previous = missingEntries; +431 boolean newMapping = true; +432 if (index < 0) { +433 index = changeIndexSign(index); +434 previous = values[index]; +435 newMapping = false; +436 } +437 keys[index] = key; +438 states[index] = FULL; +439 values[index] = value; +440 if (newMapping) { +441 ++size; +442 if (shouldGrowTable()) { +443 growTable(); +444 } +445 ++count; +446 } +447 return previous; +448 +449 } +450 +451 /** +452 * Grow the tables. +453 */ +454 private void growTable() { +455 +456 final int oldLength = states.length; +457 final int[] oldKeys = keys; +458 final T[] oldValues = values; +459 final byte[] oldStates = states; +460 +461 final int newLength = RESIZE_MULTIPLIER * oldLength; +462 final int[] newKeys = new int[newLength]; +463 final T[] newValues = buildArray(newLength); +464 final byte[] newStates = new byte[newLength]; +465 final int newMask = newLength - 1; +466 for (int i = 0; i < oldLength; ++i) { +467 if (oldStates[i] == FULL) { +468 final int key = oldKeys[i]; +469 final int index = findInsertionIndex(newKeys, newStates, key, newMask); +470 newKeys[index] = key; +471 newValues[index] = oldValues[i]; +472 newStates[index] = FULL; +473 } +474 } +475 +476 mask = newMask; +477 keys = newKeys; +478 values = newValues; +479 states = newStates; +480 +481 } +482 +483 /** +484 * Check if tables should grow due to increased size. +485 * @return true if tables should grow +486 */ +487 private boolean shouldGrowTable() { +488 return size > (mask + 1) * LOAD_FACTOR; +489 } +490 +491 /** +492 * Compute the hash value of a key +493 * @param key key to hash +494 * @return hash value of the key +495 */ +496 private static int hashOf(final int key) { +497 final int h = key ^ ((key >>> 20) ^ (key >>> 12)); +498 return h ^ (h >>> 7) ^ (h >>> 4); +499 } +500 +501 +502 /** Iterator class for the map. */ +503 public class Iterator { +504 +505 /** Reference modification count. */ +506 private final int referenceCount; +507 +508 /** Index of current element. */ +509 private int current; +510 +511 /** Index of next element. */ +512 private int next; +513 +514 /** +515 * Simple constructor. +516 */ +517 private Iterator() { +518 +519 // preserve the modification count of the map to detect concurrent modifications later +520 referenceCount = count; +521 +522 // initialize current index +523 next = -1; +524 try { +525 advance(); +526 } catch (NoSuchElementException nsee) { +527 // ignored +528 } +529 +530 } +531 +532 /** +533 * Check if there is a next element in the map. +534 * @return true if there is a next element +535 */ +536 public boolean hasNext() { +537 return next >= 0; +538 } +539 +540 /** +541 * Get the key of current entry. +542 * @return key of current entry +543 * @exception ConcurrentModificationException if the map is modified during iteration +544 * @exception NoSuchElementException if there is no element left in the map +545 */ +546 public int key() +547 throws ConcurrentModificationException, NoSuchElementException { +548 if (referenceCount != count) { +549 throw MathRuntimeException.createConcurrentModificationException( +550 CONCURRENT_MODIFICATION_MESSAGE); +551 } +552 if (current < 0) { +553 throw MathRuntimeException.createNoSuchElementException(EXHAUSTED_ITERATOR_MESSAGE); +554 } +555 return keys[current]; +556 } +557 +558 /** +559 * Get the value of current entry. +560 * @return value of current entry +561 * @exception ConcurrentModificationException if the map is modified during iteration +562 * @exception NoSuchElementException if there is no element left in the map +563 */ +564 public T value() +565 throws ConcurrentModificationException, NoSuchElementException { +566 if (referenceCount != count) { +567 throw MathRuntimeException.createConcurrentModificationException( +568 CONCURRENT_MODIFICATION_MESSAGE); +569 } +570 if (current < 0) { +571 throw MathRuntimeException.createNoSuchElementException(EXHAUSTED_ITERATOR_MESSAGE); +572 } +573 return values[current]; +574 } +575 +576 /** +577 * Advance iterator one step further. +578 * @exception ConcurrentModificationException if the map is modified during iteration +579 * @exception NoSuchElementException if there is no element left in the map +580 */ +581 public void advance() +582 throws ConcurrentModificationException, NoSuchElementException { +583 +584 if (referenceCount != count) { +585 throw MathRuntimeException.createConcurrentModificationException( +586 CONCURRENT_MODIFICATION_MESSAGE); +587 } +588 +589 // advance on step +590 current = next; +591 +592 // prepare next step +593 try { +594 while (states[++next] != FULL) { +595 // nothing to do +596 } +597 } catch (ArrayIndexOutOfBoundsException e) { +598 next = -2; +599 if (current < 0) { +600 throw MathRuntimeException.createNoSuchElementException(EXHAUSTED_ITERATOR_MESSAGE); +601 } +602 } +603 +604 } +605 +606 } +607 +608 /** +609 * Read a serialized object. +610 * @param stream input stream +611 * @throws IOException if object cannot be read +612 * @throws ClassNotFoundException if the class corresponding +613 * to the serialized object cannot be found +614 */ +615 private void readObject(final ObjectInputStream stream) +616 throws IOException, ClassNotFoundException { +617 stream.defaultReadObject(); +618 count = 0; +619 } +620 +621 /** Build an array of elements. +622 * @param length size of the array to build +623 * @return a new array +624 */ +625 @SuppressWarnings("unchecked") // field is of type T +626 private T[] buildArray(final int length) { +627 return (T[]) Array.newInstance(field.getZero().getClass(), length); +628 } +629 +630 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/OpenIntToFieldHashMap.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/OpenIntToFieldHashMap.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,696 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.util; +018 +019 import java.io.IOException; +020 import java.io.ObjectInputStream; +021 import java.io.Serializable; +022 import java.lang.reflect.Array; +023 import java.util.ConcurrentModificationException; +024 import java.util.NoSuchElementException; +025 +026 import org.apache.commons.math.Field; +027 import org.apache.commons.math.FieldElement; +028 import org.apache.commons.math.MathRuntimeException; +029 +030 /** +031 * Open addressed map from int to FieldElement. +032 * <p>This class provides a dedicated map from integers to FieldElements with a +033 * much smaller memory overhead than standard <code>java.util.Map</code>.</p> +034 * <p>This class is not synchronized. The specialized iterators returned by +035 * {@link #iterator()} are fail-fast: they throw a +036 * <code>ConcurrentModificationException</code> when they detect the map has been +037 * modified during iteration.</p> +038 * @param <T> the type of the field elements +039 * @version $Revision: 903047 $ $Date: 2010-01-25 21:07:42 -0500 (Mon, 25 Jan 2010) $ +040 * @since 2.0 +041 */ +042 public class OpenIntToFieldHashMap<T extends FieldElement<T>> implements Serializable { +043 +044 /** Status indicator for free table entries. */ +045 protected static final byte FREE = 0; +046 +047 /** Status indicator for full table entries. */ +048 protected static final byte FULL = 1; +049 +050 /** Status indicator for removed table entries. */ +051 protected static final byte REMOVED = 2; +052 +053 /** Serializable version identifier. */ +054 private static final long serialVersionUID = -9179080286849120720L; +055 +056 /** Message for map modification during iteration. */ +057 private static final String CONCURRENT_MODIFICATION_MESSAGE = +058 "map has been modified while iterating"; +059 +060 /** Message for exhausted iterator. */ +061 private static final String EXHAUSTED_ITERATOR_MESSAGE = +062 "iterator exhausted"; +063 +064 /** Load factor for the map. */ +065 private static final float LOAD_FACTOR = 0.5f; +066 +067 /** Default starting size. +068 * <p>This must be a power of two for bit mask to work properly. </p> +069 */ +070 private static final int DEFAULT_EXPECTED_SIZE = 16; +071 +072 /** Multiplier for size growth when map fills up. +073 * <p>This must be a power of two for bit mask to work properly. </p> +074 */ +075 private static final int RESIZE_MULTIPLIER = 2; +076 +077 /** Number of bits to perturb the index when probing for collision resolution. */ +078 private static final int PERTURB_SHIFT = 5; +079 +080 /** Field to which the elements belong. */ +081 private final Field<T> field; +082 +083 /** Keys table. */ +084 private int[] keys; +085 +086 /** Values table. */ +087 private T[] values; +088 +089 /** States table. */ +090 private byte[] states; +091 +092 /** Return value for missing entries. */ +093 private final T missingEntries; +094 +095 /** Current size of the map. */ +096 private int size; +097 +098 /** Bit mask for hash values. */ +099 private int mask; +100 +101 /** Modifications count. */ +102 private transient int count; +103 +104 /** +105 * Build an empty map with default size and using zero for missing entries. +106 * @param field field to which the elements belong +107 */ +108 public OpenIntToFieldHashMap(final Field<T>field) { +109 this(field, DEFAULT_EXPECTED_SIZE, field.getZero()); +110 } +111 +112 /** +113 * Build an empty map with default size +114 * @param field field to which the elements belong +115 * @param missingEntries value to return when a missing entry is fetched +116 */ +117 public OpenIntToFieldHashMap(final Field<T>field, final T missingEntries) { +118 this(field,DEFAULT_EXPECTED_SIZE, missingEntries); +119 } +120 +121 /** +122 * Build an empty map with specified size and using zero for missing entries. +123 * @param field field to which the elements belong +124 * @param expectedSize expected number of elements in the map +125 */ +126 public OpenIntToFieldHashMap(final Field<T> field,final int expectedSize) { +127 this(field,expectedSize, field.getZero()); +128 } +129 +130 /** +131 * Build an empty map with specified size. +132 * @param field field to which the elements belong +133 * @param expectedSize expected number of elements in the map +134 * @param missingEntries value to return when a missing entry is fetched +135 */ +136 public OpenIntToFieldHashMap(final Field<T> field,final int expectedSize, +137 final T missingEntries) { +138 this.field = field; +139 final int capacity = computeCapacity(expectedSize); +140 keys = new int[capacity]; +141 values = buildArray(capacity); +142 states = new byte[capacity]; +143 this.missingEntries = missingEntries; +144 mask = capacity - 1; +145 } +146 +147 /** +148 * Copy constructor. +149 * @param source map to copy +150 */ +151 public OpenIntToFieldHashMap(final OpenIntToFieldHashMap<T> source) { +152 field = source.field; +153 final int length = source.keys.length; +154 keys = new int[length]; +155 System.arraycopy(source.keys, 0, keys, 0, length); +156 values = buildArray(length); +157 System.arraycopy(source.values, 0, values, 0, length); +158 states = new byte[length]; +159 System.arraycopy(source.states, 0, states, 0, length); +160 missingEntries = source.missingEntries; +161 size = source.size; +162 mask = source.mask; +163 count = source.count; +164 } +165 +166 /** +167 * Compute the capacity needed for a given size. +168 * @param expectedSize expected size of the map +169 * @return capacity to use for the specified size +170 */ +171 private static int computeCapacity(final int expectedSize) { +172 if (expectedSize == 0) { +173 return 1; +174 } +175 final int capacity = (int) Math.ceil(expectedSize / LOAD_FACTOR); +176 final int powerOfTwo = Integer.highestOneBit(capacity); +177 if (powerOfTwo == capacity) { +178 return capacity; +179 } +180 return nextPowerOfTwo(capacity); +181 } +182 +183 /** +184 * Find the smallest power of two greater than the input value +185 * @param i input value +186 * @return smallest power of two greater than the input value +187 */ +188 private static int nextPowerOfTwo(final int i) { +189 return Integer.highestOneBit(i) << 1; +190 } +191 +192 /** +193 * Get the stored value associated with the given key +194 * @param key key associated with the data +195 * @return data associated with the key +196 */ +197 public T get(final int key) { +198 +199 final int hash = hashOf(key); +200 int index = hash & mask; +201 if (containsKey(key, index)) { +202 return values[index]; +203 } +204 +205 if (states[index] == FREE) { +206 return missingEntries; +207 } +208 +209 int j = index; +210 for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { +211 j = probe(perturb, j); +212 index = j & mask; +213 if (containsKey(key, index)) { +214 return values[index]; +215 } +216 } +217 +218 return missingEntries; +219 +220 } +221 +222 /** +223 * Check if a value is associated with a key. +224 * @param key key to check +225 * @return true if a value is associated with key +226 */ +227 public boolean containsKey(final int key) { +228 +229 final int hash = hashOf(key); +230 int index = hash & mask; +231 if (containsKey(key, index)) { +232 return true; +233 } +234 +235 if (states[index] == FREE) { +236 return false; +237 } +238 +239 int j = index; +240 for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { +241 j = probe(perturb, j); +242 index = j & mask; +243 if (containsKey(key, index)) { +244 return true; +245 } +246 } +247 +248 return false; +249 +250 } +251 +252 /** +253 * Get an iterator over map elements. +254 * <p>The specialized iterators returned are fail-fast: they throw a +255 * <code>ConcurrentModificationException</code> when they detect the map +256 * has been modified during iteration.</p> +257 * @return iterator over the map elements +258 */ +259 public Iterator iterator() { +260 return new Iterator(); +261 } +262 +263 /** +264 * Perturb the hash for starting probing. +265 * @param hash initial hash +266 * @return perturbed hash +267 */ +268 private static int perturb(final int hash) { +269 return hash & 0x7fffffff; +270 } +271 +272 /** +273 * Find the index at which a key should be inserted +274 * @param key key to lookup +275 * @return index at which key should be inserted +276 */ +277 private int findInsertionIndex(final int key) { +278 return findInsertionIndex(keys, states, key, mask); +279 } +280 +281 /** +282 * Find the index at which a key should be inserted +283 * @param keys keys table +284 * @param states states table +285 * @param key key to lookup +286 * @param mask bit mask for hash values +287 * @return index at which key should be inserted +288 */ +289 private static int findInsertionIndex(final int[] keys, final byte[] states, +290 final int key, final int mask) { +291 final int hash = hashOf(key); +292 int index = hash & mask; +293 if (states[index] == FREE) { +294 return index; +295 } else if (states[index] == FULL && keys[index] == key) { +296 return changeIndexSign(index); +297 } +298 +299 int perturb = perturb(hash); +300 int j = index; +301 if (states[index] == FULL) { +302 while (true) { +303 j = probe(perturb, j); +304 index = j & mask; +305 perturb >>= PERTURB_SHIFT; +306 +307 if (states[index] != FULL || keys[index] == key) { +308 break; +309 } +310 } +311 } +312 +313 if (states[index] == FREE) { +314 return index; +315 } else if (states[index] == FULL) { +316 // due to the loop exit condition, +317 // if (states[index] == FULL) then keys[index] == key +318 return changeIndexSign(index); +319 } +320 +321 final int firstRemoved = index; +322 while (true) { +323 j = probe(perturb, j); +324 index = j & mask; +325 +326 if (states[index] == FREE) { +327 return firstRemoved; +328 } else if (states[index] == FULL && keys[index] == key) { +329 return changeIndexSign(index); +330 } +331 +332 perturb >>= PERTURB_SHIFT; +333 +334 } +335 +336 } +337 +338 /** +339 * Compute next probe for collision resolution +340 * @param perturb perturbed hash +341 * @param j previous probe +342 * @return next probe +343 */ +344 private static int probe(final int perturb, final int j) { +345 return (j << 2) + j + perturb + 1; +346 } +347 +348 /** +349 * Change the index sign +350 * @param index initial index +351 * @return changed index +352 */ +353 private static int changeIndexSign(final int index) { +354 return -index - 1; +355 } +356 +357 /** +358 * Get the number of elements stored in the map. +359 * @return number of elements stored in the map +360 */ +361 public int size() { +362 return size; +363 } +364 +365 +366 /** +367 * Remove the value associated with a key. +368 * @param key key to which the value is associated +369 * @return removed value +370 */ +371 public T remove(final int key) { +372 +373 final int hash = hashOf(key); +374 int index = hash & mask; +375 if (containsKey(key, index)) { +376 return doRemove(index); +377 } +378 +379 if (states[index] == FREE) { +380 return missingEntries; +381 } +382 +383 int j = index; +384 for (int perturb = perturb(hash); states[index] != FREE; perturb >>= PERTURB_SHIFT) { +385 j = probe(perturb, j); +386 index = j & mask; +387 if (containsKey(key, index)) { +388 return doRemove(index); +389 } +390 } +391 +392 return missingEntries; +393 +394 } +395 +396 /** +397 * Check if the tables contain an element associated with specified key +398 * at specified index. +399 * @param key key to check +400 * @param index index to check +401 * @return true if an element is associated with key at index +402 */ +403 private boolean containsKey(final int key, final int index) { +404 return (key != 0 || states[index] == FULL) && keys[index] == key; +405 } +406 +407 /** +408 * Remove an element at specified index. +409 * @param index index of the element to remove +410 * @return removed value +411 */ +412 private T doRemove(int index) { +413 keys[index] = 0; +414 states[index] = REMOVED; +415 final T previous = values[index]; +416 values[index] = missingEntries; +417 --size; +418 ++count; +419 return previous; +420 } +421 +422 /** +423 * Put a value associated with a key in the map. +424 * @param key key to which value is associated +425 * @param value value to put in the map +426 * @return previous value associated with the key +427 */ +428 public T put(final int key, final T value) { +429 int index = findInsertionIndex(key); +430 T previous = missingEntries; +431 boolean newMapping = true; +432 if (index < 0) { +433 index = changeIndexSign(index); +434 previous = values[index]; +435 newMapping = false; +436 } +437 keys[index] = key; +438 states[index] = FULL; +439 values[index] = value; +440 if (newMapping) { +441 ++size; +442 if (shouldGrowTable()) { +443 growTable(); +444 } +445 ++count; +446 } +447 return previous; +448 +449 } +450 +451 /** +452 * Grow the tables. +453 */ +454 private void growTable() { +455 +456 final int oldLength = states.length; +457 final int[] oldKeys = keys; +458 final T[] oldValues = values; +459 final byte[] oldStates = states; +460 +461 final int newLength = RESIZE_MULTIPLIER * oldLength; +462 final int[] newKeys = new int[newLength]; +463 final T[] newValues = buildArray(newLength); +464 final byte[] newStates = new byte[newLength]; +465 final int newMask = newLength - 1; +466 for (int i = 0; i < oldLength; ++i) { +467 if (oldStates[i] == FULL) { +468 final int key = oldKeys[i]; +469 final int index = findInsertionIndex(newKeys, newStates, key, newMask); +470 newKeys[index] = key; +471 newValues[index] = oldValues[i]; +472 newStates[index] = FULL; +473 } +474 } +475 +476 mask = newMask; +477 keys = newKeys; +478 values = newValues; +479 states = newStates; +480 +481 } +482 +483 /** +484 * Check if tables should grow due to increased size. +485 * @return true if tables should grow +486 */ +487 private boolean shouldGrowTable() { +488 return size > (mask + 1) * LOAD_FACTOR; +489 } +490 +491 /** +492 * Compute the hash value of a key +493 * @param key key to hash +494 * @return hash value of the key +495 */ +496 private static int hashOf(final int key) { +497 final int h = key ^ ((key >>> 20) ^ (key >>> 12)); +498 return h ^ (h >>> 7) ^ (h >>> 4); +499 } +500 +501 +502 /** Iterator class for the map. */ +503 public class Iterator { +504 +505 /** Reference modification count. */ +506 private final int referenceCount; +507 +508 /** Index of current element. */ +509 private int current; +510 +511 /** Index of next element. */ +512 private int next; +513 +514 /** +515 * Simple constructor. +516 */ +517 private Iterator() { +518 +519 // preserve the modification count of the map to detect concurrent modifications later +520 referenceCount = count; +521 +522 // initialize current index +523 next = -1; +524 try { +525 advance(); +526 } catch (NoSuchElementException nsee) { +527 // ignored +528 } +529 +530 } +531 +532 /** +533 * Check if there is a next element in the map. +534 * @return true if there is a next element +535 */ +536 public boolean hasNext() { +537 return next >= 0; +538 } +539 +540 /** +541 * Get the key of current entry. +542 * @return key of current entry +543 * @exception ConcurrentModificationException if the map is modified during iteration +544 * @exception NoSuchElementException if there is no element left in the map +545 */ +546 public int key() +547 throws ConcurrentModificationException, NoSuchElementException { +548 if (referenceCount != count) { +549 throw MathRuntimeException.createConcurrentModificationException( +550 CONCURRENT_MODIFICATION_MESSAGE); +551 } +552 if (current < 0) { +553 throw MathRuntimeException.createNoSuchElementException(EXHAUSTED_ITERATOR_MESSAGE); +554 } +555 return keys[current]; +556 } +557 +558 /** +559 * Get the value of current entry. +560 * @return value of current entry +561 * @exception ConcurrentModificationException if the map is modified during iteration +562 * @exception NoSuchElementException if there is no element left in the map +563 */ +564 public T value() +565 throws ConcurrentModificationException, NoSuchElementException { +566 if (referenceCount != count) { +567 throw MathRuntimeException.createConcurrentModificationException( +568 CONCURRENT_MODIFICATION_MESSAGE); +569 } +570 if (current < 0) { +571 throw MathRuntimeException.createNoSuchElementException(EXHAUSTED_ITERATOR_MESSAGE); +572 } +573 return values[current]; +574 } +575 +576 /** +577 * Advance iterator one step further. +578 * @exception ConcurrentModificationException if the map is modified during iteration +579 * @exception NoSuchElementException if there is no element left in the map +580 */ +581 public void advance() +582 throws ConcurrentModificationException, NoSuchElementException { +583 +584 if (referenceCount != count) { +585 throw MathRuntimeException.createConcurrentModificationException( +586 CONCURRENT_MODIFICATION_MESSAGE); +587 } +588 +589 // advance on step +590 current = next; +591 +592 // prepare next step +593 try { +594 while (states[++next] != FULL) { +595 // nothing to do +596 } +597 } catch (ArrayIndexOutOfBoundsException e) { +598 next = -2; +599 if (current < 0) { +600 throw MathRuntimeException.createNoSuchElementException(EXHAUSTED_ITERATOR_MESSAGE); +601 } +602 } +603 +604 } +605 +606 } +607 +608 /** +609 * Read a serialized object. +610 * @param stream input stream +611 * @throws IOException if object cannot be read +612 * @throws ClassNotFoundException if the class corresponding +613 * to the serialized object cannot be found +614 */ +615 private void readObject(final ObjectInputStream stream) +616 throws IOException, ClassNotFoundException { +617 stream.defaultReadObject(); +618 count = 0; +619 } +620 +621 /** Build an array of elements. +622 * @param length size of the array to build +623 * @return a new array +624 */ +625 @SuppressWarnings("unchecked") // field is of type T +626 private T[] buildArray(final int length) { +627 return (T[]) Array.newInstance(field.getZero().getClass(), length); +628 } +629 +630 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/ResizableDoubleArray.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/ResizableDoubleArray.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,962 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.util; +018 +019 import java.io.Serializable; +020 import java.util.Arrays; +021 +022 import org.apache.commons.math.MathRuntimeException; +023 +024 /** +025 * <p> +026 * A variable length {@link DoubleArray} implementation that automatically +027 * handles expanding and contracting its internal storage array as elements +028 * are added and removed. +029 * </p> +030 * <p> +031 * The internal storage array starts with capacity determined by the +032 * <code>initialCapacity</code> property, which can be set by the constructor. +033 * The default initial capacity is 16. Adding elements using +034 * {@link #addElement(double)} appends elements to the end of the array. When +035 * there are no open entries at the end of the internal storage array, the +036 * array is expanded. The size of the expanded array depends on the +037 * <code>expansionMode</code> and <code>expansionFactor</code> properties. +038 * The <code>expansionMode</code> determines whether the size of the array is +039 * multiplied by the <code>expansionFactor</code> (MULTIPLICATIVE_MODE) or if +040 * the expansion is additive (ADDITIVE_MODE -- <code>expansionFactor</code> +041 * storage locations added). The default <code>expansionMode</code> is +042 * MULTIPLICATIVE_MODE and the default <code>expansionFactor</code> +043 * is 2.0. +044 * </p> +045 * <p> +046 * The {@link #addElementRolling(double)} method adds a new element to the end +047 * of the internal storage array and adjusts the "usable window" of the +048 * internal array forward by one position (effectively making what was the +049 * second element the first, and so on). Repeated activations of this method +050 * (or activation of {@link #discardFrontElements(int)}) will effectively orphan +051 * the storage locations at the beginning of the internal storage array. To +052 * reclaim this storage, each time one of these methods is activated, the size +053 * of the internal storage array is compared to the number of addressable +054 * elements (the <code>numElements</code> property) and if the difference +055 * is too large, the internal array is contracted to size +056 * <code>numElements + 1.</code> The determination of when the internal +057 * storage array is "too large" depends on the <code>expansionMode</code> and +058 * <code>contractionFactor</code> properties. If the <code>expansionMode</code> +059 * is <code>MULTIPLICATIVE_MODE</code>, contraction is triggered when the +060 * ratio between storage array length and <code>numElements</code> exceeds +061 * <code>contractionFactor.</code> If the <code>expansionMode</code> +062 * is <code>ADDITIVE_MODE,</code> the number of excess storage locations +063 * is compared to <code>contractionFactor.</code> +064 * </p> +065 * <p> +066 * To avoid cycles of expansions and contractions, the +067 * <code>expansionFactor</code> must not exceed the +068 * <code>contractionFactor.</code> Constructors and mutators for both of these +069 * properties enforce this requirement, throwing IllegalArgumentException if it +070 * is violated. +071 * </p> +072 * @version $Revision: 811833 $ $Date: 2009-09-06 12:27:50 -0400 (Sun, 06 Sep 2009) $ +073 */ +074 public class ResizableDoubleArray implements DoubleArray, Serializable { +075 +076 /** additive expansion mode */ +077 public static final int ADDITIVE_MODE = 1; +078 +079 /** multiplicative expansion mode */ +080 public static final int MULTIPLICATIVE_MODE = 0; +081 +082 /** Serializable version identifier */ +083 private static final long serialVersionUID = -3485529955529426875L; +084 +085 /** +086 * The contraction criteria determines when the internal array will be +087 * contracted to fit the number of elements contained in the element +088 * array + 1. +089 */ +090 protected float contractionCriteria = 2.5f; +091 +092 /** +093 * The expansion factor of the array. When the array needs to be expanded, +094 * the new array size will be +095 * <code>internalArray.length * expansionFactor</code> +096 * if <code>expansionMode</code> is set to MULTIPLICATIVE_MODE, or +097 * <code>internalArray.length + expansionFactor</code> if +098 * <code>expansionMode</code> is set to ADDITIVE_MODE. +099 */ +100 protected float expansionFactor = 2.0f; +101 +102 /** +103 * Determines whether array expansion by <code>expansionFactor</code> +104 * is additive or multiplicative. +105 */ +106 protected int expansionMode = MULTIPLICATIVE_MODE; +107 +108 /** +109 * The initial capacity of the array. Initial capacity is not exposed as a +110 * property as it is only meaningful when passed to a constructor. +111 */ +112 protected int initialCapacity = 16; +113 +114 /** +115 * The internal storage array. +116 */ +117 protected double[] internalArray; +118 +119 /** +120 * The number of addressable elements in the array. Note that this +121 * has nothing to do with the length of the internal storage array. +122 */ +123 protected int numElements = 0; +124 +125 /** +126 * The position of the first addressable element in the internal storage +127 * array. The addressable elements in the array are <code> +128 * internalArray[startIndex],...,internalArray[startIndex + numElements -1] +129 * </code> +130 */ +131 protected int startIndex = 0; +132 +133 /** +134 * Create a ResizableArray with default properties. +135 * <ul> +136 * <li><code>initialCapacity = 16</code></li> +137 * <li><code>expansionMode = MULTIPLICATIVE_MODE</code></li> +138 * <li><code>expansionFactor = 2.5</code></li> +139 * <li><code>contractionFactor = 2.0</code></li> +140 * </ul> +141 */ +142 public ResizableDoubleArray() { +143 internalArray = new double[initialCapacity]; +144 } +145 +146 /** +147 * Create a ResizableArray with the specified initial capacity. Other +148 * properties take default values: +149 * <ul> +150 * <li><code>expansionMode = MULTIPLICATIVE_MODE</code></li> +151 * <li><code>expansionFactor = 2.5</code></li> +152 * <li><code>contractionFactor = 2.0</code></li> +153 * </ul> +154 * @param initialCapacity The initial size of the internal storage array +155 * @throws IllegalArgumentException if initialCapacity is not > 0 +156 */ +157 public ResizableDoubleArray(int initialCapacity) { +158 setInitialCapacity(initialCapacity); +159 internalArray = new double[this.initialCapacity]; +160 } +161 +162 /** +163 * <p> +164 * Create a ResizableArray with the specified initial capacity +165 * and expansion factor. The remaining properties take default +166 * values: +167 * <ul> +168 * <li><code>expansionMode = MULTIPLICATIVE_MODE</code></li> +169 * <li><code>contractionFactor = 0.5 + expansionFactor</code></li> +170 * </ul></p> +171 * <p> +172 * Throws IllegalArgumentException if the following conditions are +173 * not met: +174 * <ul> +175 * <li><code>initialCapacity > 0</code></li> +176 * <li><code>expansionFactor > 1</code></li> +177 * </ul></p> +178 * +179 * @param initialCapacity The initial size of the internal storage array +180 * @param expansionFactor the array will be expanded based on this +181 * parameter +182 * @throws IllegalArgumentException if parameters are not valid +183 */ +184 public ResizableDoubleArray(int initialCapacity, float expansionFactor) { +185 this.expansionFactor = expansionFactor; +186 setInitialCapacity(initialCapacity); +187 internalArray = new double[initialCapacity]; +188 setContractionCriteria(expansionFactor +0.5f); +189 } +190 +191 /** +192 * <p> +193 * Create a ResizableArray with the specified initialCapacity, +194 * expansionFactor, and contractionCriteria. The <code>expansionMode</code> +195 * will default to <code>MULTIPLICATIVE_MODE.</code></p> +196 * <p> +197 * Throws IllegalArgumentException if the following conditions are +198 * not met: +199 * <ul> +200 * <li><code>initialCapacity > 0</code></li> +201 * <li><code>expansionFactor > 1</code></li> +202 * <li><code>contractionFactor >= expansionFactor</code></li> +203 * </ul></p> +204 * @param initialCapacity The initial size of the internal storage array +205 * @param expansionFactor the array will be expanded based on this +206 * parameter +207 * @param contractionCriteria The contraction Criteria. +208 * @throws IllegalArgumentException if parameters are not valid +209 */ +210 public ResizableDoubleArray(int initialCapacity, float expansionFactor, +211 float contractionCriteria) { +212 this.expansionFactor = expansionFactor; +213 setContractionCriteria(contractionCriteria); +214 setInitialCapacity(initialCapacity); +215 internalArray = new double[initialCapacity]; +216 } +217 +218 /** +219 * <p> +220 * Create a ResizableArray with the specified properties.</p> +221 * <p> +222 * Throws IllegalArgumentException if the following conditions are +223 * not met: +224 * <ul> +225 * <li><code>initialCapacity > 0</code></li> +226 * <li><code>expansionFactor > 1</code></li> +227 * <li><code>contractionFactor >= expansionFactor</code></li> +228 * <li><code>expansionMode in {MULTIPLICATIVE_MODE, ADDITIVE_MODE}</code> +229 * </li> +230 * </ul></p> +231 * +232 * @param initialCapacity the initial size of the internal storage array +233 * @param expansionFactor the array will be expanded based on this +234 * parameter +235 * @param contractionCriteria the contraction Criteria +236 * @param expansionMode the expansion mode +237 * @throws IllegalArgumentException if parameters are not valid +238 */ +239 public ResizableDoubleArray(int initialCapacity, float expansionFactor, +240 float contractionCriteria, int expansionMode) { +241 this.expansionFactor = expansionFactor; +242 setContractionCriteria(contractionCriteria); +243 setInitialCapacity(initialCapacity); +244 setExpansionMode(expansionMode); +245 internalArray = new double[initialCapacity]; +246 } +247 +248 /** +249 * Copy constructor. Creates a new ResizableDoubleArray that is a deep, +250 * fresh copy of the original. Needs to acquire synchronization lock +251 * on original. Original may not be null; otherwise a NullPointerException +252 * is thrown. +253 * +254 * @param original array to copy +255 * @since 2.0 +256 */ +257 public ResizableDoubleArray(ResizableDoubleArray original) { +258 copy(original, this); +259 } +260 +261 /** +262 * Adds an element to the end of this expandable array. +263 * +264 * @param value to be added to end of array +265 */ +266 public synchronized void addElement(double value) { +267 numElements++; +268 if ((startIndex + numElements) > internalArray.length) { +269 expand(); +270 } +271 internalArray[startIndex + (numElements - 1)] = value; +272 if (shouldContract()) { +273 contract(); +274 } +275 } +276 +277 /** +278 * <p> +279 * Adds an element to the end of the array and removes the first +280 * element in the array. Returns the discarded first element. +281 * The effect is similar to a push operation in a FIFO queue. +282 * </p> +283 * <p> +284 * Example: If the array contains the elements 1, 2, 3, 4 (in that order) +285 * and addElementRolling(5) is invoked, the result is an array containing +286 * the entries 2, 3, 4, 5 and the value returned is 1. +287 * </p> +288 * +289 * @param value the value to be added to the array +290 * @return the value which has been discarded or "pushed" out of the array +291 * by this rolling insert +292 */ +293 public synchronized double addElementRolling(double value) { +294 double discarded = internalArray[startIndex]; +295 +296 if ((startIndex + (numElements + 1)) > internalArray.length) { +297 expand(); +298 } +299 // Increment the start index +300 startIndex += 1; +301 +302 // Add the new value +303 internalArray[startIndex + (numElements - 1)] = value; +304 +305 // Check the contraction criteria +306 if (shouldContract()) { +307 contract(); +308 } +309 return discarded; +310 } +311 +312 /** +313 * Substitutes <code>value</code> for the most recently added value. +314 * Returns the value that has been replaced. If the array is empty (i.e. +315 * if {@link #numElements} is zero), a MathRuntimeException is thrown. +316 * +317 * @param value new value to substitute for the most recently added value +318 * @return value that has been replaced in the array +319 * @since 2.0 +320 */ +321 public synchronized double substituteMostRecentElement(double value) { +322 if (numElements < 1) { +323 throw MathRuntimeException.createArrayIndexOutOfBoundsException( +324 "cannot substitute an element from an empty array"); +325 } +326 +327 double discarded = internalArray[startIndex + (numElements - 1)]; +328 +329 internalArray[startIndex + (numElements - 1)] = value; +330 +331 return discarded; +332 } +333 +334 +335 /** +336 * Checks the expansion factor and the contraction criteria and throws an +337 * IllegalArgumentException if the contractionCriteria is less than the +338 * expansionCriteria +339 * +340 * @param expansion factor to be checked +341 * @param contraction criteria to be checked +342 * @throws IllegalArgumentException if the contractionCriteria is less than +343 * the expansionCriteria. +344 */ +345 protected void checkContractExpand(float contraction, float expansion) { +346 +347 if (contraction < expansion) { +348 throw MathRuntimeException.createIllegalArgumentException( +349 "contraction criteria ({0}) smaller than the expansion factor ({1}). This would " + +350 "lead to a never ending loop of expansion and contraction as a newly expanded " + +351 "internal storage array would immediately satisfy the criteria for contraction", +352 contraction, expansion); +353 } +354 +355 if (contraction <= 1.0) { +356 throw MathRuntimeException.createIllegalArgumentException( +357 "contraction criteria smaller than one ({0}). This would lead to a never ending " + +358 "loop of expansion and contraction as an internal storage array length equal " + +359 "to the number of elements would satisfy the contraction criteria.", +360 contraction); +361 } +362 +363 if (expansion <= 1.0) { +364 throw MathRuntimeException.createIllegalArgumentException( +365 "expansion factor smaller than one ({0})", +366 expansion); +367 } +368 } +369 +370 /** +371 * Clear the array, reset the size to the initialCapacity and the number +372 * of elements to zero. +373 */ +374 public synchronized void clear() { +375 numElements = 0; +376 startIndex = 0; +377 internalArray = new double[initialCapacity]; +378 } +379 +380 /** +381 * Contracts the storage array to the (size of the element set) + 1 - to +382 * avoid a zero length array. This function also resets the startIndex to +383 * zero. +384 */ +385 public synchronized void contract() { +386 double[] tempArray = new double[numElements + 1]; +387 +388 // Copy and swap - copy only the element array from the src array. +389 System.arraycopy(internalArray, startIndex, tempArray, 0, numElements); +390 internalArray = tempArray; +391 +392 // Reset the start index to zero +393 startIndex = 0; +394 } +395 +396 /** +397 * Discards the <code>i<code> initial elements of the array. For example, +398 * if the array contains the elements 1,2,3,4, invoking +399 * <code>discardFrontElements(2)</code> will cause the first two elements +400 * to be discarded, leaving 3,4 in the array. Throws illegalArgumentException +401 * if i exceeds numElements. +402 * +403 * @param i the number of elements to discard from the front of the array +404 * @throws IllegalArgumentException if i is greater than numElements. +405 * @since 2.0 +406 */ +407 public synchronized void discardFrontElements(int i) { +408 +409 discardExtremeElements(i,true); +410 +411 } +412 +413 /** +414 * Discards the <code>i<code> last elements of the array. For example, +415 * if the array contains the elements 1,2,3,4, invoking +416 * <code>discardMostRecentElements(2)</code> will cause the last two elements +417 * to be discarded, leaving 1,2 in the array. Throws illegalArgumentException +418 * if i exceeds numElements. +419 * +420 * @param i the number of elements to discard from the end of the array +421 * @throws IllegalArgumentException if i is greater than numElements. +422 * @since 2.0 +423 */ +424 public synchronized void discardMostRecentElements(int i) { +425 +426 discardExtremeElements(i,false); +427 +428 } +429 +430 /** +431 * Discards the <code>i<code> first or last elements of the array, +432 * depending on the value of <code>front</code>. +433 * For example, if the array contains the elements 1,2,3,4, invoking +434 * <code>discardExtremeElements(2,false)</code> will cause the last two elements +435 * to be discarded, leaving 1,2 in the array. +436 * For example, if the array contains the elements 1,2,3,4, invoking +437 * <code>discardExtremeElements(2,true)</code> will cause the first two elements +438 * to be discarded, leaving 3,4 in the array. +439 * Throws illegalArgumentException +440 * if i exceeds numElements. +441 * +442 * @param i the number of elements to discard from the front/end of the array +443 * @param front true if elements are to be discarded from the front +444 * of the array, false if elements are to be discarded from the end +445 * of the array +446 * @throws IllegalArgumentException if i is greater than numElements. +447 * @since 2.0 +448 */ +449 private synchronized void discardExtremeElements(int i,boolean front) { +450 if (i > numElements) { +451 throw MathRuntimeException.createIllegalArgumentException( +452 "cannot discard {0} elements from a {1} elements array", +453 i, numElements); +454 } else if (i < 0) { +455 throw MathRuntimeException.createIllegalArgumentException( +456 "cannot discard a negative number of elements ({0})", +457 i); +458 } else { +459 // "Subtract" this number of discarded from numElements +460 numElements -= i; +461 if (front) startIndex += i; +462 } +463 if (shouldContract()) { +464 contract(); +465 } +466 } +467 +468 /** +469 * Expands the internal storage array using the expansion factor. +470 * <p> +471 * if <code>expansionMode</code> is set to MULTIPLICATIVE_MODE, +472 * the new array size will be <code>internalArray.length * expansionFactor.</code> +473 * If <code>expansionMode</code> is set to ADDITIVE_MODE, the length +474 * after expansion will be <code>internalArray.length + expansionFactor</code> +475 * </p> +476 */ +477 protected synchronized void expand() { +478 +479 // notice the use of Math.ceil(), this guarantees that we will always +480 // have an array of at least currentSize + 1. Assume that the +481 // current initial capacity is 1 and the expansion factor +482 // is 1.000000000000000001. The newly calculated size will be +483 // rounded up to 2 after the multiplication is performed. +484 int newSize = 0; +485 if (expansionMode == MULTIPLICATIVE_MODE) { +486 newSize = (int) Math.ceil(internalArray.length * expansionFactor); +487 } else { +488 newSize = internalArray.length + Math.round(expansionFactor); +489 } +490 double[] tempArray = new double[newSize]; +491 +492 // Copy and swap +493 System.arraycopy(internalArray, 0, tempArray, 0, internalArray.length); +494 internalArray = tempArray; +495 } +496 +497 /** +498 * Expands the internal storage array to the specified size. +499 * +500 * @param size Size of the new internal storage array +501 */ +502 private synchronized void expandTo(int size) { +503 double[] tempArray = new double[size]; +504 // Copy and swap +505 System.arraycopy(internalArray, 0, tempArray, 0, internalArray.length); +506 internalArray = tempArray; +507 } +508 +509 /** +510 * The contraction criteria defines when the internal array will contract +511 * to store only the number of elements in the element array. +512 * If the <code>expansionMode</code> is <code>MULTIPLICATIVE_MODE</code>, +513 * contraction is triggered when the ratio between storage array length +514 * and <code>numElements</code> exceeds <code>contractionFactor</code>. +515 * If the <code>expansionMode</code> is <code>ADDITIVE_MODE</code>, the +516 * number of excess storage locations is compared to +517 * <code>contractionFactor.</code> +518 * +519 * @return the contraction criteria used to reclaim memory. +520 */ +521 public float getContractionCriteria() { +522 return contractionCriteria; +523 } +524 +525 /** +526 * Returns the element at the specified index +527 * +528 * @param index index to fetch a value from +529 * @return value stored at the specified index +530 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is less than +531 * zero or is greater than <code>getNumElements() - 1</code>. +532 */ +533 public synchronized double getElement(int index) { +534 if (index >= numElements) { +535 throw MathRuntimeException.createArrayIndexOutOfBoundsException( +536 "the index specified: {0} is larger than the current maximal index {1}", +537 index, numElements - 1); +538 } else if (index >= 0) { +539 return internalArray[startIndex + index]; +540 } else { +541 throw MathRuntimeException.createArrayIndexOutOfBoundsException( +542 "elements cannot be retrieved from a negative array index {0}", +543 index); +544 } +545 } +546 +547 /** +548 * Returns a double array containing the elements of this +549 * <code>ResizableArray</code>. This method returns a copy, not a +550 * reference to the underlying array, so that changes made to the returned +551 * array have no effect on this <code>ResizableArray.</code> +552 * @return the double array. +553 */ +554 public synchronized double[] getElements() { +555 double[] elementArray = new double[numElements]; +556 System.arraycopy( internalArray, startIndex, elementArray, 0, +557 numElements); +558 return elementArray; +559 } +560 +561 /** +562 * The expansion factor controls the size of a new array when an array +563 * needs to be expanded. The <code>expansionMode</code> +564 * determines whether the size of the array is multiplied by the +565 * <code>expansionFactor</code> (MULTIPLICATIVE_MODE) or if +566 * the expansion is additive (ADDITIVE_MODE -- <code>expansionFactor</code> +567 * storage locations added). The default <code>expansionMode</code> is +568 * MULTIPLICATIVE_MODE and the default <code>expansionFactor</code> +569 * is 2.0. +570 * +571 * @return the expansion factor of this expandable double array +572 */ +573 public float getExpansionFactor() { +574 return expansionFactor; +575 } +576 +577 /** +578 * The <code>expansionMode</code> determines whether the internal storage +579 * array grows additively (ADDITIVE_MODE) or multiplicatively +580 * (MULTIPLICATIVE_MODE) when it is expanded. +581 * +582 * @return Returns the expansionMode. +583 */ +584 public int getExpansionMode() { +585 return expansionMode; +586 } +587 +588 /** +589 * Notice the package scope on this method. This method is simply here +590 * for the JUnit test, it allows us check if the expansion is working +591 * properly after a number of expansions. This is not meant to be a part +592 * of the public interface of this class. +593 * +594 * @return the length of the internal storage array. +595 */ +596 synchronized int getInternalLength() { +597 return internalArray.length; +598 } +599 +600 /** +601 * Returns the number of elements currently in the array. Please note +602 * that this is different from the length of the internal storage array. +603 * +604 * @return number of elements +605 */ +606 public synchronized int getNumElements() { +607 return numElements; +608 } +609 +610 /** +611 * Returns the internal storage array. Note that this method returns +612 * a reference to the internal storage array, not a copy, and to correctly +613 * address elements of the array, the <code>startIndex</code> is +614 * required (available via the {@link #start} method). This method should +615 * only be used in cases where copying the internal array is not practical. +616 * The {@link #getElements} method should be used in all other cases. +617 * +618 * +619 * @return the internal storage array used by this object +620 * @deprecated replaced by {@link #getInternalValues()} as of 2.0 +621 */ +622 @Deprecated +623 public synchronized double[] getValues() { +624 return internalArray; +625 } +626 +627 /** +628 * Returns the internal storage array. Note that this method returns +629 * a reference to the internal storage array, not a copy, and to correctly +630 * address elements of the array, the <code>startIndex</code> is +631 * required (available via the {@link #start} method). This method should +632 * only be used in cases where copying the internal array is not practical. +633 * The {@link #getElements} method should be used in all other cases. +634 * +635 * +636 * @return the internal storage array used by this object +637 * @since 2.0 +638 */ +639 public synchronized double[] getInternalValues() { +640 return internalArray; +641 } +642 +643 /** +644 * Sets the contraction criteria for this ExpandContractDoubleArray. +645 * +646 * @param contractionCriteria contraction criteria +647 */ +648 public void setContractionCriteria(float contractionCriteria) { +649 checkContractExpand(contractionCriteria, getExpansionFactor()); +650 synchronized(this) { +651 this.contractionCriteria = contractionCriteria; +652 } +653 } +654 +655 +656 /** +657 * Sets the element at the specified index. If the specified index is greater than +658 * <code>getNumElements() - 1</code>, the <code>numElements</code> property +659 * is increased to <code>index +1</code> and additional storage is allocated +660 * (if necessary) for the new element and all (uninitialized) elements +661 * between the new element and the previous end of the array). +662 * +663 * @param index index to store a value in +664 * @param value value to store at the specified index +665 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is less than +666 * zero. +667 */ +668 public synchronized void setElement(int index, double value) { +669 if (index < 0) { +670 throw MathRuntimeException.createArrayIndexOutOfBoundsException( +671 "cannot set an element at a negative index {0}", +672 index); +673 } +674 if (index + 1 > numElements) { +675 numElements = index + 1; +676 } +677 if ((startIndex + index) >= internalArray.length) { +678 expandTo(startIndex + (index + 1)); +679 } +680 internalArray[startIndex + index] = value; +681 } +682 +683 /** +684 * Sets the expansionFactor. Throws IllegalArgumentException if the +685 * the following conditions are not met: +686 * <ul> +687 * <li><code>expansionFactor > 1</code></li> +688 * <li><code>contractionFactor >= expansionFactor</code></li> +689 * </ul> +690 * @param expansionFactor the new expansion factor value. +691 * @throws IllegalArgumentException if expansionFactor is <= 1 or greater +692 * than contractionFactor +693 */ +694 public void setExpansionFactor(float expansionFactor) { +695 checkContractExpand(getContractionCriteria(), expansionFactor); +696 // The check above verifies that the expansion factor is > 1.0; +697 synchronized(this) { +698 this.expansionFactor = expansionFactor; +699 } +700 } +701 +702 /** +703 * Sets the <code>expansionMode</code>. The specified value must be one of +704 * ADDITIVE_MODE, MULTIPLICATIVE_MODE. +705 * +706 * @param expansionMode The expansionMode to set. +707 * @throws IllegalArgumentException if the specified mode value is not valid +708 */ +709 public void setExpansionMode(int expansionMode) { +710 if (expansionMode != MULTIPLICATIVE_MODE && +711 expansionMode != ADDITIVE_MODE) { +712 throw MathRuntimeException.createIllegalArgumentException( +713 "unsupported expansion mode {0}, supported modes are {1} ({2}) and {3} ({4})", +714 expansionMode, MULTIPLICATIVE_MODE, "MULTIPLICATIVE_MODE", +715 ADDITIVE_MODE, "ADDITIVE_MODE"); +716 } +717 synchronized(this) { +718 this.expansionMode = expansionMode; +719 } +720 } +721 +722 /** +723 * Sets the initial capacity. Should only be invoked by constructors. +724 * +725 * @param initialCapacity of the array +726 * @throws IllegalArgumentException if <code>initialCapacity</code> is not +727 * positive. +728 */ +729 protected void setInitialCapacity(int initialCapacity) { +730 if (initialCapacity > 0) { +731 synchronized(this) { +732 this.initialCapacity = initialCapacity; +733 } +734 } else { +735 throw MathRuntimeException.createIllegalArgumentException( +736 "initial capacity ({0}) is not positive", +737 initialCapacity); +738 } +739 } +740 +741 /** +742 * This function allows you to control the number of elements contained +743 * in this array, and can be used to "throw out" the last n values in an +744 * array. This function will also expand the internal array as needed. +745 * +746 * @param i a new number of elements +747 * @throws IllegalArgumentException if <code>i</code> is negative. +748 */ +749 public synchronized void setNumElements(int i) { +750 +751 // If index is negative thrown an error +752 if (i < 0) { +753 throw MathRuntimeException.createIllegalArgumentException( +754 "index ({0}) is not positive", +755 i); +756 } +757 +758 // Test the new num elements, check to see if the array needs to be +759 // expanded to accommodate this new number of elements +760 if ((startIndex + i) > internalArray.length) { +761 expandTo(startIndex + i); +762 } +763 +764 // Set the new number of elements to new value +765 numElements = i; +766 } +767 +768 /** +769 * Returns true if the internal storage array has too many unused +770 * storage positions. +771 * +772 * @return true if array satisfies the contraction criteria +773 */ +774 private synchronized boolean shouldContract() { +775 if (expansionMode == MULTIPLICATIVE_MODE) { +776 return (internalArray.length / ((float) numElements)) > contractionCriteria; +777 } else { +778 return (internalArray.length - numElements) > contractionCriteria; +779 } +780 } +781 +782 /** +783 * Returns the starting index of the internal array. The starting index is +784 * the position of the first addressable element in the internal storage +785 * array. The addressable elements in the array are <code> +786 * internalArray[startIndex],...,internalArray[startIndex + numElements -1] +787 * </code> +788 * +789 * @return starting index +790 */ +791 public synchronized int start() { +792 return startIndex; +793 } +794 +795 /** +796 * <p>Copies source to dest, copying the underlying data, so dest is +797 * a new, independent copy of source. Does not contract before +798 * the copy.</p> +799 * +800 * <p>Obtains synchronization locks on both source and dest +801 * (in that order) before performing the copy.</p> +802 * +803 * <p>Neither source nor dest may be null; otherwise a NullPointerException +804 * is thrown</p> +805 * +806 * @param source ResizableDoubleArray to copy +807 * @param dest ResizableArray to replace with a copy of the source array +808 * @since 2.0 +809 * +810 */ +811 public static void copy(ResizableDoubleArray source, ResizableDoubleArray dest) { +812 synchronized(source) { +813 synchronized(dest) { +814 dest.initialCapacity = source.initialCapacity; +815 dest.contractionCriteria = source.contractionCriteria; +816 dest.expansionFactor = source.expansionFactor; +817 dest.expansionMode = source.expansionMode; +818 dest.internalArray = new double[source.internalArray.length]; +819 System.arraycopy(source.internalArray, 0, dest.internalArray, +820 0, dest.internalArray.length); +821 dest.numElements = source.numElements; +822 dest.startIndex = source.startIndex; +823 } +824 } +825 } +826 +827 /** +828 * Returns a copy of the ResizableDoubleArray. Does not contract before +829 * the copy, so the returned object is an exact copy of this. +830 * +831 * @return a new ResizableDoubleArray with the same data and configuration +832 * properties as this +833 * @since 2.0 +834 */ +835 public synchronized ResizableDoubleArray copy() { +836 ResizableDoubleArray result = new ResizableDoubleArray(); +837 copy(this, result); +838 return result; +839 } +840 +841 /** +842 * Returns true iff object is a ResizableDoubleArray with the same properties +843 * as this and an identical internal storage array. +844 * +845 * @param object object to be compared for equality with this +846 * @return true iff object is a ResizableDoubleArray with the same data and +847 * properties as this +848 * @since 2.0 +849 */ +850 @Override +851 public boolean equals(Object object) { +852 if (object == this ) { +853 return true; +854 } +855 if (object instanceof ResizableDoubleArray == false) { +856 return false; +857 } +858 synchronized(this) { +859 synchronized(object) { +860 boolean result = true; +861 ResizableDoubleArray other = (ResizableDoubleArray) object; +862 result = result && (other.initialCapacity == initialCapacity); +863 result = result && (other.contractionCriteria == contractionCriteria); +864 result = result && (other.expansionFactor == expansionFactor); +865 result = result && (other.expansionMode == expansionMode); +866 result = result && (other.numElements == numElements); +867 result = result && (other.startIndex == startIndex); +868 if (!result) { +869 return false; +870 } else { +871 return Arrays.equals(internalArray, other.internalArray); +872 } +873 } +874 } +875 } +876 +877 /** +878 * Returns a hash code consistent with equals. +879 * +880 * @return hash code representing this ResizableDoubleArray +881 * @since 2.0 +882 */ +883 @Override +884 public synchronized int hashCode() { +885 int[] hashData = new int[7]; +886 hashData[0] = new Float(expansionFactor).hashCode(); +887 hashData[1] = new Float(contractionCriteria).hashCode(); +888 hashData[2] = expansionMode; +889 hashData[3] = Arrays.hashCode(internalArray); +890 hashData[4] = initialCapacity; +891 hashData[5] = numElements; +892 hashData[6] = startIndex; +893 return Arrays.hashCode(hashData); +894 } +895 +896 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + diff -r 970d26a94fb7 -r cbf34dd4d7e6 libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/TransformerMap.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/util/TransformerMap.html Tue Jan 04 10:02:07 2011 +0100 @@ -0,0 +1,255 @@ + + +
+001 /* +002 * Licensed to the Apache Software Foundation (ASF) under one or more +003 * contributor license agreements. See the NOTICE file distributed with +004 * this work for additional information regarding copyright ownership. +005 * The ASF licenses this file to You under the Apache License, Version 2.0 +006 * (the "License"); you may not use this file except in compliance with +007 * the License. You may obtain a copy of the License at +008 * +009 * http://www.apache.org/licenses/LICENSE-2.0 +010 * +011 * Unless required by applicable law or agreed to in writing, software +012 * distributed under the License is distributed on an "AS IS" BASIS, +013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +014 * See the License for the specific language governing permissions and +015 * limitations under the License. +016 */ +017 package org.apache.commons.math.util; +018 +019 import java.io.Serializable; +020 import java.util.Collection; +021 import java.util.HashMap; +022 import java.util.Map; +023 import java.util.Set; +024 +025 import org.apache.commons.math.MathException; +026 +027 /** +028 * This TansformerMap automates the transformation of mixed object types. +029 * It provides a means to set NumberTransformers that will be selected +030 * based on the Class of the object handed to the Maps +031 * <code>double transform(Object o)</code> method. +032 * @version $Revision: 922713 $ $Date: 2010-03-13 20:26:13 -0500 (Sat, 13 Mar 2010) $ +033 */ +034 public class TransformerMap implements NumberTransformer, Serializable { +035 +036 /** Serializable version identifier */ +037 private static final long serialVersionUID = 4605318041528645258L; +038 +039 /** +040 * A default Number Transformer for Numbers and numeric Strings. +041 */ +042 private NumberTransformer defaultTransformer = null; +043 +044 /** +045 * The internal Map. +046 */ +047 private Map<Class<?>, NumberTransformer> map = null; +048 +049 /** +050 * Build a map containing only the default transformer. +051 */ +052 public TransformerMap() { +053 map = new HashMap<Class<?>, NumberTransformer>(); +054 defaultTransformer = new DefaultTransformer(); +055 } +056 +057 /** +058 * Tests if a Class is present in the TransformerMap. +059 * @param key Class to check +060 * @return true|false +061 */ +062 public boolean containsClass(Class<?> key) { +063 return map.containsKey(key); +064 } +065 +066 /** +067 * Tests if a NumberTransformer is present in the TransformerMap. +068 * @param value NumberTransformer to check +069 * @return true|false +070 */ +071 public boolean containsTransformer(NumberTransformer value) { +072 return map.containsValue(value); +073 } +074 +075 /** +076 * Returns the Transformer that is mapped to a class +077 * if mapping is not present, this returns null. +078 * @param key The Class of the object +079 * @return the mapped NumberTransformer or null. +080 */ +081 public NumberTransformer getTransformer(Class<?> key) { +082 return map.get(key); +083 } +084 +085 /** +086 * Sets a Class to Transformer Mapping in the Map. If +087 * the Class is already present, this overwrites that +088 * mapping. +089 * @param key The Class +090 * @param transformer The NumberTransformer +091 * @return the replaced transformer if one is present +092 */ +093 public NumberTransformer putTransformer(Class<?> key, NumberTransformer transformer) { +094 return map.put(key, transformer); +095 } +096 +097 /** +098 * Removes a Class to Transformer Mapping in the Map. +099 * @param key The Class +100 * @return the removed transformer if one is present or +101 * null if none was present. +102 */ +103 public NumberTransformer removeTransformer(Class<?> key) { +104 return map.remove(key); +105 } +106 +107 /** +108 * Clears all the Class to Transformer mappings. +109 */ +110 public void clear() { +111 map.clear(); +112 } +113 +114 /** +115 * Returns the Set of Classes used as keys in the map. +116 * @return Set of Classes +117 */ +118 public Set<Class<?>> classes() { +119 return map.keySet(); +120 } +121 +122 /** +123 * Returns the Set of NumberTransformers used as values +124 * in the map. +125 * @return Set of NumberTransformers +126 */ +127 public Collection<NumberTransformer> transformers() { +128 return map.values(); +129 } +130 +131 /** +132 * Attempts to transform the Object against the map of +133 * NumberTransformers. Otherwise it returns Double.NaN. +134 * +135 * @param o the Object to be transformed. +136 * @return the double value of the Object. +137 * @throws MathException if the Object can not be transformed into a Double. +138 * @see org.apache.commons.math.util.NumberTransformer#transform(java.lang.Object) +139 */ +140 public double transform(Object o) throws MathException { +141 double value = Double.NaN; +142 +143 if (o instanceof Number || o instanceof String) { +144 value = defaultTransformer.transform(o); +145 } else { +146 NumberTransformer trans = getTransformer(o.getClass()); +147 if (trans != null) { +148 value = trans.transform(o); +149 } +150 } +151 +152 return value; +153 } +154 +155 /** {@inheritDoc} */ +156 @Override +157 public boolean equals(Object other) { +158 if (this == other) { +159 return true; +160 } +161 if (other instanceof TransformerMap) { +162 TransformerMap rhs = (TransformerMap) other; +163 if (! defaultTransformer.equals(rhs.defaultTransformer)) { +164 return false; +165 } +166 if (map.size() != rhs.map.size()) { +167 return false; +168 } +169 for (Map.Entry<Class<?>, NumberTransformer> entry : map.entrySet()) { +170 if (! entry.getValue().equals(rhs.map.get(entry.getKey()))) { +171 return false; +172 } +173 } +174 return true; +175 } +176 return false; +177 } +178 +179 /** {@inheritDoc} */ +180 @Override +181 public int hashCode() { +182 int hash = defaultTransformer.hashCode(); +183 for (NumberTransformer t : map.values()) { +184 hash = hash * 31 + t.hashCode(); +185 } +186 return hash; +187 } +188 +189 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ +