void Residual<_Type>::jacobian( const DenseVector<_Type>& state, DenseMatrix<_Type>& jac ) const { DenseVector<_Type> new_state( state ); // evaluation of the function DenseVector<_Type> f_at_new_state( ORDER_OF_SYSTEM, 0.0 ); // default is to FD the Jacobian for ( std::size_t i = 0; i < NUMBER_OF_VARS; ++i ) { new_state[ i ] += DELTA; residual_fn( new_state, f_at_new_state ); new_state[ i ] -= DELTA; jac.set_col( i, ( f_at_new_state - FN_AT_LAST_STATE ) / DELTA ); } }
void Tresidual<T>::jacobian( Tmatrix<T>& J, const Tvector<T>& x_k ) const { Tvector<T> new_state( ORDER, 0.0 ); // New state vector Tvector<T> f_eval( ORDER, 0.0 ); // Function evaluation Tvector<T> f_at_new_state( ORDER, 0.0); // Function evaluation at the new state for ( std::size_t alpha = 0; alpha < ORDER; ++alpha ) // Row index { for ( std::size_t beta = 0; beta < ORDER; ++beta ) // Column index { Tvector<T> delta(ORDER,0.0); // Perturbation vector delta[ beta ] += DELTA; new_state = x_k + delta; // Perturb the known value // Perurbed function evaluation residual_function( f_at_new_state, new_state ); residual_function( f_eval, x_k ); // Approximate the entry in the Jacobian J(alpha,beta) = ( f_at_new_state[ alpha ] - f_eval[ alpha ] ) / DELTA; } } }