View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math.analysis;
18  
19  import java.io.Serializable;
20  
21  /**
22   * Provide a default implementation for several generic functions.
23   *  
24   * @version $Revision: 620312 $ $Date: 2008-02-10 12:28:59 -0700 (Sun, 10 Feb 2008) $
25   * @since 1.2
26   */
27  public abstract class UnivariateRealIntegratorImpl implements
28      UnivariateRealIntegrator, Serializable {
29  
30      /** serializable version identifier */
31      static final long serialVersionUID = -3365294665201465048L;
32  
33      /** maximum relative error */
34      protected double relativeAccuracy;
35  
36      /** maximum number of iterations */
37      protected int maximalIterationCount;
38  
39      /** minimum number of iterations */
40      protected int minimalIterationCount;
41  
42      /** default maximum relative error */
43      protected double defaultRelativeAccuracy;
44  
45      /** default maximum number of iterations */
46      protected int defaultMaximalIterationCount;
47  
48      /** default minimum number of iterations */
49      protected int defaultMinimalIterationCount;
50  
51      /** indicates whether an integral has been computed */
52      protected boolean resultComputed = false;
53  
54      /** the last computed integral */
55      protected double result;
56  
57      /** the last iteration count */
58      protected int iterationCount;
59  
60      /** the integrand function */
61      protected UnivariateRealFunction f;
62  
63      /**
64       * Construct an integrator with given iteration count and accuracy.
65       * 
66       * @param f the integrand function
67       * @param defaultMaximalIterationCount maximum number of iterations
68       * @throws IllegalArgumentException if f is null or the iteration
69       * limits are not valid
70       */
71      protected UnivariateRealIntegratorImpl(
72          UnivariateRealFunction f,
73          int defaultMaximalIterationCount) throws IllegalArgumentException {
74          
75          if (f == null) {
76              throw new IllegalArgumentException("Function can not be null.");
77          }
78  
79          this.f = f;
80          // parameters that may depend on algorithm
81          this.defaultMaximalIterationCount = defaultMaximalIterationCount;
82          this.maximalIterationCount = defaultMaximalIterationCount;
83          // parameters that are problem specific
84          this.defaultRelativeAccuracy = 1E-6;
85          this.relativeAccuracy = defaultRelativeAccuracy;
86          this.defaultMinimalIterationCount = 3;
87          this.minimalIterationCount = defaultMinimalIterationCount;
88          
89          verifyIterationCount();
90      }
91  
92      /**
93       * Access the last computed integral.
94       * 
95       * @return the last computed integral
96       * @throws IllegalStateException if no integral has been computed
97       */
98      public double getResult() throws IllegalStateException {
99          if (resultComputed) {
100             return result;
101         } else {
102             throw new IllegalStateException("No result available.");
103         }
104     }
105 
106     /**
107      * Access the last iteration count.
108      * 
109      * @return the last iteration count
110      * @throws IllegalStateException if no integral has been computed
111      */
112     public int getIterationCount() throws IllegalStateException {
113         if (resultComputed) {
114             return iterationCount;
115         } else {
116             throw new IllegalStateException("No result available.");
117         }
118     }
119 
120     /**
121      * Convenience function for implementations.
122      * 
123      * @param result the result to set
124      * @param iterationCount the iteration count to set
125      */
126     protected final void setResult(double result, int iterationCount) {
127         this.result = result;
128         this.iterationCount = iterationCount;
129         this.resultComputed = true;
130     }
131 
132     /**
133      * Convenience function for implementations.
134      */
135     protected final void clearResult() {
136         this.resultComputed = false;
137     }
138 
139     /**
140      * Set the upper limit for the number of iterations.
141      * 
142      * @param count maximum number of iterations
143      */
144     public void setMaximalIterationCount(int count) {
145         maximalIterationCount = count;
146     }
147 
148     /**
149      * Get the upper limit for the number of iterations.
150      * 
151      * @return the actual upper limit
152      */
153     public int getMaximalIterationCount() {
154         return maximalIterationCount;
155     }
156 
157     /**
158      * Reset the upper limit for the number of iterations to the default.
159      */
160     public void resetMaximalIterationCount() {
161         maximalIterationCount = defaultMaximalIterationCount;
162     }
163 
164     /**
165      * Set the lower limit for the number of iterations.
166      * 
167      * @param count minimum number of iterations
168      */
169     public void setMinimalIterationCount(int count) {
170         minimalIterationCount = count;
171     }
172 
173     /**
174      * Get the lower limit for the number of iterations.
175      * 
176      * @return the actual lower limit
177      */
178     public int getMinimalIterationCount() {
179         return minimalIterationCount;
180     }
181 
182     /**
183      * Reset the lower limit for the number of iterations to the default.
184      */
185     public void resetMinimalIterationCount() {
186         minimalIterationCount = defaultMinimalIterationCount;
187     }
188 
189     /**
190      * Set the relative accuracy.
191      * 
192      * @param accuracy the relative accuracy
193      * @throws IllegalArgumentException if the accuracy can't be achieved by
194      * the integrator or is otherwise deemed unreasonable
195      */
196     public void setRelativeAccuracy(double accuracy) {
197         relativeAccuracy = accuracy;
198     }
199 
200     /**
201      * Get the actual relative accuracy.
202      *
203      * @return the accuracy
204      */
205     public double getRelativeAccuracy() {
206         return relativeAccuracy;
207     }
208 
209     /**
210      * Reset the relative accuracy to the default.
211      */
212     public void resetRelativeAccuracy() {
213         relativeAccuracy = defaultRelativeAccuracy;
214     }
215 
216     /**
217      * Returns true if the arguments form a (strictly) increasing sequence
218      * 
219      * @param start first number
220      * @param mid second number
221      * @param end third number
222      * @return true if the arguments form an increasing sequence
223      */
224     protected boolean isSequence(double start, double mid, double end) {
225         return (start < mid) && (mid < end);
226     }
227 
228     /**
229      * Verifies that the endpoints specify an interval.
230      * 
231      * @param lower lower endpoint
232      * @param upper upper endpoint
233      * @throws IllegalArgumentException if not interval
234      */
235     protected void verifyInterval(double lower, double upper) throws
236         IllegalArgumentException {
237         if (lower >= upper) {
238             throw new IllegalArgumentException
239                 ("Endpoints do not specify an interval: [" + lower +
240                 ", " + upper + "]");
241         }       
242     }
243 
244     /**
245      * Verifies that the upper and lower limits of iterations are valid.
246      * 
247      * @throws IllegalArgumentException if not valid
248      */
249     protected void verifyIterationCount() throws IllegalArgumentException {
250         if (!isSequence(0, minimalIterationCount, maximalIterationCount+1)) {
251             throw new IllegalArgumentException
252                 ("Invalid iteration limits: min=" + minimalIterationCount +
253                 " max=" + maximalIterationCount);
254         }       
255     }
256 }