function [gradf, err] = tapas_riddersgradient(f, x, varargin) % Calculates the gradient of the function f at point x according to Ridders' method: % % Ridders, CJF. (1982). Accurate computation of F'(x) and F'(x) F''(x). Advances in Engineering % Software, 4(2), 75-6. % % INPUT: % f Function handle of a real function of n real variables which are passed as % *one* vector with n elements % x Point at which to differentiate f % % OUTPUT: % gradf Gradient of f at x (row vector) % err Error estimates (row vector) % % OPTIONS: % Optionally, the third argument of the function can be a structure containing further % settings for Ridder's method. % % varargin{1}.init_h Initial finite difference (default: 1) % varargin{1}.div Divisor used to reduce h on each step (default: 1.2) % varargin{1}.min_steps Minimum number of steps in h (default: 3) % varargin{1}.max_steps Maximum number of steps in h (default: 100) % varargin{1}.tf Terminate if last step worse than preceding by a factor of tf % (default: 2) % % -------------------------------------------------------------------------------------------------- % Copyright (C) 2012-2013 Christoph Mathys, TNU, UZH & ETHZ % % This file is released under the terms of the GNU General Public Licence (GPL), version 3. You can % redistribute it and/or modify it under the terms of the GPL (either version 3 or, at your option, % any later version). For further details, see the file COPYING or . n = length(x); % Defaults options.init_h = 1; options.div = 1.2; options.min_steps = 3; options.max_steps = 100; options.tf = 2; gradf = NaN(1,n); err = NaN(1,n); % Overrides if nargin > 2 options_ovr = varargin{1}; if isfield(options_ovr,'init_h') options.init_h = options_ovr.init_h; end if isfield(options_ovr,'div') options.div = options_ovr.div; end if isfield(options_ovr,'min_steps') options.min_steps = options_ovr.min_steps; end if isfield(options_ovr,'max_steps') options.max_steps = options_ovr.max_steps; end if isfield(options_ovr,'tf') options.tf = options_ovr.tf; end end % Check if f and x match try f(x); catch err error('tapas:hgf:ridders:CannotEvalFun', 'Function cannot be evaluated at differentiation point.'); end % Loop through argument variables for i = 1:n % Construct filehandle to be passed to riddersdiff fxi = @(xi) fxi(f,x,i,xi); % Calculate derivative [gradf(i), err(i)] = tapas_riddersdiff(fxi,x(i),options); end end function fxi = fxi(f,x,i,xi) xx = x; xx(i) = xi; fxi = f(xx); end