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