1 /* 2 * Copyright (C) 2012 Alberto Irurueta Carro (alberto@irurueta.com) 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.irurueta.numerical; 17 18 /** 19 * This class evaluates a multidimensional function and obtains its gradient 20 * along a line; such line is defined by an input point and a given direction. 21 * Using provided input point and direction, the multidimensional function's 22 * input parameters are determined, so they all lay on a line. 23 */ 24 public class DirectionalDerivativeEvaluator extends DirectionalEvaluator { 25 26 /** 27 * Listener to evaluate a multidimensional function's gradient. 28 */ 29 private GradientFunctionEvaluatorListener gradientListener; 30 31 /** 32 * Array containing gradient at point p. This is used internally. 33 */ 34 final double[] dft; 35 36 /** 37 * Constructor. 38 * 39 * @param listener Listener to evaluate a multidimensional function. 40 * @param gradientListener Listener to evaluate a multidimensional 41 * function's gradient. 42 * @param point Point used as a reference to determine the function's input 43 * parameters along a line. 44 * @param direction Vector indicating the direction of the line where the 45 * function is evaluated. 46 * @throws IllegalArgumentException Raised if point and direction don't have 47 * the same length. 48 */ 49 public DirectionalDerivativeEvaluator( 50 final MultiDimensionFunctionEvaluatorListener listener, 51 final GradientFunctionEvaluatorListener gradientListener, final double[] point, final double[] direction) { 52 super(listener, point, direction); 53 54 this.gradientListener = gradientListener; 55 dft = new double[point.length]; 56 } 57 58 /** 59 * Returns gradient listener that evaluates a multidimensional function 60 * gradient. 61 * If the gradient expression is not known (e.g. is not a closed 62 * expression), then a GradientEstimator can be used internally in the 63 * listener implementation. 64 * 65 * @return Gradient listener. 66 */ 67 public GradientFunctionEvaluatorListener getGradientListener() { 68 return gradientListener; 69 } 70 71 /** 72 * Sets gradient listener that evaluates a multidimensional function 73 * gradient. 74 * If the gradient expression is not known (e.g. is not a closed 75 * expression), then a GradientEstimator can be used internally in the 76 * listener implementation being provided. 77 * 78 * @param gradientListener Gradient listener 79 */ 80 public void setGradientListener(final GradientFunctionEvaluatorListener gradientListener) { 81 this.gradientListener = gradientListener; 82 } 83 84 /** 85 * Computes derivative on current direction of a function at distance x from 86 * current point and using current listener and gradient listener. 87 * 88 * @param x Distance from current point using current direction where 89 * function is being evaluated. 90 * @return Result of evaluating function. 91 * @throws EvaluationException Thrown if function evaluation fails. 92 */ 93 public double differentiateAt(final double x) throws EvaluationException { 94 final var length = point.length; 95 96 for (var i = 0; i < length; i++) { 97 p[i] = point[i] + x * direction[i]; 98 } 99 100 // Compute gradient at such point 101 gradientListener.evaluateGradient(p, dft); 102 103 // Obtain 1D derivative on corresponding direction 104 var df1 = 0.0; 105 for (var i = 0; i < length; i++) { 106 df1 += dft[i] * direction[i]; 107 } 108 return df1; 109 } 110 }