001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF 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 }