151 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
		
		
			
		
	
	
			151 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
|  | /**
 | ||
|  |  * @file    numericalDerivative.h | ||
|  |  * @brief   Some functions to compute numerical derivatives | ||
|  |  * @author  Frank Dellaert | ||
|  |  */ | ||
|  | 
 | ||
|  | // \callgraph
 | ||
|  | 
 | ||
|  | #pragma once
 | ||
|  | 
 | ||
|  | #include "Matrix.h"
 | ||
|  | 
 | ||
|  | namespace gtsam { | ||
|  | 
 | ||
|  |   /**
 | ||
|  |    * Compute numerical derivative in arument 1 of unary function | ||
|  |    * @param h unary function yielding m-vector | ||
|  |    * @param x n-dimensional value at which to evaluate h | ||
|  |    * @param delta increment for numerical derivative | ||
|  |    * @return m*n Jacobian computed via central differencing | ||
|  |    */ | ||
|  |   Matrix NumericalDerivative11 | ||
|  |    (Vector (*h)(const Vector&), const Vector& x, double delta=1e-5); | ||
|  | 
 | ||
|  |   /**
 | ||
|  | 	* templated version (starts with LOWERCASE n) | ||
|  | 	 * Class Y is the output arguement | ||
|  | 	 * Class X is the input argument | ||
|  |    * both classes need dim, exmap, vector | ||
|  |    */ | ||
|  |   template<class Y, class X> | ||
|  |     Matrix numericalDerivative11 | ||
|  |     (Y (*h)(const X&), const X& x, double delta=1e-5) { | ||
|  |     Vector hx = h(x).vector(); | ||
|  |     double factor = 1.0/(2.0*delta); | ||
|  |     const size_t m = hx.size(), n = x.dim(); | ||
|  |     Vector d(n,0.0); | ||
|  |     Matrix H = zeros(m,n); | ||
|  |     for (size_t j=0;j<n;j++) { | ||
|  |       d(j) +=   delta; Vector hxplus = h(x.exmap(d)).vector();  | ||
|  |       d(j) -= 2*delta; Vector hxmin  = h(x.exmap(d)).vector(); | ||
|  |       d(j) +=   delta; Vector dh = (hxplus-hxmin)*factor; | ||
|  |       for (size_t i=0;i<m;i++) H(i,j) = dh(i); | ||
|  |     } | ||
|  |     return H; | ||
|  |   } | ||
|  | 
 | ||
|  |   /**
 | ||
|  |    * Compute numerical derivative in argument 1 of binary function | ||
|  |    * @param h binary function yielding m-vector | ||
|  |    * @param x1 n-dimensional first argument value | ||
|  |    * @param x2 second argument value | ||
|  |    * @param delta increment for numerical derivative | ||
|  |    * @return m*n Jacobian computed via central differencing | ||
|  |    */ | ||
|  |   Matrix NumericalDerivative21 | ||
|  |     (Vector (*h)(const Vector&, const Vector&), const Vector& x1, const Vector& x2, double delta=1e-5); | ||
|  | 
 | ||
|  |   /**
 | ||
|  |    * templated version (starts with LOWERCASE n) | ||
|  |    * classes need dim, exmap, vector | ||
|  |    */ | ||
|  |    template<class Y, class X1, class X2> | ||
|  |     Matrix numericalDerivative21 | ||
|  |     (Y (*h)(const X1&, const X2&),  | ||
|  |      const X1& x1, const X2& x2, double delta=1e-5)  | ||
|  |   { | ||
|  |     Vector hx = h(x1,x2).vector(); | ||
|  |     double factor = 1.0/(2.0*delta); | ||
|  |     const size_t m = hx.size(), n = x1.dim(); | ||
|  |     Vector d(n,0.0); | ||
|  |     Matrix H = zeros(m,n); | ||
|  |     for (size_t j=0;j<n;j++) { | ||
|  |       d(j) +=   delta; Vector hxplus = h(x1.exmap(d),x2).vector(); | ||
|  |       d(j) -= 2*delta; Vector hxmin  = h(x1.exmap(d),x2).vector(); | ||
|  |       d(j) +=   delta; Vector dh = (hxplus-hxmin)*factor; | ||
|  |       for (size_t i=0;i<m;i++) H(i,j) = dh(i); | ||
|  |     } | ||
|  |     return H; | ||
|  |   } | ||
|  | 
 | ||
|  |   /**
 | ||
|  |    * Compute numerical derivative in arument 2 of binary function | ||
|  |    * @param h binary function yielding m-vector | ||
|  |    * @param x1 first argument value | ||
|  |    * @param x2 n-dimensional second argument value | ||
|  |    * @param delta increment for numerical derivative | ||
|  |    * @return m*n Jacobian computed via central differencing | ||
|  |    */ | ||
|  |   Matrix NumericalDerivative22 | ||
|  |     (Vector (*h)(const Vector&, const Vector&), const Vector& x1, const Vector& x2, double delta=1e-5); | ||
|  | 
 | ||
|  |   /**
 | ||
|  |    *  templated version (starts with LOWERCASE n) | ||
|  |    * classes need dim, exmap, vector | ||
|  |    */ | ||
|  |   template<class Y, class X1, class X2> | ||
|  |     Matrix numericalDerivative22 | ||
|  |     (Y (*h)(const X1&, const X2&),  | ||
|  |      const X1& x1, const X2& x2, double delta=1e-5)  | ||
|  |   { | ||
|  |     Vector hx = h(x1,x2).vector(); | ||
|  |     double factor = 1.0/(2.0*delta); | ||
|  |     const size_t m = hx.size(), n = x2.dim(); | ||
|  |     Vector d(n,0.0); | ||
|  |     Matrix H = zeros(m,n); | ||
|  |     for (size_t j=0;j<n;j++) { | ||
|  |       d(j) +=   delta; Vector hxplus = h(x1,x2.exmap(d)).vector(); | ||
|  |       d(j) -= 2*delta; Vector hxmin  = h(x1,x2.exmap(d)).vector(); | ||
|  |       d(j) +=   delta; Vector dh = (hxplus-hxmin)*factor; | ||
|  |       for (size_t i=0;i<m;i++) H(i,j) = dh(i); | ||
|  |     } | ||
|  |     return H; | ||
|  |   } | ||
|  | 
 | ||
|  |   /**
 | ||
|  |    * Compute numerical derivative in argument 1 of binary function | ||
|  |    * @param h binary function yielding m-vector | ||
|  |    * @param x1 n-dimensional first argument value | ||
|  |    * @param x2 second argument value | ||
|  |    * @param delta increment for numerical derivative | ||
|  |    * @return m*n Jacobian computed via central differencing | ||
|  |    */ | ||
|  |   Matrix NumericalDerivative31 | ||
|  |     (Vector (*h)(const Vector&, const Vector&, const Vector&), const Vector& x1, const Vector& x2, const Vector& x3, double delta=1e-5); | ||
|  | 
 | ||
|  |   /**
 | ||
|  |    * templated version (starts with LOWERCASE n) | ||
|  |    * classes need dim, exmap, vector | ||
|  |    */ | ||
|  |   template<class Y, class X1, class X2, class X3> | ||
|  |     Matrix numericalDerivative31 | ||
|  |     (Y (*h)(const X1&, const X2&, const X3&),  | ||
|  |      const X1& x1, const X2& x2, const X3& x3, double delta=1e-5)  | ||
|  |   { | ||
|  |     Vector hx = h(x1,x2,x3).vector(); | ||
|  |     double factor = 1.0/(2.0*delta); | ||
|  |     const size_t m = hx.size(), n = x1.dim(); | ||
|  |     Vector d(n,0.0); | ||
|  |     Matrix H = zeros(m,n); | ||
|  |     for (size_t j=0;j<n;j++) { | ||
|  |       d(j) +=   delta; Vector hxplus = h(x1.exmap(d),x2,x3).vector(); | ||
|  |       d(j) -= 2*delta; Vector hxmin  = h(x1.exmap(d),x2,x3).vector(); | ||
|  |       d(j) +=   delta; Vector dh = (hxplus-hxmin)*factor; | ||
|  |       for (size_t i=0;i<m;i++) H(i,j) = dh(i); | ||
|  |     } | ||
|  |     return H; | ||
|  |   } | ||
|  | 
 | ||
|  | } |