001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF 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.nabla.numerical;
018
019 import java.io.Serializable;
020
021 import org.apache.commons.nabla.core.UnivariateDifferentiator;
022
023 /** This class represents a differentiation scheme based on finite differences.
024 * <p>The differences are based on regularly distributed points around the
025 * central test point according to a given h step.
026 * For example a four points scheme would use a linear combination of points
027 * <code>f(x-2h)</code>, <code>f(x-h)</code>, <code>f(x+h)</code> and
028 * <code>f(x+2h)</code> to compute the first derivative <code>f'(x)</code>
029 * (note that <code>f(x)</code> by itself is not used for the evaluation of
030 * <code>f'(x)</code>, but is used to compute the value of the function
031 * <code>f(x)</code).</p>
032 * <p>The computed differential is only an approximation. The error depends on
033 * the value of the high order derivatives of the function which were not
034 * canceled by the linear combination, the number of points and the step size.
035 * For example the four points scheme cancels the
036 * <code>f<sup>(2)</sup></code>, <code>f<sup>(3)</sup></code> and
037 * <code>f<sup>(4)</sup></code> high order derivatives but not the
038 * <code>f<sup>(5)</sup></code> and higher order terms. The theoretical error
039 * model for this scheme is <code>-2h<sup>4</sup>/5 f<sup>(5)</sup>(x) +
040 * O(h<sup>6</sup>)</code>. This model doesn't take into account numerical
041 * cancellation which occur when the steps are too small.</p>
042 * <p>The general expression of the theoretical error model is
043 * <code>A f<sup>(k)</sup> + O(h<sup>k+1</sup>)</code> where <code>A</code>
044 * is the value returned by {@link #getSignedErrorScaleFactor()} and
045 * <code>k</code> is the value returned by {@link #getOrderFirstNonCanceled()}.</p>
046 */
047 public abstract class FiniteDifferencesDifferentiator
048 implements UnivariateDifferentiator, Serializable {
049
050 /** Serializable UID. */
051 private static final long serialVersionUID = 3971239681079110480L;
052
053 /** Step size. */
054 private final double stepSize;
055
056 /** Error scale factor. */
057 private final double factor;
058
059 /** Order of the first non-canceled derivative. */
060 private final int order;
061
062 /** Simple constructor.
063 * @param stepSize step stepSize
064 * @param factor error scale factor
065 * @param order order of the first non-canceled derivative
066 */
067 protected FiniteDifferencesDifferentiator(final double stepSize,
068 final double factor,
069 final int order) {
070 this.stepSize = stepSize;
071 this.factor = factor;
072 this.order = order;
073 }
074
075 /** Get the signed error scale factor for the finite differences scheme.
076 * <p>The error scale factor is the value of the h-dependent
077 * factor of the first non-canceled high order differential of the function.
078 * For example since the error model for the four points scheme is
079 * <code>-2h<sup>4</sup>/5 f<sup>(5)</sup>(x) + O(h<sup>6</sup>)</code>,
080 * the signed error scale factor is <code>-2h<sup>4</sup>/5</code>.</p>
081 * @return error signed scale factor
082 * @see #getOrderFirstNonCanceled()
083 */
084 public double getSignedErrorScaleFactor() {
085 return factor;
086 }
087
088 /** Get the order of the first non-canceled derivative.
089 * <p>The error model of the scheme depends on the first non-canceled
090 * high order differential of the function. For example since the error
091 * model for the four points scheme is <code>-2h<sup>4</sup>/5
092 * f<sup>(5)</sup>(x) + O(h<sup>6</sup>)</code>, the order of the first
093 * non-canceled derivative is 5.
094 * @return order of the first non-canceled derivative
095 * @see #getSignedErrorScaleFactor()
096 */
097 public int getOrderFirstNonCanceled() {
098 return order;
099 }
100
101 /** Get the step size.
102 * @return step size
103 */
104 protected double getStepSize() {
105 return stepSize;
106 }
107
108 }