166 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			166 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
| /**
 | |
|  * @file    numericalDerivative.h
 | |
|  * @brief   Some functions to compute numerical derivatives
 | |
|  * @author  Frank Dellaert
 | |
|  */
 | |
| 
 | |
| // \callgraph
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include "Lie.h"
 | |
| #include "Matrix.h"
 | |
| 
 | |
| //#define LINEARIZE_AT_IDENTITY
 | |
| 
 | |
| namespace gtsam {
 | |
| 
 | |
|   /**
 | |
|    * Numerically compute gradient of scalar function
 | |
|    * Class X is the input argument
 | |
|    * The class X needs to have dim, expmap, logmap
 | |
|    */
 | |
|   template<class X>
 | |
|   Vector numericalGradient(double (*h)(const X&), const X& x, double delta=1e-5) {
 | |
|     double hx = h(x);
 | |
|     double factor = 1.0/(2.0*delta);
 | |
|     const size_t n = x.dim();
 | |
|     Vector d(n,0.0), g(n,0.0);
 | |
|     for (size_t j=0;j<n;j++) {
 | |
|       d(j) +=   delta; double hxplus = h(expmap(x,d));
 | |
|       d(j) -= 2*delta; double hxmin  = h(expmap(x,d));
 | |
|       d(j) +=   delta; g(j) = (hxplus-hxmin)*factor;
 | |
|     }
 | |
|     return g;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Compute numerical derivative in argument 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
 | |
|    * Class Y is the output argument
 | |
|    * Class X is the input argument
 | |
|    * @return m*n Jacobian computed via central differencing
 | |
|    * Both classes X,Y need dim, expmap, logmap
 | |
|    */
 | |
|   template<class Y, class X>
 | |
|   Matrix numericalDerivative11(Y (*h)(const X&), const X& x, double delta=1e-5) {
 | |
|     Y hx = h(x);
 | |
|     double factor = 1.0/(2.0*delta);
 | |
|     const size_t m = dim(hx), n = dim(x);
 | |
|     Vector d(n,0.0);
 | |
|     Matrix H = zeros(m,n);
 | |
|     for (size_t j=0;j<n;j++) {
 | |
| #ifdef LINEARIZE_AT_IDENTITY
 | |
|       d(j) +=   delta; Vector hxplus = logmap(h(expmap(x,d)));
 | |
|       d(j) -= 2*delta; Vector hxmin  = logmap(h(expmap(x,d)));
 | |
| #else
 | |
|       d(j) +=   delta; Vector hxplus = logmap(hx, h(expmap(x,d)));
 | |
|       d(j) -= 2*delta; Vector hxmin  = logmap(hx, h(expmap(x,d)));
 | |
| #endif
 | |
|       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
 | |
|    * All classes Y,X1,X2 need dim, expmap, logmap
 | |
|    */
 | |
|   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) {
 | |
|     Y hx = h(x1,x2);
 | |
|     double factor = 1.0/(2.0*delta);
 | |
|     const size_t m = dim(hx), n = dim(x1);
 | |
|     Vector d(n,0.0);
 | |
|     Matrix H = zeros(m,n);
 | |
|     for (size_t j=0;j<n;j++) {
 | |
| #ifdef LINEARIZE_AT_IDENTITY
 | |
|       d(j) +=   delta; Vector hxplus = logmap(h(expmap(x1,d),x2));
 | |
|       d(j) -= 2*delta; Vector hxmin  = logmap(h(expmap(x1,d),x2));
 | |
| #else
 | |
|       d(j) +=   delta; Vector hxplus = logmap(hx, h(expmap(x1,d),x2));
 | |
|       d(j) -= 2*delta; Vector hxmin  = logmap(hx, h(expmap(x1,d),x2));
 | |
| #endif
 | |
|       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 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
 | |
|    * All classes Y,X1,X2 need dim, expmap, logmap
 | |
|    */
 | |
|   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)
 | |
|   {
 | |
|     Y hx = h(x1,x2);
 | |
|     double factor = 1.0/(2.0*delta);
 | |
|     const size_t m = dim(hx), n = dim(x2);
 | |
|     Vector d(n,0.0);
 | |
|     Matrix H = zeros(m,n);
 | |
|     for (size_t j=0;j<n;j++) {
 | |
| #ifdef LINEARIZE_AT_IDENTITY
 | |
|       d(j) +=   delta; Vector hxplus = logmap(h(x1,expmap(x2,d)));
 | |
|       d(j) -= 2*delta; Vector hxmin  = logmap(h(x1,expmap(x2,d)));
 | |
| #else
 | |
|       d(j) +=   delta; Vector hxplus = logmap(hx, h(x1,expmap(x2,d)));
 | |
|       d(j) -= 2*delta; Vector hxmin  = logmap(hx, h(x1,expmap(x2,d)));
 | |
| #endif
 | |
|       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
 | |
|    * All classes Y,X1,X2,X3 need dim, expmap, logmap
 | |
|    */
 | |
|   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)
 | |
|   {
 | |
|     Y hx = h(x1,x2,x3);
 | |
|     double factor = 1.0/(2.0*delta);
 | |
|     const size_t m = dim(hx), n = dim(x1);
 | |
|     Vector d(n,0.0);
 | |
|     Matrix H = zeros(m,n);
 | |
|     for (size_t j=0;j<n;j++) {
 | |
| #ifdef LINEARIZE_AT_IDENTITY
 | |
|       d(j) +=   delta; Vector hxplus = logmap(h(expmap(x1,d),x2,x3));
 | |
|       d(j) -= 2*delta; Vector hxmin  = logmap(h(expmap(x1,d),x2,x3));
 | |
| #else
 | |
|       d(j) +=   delta; Vector hxplus = logmap(hx, h(expmap(x1,d),x2,x3));
 | |
|       d(j) -= 2*delta; Vector hxmin  = logmap(hx, h(expmap(x1,d),x2,x3));
 | |
| #endif
 | |
|       d(j) +=   delta; Vector dh = (hxplus-hxmin)*factor;
 | |
|       for (size_t i=0;i<m;i++) H(i,j) = dh(i);
 | |
|     }
 | |
|     return H;
 | |
|   }
 | |
| 
 | |
| }
 |