    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF 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    import org.apache.commons.math.exception.util.LocalizedFormats;
    023    import org.apache.commons.math.exception.NullArgumentException;
    024
    025    /**
    026     * Provide a default implementation for several generic functions.
    027     *
    028     * @version $Revision: 1072409 $ $Date: 2011-02-19 19:50:36 +0100 (sam. 19 f??vr. 2011) $
    029     * @since 1.2
    030     */
    031    public abstract class UnivariateRealIntegratorImpl
    032        extends ConvergingAlgorithmImpl implements UnivariateRealIntegrator {
    033
    034        /** Serializable version identifier. */
    035        private static final long serialVersionUID = 6248808456637441533L;
    036
    037        /** minimum number of iterations */
    038        protected int minimalIterationCount;
    039
    040        /** default minimum number of iterations */
    041        protected int defaultMinimalIterationCount;
    042
    043        /** indicates whether an integral has been computed */
    044        protected boolean resultComputed = false;
    045
    046        /** the last computed integral */
    047        protected double result;
    048
    049        /**
    050         * The integrand function.
    051         *
    052         * @deprecated as of 2.0 the integrand function is passed as an argument
    053         * to the {@link #integrate(UnivariateRealFunction, double, double)}method.
    054         */
    055        @Deprecated
    056        protected UnivariateRealFunction f;
    057
    058        /**
    059         * Construct an integrator with given iteration count and accuracy.
    060         *
    061         * @param f the integrand function
    062         * @param defaultMaximalIterationCount maximum number of iterations
    063         * @throws IllegalArgumentException if f is null or the iteration
    064         * limits are not valid
    065         * @deprecated as of 2.0 the integrand function is passed as an argument
    066         * to the {@link #integrate(UnivariateRealFunction, double, double)}method.
    067         */
    068        @Deprecated
    069        protected UnivariateRealIntegratorImpl(final UnivariateRealFunction f,
    070                                               final int defaultMaximalIterationCount)
    071            throws IllegalArgumentException {
    072            super(defaultMaximalIterationCount, 1.0e-15);
    073            if (f == null) {
    074                throw new NullArgumentException(LocalizedFormats.FUNCTION);
    075            }
    076
    077            this.f = f;
    078
    079            // parameters that are problem specific
    080            setRelativeAccuracy(1.0e-6);
    081            this.defaultMinimalIterationCount = 3;
    082            this.minimalIterationCount = defaultMinimalIterationCount;
    083
    084            verifyIterationCount();
    085        }
    086
    087        /**
    088         * Construct an integrator with given iteration count and accuracy.
    089         *
    090         * @param defaultMaximalIterationCount maximum number of iterations
    091         * @throws IllegalArgumentException if f is null or the iteration
    092         * limits are not valid
    093         */
    094        protected UnivariateRealIntegratorImpl(final int defaultMaximalIterationCount)
    095            throws IllegalArgumentException {
    096            super(defaultMaximalIterationCount, 1.0e-15);
    097
    098            // parameters that are problem specific
    099            setRelativeAccuracy(1.0e-6);
    100            this.defaultMinimalIterationCount = 3;
    101            this.minimalIterationCount = defaultMinimalIterationCount;
    102
    103            verifyIterationCount();
    104        }
    105
    106        /**
    107         * Access the last computed integral.
    108         *
    109         * @return the last computed integral
    110         * @throws IllegalStateException if no integral has been computed
    111         */
    112        public double getResult() throws IllegalStateException {
    113            if (resultComputed) {
    114                return result;
    115            } else {
    116                throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_RESULT_AVAILABLE);
    117            }
    118        }
    119
    120        /**
    121         * Convenience function for implementations.
    122         *
    123         * @param newResult the result to set
    124         * @param iterationCount the iteration count to set
    125         */
    126        protected final void setResult(double newResult, int iterationCount) {
    127            this.result         = newResult;
    128            this.iterationCount = iterationCount;
    129            this.resultComputed = true;
    130        }
    131
    132        /**
    133         * Convenience function for implementations.
    134         */
    135        protected final void clearResult() {
    136            this.iterationCount = 0;
    137            this.resultComputed = false;
    138        }
    139
    140        /** {@inheritDoc} */
    141        public void setMinimalIterationCount(int count) {
    142            minimalIterationCount = count;
    143        }
    144
    145        /** {@inheritDoc} */
    146        public int getMinimalIterationCount() {
    147            return minimalIterationCount;
    148        }
    149
    150        /** {@inheritDoc} */
    151        public void resetMinimalIterationCount() {
    152            minimalIterationCount = defaultMinimalIterationCount;
    153        }
    154
    155        /**
    156         * Verifies that the endpoints specify an interval.
    157         *
    158         * @param lower lower endpoint
    159         * @param upper upper endpoint
    160         * @throws IllegalArgumentException if not interval
    161         */
    162        protected void verifyInterval(double lower, double upper) throws
    163            IllegalArgumentException {
    164            if (lower >= upper) {
    165                throw MathRuntimeException.createIllegalArgumentException(
    166                        LocalizedFormats.ENDPOINTS_NOT_AN_INTERVAL,
    167                        lower, upper);
    168            }
    169        }
    170
    171        /**
    172         * Verifies that the upper and lower limits of iterations are valid.
    173         *
    174         * @throws IllegalArgumentException if not valid
    175         */
    176        protected void verifyIterationCount() throws IllegalArgumentException {
    177            if ((minimalIterationCount <= 0) || (maximalIterationCount <= minimalIterationCount)) {
    178                throw MathRuntimeException.createIllegalArgumentException(
    179                        LocalizedFormats.INVALID_ITERATIONS_LIMITS,
    180                        minimalIterationCount, maximalIterationCount);
    181            }
    182        }
    183    }