optimization/GaussNewtonOptimizer.cpp
// Use cholesky decomposition to calculate the descent direction
// Split fx into fx1(explicit part) and fx2(implicit part)
Use cholesky decomposition to calculate the descent direction
Split fx into fx1(explicit part) and fx2(implicit part)
Use cholesky decomposition to calculate the descent direction Split fx into fx1 ( explicit part ) and fx2 ( implicit part )
VectorXd GaussNewtonOptimizer::descentDirection(const Eigen::SparseMatrix<double> &Jf,
												const VectorXd &fx,
												SimplicialLDLT<SparseMd> &chol,
												bool symbolic)
{
	MatrixXd I = MatrixXd::Identity(Jf.cols(), Jf.cols());
  	SparseMd JfTJf = Jf.transpose() * Jf + mu * I;
  	if(symbolic)
  		chol.analyzePattern(JfTJf);
  	chol.compute(JfTJf);
  	VectorXd x = chol.solve(-1.0 * Jf.transpose() * fx);
  	if(chol.info() == Eigen::ComputationInfo::NumericalIssue)
  	{
  		std::cout << "ERROR: Cholesky Decompostion Fail! JfTJf is not positive definite" << std::endl;
  		MatrixXd temp = MatrixXd(JfTJf);
  		SelfAdjointEigenSolver<MatrixXd> solver(temp);
  		int size = solver.eigenvalues().size();
  		VectorXd x;
  		for(int k = 0; k < size; k++)
  		{
  			complex<double> result = solver.eigenvalues()(k);
  			if(result.real() < 0.0f)
  			{
  				std::cout << "catch negative eigenvalue (" << k << ") : " << result << std::endl;
  				x = solver.eigenvectors().col(k);
  			}
  		}
  		return x;
	}
  	return x;
}
VectorXd GaussNewtonOptimizer :: descentDirection ( const Eigen :: SparseMatrix < double > & Jf , const VectorXd & fx , SimplicialLDLT < SparseMd > & chol , bool symbolic ) { MatrixXd I = MatrixXd :: Identity ( Jf . cols ( ) , Jf . cols ( ) ) ; SparseMd JfTJf = Jf . transpose ( ) * Jf + mu * I ; if ( symbolic ) chol . analyzePattern ( JfTJf ) ; chol . compute ( JfTJf ) ; VectorXd x = chol . solve ( -1.0 * Jf . transpose ( ) * fx ) ; if ( chol . info ( ) == Eigen :: ComputationInfo :: NumericalIssue ) { std :: cout << " " << std :: endl ; MatrixXd temp = MatrixXd ( JfTJf ) ; SelfAdjointEigenSolver < MatrixXd > solver ( temp ) ; int size = solver . eigenvalues ( ) . size ( ) ; VectorXd x ; for ( int k = 0 ; k < size ; k ++ ) { complex < double > result = solver . eigenvalues ( ) ( k ) ; if ( result . real ( ) < 0.0f ) { std :: cout << " " << k << " " << result << std :: endl ; x = solver . eigenvectors ( ) . col ( k ) ; } } return x ; } return x ; }
Use cholesky decomposition to calculate the descent direction
Split fx into fx1(explicit part) and fx2(implicit part)
Use cholesky decomposition to calculate the descent direction Split fx into fx1 ( explicit part ) and fx2 ( implicit part )
// Solving // Compute the sparse Cholesky Decomposition of Jf^T * Jf // get the solution to the given right hand side // Calculate all the eigenvalues and catch the negative ones // use the first 0 eigenvector as the descent direction for debug // std::cout << solver.eigenvalues() << std::endl;