diff --git a/CoMISo/CMakeLists.txt b/CoMISo/CMakeLists.txt index 9ecb9e2911ae0dc8b05ad9f5ac41e2a3a57ee161..2530596c8f506c8f00d36be4af06f1f1481dc047 100644 --- a/CoMISo/CMakeLists.txt +++ b/CoMISo/CMakeLists.txt @@ -39,8 +39,43 @@ endif () #added by CAT find_package (SUITESPARSE) -if (NOT SUITESPARSE_FOUND ) - message (FATAL_ERROR "SUITESPARSE not found!") +if (SUITESPARSE_FOUND ) + set (COMISO_SUITESPARSE_CONFIG_FILE_SETTINGS "#define COMISO_SUITESPARSE_AVAILABLE 1" ) +else () + message (STATUS "SUITESPARSE not found!") + set (COMISO_SUITESPARSE_CONFIG_FILE_SETTINGS "#define COMISO_SUITESPARSE_AVAILABLE 0" ) +endif () + +find_package (MPI) +if (MPI_FOUND ) + set (COMISO_MPI_CONFIG_FILE_SETTINGS "#define COMISO_MPI_AVAILABLE 1" ) +else () + message (STATUS "MPI not found!") + set (COMISO_MPI_CONFIG_FILE_SETTINGS "#define COMISO_MPI_AVAILABLE 0" ) +endif () + +find_package (PETSC) +if (PETSC_FOUND ) + set (COMISO_PETSC_CONFIG_FILE_SETTINGS "#define COMISO_PETSC_AVAILABLE 1" ) +else () + message (STATUS "PETSC not found!") + set (COMISO_PETSC_CONFIG_FILE_SETTINGS "#define COMISO_PETSC_AVAILABLE 0" ) +endif () + +find_package (TAO) +if (TAO_FOUND ) + set (COMISO_TAO_CONFIG_FILE_SETTINGS "#define COMISO_TAO_AVAILABLE 1" ) +else () + message (STATUS "PETSC not found!") + set (COMISO_TAO_CONFIG_FILE_SETTINGS "#define COMISO_TAO_AVAILABLE 0" ) +endif () + +find_package (IPOPT) +if (IPOPT_FOUND ) + set (COMISO_IPOPT_CONFIG_FILE_SETTINGS "#define COMISO_IPOPT_AVAILABLE 1" ) +else () + message (STATUS "IPOPT not found!") + set (COMISO_IPOPT_CONFIG_FILE_SETTINGS "#define COMISO_IPOPT_AVAILABLE 0" ) endif () if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/factored_solver/CMakeLists.txt" ) @@ -60,8 +95,6 @@ if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/small_factored_example/CMakeLists.txt" add_subdirectory (Examples/small_factored_example) endif() - - include_directories ( .. ${CMAKE_CURRENT_SOURCE_DIR} @@ -69,6 +102,10 @@ include_directories ( ${Boost_INCLUDE_DIR} ${GMM_INCLUDE_DIR} ${SUITESPARSE_INCLUDE_DIRS} + ${MPI_INCLUDE_PATH} + ${PETSC_INCLUDE_DIRS} + ${TAO_INCLUDE_DIRS} + ${IPOPT_INCLUDE_DIR} ) # generate dllexport macros on windows @@ -79,12 +116,17 @@ endif () link_directories ( ${SUITESPARSE_LIBRARY_DIRS} +# ${MPI_LIBRARY_DIR} + ${PETSC_LIBRARY_DIR} + ${TAO_LIBRARY_DIR} + ${IPOPT_LIBRARY_DIR} ) # source code directories set (directories . - Solver + Solver + NSolver Config Utils QtWidgets @@ -142,26 +184,17 @@ else(NOT APPLE) ${QT_LIBRARIES} ${SUITESPARSE_LIBRARIES} ${BLAS_LIBRARIES} + ${PETSC_LIBRARIES} + ${TAO_LIBRARIES} + ${MPI_LIBRARIES} + ${IPOPT_LIBRARIES} ) endif(NOT APPLE) # display results acg_print_configure_header (COMISO "CoMISo") - - -if ( SUITESPARSE_FOUND ) - set (COMISO_SUITESPARSE_COFIG_FILE_SETTINGS "#define COMISO_ENABLE_SUITESPARSE" ) -else () - set (COMISO_SUITESPARSE_COFIG_FILE_SETTINGS "#define COMISO_DISABLE_SUITESPARSE" ) -endif () - - - - - - - +# write config file configure_file ("${CMAKE_CURRENT_SOURCE_DIR}/Config/config.hh.in" "${CMAKE_CURRENT_SOURCE_DIR}/Config/config.hh" @ONLY IMMEDIATE) diff --git a/CoMISo/Config/config.hh.in b/CoMISo/Config/config.hh.in index 069f2598ad422b3509334ee0f11483c31a0a7710..e884f27ba6af9a81cbeae1d4762e7faefc3ef98a 100644 --- a/CoMISo/Config/config.hh.in +++ b/CoMISo/Config/config.hh.in @@ -1,6 +1,10 @@ // Build time dependencies for CoMiso -@COMISO_SUITESPARSE_COFIG_FILE_SETTINGS@ +@COMISO_SUITESPARSE_CONFIG_FILE_SETTINGS@ +@COMISO_MPI_CONFIG_FILE_SETTINGS@ +@COMISO_PETSC_CONFIG_FILE_SETTINGS@ +@COMISO_TAO_CONFIG_FILE_SETTINGS@ +@COMISO_IPOPT_CONFIG_FILE_SETTINGS@ diff --git a/CoMISo/Examples/factored_solver/CMakeLists.txt b/CoMISo/Examples/factored_solver/CMakeLists.txt index 5e13f2133fad6719da903952478c1835a9458445..613a9e29550b092c6bfbe44533d293108c1680e4 100644 --- a/CoMISo/Examples/factored_solver/CMakeLists.txt +++ b/CoMISo/Examples/factored_solver/CMakeLists.txt @@ -1,5 +1,8 @@ include (ACGCommon) find_package(CoMISo) +find_package(SUITESPARSE) +find_package(MPI) + include_directories ( .. @@ -7,9 +10,13 @@ include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${COMISO_INCLUDE_DIR} + ${SUITESPARSE_INCLUDE_DIRS} ) link_directories ( + ${SUITESPARSE_LIBRARY_DIRS} + ${TAO_LIBRARY_DIR} + ${PETSC_LIBRARY_DIR} ) # source code directories @@ -33,8 +40,15 @@ else () acg_add_executable (factored_solver ${sources} ${headers} ) endif () +# enable rpath linking +set_target_properties(factored_solver PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1) + target_link_libraries (factored_solver CoMISo + ${SUITESPARSE_LIBRARIES} + ${MPI_LIBRARY} + ${PETSC_LIBRARY} + ${TAO_LIBRARY} ) if (APPLE) diff --git a/CoMISo/Examples/quadratic_solver/CMakeLists.txt b/CoMISo/Examples/quadratic_solver/CMakeLists.txt index ec707d0f000afd92f09a007d5a2c022de60696b9..e7a87a7558048f846df762691edc773f9dd42bdb 100644 --- a/CoMISo/Examples/quadratic_solver/CMakeLists.txt +++ b/CoMISo/Examples/quadratic_solver/CMakeLists.txt @@ -1,5 +1,7 @@ include (ACGCommon) find_package(CoMISo) +find_package(SUITESPARSE) +find_package(MPI) include_directories ( .. @@ -7,11 +9,13 @@ include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${COMISO_INCLUDE_DIR} + ${SUITESPARSE_INCLUDE_DIRS} ) link_directories ( - # ${CMAKE_CURRENT_BINARY_DIR}/Build/lib/CoMISo -#/data/home1/zimmer/projects/ConstrainedSolver/package/CoMISo/build/Build/lib/CoMISo + ${SUITESPARSE_LIBRARY_DIRS} + ${TAO_LIBRARY_DIR} + ${PETSC_LIBRARY_DIR} ) # source code directories @@ -35,8 +39,15 @@ else () acg_add_executable (quadratic_solver ${sources} ${headers} ) endif () +# enable rpath linking +set_target_properties(quadratic_solver PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1) + target_link_libraries (quadratic_solver CoMISo + ${SUITESPARSE_LIBRARIES} + ${MPI_LIBRARY} + ${PETSC_LIBRARY} + ${TAO_LIBRARY} ) if (APPLE) @@ -49,4 +60,3 @@ if (APPLE) MACOSX_BUNDLE_INFO_STRING "CoMISo quadratic_solver" ) endif () - diff --git a/CoMISo/Examples/small_factored_example/CMakeLists.txt b/CoMISo/Examples/small_factored_example/CMakeLists.txt index 1bb91799ca4062c53542bcf12d3dbd5f18129ba0..56b8405127a9f19d5f6134c1426ed4eea498b813 100644 --- a/CoMISo/Examples/small_factored_example/CMakeLists.txt +++ b/CoMISo/Examples/small_factored_example/CMakeLists.txt @@ -1,5 +1,7 @@ include (ACGCommon) find_package(CoMISo) +find_package(SUITESPARSE) +find_package(MPI) include_directories ( .. @@ -7,9 +9,13 @@ include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${COMISO_INCLUDE_DIR} + ${SUITESPARSE_INCLUDE_DIRS} ) link_directories ( + ${SUITESPARSE_LIBRARY_DIRS} + ${TAO_LIBRARY_DIR} + ${PETSC_LIBRARY_DIR} ) # source code directories @@ -33,8 +39,15 @@ else () acg_add_executable (small_factored_solver ${sources} ${headers} ) endif () +# enable rpath linking +set_target_properties(small_factored_solver PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1) + target_link_libraries (small_factored_solver CoMISo + ${SUITESPARSE_LIBRARIES} + ${MPI_LIBRARY} + ${PETSC_LIBRARY} + ${TAO_LIBRARY} ) if (APPLE) @@ -48,3 +61,4 @@ if (APPLE) ) endif () + diff --git a/CoMISo/Examples/small_quadratic_example/CMakeLists.txt b/CoMISo/Examples/small_quadratic_example/CMakeLists.txt index 605ebc6660c674d14ad20aaaf60721934b57ea0a..7ed6aec92e79cff7ea990e6a20d56089e4febb7a 100644 --- a/CoMISo/Examples/small_quadratic_example/CMakeLists.txt +++ b/CoMISo/Examples/small_quadratic_example/CMakeLists.txt @@ -1,5 +1,7 @@ include (ACGCommon) find_package(CoMISo) +find_package(SUITESPARSE) +find_package(MPI) include_directories ( .. @@ -7,9 +9,13 @@ include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${COMISO_INCLUDE_DIR} + ${SUITESPARSE_INCLUDE_DIRS} ) link_directories ( + ${SUITESPARSE_LIBRARY_DIRS} + ${TAO_LIBRARY_DIR} + ${PETSC_LIBRARY_DIR} ) # source code directories @@ -33,8 +39,15 @@ else () acg_add_executable (small_quadratic_solver ${sources} ${headers} ) endif () +# enable rpath linking +set_target_properties(small_quadratic_solver PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1) + target_link_libraries (small_quadratic_solver CoMISo + ${SUITESPARSE_LIBRARIES} + ${MPI_LIBRARY} + ${PETSC_LIBRARY} + ${TAO_LIBRARY} ) if (APPLE) @@ -48,3 +61,4 @@ if (APPLE) ) endif () + diff --git a/CoMISo/NSolver/LinearConstraintHandlerElimination.cc b/CoMISo/NSolver/LinearConstraintHandlerElimination.cc new file mode 100644 index 0000000000000000000000000000000000000000..6aee5c65b732ad617a72ca284532755ce68d7f74 --- /dev/null +++ b/CoMISo/NSolver/LinearConstraintHandlerElimination.cc @@ -0,0 +1,172 @@ +//============================================================================= +// +// CLASS LinearConstraintHandlerElimination - IMPLEMENTATION TEMPLATES +// +//============================================================================= + + + +//== INCLUDES ================================================================= + +#include "LinearConstraintHandlerElimination.hh" + +//== NAMESPACES =============================================================== + +namespace ACG { + +//== IMPLEMENTATION ========================================================== + + +void +LinearConstraintHandlerElimination:: +initialize_identity(int _n) +{ + n_ = _n; + n_red_ = _n; + m_ = 0; + b_.resize(n_); + gmm::resize(C_, n_, n_); + gmm::resize(Ct_, n_, n_); + gmm::clear(C_); + gmm::clear(Ct_); + for(int i=0; i& _c) +{ + if( _c.size() ) + initialize( (double*) &(_c[0])); +} + + +//----------------------------------------------------------------------------- + + +void +LinearConstraintHandlerElimination:: +initialize( double* _c) +{ + // TODO +} + +//----------------------------------------------------------------------------- + +void +LinearConstraintHandlerElimination:: +transform_x( const std::vector& _x, std::vector& _xC) +{ + _xC.resize(n_red_); + if( _x.size() && _xC.size()) + transform_x((double*)&(_x[0]), &(_xC[0])); +} + + +//----------------------------------------------------------------------------- + + +void +LinearConstraintHandlerElimination:: +transform_x( double* _x, double* _xC) +{ + // directly exploit orthogonality of QR-factorization + // _xC = Ct_*(_x-b_) + + Vtemp_.resize(n_); + gmm::add(VectorPT(_x,n_), gmm::scaled(b_,-1.0), Vtemp_); + gmm::mult(Ct_,Vtemp_, VectorPT(_xC,n_red_)); + + // // set up least squares problem +// // Ct (_x - b_) = CtC _xC +// +// Vtemp_.resize(n_); +// Vtemp2_.resize(n_red_); +// gmm::add(VectorPT(_x,n_), gmm::scaled(b_,-1.0), Vtemp_); +// gmm::mult(Ct_,Vtemp_, Vtemp2_); +// +// // solve least squares problem +// if( n_red_) +// chol_CtC_.solve(_xC, (double*)(&(Vtemp2_[0]))); +} + + +//----------------------------------------------------------------------------- + + +void +LinearConstraintHandlerElimination:: +inv_transform_x( const std::vector& _xC, std::vector& _x) +{ + _x.resize(n_); + if( _x.size()) + inv_transform_x( (double*)&(_xC[0]), &(_x[0])); +} + + +//----------------------------------------------------------------------------- + + +void +LinearConstraintHandlerElimination:: +inv_transform_x( double* _xC, double* _x) +{ + gmm::copy(b_, VectorPT(_x, n_)); + gmm::mult_add(C_, VectorPT(_xC, n_red_), VectorPT(_x, n_)); +} + + +//----------------------------------------------------------------------------- + + +void +LinearConstraintHandlerElimination:: +transform_gradient( const std::vector& _g, std::vector& _gC) +{ + _gC.resize(n_red_); + if( _g.size() && _gC.size()) + transform_gradient( (double*)&(_g[0]), &(_gC[0])); +} + + +//----------------------------------------------------------------------------- + + +void +LinearConstraintHandlerElimination:: +transform_gradient( double* _g, double* _gC) +{ + gmm::mult( Ct_, VectorPT(_g, n_), VectorPT(_gC, n_red_)); +} + + +//----------------------------------------------------------------------------- + + +void +LinearConstraintHandlerElimination:: +transform_hessian( const RMatrix& _H, RMatrix& _HC) +{ + // resize and clear matrix + gmm::resize(_HC, n_red_, n_red_); + gmm::clear(_HC); + + gmm::resize(Mtemp_, n_, n_red_); + gmm::mult(_H,C_, Mtemp_); + gmm::mult(Ct_, Mtemp_, _HC); +} + + +//----------------------------------------------------------------------------- + + +//============================================================================= +} // namespace ACG +//============================================================================= diff --git a/CoMISo/NSolver/LinearConstraintHandlerElimination.hh b/CoMISo/NSolver/LinearConstraintHandlerElimination.hh new file mode 100644 index 0000000000000000000000000000000000000000..1a2af0cb0b28af2f8c9945f9233affd3110fbeba --- /dev/null +++ b/CoMISo/NSolver/LinearConstraintHandlerElimination.hh @@ -0,0 +1,121 @@ +//============================================================================= +// +// CLASS LinearConstraintHandlerElimination +// +//============================================================================= + + +#ifndef ACG_LINEARCONSTRAINTHANDLERELIMINATION_HH +#define ACG_LINEARCONSTRAINTHANDLERELIMINATION_HH + + +//== INCLUDES ================================================================= + +#include +#include + +//== FORWARDDECLARATIONS ====================================================== + +//== NAMESPACES =============================================================== + +namespace ACG { + +//== CLASS DEFINITION ========================================================= + + + + +/** \class LinearConstraintHandler LinearConstraintHandler.hh + + Brief Description. + + A more elaborate description follows. +*/ + + +class LinearConstraintHandlerElimination +{ +public: + + typedef gmm::col_matrix< gmm::wsvector< double> > CMatrix; + typedef gmm::row_matrix< gmm::wsvector< double> > RMatrix; + + // use c-arrays as vectors for gmm + typedef gmm::array1D_reference VectorPT; + + /// Constructor + LinearConstraintHandlerElimination() {initialize_identity(0);} + + // initialize Constructor + template + LinearConstraintHandlerElimination( const MatrixT& _C, const VectorT& _c) + {initialize(_C, _c); } + + + /// Destructor + ~LinearConstraintHandlerElimination() {} + + // number of variables + int n() {return n_;} + // number of reduced variables (after elimination) + int n_reduced() {return n_red_;} + // number of linearly independent constraints (n-n_reduced) + int n_constraints() { return m_;} + + // initialize new constraints + template + void initialize( const MatrixT& _C, const VectorT& _c); + + // no constraints + void initialize_identity(int _n); + + // initialize new constraints rhs only + void initialize( const std::vector& _c); + void initialize( double* _c); + + // transform x vector (least squares solution, fulfilling the constraints) + void transform_x( const std::vector& _x, std::vector& _xC); + void transform_x( double* _x, double* _xC); + + // inverse transform x ( x_reduced -> x) + void inv_transform_x( const std::vector& _xC, std::vector& _x); + void inv_transform_x( double* _xC, double* _x); + + // transform gradient + void transform_gradient( const std::vector& _g, std::vector& _gC); + void transform_gradient( double* _g, double* _gC); + + // transform hessian + void transform_hessian( const RMatrix& _H, RMatrix& _HC); + +private: + + // Constraints in basis transformation form x_orig = b_ + C_*x_reduced + // notice that C_ is a basis of the nullspace of the constraints + RMatrix C_; + RMatrix Ct_; + std::vector b_; + + // number of variables + int n_; + // number of constraints (linear independent) + int m_; + // number of reduced variables + int n_red_; + + // temp matrix to transform hessian and temp vectors + RMatrix Mtemp_; + std::vector Vtemp_; +}; + +//============================================================================= +} // namespace ACG +//============================================================================= +#if defined(INCLUDE_TEMPLATES) && !defined(ACG_LINEARCONSTRAINTHANDLERELIMINATION_C) +#define ACG_LINEARCONSTRAINTHANDLERELIMINATION_TEMPLATES +#include "LinearConstraintHandlerEliminationT.cc" +#endif +//============================================================================= +#endif // ACG_LINEARCONSTRAINTHANDLERELIMINATION_HH defined +//============================================================================= + diff --git a/CoMISo/NSolver/LinearConstraintHandlerEliminationT.cc b/CoMISo/NSolver/LinearConstraintHandlerEliminationT.cc new file mode 100644 index 0000000000000000000000000000000000000000..8108b2389282714e7671ad8727ff5a671f9fb7dd --- /dev/null +++ b/CoMISo/NSolver/LinearConstraintHandlerEliminationT.cc @@ -0,0 +1,89 @@ +//============================================================================= +// +// CLASS LinearConstraintHandlerElimination - IMPLEMENTATION +// +//============================================================================= + +#define ACG_LINEARCONSTRAINTHANDLERELIMINATION_C + +//== INCLUDES ================================================================= + +#include "LinearConstraintHandlerElimination.hh" +#include + +//== NAMESPACES =============================================================== + +namespace ACG { + +//== IMPLEMENTATION ========================================================== + +template +void +LinearConstraintHandlerElimination:: +initialize( const MatrixT& _C, const VectorT& _c) +{ + // no constraints? + if( gmm::mat_nrows(_C) == 0) + { + initialize_identity( gmm::mat_ncols(_C)); + } + else + { + // Construct constraints basis form via QR-factorization (see Nocedal 426...) + // Constraints in basis transformation form x_orig = b_ + C_*x_reduced + // notice that C_ is a basis of the nullspace of the constraints + // and _C*b_ = _c (means b_ is one solution of the constraints) + + std::cerr << "Initialize Linear Constraint handler...\n"; + COMISO::SparseQRSolver sqr; + // sqr.calc_system_gmm(_C); + CMatrix Q; + CMatrix R; + std::vector P; + int rank = sqr.factorize_system_gmm(gmm::transposed(_C), Q, R, P); + + // Q[0..m-1,rank..m-1] is basis of the nullspace -> C_, Ct_ + int m = gmm::mat_nrows(Q); + gmm::resize(C_, m, m-rank); + gmm::clear (C_); + gmm::copy( gmm::sub_matrix(Q, gmm::sub_interval(0,m), gmm::sub_interval(rank,m-rank)), C_); + gmm::resize(Ct_, gmm::mat_ncols(C_), gmm::mat_nrows(C_)); + gmm::copy( gmm::transposed(C_), Ct_); + + // compute b_ + b_.resize(gmm::mat_ncols(_C)); + // hack (too expensive, directly exploit Q,R,P from above) + sqr.calc_system_gmm(_C); + sqr.solve(b_, _c); + + n_ = gmm::mat_nrows(C_); + n_red_ = gmm::mat_ncols(C_); + m_ = n_ - n_red_; + /* + // set up least squares problem + gmm::resize(Mtemp_, gmm::mat_ncols(C_), gmm::mat_ncols(C_)); + gmm::mult(Ct_, C_, Mtemp_); + chol_CtC_.calc_system_gmm(Mtemp_); + */ + + // std::cerr << "Q: " << Q << std::endl; + // std::cerr << "R: " << R << std::endl; + // std::cerr << "P: " << P << std::endl; + // std::cerr << "C_:" << C_ << std::endl; + // std::cerr << "b_:" << b_ << std::endl; + // + // std::cerr << "#rows: " << gmm::mat_nrows(_C) << std::endl; + // std::cerr << "#nullspace: " << m << std::endl; + // std::cerr << "rank: " << rank << std::endl; + // std::cerr << "dim Q = " << gmm::mat_nrows(Q) << " x " << gmm::mat_ncols(Q) << std::endl; + // std::cerr << "dim R = " << gmm::mat_nrows(R) << " x " << gmm::mat_ncols(R) << std::endl; + } +} + +//----------------------------------------------------------------------------- + + + +//============================================================================= +} // namespace ACG +//============================================================================= diff --git a/CoMISo/NSolver/LinearConstraintHandlerPenalty.cc b/CoMISo/NSolver/LinearConstraintHandlerPenalty.cc new file mode 100644 index 0000000000000000000000000000000000000000..a9ffb2cf3d9a4f14b38fcd82fa2dd00cb7be7aa4 --- /dev/null +++ b/CoMISo/NSolver/LinearConstraintHandlerPenalty.cc @@ -0,0 +1,101 @@ +//============================================================================= +// +// CLASS LinearConstraintHandlerPenalty - IMPLEMENTATION TEMPLATES +// +//============================================================================= + + + +//== INCLUDES ================================================================= + +#include "LinearConstraintHandlerPenalty.hh" + +//== NAMESPACES =============================================================== + +namespace ACG { + +//== IMPLEMENTATION ========================================================== + + +void +LinearConstraintHandlerPenalty:: +initialize( const std::vector& _c) +{ + if( _c.size() ) + initialize( (double*) &(_c[0])); +} + + +//----------------------------------------------------------------------------- + + +void +LinearConstraintHandlerPenalty:: +initialize( double* _c) +{ + for(unsigned int i=0; i& _x, std::vector& _g) +{ + _g.resize(n_); + if( _x.size() && _g.size()) + add_penalty_gradient( (double*)&(_x[0]), &(_g[0])); +} + + +//----------------------------------------------------------------------------- + + +void +LinearConstraintHandlerPenalty:: +add_penalty_gradient( double* _x, double* _g) +{ + gmm::add( penalty_grad_b_, VectorPT(_g, n_)); + gmm::mult_add(penalty_H_, VectorPT(_x, n_), VectorPT(_g, n_)); +} + + +//----------------------------------------------------------------------------- + + +void +LinearConstraintHandlerPenalty:: +add_penalty_hessian( RMatrix& _H) +{ + gmm::add(penalty_H_, _H); +} + + +//----------------------------------------------------------------------------- + + +//============================================================================= +} // namespace ACG +//============================================================================= diff --git a/CoMISo/NSolver/LinearConstraintHandlerPenalty.hh b/CoMISo/NSolver/LinearConstraintHandlerPenalty.hh new file mode 100644 index 0000000000000000000000000000000000000000..283167c4d60d7b5028bd11d2ba6bd9d8b2372f9b --- /dev/null +++ b/CoMISo/NSolver/LinearConstraintHandlerPenalty.hh @@ -0,0 +1,116 @@ +//============================================================================= +// +// CLASS LinearConstraintHandlerElimination +// +//============================================================================= + + +#ifndef ACG_LINEARCONSTRAINTHANDLERPENALTY_HH +#define ACG_LINEARCONSTRAINTHANDLERPENALTY_HH + + +//== INCLUDES ================================================================= + +#include +#include + +//== FORWARDDECLARATIONS ====================================================== + +//== NAMESPACES =============================================================== + +namespace ACG { + +//== CLASS DEFINITION ========================================================= + + + + +/** \class LinearConstraintHandler LinearConstraintHandler.hh + + Brief Description. + + A more elaborate description follows. +*/ + + +class LinearConstraintHandlerPenalty +{ +public: + + typedef gmm::col_matrix< gmm::wsvector< double> > CMatrix; + typedef gmm::row_matrix< gmm::wsvector< double> > RMatrix; + + // use c-arrays as vectors for gmm + typedef gmm::array1D_reference VectorPT; + + /// Constructor + LinearConstraintHandlerPenalty() : penalty_(10000) {} + + // initialize Constructor + template + LinearConstraintHandlerPenalty( const MatrixT& _C, const VectorT& _c) : penalty_(10000) + {initialize(_C, _c); } + + + /// Destructor + ~LinearConstraintHandlerPenalty() {} + + // penalty weight + double& penalty() { return penalty_; } + + // number of variables + int n() {return n_;} + + // number of linearly independent constraints (n-n_reduced) + int n_constraints() { return m_;} + + // initialize new constraints + template + void initialize( const MatrixT& _C, const VectorT& _c); + + // initialize new constraints rhs only + void initialize( const std::vector& _c); + void initialize( double* _c); + + // transform energy + double add_penalty_f( double* _x, const double _f); + + // transform gradient + void add_penalty_gradient( const std::vector& _x, std::vector& _g); + void add_penalty_gradient( double* _x, double* _g); + + // transform hessian + void add_penalty_hessian( RMatrix& _H); + +private: + // penalty weight + double penalty_; + + // Linear Constraints C_*x_ = b_ + RMatrix C_; + std::vector b_; + + // precomputed penalty terms + RMatrix penalty_H_; + std::vector penalty_grad_b_; + + // temp vector + std::vector temp_; + + // number of variables + int n_; + // number of constraints (linear independent) + int m_; +}; + +//============================================================================= +} // namespace ACG +//============================================================================= +#if defined(INCLUDE_TEMPLATES) && !defined(ACG_LINEARCONSTRAINTHANDLERPENALTY_C) +#define ACG_LINEARCONSTRAINTHANDLERPENALTY_TEMPLATES +#include "LinearConstraintHandlerPenaltyT.cc" +#endif +//============================================================================= +#endif // ACG_LINEARCONSTRAINTHANDLERPENALTY_HH defined +//============================================================================= + diff --git a/CoMISo/NSolver/LinearConstraintHandlerPenaltyT.cc b/CoMISo/NSolver/LinearConstraintHandlerPenaltyT.cc new file mode 100644 index 0000000000000000000000000000000000000000..99ea49023c7b52ffc9a5cf4e7b687b7bd4ac2931 --- /dev/null +++ b/CoMISo/NSolver/LinearConstraintHandlerPenaltyT.cc @@ -0,0 +1,53 @@ +//============================================================================= +// +// CLASS LinearConstraintHandlerPenalty - IMPLEMENTATION +// +//============================================================================= + +#define ACG_LINEARCONSTRAINTHANDLERPENALTY_C + +//== INCLUDES ================================================================= + +#include "LinearConstraintHandlerPenalty.hh" + +//== NAMESPACES =============================================================== + +namespace ACG { + +//== IMPLEMENTATION ========================================================== + +template +void +LinearConstraintHandlerPenalty:: +initialize( const MatrixT& _C, const VectorT& _c) +{ + gmm::resize(C_, gmm::mat_nrows(_C), gmm::mat_ncols(_C)); + gmm::copy(_C,C_); + b_ = _c; + + n_ = gmm::mat_ncols(_C); + m_ = b_.size(); + + // initialize penalty stuff + // penalty_H_ = 2*penalty*A^t A + // penalty_grad_b_ = -2*penalty*A^t b + gmm::resize(penalty_H_, n_, n_); + gmm::clear(penalty_H_); + RMatrix temp(n_,m_); + gmm::copy( gmm::transposed(C_), temp); + gmm::mult( temp,C_, penalty_H_); + gmm::scale(penalty_H_, 2.0*penalty_); + + penalty_grad_b_.clear(); + penalty_grad_b_.resize(n_); + gmm::mult(gmm::transposed(C_), b_, penalty_grad_b_); + gmm::scale(penalty_grad_b_, -2.0*penalty_); +} + +//----------------------------------------------------------------------------- + + + +//============================================================================= +} // namespace ACG +//============================================================================= diff --git a/CoMISo/NSolver/NPDerivativeChecker.hh b/CoMISo/NSolver/NPDerivativeChecker.hh new file mode 100644 index 0000000000000000000000000000000000000000..6b7110a421b8e66e90855b5f92953e1c2f1fc513 --- /dev/null +++ b/CoMISo/NSolver/NPDerivativeChecker.hh @@ -0,0 +1,196 @@ +//============================================================================= +// +// CLASS NPDERIVATIVECHECKER +// +//============================================================================= + + +#ifndef ACG_NPDERIVATIVECHECKER_HH +#define ACG_NPDERIVATIVECHECKER_HH + + +//== INCLUDES ================================================================= + +#include +#include + +#include +#include +#include "NSolverGmmInterface.hh" + +//== FORWARDDECLARATIONS ====================================================== + +//== NAMESPACES =============================================================== + +namespace ACG { + +//== CLASS DEFINITION ========================================================= + + + +/** \class NPDerivativeChecker + + Brief Description. + + A more elaborate description follows. +*/ +class NPDerivativeChecker +{ +public: + + struct Config + { + Config() : x_min(-1.0), x_max(1.0), n_iters(1), dx(1e-5), eps(1e-3) + {} + + double x_min; + double x_max; + int n_iters; + double dx; + double eps; + }; + + /// Default constructor + NPDerivativeChecker() {} + + /// Destructor + ~NPDerivativeChecker() {} + + bool check_all(NSolverGmmInterface* _np, double _dx, double _eps) + { + conf_.dx = _dx; + conf_.eps = _eps; + return check_all(_np); + } + + bool check_all(NSolverGmmInterface* _np) + { + bool d1_ok = check_d1(_np); + bool d2_ok = check_d2(_np); + + return ( d1_ok && d2_ok); + } + + bool check_d1(NSolverGmmInterface* _np) + { + int n_ok = 0; + int n_errors = 0; + + + int n = _np->n_unknowns(); + std::vector x(n), g(n); + + for(int i=0; ieval_gradient(P(x), P(g)); + + for(int j=0; jeval_f(P(x)); + x[j] -= 2.0*conf_.dx; + double f0 = _np->eval_f(P(x)); + x[j] += conf_.dx; + double fd = (f1-f0)/(2.0*conf_.dx); + + if( fabs(fd-g[j]) > conf_.eps) + { + ++ n_errors; + std::cerr << "Gradient error in component " << j << ": " << g[j] + << " should be " << fd << " (" << fabs(fd-g[j]) << ")" << std::endl; + } + else ++ n_ok; + } + } + std::cerr << "############## Gradient Checker #############\n"; + std::cerr << "#ok : " << n_ok << std::endl; + std::cerr << "#error: " << n_errors << std::endl; + + return (n_errors == 0); + } + + bool check_d2(NSolverGmmInterface* _np) + { + int n_ok = 0; + int n_errors = 0; + + int n = _np->n_unknowns(); + std::vector x(n); + NSolverGmmInterface::SMatrixNS H(n,n); + + for(int i=0; ieval_hessian(P(x), H); + + for(int j=0; jeval_f(P(x)); + x[j] -= 2.0*conf_.dx; + double f1 = _np->eval_f(P(x)); + x[j] += 2.0*conf_.dx; + x[k] -= 2.0*conf_.dx; + double f2 = _np->eval_f(P(x)); + x[j] -= 2.0*conf_.dx; + double f3 = _np->eval_f(P(x)); + + double fd = (f0-f1-f2+f3)/(4.0*conf_.dx*conf_.dx); + + + if( fabs(fd-H(j,k)) > conf_.eps) + { + ++ n_errors; + std::cerr << "Hessian error in component " << j << "," << k << ": " << H(j,k) + << " should be (following FiniteDifferences) " << fd << " (" << fabs(fd-H(j,k)) << ")" << std::endl; + } + else ++ n_ok; + } + } + + std::cerr << "############## Hessian Checker #############\n"; + std::cerr << "#ok : " << n_ok << std::endl; + std::cerr << "#error: " << n_errors << std::endl; + + return (n_errors == 0); + } + + Config& config() { return conf_; } + +protected: + void get_random_x(std::vector& _x, double _xmin, double _xmax) + { + // get random values in [-1,1] + gmm::fill_random(_x); + double range = _xmax - _xmin; + for(unsigned int i=0; i<_x.size(); ++i) + _x[i] = (((_x[i]+1.0)/2.0)*range + _xmin); + } + + double* P(std::vector& _v) + { + if( !_v.empty()) + return ((double*)&_v[0]); + else + return 0; + } + +private: + Config conf_; +}; + + +//============================================================================= +} // namespace ACG +//============================================================================= +#endif // ACG_NPDERIVATIVECHECKER defined +//============================================================================= + diff --git a/CoMISo/NSolver/NPLinearConstraints.hh b/CoMISo/NSolver/NPLinearConstraints.hh new file mode 100644 index 0000000000000000000000000000000000000000..dfa6b5d4ba6b5feb15c4585abfce0d6e3d3be24c --- /dev/null +++ b/CoMISo/NSolver/NPLinearConstraints.hh @@ -0,0 +1,228 @@ +//============================================================================= +// +// CLASS NPLinearConstraints +// +//============================================================================= + + +#ifndef ACG_NPLINEARCONSTRAINTS_HH +#define ACG_NPLINEARCONSTRAINTS_HH + + +//== INCLUDES ================================================================= + +#include +#include "NSolverGmmInterface.hh" +#include "LinearConstraintHandlerElimination.hh" +#include "LinearConstraintHandlerPenalty.hh" +//#include "LinearConstraintHandlerLagrange.hh" + + +//== FORWARDDECLARATIONS ====================================================== + +//== NAMESPACES =============================================================== + +namespace ACG { + +//== CLASS DEFINITION ========================================================= + + + +/** \class NPLinearConstraints{ Elimination, Penalty, Lagrange} +providing different techniques to handle linear constraints within +non-linear optimization. All three techniques transfer the constraint +problem into an unconstrained one. +*/ + + +// ConstraintHandler working with Elimination approach +class NPLinearConstraintsElimination : public NSolverGmmInterface, public LinearConstraintHandlerElimination +{ +public: + + // use c-arrays as vectors for gmm + typedef gmm::array1D_reference VectorPT; + + /// Default constructor having a pointer to the main problem + NPLinearConstraintsElimination( NSolverGmmInterface* _np) : base_(_np), cache_initialized_(false) + { + if( !base_) std::cerr << "Warning: initialized NPLinearConstraints with zero pointer...\n"; + this->initialize_identity(base_->n_unknowns()); + } + + /// Destructor + ~NPLinearConstraintsElimination() {} + + // initialize constraints + template + void initialize_constraints( const MatrixT& _C, const VectorT& _c) + { + initialize(_C, _c); + cache_initialized_ = false; + } + + + // NSolverInterface + virtual int n_unknowns () + { return this->n_reduced(); } + + virtual void initial_x ( double* _x ) + { + // transform initial x from parent NP + x_.resize(this->n()); + base_->initial_x(P(x_)); + this->transform_x(P(x_), _x); + cache_initialized_ = false; + update_x(_x); + } + + virtual double eval_f( const double* _x ) + { + update_x(_x); + + return base_->eval_f(P(x_)); + } + + virtual void eval_gradient( const double* _x, double* _g) + { + update_x(_x); + vtemp_.resize(this->n()); + base_->eval_gradient( P(x_), P(vtemp_)); + this->transform_gradient( P(vtemp_), _g); + } + + virtual void eval_hessian ( const double* _x, SMatrixNS& _H) + { + update_x(_x); + SMatrixNS H; + base_->eval_hessian(P(x_), H); + this->transform_hessian(H,_H); + } + + virtual void store_result ( const double* _x ) + { + update_x(_x); + + base_->store_result( P(x_)); + } + +protected: + + void update_x(const double* _xr) + { + if(!cache_initialized_) + { + x_.resize(this->n()); + xr_.resize(this->n_reduced()); + + if(!xr_.empty()) + xr_[0] = _xr[0] + 1.0; + else + { + x_.resize(this->n()); + this->inv_transform_x(xr_, x_); + cache_initialized_ = true; + } + } + + for( int i=0; in_reduced(); ++i) + if( _xr[i] != xr_[i]) + { + gmm::copy( VectorPT((double*)_xr, this->n_reduced()), this->xr_); + x_.resize(this->n()); + this->inv_transform_x(xr_, x_); + + cache_initialized_ = true; + + //quit + return; + } + } + + // convert vector into pointer + double* P(const std::vector& _v) + { + if(_v.size()) + return (double*) (&(_v[0])); + else + return 0; + } + +private: + NSolverGmmInterface* base_; + + bool cache_initialized_; + + std::vector x_; + std::vector xr_; + std::vector vtemp_; +}; + + +//============================================================================= + + +// ConstraintHandler working with Penalty +class NPLinearConstraintsPenalty : public NSolverGmmInterface, public LinearConstraintHandlerPenalty +{ +public: + + // use c-arrays as vectors for gmm + typedef gmm::array1D_reference VectorPT; + + /// Default constructor having a pointer to the main problem + NPLinearConstraintsPenalty( NSolverGmmInterface* _np) : base_(_np) + { if( !base_) std::cerr << "Warning: initialized NPLinearConstraints with zero pointer...\n"; } + + /// Destructor + ~NPLinearConstraintsPenalty() {} + + // initialize constraints + template + void initialize_constraints( const MatrixT& _C, const VectorT& _c) + { + initialize(_C, _c); + } + + // NSolverInterface + virtual int n_unknowns () + { return base_->n_unknowns(); } + + virtual void initial_x ( double* _x ) + { + base_->initial_x(_x); + } + + virtual double eval_f( const double* _x ) + { + return this->add_penalty_f((double*)_x, base_->eval_f(_x)); + } + + virtual void eval_gradient( const double* _x, double* _g) + { + base_->eval_gradient( _x, _g); + this->add_penalty_gradient((double*)_x, _g); + } + + virtual void eval_hessian ( const double* _x, SMatrixNS& _H) + { + base_->eval_hessian(_x, _H); + this->add_penalty_hessian(_H); + } + + virtual void store_result ( const double* _x ) + { + base_->store_result( _x); + } + +private: + NSolverGmmInterface* base_; +}; + + +//============================================================================= +} // namespace ACG +//============================================================================= +#endif // ACG_NSOLVERGMMINTERFACE_HH defined +//============================================================================= + diff --git a/CoMISo/NSolver/NPTiming.hh b/CoMISo/NSolver/NPTiming.hh new file mode 100644 index 0000000000000000000000000000000000000000..fcdded07b3483e458c4ad8d723973fa25242a262 --- /dev/null +++ b/CoMISo/NSolver/NPTiming.hh @@ -0,0 +1,149 @@ +//============================================================================= +// +// CLASS NPTiming +// +//============================================================================= + + +#ifndef ACG_NPTIMING_HH +#define ACG_NPTIMING_HH + + +//== INCLUDES ================================================================= + +#include +#include + +#include +#include +#include "NSolverGmmInterface.hh" + +//== FORWARDDECLARATIONS ====================================================== + +//== NAMESPACES =============================================================== + +namespace ACG { + +//== CLASS DEFINITION ========================================================= + + + +/** \class NSolverGmmInterface NSolverGmmInterface.hh + + Brief Description. + + A more elaborate description follows. +*/ +class NPTiming : public NSolverGmmInterface +{ +public: + + /// Default constructor + NPTiming(NSolverGmmInterface* _base) : base_(_base) {start_timing();} + + /// Destructor + ~NPTiming() {} + + virtual int n_unknowns () + { + return base_->n_unknowns(); + } + + virtual void initial_x( double* _x ) + { + base_->initial_x(_x); + } + + virtual double eval_f( const double* _x ) + { + ++n_eval_f_; + sw_.start(); + double f = base_->eval_f(_x); + timing_eval_f_ += sw_.stop(); + return f; + } + + virtual void eval_gradient( const double* _x, double* _g) + { + ++n_eval_gradient_; + sw_.start(); + base_->eval_gradient(_x, _g); + timing_eval_gradient_ += sw_.stop(); + } + + virtual void eval_hessian ( const double* _x, SMatrixNS& _H) + { + ++n_eval_hessian_; + sw_.start(); + base_->eval_hessian(_x, _H); + timing_eval_hessian_ += sw_.stop(); + } + + virtual void store_result ( const double* _x ) + { + base_->store_result(_x); + print_statistics(); + } + + void start_timing() + { + swg_.start(); + + timing_eval_f_ = 0.0; + timing_eval_gradient_ = 0.0; + timing_eval_hessian_ = 0.0; + + n_eval_f_ = 0; + n_eval_gradient_ = 0; + n_eval_hessian_ = 0; + } + +protected: + + void print_statistics() + { + double time_total = swg_.stop(); + + double time_np = timing_eval_f_ + timing_eval_gradient_ + timing_eval_hessian_; + + + + std::cerr << "######## NP-Timings ########" << std::endl; + std::cerr << "total time : " << time_total/1000.0 << "s\n"; + std::cerr << "total time NP : " << time_np/1000.0 << "s (" << time_np/time_total*100.0 << " %)\n"; + + std::cerr << std::fixed << std::setprecision(5) + << "eval_f time : " << timing_eval_f_/1000.0 + << "s ( #evals: " << n_eval_f_ << " -> avg " + << timing_eval_f_/(1000.0*double(n_eval_f_)) << "s )\n" + << "eval_grad time: " << timing_eval_gradient_/1000.0 + << "s ( #evals: " << n_eval_gradient_ << " -> avg " + << timing_eval_gradient_/(1000.0*double(n_eval_gradient_)) << "s )\n" + << "eval_hess time: " << timing_eval_hessian_/1000.0 + << "s ( #evals: " << n_eval_hessian_ << " -> avg " + << timing_eval_hessian_/(1000.0*double(n_eval_hessian_)) << "s )\n"; + } + +private: + NSolverGmmInterface* base_; + StopWatch swg_; + StopWatch sw_; + + // timings + double timing_eval_f_; + double timing_eval_gradient_; + double timing_eval_hessian_; + + // number of function executions + int n_eval_f_; + int n_eval_gradient_; + int n_eval_hessian_; +}; + + +//============================================================================= +} // namespace ACG +//============================================================================= +#endif // ACG_NPTIMING_HH defined +//============================================================================= + diff --git a/CoMISo/NSolver/NSolverGmmInterface.hh b/CoMISo/NSolver/NSolverGmmInterface.hh new file mode 100644 index 0000000000000000000000000000000000000000..c6cd1213a21eb53e5650b6b00f31c1491c338236 --- /dev/null +++ b/CoMISo/NSolver/NSolverGmmInterface.hh @@ -0,0 +1,59 @@ +//============================================================================= +// +// CLASS BaseTaoGmmInterface +// +//============================================================================= + + +#ifndef ACG_NSOLVERGMMINTERFACE_HH +#define ACG_NSOLVERGMMINTERFACE_HH + + +//== INCLUDES ================================================================= + +#include + +//== FORWARDDECLARATIONS ====================================================== + +//== NAMESPACES =============================================================== + +namespace ACG { + +//== CLASS DEFINITION ========================================================= + + + +/** \class NSolverGmmInterface NSolverGmmInterface.hh + + Brief Description. + + A more elaborate description follows. +*/ +class NSolverGmmInterface +{ +public: + + // ToDo: appropriate MatrixType ??? + typedef gmm::row_matrix< gmm::wsvector > SMatrixNS; + + /// Default constructor + NSolverGmmInterface() {} + + /// Destructor + ~NSolverGmmInterface() {} + + virtual int n_unknowns ( ) = 0; + virtual void initial_x ( double* _x ) = 0; + virtual double eval_f ( const double* _x ) = 0; + virtual void eval_gradient( const double* _x, double* _g) = 0; + virtual void eval_hessian ( const double* _x, SMatrixNS& _H) = 0; + virtual void store_result ( const double* _x ) = 0; +}; + + +//============================================================================= +} // namespace ACG +//============================================================================= +#endif // ACG_NSOLVERGMMINTERFACE_HH defined +//============================================================================= + diff --git a/CoMISo/NSolver/NewtonSolver.cc b/CoMISo/NSolver/NewtonSolver.cc new file mode 100644 index 0000000000000000000000000000000000000000..5a6b2ac121d370e32980349cae241948a6ad7111 --- /dev/null +++ b/CoMISo/NSolver/NewtonSolver.cc @@ -0,0 +1,118 @@ +//============================================================================= +// +// CLASS NewtonSolver - IMPLEMENTATION +// +//============================================================================= + +//== INCLUDES ================================================================= + +#include "NewtonSolver.hh" +#include + +//== NAMESPACES =============================================================== + +namespace ACG { + +//== IMPLEMENTATION ========================================================== + + +// solve +int +NewtonSolver:: +solve(NSolverGmmInterface* _problem) +{ + // get problem size + int n = _problem->n_unknowns(); + + // hesse matrix + NSolverGmmInterface::SMatrixNS H; + // gradient + std::vector x(n), x_new(n), dx(n), g(n); + + // get initial x, initial grad and initial f + _problem->initial_x(P(x)); + double f = _problem->eval_f(P(x)); + + double reg = 1e-3; + COMISO::CholmodSolver chol; + + for(int i=0; ieval_gradient(P(x), P(g)); + // check for convergence + if( gmm::vect_norm2(g) < convergence_eps_) + { + std::cerr << "Newton Solver converged after " + << i << " iterations" << std::endl; + _problem->store_result(P(x)); + return true; + } + + // get current hessian + _problem->eval_hessian(P(x), H); + + // regularize + double reg_comp = reg*gmm::mat_trace(H)/double(n); + for(int j=0; jeval_f(P(x_new)); + + if( f_new < f) + { + // swap x and x_new (and f and f_new) + x_new.swap(x); + f = f_new; + improvement = true; + + std::cerr << "energy improved to " << f << std::endl; + } + } + + // adapt regularization + if(improvement) + { + if(reg > 1e-9) + reg *= 0.1; + } + else + { + if(reg < 1e4) + reg *= 10.0; + else + { + _problem->store_result(P(x)); + std::cerr << "Newton solver reached max regularization but did not converge ... " << std::endl; + return false; + } + } + } + + _problem->store_result(P(x)); + std::cerr << "Newton Solver did not converge!!! after " + << max_iter_ << " iterations." << std::endl; + return false; +} + + +//----------------------------------------------------------------------------- + + + + + +//============================================================================= +} // namespace ACG +//============================================================================= diff --git a/CoMISo/NSolver/NewtonSolver.hh b/CoMISo/NSolver/NewtonSolver.hh new file mode 100644 index 0000000000000000000000000000000000000000..c7242db30001425cfe500f48f03d599bcd32b601 --- /dev/null +++ b/CoMISo/NSolver/NewtonSolver.hh @@ -0,0 +1,77 @@ +//============================================================================= +// +// CLASS NewtonSolver +// +//============================================================================= + + +#ifndef ACG_NEWTONSOLVER_HH +#define ACG_NEWTONSOLVER_HH + + +//== INCLUDES ================================================================= + +#include +#include "NSolverGmmInterface.hh" + +//== FORWARDDECLARATIONS ====================================================== + +//== NAMESPACES =============================================================== + +namespace ACG { + +//== CLASS DEFINITION ========================================================= + + + +/** \class NewtonSolver NewtonSolver.hh + + Brief Description. + + A more elaborate description follows. +*/ +class NewtonSolver +{ +public: + + /// Default constructor + NewtonSolver() : max_iter_(20), convergence_eps_(1e-6), constant_hessian_structure_(false) {} + + /// Destructor + ~NewtonSolver() {} + + // solve + int solve(NSolverGmmInterface* _problem); + + // solve specifying parameters + int solve(NSolverGmmInterface* _problem, int _max_iter, double _eps) + { + max_iter_ = _max_iter; + convergence_eps_ = _eps; + return solve(_problem); + } + + bool& constant_hessian_structure() { return constant_hessian_structure_; } + +protected: + double* P(std::vector& _v) + { + if( !_v.empty()) + return ((double*)&_v[0]); + else + return 0; + } + +private: + int max_iter_; + double convergence_eps_; + bool constant_hessian_structure_; +}; + + +//============================================================================= +} // namespace ACG +//============================================================================= +#endif // ACG_NEWTONSOLVER_HH defined +//============================================================================= + diff --git a/CoMISo/NSolver/TAOSolver.cc b/CoMISo/NSolver/TAOSolver.cc new file mode 100644 index 0000000000000000000000000000000000000000..c798199709bcae5302f3d0449150717f13f92a18 --- /dev/null +++ b/CoMISo/NSolver/TAOSolver.cc @@ -0,0 +1,286 @@ +//============================================================================= +// +// CLASS TAOSolver - IMPLEMENTATION +// +//============================================================================= + +//== COMPILE-TIME PACKAGE REQUIREMENTS ======================================== +#include +#if COMISO_TAO_AVAILABLE + + +//== INCLUDES ================================================================= + +#include "TAOSolver.hh" + +//#include + +//== NAMESPACES =============================================================== + +namespace ACG { + +//== IMPLEMENTATION ========================================================== + +// static member initialization +bool TAOSolver::initialized_ = false; + + + +int +TAOSolver:: +solve( NSolverGmmInterface* _base) +{ + // // initialize (only once) + // initialize(); + + // std::cerr << "tao 1\n"; + // // MPI_Init(0,0); + // char *libm="libmpi.so"; + // dlopen(libm,RTLD_GLOBAL); + + if(!initialized_) + { + /* Initialize TAO,PETSc */ + // non command line arguments necessary ... + std::cerr << "Initialize MPI/Petsc/TAO "; + static char help[] ="help\n"; + int argc = 0; + char **argv; + // MPI_Init(&argc, &argv); + PetscInitialize( &argc, &argv,(char *)0,help ); + TaoInitialize ( &argc, &argv,(char *)0,help ); + + initialized_ = true; + std::cerr << " done!!!\n"; + } + + /* used to check for functions returning nonzeros */ + int info; + + // check for single processor + int size; + MPI_Comm_size(MPI_COMM_WORLD,&size); + if (size >1) { + PetscPrintf(PETSC_COMM_SELF,"TAOSolver is intended for single processor use!\n"); + SETERRQ(1,"Incorrect number of processors"); + } + + /* Create TAO solver and set desired solution method */ + // TaoMethod method="tao_cg"; /* minimization method */ + TaoMethod method="tao_ntr"; /* minimization method */ + // TaoMethod method="tao_nm"; /* minimization method */ + TAO_SOLVER tao; /* TAO_SOLVER solver context */ + TAO_APPLICATION testapp; /* The PETSc application */ + + info = TaoCreate(PETSC_COMM_SELF,method,&tao); CHKERRQ(info); + info = TaoApplicationCreate(PETSC_COMM_SELF,&testapp); CHKERRQ(info); + + // initalize vector + int n = _base->n_unknowns(); + Vec x; + info = VecCreateSeq(PETSC_COMM_SELF, n, &x); CHKERRQ(info); + PetscScalar* X; + info = VecGetArray(x,&X); CHKERRQ(info); + _base->initial_x(X); + info = VecRestoreArray(x,&X); CHKERRQ(info); + + // initialize matrix + /* Create a matrix data structure to store the Hessian. This structure will be used by TAO */ + Mat H; + // ToDo: get nonzero_pattern + // int nnz[1]; nnz[0] = 1; + // info = MatCreateSeqAIJ(PETSC_COMM_SELF,n,n,0,nnz,&H); /* PETSc routine */ + info = MatCreateSeqAIJ(PETSC_COMM_SELF,n,n,0,0,&H); /* PETSc routine */ + info = MatSetOption(H,MAT_SYMMETRIC,PETSC_TRUE); CHKERRQ(info); /* PETSc flag */ + info = TaoAppSetHessianMat(testapp,H,H); CHKERRQ(info); /* A TAO routine */ + + // initialize solution vector + info = TaoAppSetInitialSolutionVec(testapp,x); CHKERRQ(info); + + /* Provide TAO routines for function evaluation */ + info = TaoAppSetObjectiveRoutine(testapp, objective, (void*) _base); CHKERRQ(info); + info = TaoAppSetGradientRoutine (testapp, gradient , (void*) _base); CHKERRQ(info); + info = TaoAppSetHessianRoutine (testapp, hessian , (void*) _base); CHKERRQ(info); + + /* SOLVE THE APPLICATION */ + info = TaoSolveApplication(testapp,tao); CHKERRQ(info); + + /* Get information on termination */ + TaoTerminateReason reason; + info = TaoGetTerminationReason(tao,&reason); CHKERRQ(info); + if (reason <= 0) + std::cerr << "Warning: TAO-Solver did not converge!!!\n"; + else + std::cerr << "TAO-Solver converged!!!\n"; + + // To View TAO solver information use + info = TaoView(tao); CHKERRQ(info); + + // if successfull get and store result + // if( reason) + { + info = TaoAppGetSolutionVec(testapp, &x); + info = VecGetArray(x,&X); CHKERRQ(info); + _base->store_result( X); + info = VecRestoreArray(x,&X); CHKERRQ(info); + } + // VecView(x, PETSC_VIEWER_STDOUT_WORLD); + + // /* Free TAO data structures */ + info = TaoDestroy(tao); CHKERRQ(info); + info = TaoAppDestroy(testapp); CHKERRQ(info); + + return reason; +} + + +//----------------------------------------------------------------------------- + + +int +TAOSolver:: +objective( TAO_APPLICATION _app, Vec _x, double* _result, void* _base) +{ + NSolverGmmInterface* base = (NSolverGmmInterface*) _base; + + PetscScalar *x; + + /* Get pointers to vector data */ + int info = VecGetArray(_x,&x); CHKERRQ(info); + + // evaluate function + (*_result) = base->eval_f(x); + + /* Restore vectors */ + info = VecRestoreArray(_x,&x); CHKERRQ(info); + + return 0; +} + + +//----------------------------------------------------------------------------- + + +int +TAOSolver:: +gradient(TAO_APPLICATION _app, Vec _x, Vec _g, void* _base) +{ + NSolverGmmInterface* base = (NSolverGmmInterface*) _base; + + PetscScalar *x, *g; + int info; + + /* Get pointers to vector data */ + info = VecGetArray(_x,&x); CHKERRQ(info); + info = VecGetArray(_g,&g); CHKERRQ(info); + + // compute gradient + base->eval_gradient( x, g); + + /* Restore vectors */ + info = VecRestoreArray(_x,&x); CHKERRQ(info); + info = VecRestoreArray(_g,&g); CHKERRQ(info); + + return 0; +} + + +//----------------------------------------------------------------------------- + + +int +TAOSolver:: +hessian(TAO_APPLICATION _app, Vec _x, Mat* _H, Mat* _H_pre, MatStructure* _H_struct, void* _base) +{ + NSolverGmmInterface* base = (NSolverGmmInterface*) _base; + + PetscScalar *x; + + /* Get pointers to vector data */ + int info = VecGetArray(_x,&x); CHKERRQ(info); + + /* Initialize matrix entries to zero */ + info = MatZeroEntries(*_H); CHKERRQ(info); + + // iterate over non-zero elements + NSolverGmmInterface::SMatrixNS H; + base->eval_hessian( x, H); + + for (unsigned int i = 0; i < gmm::mat_nrows(H); ++i) + { + typedef gmm::linalg_traits::const_sub_row_type + CRow; + CRow row = gmm::mat_const_row(H, i); + + gmm::linalg_traits::const_iterator it = gmm::vect_const_begin(row); + gmm::linalg_traits::const_iterator ite = gmm::vect_const_end(row); + + int m = 1; + int n = 1; + int idxm[1]; idxm[0] = i; + int idxn[1]; + PetscScalar values[1]; + for(; it != ite; ++it) + { + idxn[0] = it.index(); + values[0] = *it; + info = MatSetValues(*_H, m, idxm, n, idxn, values, INSERT_VALUES); + } + } + + /* Assemble the matrix */ + info = MatAssemblyBegin(*_H,MAT_FINAL_ASSEMBLY); CHKERRQ(info); + info = MatAssemblyEnd(*_H,MAT_FINAL_ASSEMBLY); CHKERRQ(info); + + *_H_struct = SAME_NONZERO_PATTERN; + + /* Restore vectors */ + info = VecRestoreArray(_x,&x); CHKERRQ(info); + + return 0; +} + + +//----------------------------------------------------------------------------- + + +void +TAOSolver:: +initialize() +{ + if(!initialized_) + { + /* Initialize TAO,PETSc */ + // non command line arguments necessary ... + std::cerr << "Initialize MPI/Petsc/TAO "; + static char help[] ="help\n"; + static int argc = 0; + static char **argv; + // MPI_Init(&argc, &argv); + PetscInitialize( &argc, &argv,(char *)0,help ); + TaoInitialize ( &argc, &argv,(char *)0,help ); + + initialized_ = true; + std::cerr << " done!!!\n"; + } +} + + +//----------------------------------------------------------------------------- + + +void +TAOSolver:: +cleanup() +{ + /* Finalize TAO */ + TaoFinalize(); + PetscFinalize(); +} + + +//============================================================================= +} // namespace ACG +//============================================================================= +#endif // COMISO_TAO_AVAILABLE + diff --git a/CoMISo/NSolver/TAOSolver.hh b/CoMISo/NSolver/TAOSolver.hh new file mode 100644 index 0000000000000000000000000000000000000000..ddad5b6eb0bea3ff0f8c7c376ec50892a59b07b9 --- /dev/null +++ b/CoMISo/NSolver/TAOSolver.hh @@ -0,0 +1,79 @@ +//============================================================================= +// +// CLASS TAOSolver +// +//============================================================================= + + +#ifndef ACG_TAOSOLVER_HH +#define ACG_TAOSOLVER_HH + +// check availability of package +#include +#if COMISO_TAO_AVAILABLE + +//== INCLUDES ================================================================= + +#include +#include +#include + +#include "NSolverGmmInterface.hh" + +//== FORWARDDECLARATIONS ====================================================== + +//== NAMESPACES =============================================================== + +namespace ACG { + +//== CLASS DEFINITION ========================================================= + + + +/** \class TAOSolver TAOSolver.hh + + Brief Description. + + A more elaborate description follows. +*/ +class TAOSolver +{ +public: + + /// Default constructor + TAOSolver() {} + + /// Destructor + ~TAOSolver() {} + + // solve problem + static int solve( NSolverGmmInterface* _base); + + +private: + + static void initialize(); + + // ToDo: cleanup has to be started automatically + static void cleanup(); + + // declar TAO function prototypes + static int objective(TAO_APPLICATION,Vec,double*,void*); + static int gradient (TAO_APPLICATION,Vec,Vec ,void*); + static int hessian (TAO_APPLICATION,Vec,Mat*,Mat*,MatStructure*,void*); + +private: + // initialized? + static bool initialized_; +}; + + +//============================================================================= +} // namespace ACG + +//============================================================================= +#endif // COMISO_TAO_AVAILABLE +//============================================================================= +#endif // ACG_TAOSOLVER_HH defined +//============================================================================= + diff --git a/CoMISo/Solver/MISolver.cc b/CoMISo/Solver/MISolver.cc index 2d983e02792ad21f223eeb4c7f799e72802b6ddd..d828526c4b927c0dc17cd03633fa6d39d497ca5e 100644 --- a/CoMISo/Solver/MISolver.cc +++ b/CoMISo/Solver/MISolver.cc @@ -35,8 +35,9 @@ #include #include -// #include "SparseQRSolver.hh" -// #include "UMFPACKSolver.hh" +// hack for testing only +#include "SparseQRSolver.hh" +#include "UMFPACKSolver.hh" #define ROUND(x) ((x)<0?int((x)-0.5):int((x)+0.5)) @@ -137,29 +138,55 @@ MISolver::solve_direct_rounding( chol_.calc_system_gmm(_A); chol_.solve(_x, _rhs); + // check solver performance (only for testing!!!) + { + StopWatch sw; - // // performance comparison code - // { - // COMISO::SparseQRSolver spqr; - // spqr.calc_system_gmm(_A); - // Vecd x2(_x); - // spqr.solve(x2,_rhs); - // Vecd res(_x); - // gmm::add(_x,gmm::scaled(x2,-1.0),res); - // std::cerr << "DIFFERENCE IN RESULT: " << gmm::vect_norm2(res) << std::endl; - // } - - // // performance comparison code - // { - // COMISO::UMFPACKSolver umf; - // umf.calc_system_gmm(_A); - // Vecd x3(_x); - // umf.solve(x3,_rhs); - // Vecd res2(_x); - // gmm::add(_x,gmm::scaled(x3,-1.0),res2); - // std::cerr << "UMFPACK DIFFERENCE IN RESULT: " << gmm::vect_norm2(res2) << std::endl; - // } + // performance comparison code + { + sw.start(); + COMISO::SparseQRSolver spqr; + spqr.calc_system_gmm(_A); + std::cerr << "SparseQR factor took: " << sw.stop()/1000.0 << "s\n"; + Vecd x2(_x); + sw.start(); + spqr.solve(x2,_rhs); + std::cerr << "SparseQR solve took: " << sw.stop()/1000.0 << "s\n"; + Vecd res(_x); + gmm::add(_x,gmm::scaled(x2,-1.0),res); + std::cerr << "DIFFERENCE IN RESULT: " << gmm::vect_norm2(res) << std::endl; + } + // performance comparison code + { + sw.start(); + COMISO::UMFPACKSolver umf; + umf.calc_system_gmm(_A); + std::cerr << "UMFPack factor took: " << sw.stop()/1000.0 << "s\n"; + Vecd x3(_x); + sw.start(); + umf.solve(x3,_rhs); + std::cerr << "UMFPack solve took: " << sw.stop()/1000.0 << "s\n"; + Vecd res2(_x); + gmm::add(_x,gmm::scaled(x3,-1.0),res2); + std::cerr << "UMFPACK DIFFERENCE IN RESULT: " << gmm::vect_norm2(res2) << std::endl; + } + + // performance comparison code + { + sw.start(); + COMISO::CholmodSolver chol; + chol.calc_system_gmm(_A); + std::cerr << "Choldmod factor took: " << sw.stop()/1000.0 << "s\n"; + Vecd x4(_x); + sw.start(); + chol.solve(x4,_rhs); + std::cerr << "Choldmod solve took: " << sw.stop()/1000.0 << "s\n"; + Vecd res(_x); + gmm::add(_x,gmm::scaled(x4,-1.0),res); + std::cerr << "DIFFERENCE IN RESULT: " << gmm::vect_norm2(res) << std::endl; + } + } // round and eliminate variables Vecui elim_i; diff --git a/CoMISo/cmake/CheckCSourceRuns.cmake b/CoMISo/cmake/CheckCSourceRuns.cmake new file mode 100644 index 0000000000000000000000000000000000000000..764c756d48220d05859d38056e17ee51a59dfcaf --- /dev/null +++ b/CoMISo/cmake/CheckCSourceRuns.cmake @@ -0,0 +1,86 @@ +# - Check if the given C source code compiles and runs. +# CHECK_C_SOURCE_RUNS( ) +# - source code to try to compile +# - variable to store the result +# (1 for success, empty for failure) +# The following variables may be set before calling this macro to +# modify the way the check is run: +# +# CMAKE_REQUIRED_FLAGS = string of compile command line flags +# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) +# CMAKE_REQUIRED_INCLUDES = list of include directories +# CMAKE_REQUIRED_LIBRARIES = list of libraries to link + +#============================================================================= +# Copyright 2006-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +MACRO(CHECK_C_SOURCE_RUNS SOURCE VAR) + IF("${VAR}" MATCHES "^${VAR}$") + SET(MACRO_CHECK_FUNCTION_DEFINITIONS + "-D${VAR} ${CMAKE_REQUIRED_FLAGS}") + IF(CMAKE_REQUIRED_LIBRARIES) + SET(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES + "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + ELSE(CMAKE_REQUIRED_LIBRARIES) + SET(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES) + ENDIF(CMAKE_REQUIRED_LIBRARIES) + IF(CMAKE_REQUIRED_INCLUDES) + SET(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES + "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") + ELSE(CMAKE_REQUIRED_INCLUDES) + SET(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES) + ENDIF(CMAKE_REQUIRED_INCLUDES) + FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c" + "${SOURCE}\n") + + MESSAGE(STATUS "Performing Test ${VAR}") + TRY_RUN(${VAR}_EXITCODE ${VAR}_COMPILED + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c + COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} + -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH} + "${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}" + "${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}" + COMPILE_OUTPUT_VARIABLE OUTPUT) + # if it did not compile make the return value fail code of 1 + IF(NOT ${VAR}_COMPILED) + SET(${VAR}_EXITCODE 1) + ENDIF(NOT ${VAR}_COMPILED) + # if the return value was 0 then it worked + IF("${${VAR}_EXITCODE}" EQUAL 0) + SET(${VAR} 1 CACHE INTERNAL "Test ${VAR}") + MESSAGE(STATUS "Performing Test ${VAR} - Success") + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n" + "${OUTPUT}\n" + "Return value: ${${VAR}}\n" + "Source file was:\n${SOURCE}\n") + ELSE("${${VAR}_EXITCODE}" EQUAL 0) + IF(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN") + SET(${VAR} "${${VAR}_EXITCODE}") + ELSE(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN") + SET(${VAR} "" CACHE INTERNAL "Test ${VAR}") + ENDIF(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN") + + MESSAGE(STATUS "Performing Test ${VAR} - Failed") + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Performing C SOURCE FILE Test ${VAR} failed with the following output:\n" + "${OUTPUT}\n" + "Return value: ${${VAR}_EXITCODE}\n" + "Source file was:\n${SOURCE}\n") + + ENDIF("${${VAR}_EXITCODE}" EQUAL 0) + ENDIF("${VAR}" MATCHES "^${VAR}$") +ENDMACRO(CHECK_C_SOURCE_RUNS) + diff --git a/CoMISo/cmake/FindIPOPT.cmake b/CoMISo/cmake/FindIPOPT.cmake new file mode 100644 index 0000000000000000000000000000000000000000..b012f9f116cdfbadc7d23add604544627c4ca4ef --- /dev/null +++ b/CoMISo/cmake/FindIPOPT.cmake @@ -0,0 +1,64 @@ +if (IPOPT_INCLUDE_DIR) + # in cache already + SET(IPOPT_FIND_QUIETLY TRUE) +endif (IPOPT_INCLUDE_DIR) + +if (WIN32) + find_path(IPOPT_INCLUDE_DIR NAMES tao.h + PREFIXES SRC + PATHS + "C:\\libs\\gurobi45" + ${IPOPT_DIR}/include + ) + + find_library( IPOPT_LIBRARY_RELEASE + SuperLU + PATHS "C:\\libs\\gurobi45\\lib" ) + find_library( IPOPT_LIBRARY_DEBUG + SuperLUd + PATHS "C:\\libs\\gurobi45\\lib" ) + + + set ( IPOPT_LIBRARY "optimized;${IPOPT_LIBRARY_RELEASE};debug;${IPOPT_LIBRARY_DEBUG}" CACHE STRING "IPOPT Libraries" ) + +ELSEIF(APPLE) + + find_path(IPOPT_INCLUDE_DIR NAMES gurobi_c++.h + PATHS "${CMAKE_SOURCE_DIR}/MacOS/Libs/gurobi40" + ${IPOPT_INCLUDE_PATH} + ) + + find_library( IPOPT_LIBRARY + SuperLU + PATHS "${CMAKE_SOURCE_DIR}/MacOS/Libs/gurobi40") + +ELSE( WIN32 ) + find_path(IPOPT_INCLUDE_DIR NAMES IpNLP.hpp + PATHS "/usr/include/coin" + ${IPOPT_INCLUDE_PATH} + ) + +# MESSAGE(STATUS "$ENV{IPOPT_HOME}/include") + IF(IPOPT_INCLUDE_DIR) + SET(IPOPT_FOUND TRUE) + SET(IPOPT_INCLUDE_DIR ${IPOPT_INCLUDE_DIR}) +# SET(IPOPT_LIBRARY_DIR "$ENV{IPOPT_DIR}/lib/$ENV{IPOPT_ARCH}/" CACHE PATH "Path to IPOPT Library") +# SET(IPOPT_LIBRARY "tao;taopetsc;taofortran" CACHE STRING "IPOPT Libraries") +# MESSAGE(STATUS "${IPOPT_LIBRARY_DIR}") +# MESSAGE(STATUS "${IPOPT_LIBRARY}") + ELSE(IPOPT_INCLUDE_DIR) + SET(IPOPT_FOUND FALSE) + SET(IPOPT_INCLUDE_DIR ${IPOPT_INCLUDE_DIR}) + ENDIF(IPOPT_INCLUDE_DIR) + + find_library( IPOPT_LIBRARY + ipopt + PATHS "/usr/lib" ) + + # set optional path to HSL Solver + find_path(IPOPT_HSL_LIBRARY_DIR NAMES libhsl.so + PATHS "$ENV{HOME}/opt/HSL/lib" + ) + + set(IPOPT_LIBRARY_DIR ${IPOPT_HSL_LIBRARY_DIR}) +ENDIF() diff --git a/CoMISo/cmake/FindPETSC.cmake b/CoMISo/cmake/FindPETSC.cmake new file mode 100644 index 0000000000000000000000000000000000000000..0f8499c17b445867a7cc452e0e9137559cdc3e74 --- /dev/null +++ b/CoMISo/cmake/FindPETSC.cmake @@ -0,0 +1,60 @@ +if (PETSC_INCLUDE_DIRS) + # Already in cache, be silent + SET(PETSC_FIND_QUIETLY TRUE) +endif(PETSC_INCLUDE_DIRS) + +if (WIN32) + find_path(PETSC_INCLUDE_DIR NAMES petsc.h + PREFIXES SRC + PATHS + "C:\\libs\\gurobi45" + ${PETSC_DIR}/include + ) + + find_library( PETSC_LIBRARY_RELEASE + SuperLU + PATHS "C:\\libs\\gurobi45\\lib" ) + find_library( PETSC_LIBRARY_DEBUG + SuperLUd + PATHS "C:\\libs\\gurobi45\\lib" ) + + + set ( PETSC_LIBRARY "optimized;${PETSC_LIBRARY_RELEASE};debug;${PETSC_LIBRARY_DEBUG}" CACHE STRING "PETSC Libraries" ) + +ELSEIF(APPLE) + + find_path(PETSC_INCLUDE_DIR NAMES gurobi_c++.h + PATHS "${CMAKE_SOURCE_DIR}/MacOS/Libs/gurobi40" + ${PETSC_INCLUDE_PATH} + ) + + find_library( PETSC_LIBRARY + SuperLU + PATHS "${CMAKE_SOURCE_DIR}/MacOS/Libs/gurobi40") + +ELSE( WIN32 ) + find_path(PETSC_INCLUDE_DIR1 NAMES petsc.h + PATHS "$ENV{PETSC_DIR}/include" + ${PETSC_INCLUDE_DIR1} + ) + + find_path(PETSC_INCLUDE_DIR2 NAMES petscconf.h + PATHS "$ENV{PETSC_DIR}/$ENV{PETSC_ARCH}/include" + ${PETSC_INCLUDE_DIR2} + ) + +# MESSAGE(STATUS "$ENV{PETSC_HOME}/include") + IF(PETSC_INCLUDE_DIR1 AND PETSC_INCLUDE_DIR2) + SET(PETSC_FOUND TRUE) + SET(PETSC_INCLUDE_DIRS "${PETSC_INCLUDE_DIR1};${PETSC_INCLUDE_DIR2}") + SET(PETSC_LIBRARY_DIR "$ENV{PETSC_DIR}/$ENV{PETSC_ARCH}/lib" CACHE PATH "Path to PETSC Library") + SET(PETSC_LIBRARY "petsc" CACHE STRING "PETSC Libraries") + ELSE(PETSC_INCLUDE_DIR1 AND PETSC_INCLUDE_DIR2) + SET(PETSC_FOUND FALSE) + SET(PETSC_INCLUDE_DIR ${PETSC_INCLUDE_DIR}) + ENDIF(PETSC_INCLUDE_DIR1 AND PETSC_INCLUDE_DIR2) + + #find_library( PETSC_LIBRARY + # gurobi + # PATHS "${PETSC_HOME}/lib" ) +ENDIF() \ No newline at end of file diff --git a/CoMISo/cmake/FindPackageHandleStandardArgs.cmake b/CoMISo/cmake/FindPackageHandleStandardArgs.cmake new file mode 100644 index 0000000000000000000000000000000000000000..1acb021e80bc2d47ce0de0ad99871fd2b4aa7984 --- /dev/null +++ b/CoMISo/cmake/FindPackageHandleStandardArgs.cmake @@ -0,0 +1,260 @@ +# FIND_PACKAGE_HANDLE_STANDARD_ARGS( ... ) +# +# This function is intended to be used in FindXXX.cmake modules files. +# It handles the REQUIRED, QUIET and version-related arguments to FIND_PACKAGE(). +# It also sets the _FOUND variable. +# The package is considered found if all variables ... listed contain +# valid results, e.g. valid filepaths. +# +# There are two modes of this function. The first argument in both modes is +# the name of the Find-module where it is called (in original casing). +# +# The first simple mode looks like this: +# FIND_PACKAGE_HANDLE_STANDARD_ARGS( (DEFAULT_MSG|"Custom failure message") ... ) +# If the variables to are all valid, then _FOUND +# will be set to TRUE. +# If DEFAULT_MSG is given as second argument, then the function will generate +# itself useful success and error messages. You can also supply a custom error message +# for the failure case. This is not recommended. +# +# The second mode is more powerful and also supports version checking: +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME [REQUIRED_VARS ...] +# [VERSION_VAR +# [CONFIG_MODE] +# [FAIL_MESSAGE "Custom failure message"] ) +# +# As above, if through are all valid, _FOUND +# will be set to TRUE. +# After REQUIRED_VARS the variables which are required for this package are listed. +# Following VERSION_VAR the name of the variable can be specified which holds +# the version of the package which has been found. If this is done, this version +# will be checked against the (potentially) specified required version used +# in the find_package() call. The EXACT keyword is also handled. The default +# messages include information about the required version and the version +# which has been actually found, both if the version is ok or not. +# Use the option CONFIG_MODE if your FindXXX.cmake module is a wrapper for +# a find_package(... NO_MODULE) call, in this case all the information +# provided by the config-mode of find_package() will be evaluated +# automatically. +# Via FAIL_MESSAGE a custom failure message can be specified, if this is not +# used, the default message will be displayed. +# +# Example for mode 1: +# +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) +# +# LibXml2 is considered to be found, if both LIBXML2_LIBRARY and +# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE. +# If it is not found and REQUIRED was used, it fails with FATAL_ERROR, +# independent whether QUIET was used or not. +# If it is found, success will be reported, including the content of . +# On repeated Cmake runs, the same message won't be printed again. +# +# Example for mode 2: +# +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(BISON REQUIRED_VARS BISON_EXECUTABLE +# VERSION_VAR BISON_VERSION) +# In this case, BISON is considered to be found if the variable(s) listed +# after REQUIRED_VAR are all valid, i.e. BISON_EXECUTABLE in this case. +# Also the version of BISON will be checked by using the version contained +# in BISON_VERSION. +# Since no FAIL_MESSAGE is given, the default messages will be printed. +# +# Another example for mode 2: +# +# FIND_PACKAGE(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(Automoc4 CONFIG_MODE) +# In this case, FindAutmoc4.cmake wraps a call to FIND_PACKAGE(Automoc4 NO_MODULE) +# and adds an additional search directory for automoc4. +# The following FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper +# success/error message. + +#============================================================================= +# Copyright 2007-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +INCLUDE(FindPackageMessage) +INCLUDE(CMakeParseArguments) + +# internal helper macro +MACRO(_FPHSA_FAILURE_MESSAGE _msg) + IF (${_NAME}_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "${_msg}") + ELSE (${_NAME}_FIND_REQUIRED) + IF (NOT ${_NAME}_FIND_QUIETLY) + MESSAGE(STATUS "${_msg}") + ENDIF (NOT ${_NAME}_FIND_QUIETLY) + ENDIF (${_NAME}_FIND_REQUIRED) +ENDMACRO(_FPHSA_FAILURE_MESSAGE _msg) + + +# internal helper macro to generate the failure message when used in CONFIG_MODE: +MACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) + # _CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found: + IF(${_NAME}_CONFIG) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})") + ELSE(${_NAME}_CONFIG) + # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version. + # List them all in the error message: + IF(${_NAME}_CONSIDERED_CONFIGS) + SET(configsText "") + LIST(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount) + MATH(EXPR configsCount "${configsCount} - 1") + FOREACH(currentConfigIndex RANGE ${configsCount}) + LIST(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename) + LIST(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) + SET(configsText "${configsText} ${filename} (version ${version})\n") + ENDFOREACH(currentConfigIndex) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") + + ELSE(${_NAME}_CONSIDERED_CONFIGS) + # Simple case: No Config-file was found at all: + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}") + ENDIF(${_NAME}_CONSIDERED_CONFIGS) + ENDIF(${_NAME}_CONFIG) +ENDMACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) + + +FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) + +# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in +# new extended or in the "old" mode: + SET(options CONFIG_MODE) + SET(oneValueArgs FAIL_MESSAGE VERSION_VAR) + SET(multiValueArgs REQUIRED_VARS) + SET(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} ) + LIST(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX) + + IF(${INDEX} EQUAL -1) + SET(FPHSA_FAIL_MESSAGE ${_FIRST_ARG}) + SET(FPHSA_REQUIRED_VARS ${ARGN}) + SET(FPHSA_VERSION_VAR) + ELSE(${INDEX} EQUAL -1) + + CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) + + IF(FPHSA_UNPARSED_ARGUMENTS) + MESSAGE(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"") + ENDIF(FPHSA_UNPARSED_ARGUMENTS) + + IF(NOT FPHSA_FAIL_MESSAGE) + SET(FPHSA_FAIL_MESSAGE "DEFAULT_MSG") + ENDIF(NOT FPHSA_FAIL_MESSAGE) + ENDIF(${INDEX} EQUAL -1) + +# now that we collected all arguments, process them + + IF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG") + SET(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}") + ENDIF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG") + + # In config-mode, we rely on the variable _CONFIG, which is set by find_package() + # when it successfully found the config-file, including version checking: + IF(FPHSA_CONFIG_MODE) + LIST(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG) + LIST(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS) + SET(FPHSA_VERSION_VAR ${_NAME}_VERSION) + ENDIF(FPHSA_CONFIG_MODE) + + IF(NOT FPHSA_REQUIRED_VARS) + MESSAGE(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()") + ENDIF(NOT FPHSA_REQUIRED_VARS) + + LIST(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR) + + STRING(TOUPPER ${_NAME} _NAME_UPPER) + STRING(TOLOWER ${_NAME} _NAME_LOWER) + + # collect all variables which were not found, so they can be printed, so the + # user knows better what went wrong (#6375) + SET(MISSING_VARS "") + SET(DETAILS "") + SET(${_NAME_UPPER}_FOUND TRUE) + # check if all passed variables are valid + FOREACH(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) + IF(NOT ${_CURRENT_VAR}) + SET(${_NAME_UPPER}_FOUND FALSE) + SET(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}") + ELSE(NOT ${_CURRENT_VAR}) + SET(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]") + ENDIF(NOT ${_CURRENT_VAR}) + ENDFOREACH(_CURRENT_VAR) + + + # version handling: + SET(VERSION_MSG "") + SET(VERSION_OK TRUE) + SET(VERSION ${${FPHSA_VERSION_VAR}} ) + IF (${_NAME}_FIND_VERSION) + + IF(VERSION) + + IF(${_NAME}_FIND_VERSION_EXACT) # exact version required + IF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") + SET(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"") + SET(VERSION_OK FALSE) + ELSE (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") + SET(VERSION_MSG "(found suitable exact version \"${VERSION}\")") + ENDIF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}") + + ELSE(${_NAME}_FIND_VERSION_EXACT) # minimum version specified: + IF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") + SET(VERSION_MSG "Found unsuitable version \"${VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"") + SET(VERSION_OK FALSE) + ELSE ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") + SET(VERSION_MSG "(found suitable version \"${VERSION}\", required is \"${${_NAME}_FIND_VERSION}\")") + ENDIF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}") + ENDIF(${_NAME}_FIND_VERSION_EXACT) + + ELSE(VERSION) + + # if the package was not found, but a version was given, add that to the output: + IF(${_NAME}_FIND_VERSION_EXACT) + SET(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")") + ELSE(${_NAME}_FIND_VERSION_EXACT) + SET(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")") + ENDIF(${_NAME}_FIND_VERSION_EXACT) + + ENDIF(VERSION) + ELSE (${_NAME}_FIND_VERSION) + IF(VERSION) + SET(VERSION_MSG "(found version \"${VERSION}\")") + ENDIF(VERSION) + ENDIF (${_NAME}_FIND_VERSION) + + IF(VERSION_OK) + SET(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]") + ELSE(VERSION_OK) + SET(${_NAME_UPPER}_FOUND FALSE) + ENDIF(VERSION_OK) + + + # print the result: + IF (${_NAME_UPPER}_FOUND) + FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG}" "${DETAILS}") + ELSE (${_NAME_UPPER}_FOUND) + + IF(FPHSA_CONFIG_MODE) + _FPHSA_HANDLE_FAILURE_CONFIG_MODE() + ELSE(FPHSA_CONFIG_MODE) + IF(NOT VERSION_OK) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})") + ELSE(NOT VERSION_OK) + _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}") + ENDIF(NOT VERSION_OK) + ENDIF(FPHSA_CONFIG_MODE) + + ENDIF (${_NAME_UPPER}_FOUND) + + SET(${_NAME_UPPER}_FOUND ${${_NAME_UPPER}_FOUND} PARENT_SCOPE) + +ENDFUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _FIRST_ARG) diff --git a/CoMISo/cmake/FindSUITESPARSE.cmake b/CoMISo/cmake/FindSUITESPARSE.cmake index b988440f6344c79fa93f7b763d50505eebd3da95..2f8e2ce5efb63686579f09bc9872e7773c09d112 100644 --- a/CoMISo/cmake/FindSUITESPARSE.cmake +++ b/CoMISo/cmake/FindSUITESPARSE.cmake @@ -1,10 +1,13 @@ # - Try to find SUITESPARSE # Once done this will define # -# SUITESPARSE_FOUND - system has SUITESPARSE -# SUITESPARSE_INCLUDE_DIRS - the SUITESPARSE include directory -# SUITESPARSE_LIBRARIES - Link these to use SUITESPARSE -# SUITESPARSE_LIBRARY_DIR - Library directory containing suitesparse libs +# SUITESPARSE_FOUND - system has SUITESPARSE +# SUITESPARSE_INCLUDE_DIRS - the SUITESPARSE include directory +# SUITESPARSE_LIBRARIES - Link these to use SUITESPARSE +# SUITESPARSE_SPQR_LIBRARY - name of spqr library (necessary due to error in debian package) +# SUITESPARSE_SPQR_LIBRARY_DIR - name of spqr library (necessary due to error in debian package) +# SUITESPARSE_LIBRARY_DIR - Library main directory containing suitesparse libs +# SUITESPARSE_LIBRARY_DIRS - all Library directories containing suitesparse libs # IF (SUITESPARSE_INCLUDE_DIRS) @@ -25,21 +28,21 @@ if( WIN32 ) # find path suitesparse library - FIND_PATH( SUITESPARSE_LIBRARY_DIRS + FIND_PATH( SUITESPARSE_LIBRARY_DIR amd.lib PATHS "C:\\libs\\win32\\SuiteSparse\\libs" ) # if we found the library, add it to the defined libraries - IF ( SUITESPARSE_LIBRARY_DIRS ) + IF ( SUITESPARSE_LIBRARY_DIR ) list ( APPEND SUITESPARSE_LIBRARIES optimized;amd;optimized;camd;optimized;ccolamd;optimized;cholmod;optimized;colamd;optimized;metis;optimized;spqr;optimized;umfpack;debug;amdd;debug;camdd;debug;ccolamdd;debug;cholmodd;debug;spqrd;debug;umfpackd;debug;colamdd;debug;metisd;optimized;blas;optimized;libf2c;optimized;lapack;debug;blasd;debug;libf2cd;debug;lapackd ) - ENDIF( SUITESPARSE_LIBRARY_DIRS ) + ENDIF( SUITESPARSE_LIBRARY_DIR ) else( WIN32 ) IF( APPLE) FIND_PATH( CHOLMOD_INCLUDE_DIR cholmod.h PATHS /opt/local/include/ufsparse ) - FIND_PATH( SUITESPARSE_LIBRARY_DIR + FIND_PATH( SUITESPARSE_LIBRARY_DIRS NAMES libcholmod.a PATHS /opt/local/lib ) @@ -66,14 +69,23 @@ else( WIN32 ) # if we found the library, add it to the defined libraries IF ( SUITESPARSE_LIBRARY_DIR ) - list ( APPEND SUITESPARSE_LIBRARY_DIRS ${SUITESPARSE_LIBRARY_DIR} ) FIND_LIBRARY( CHOLMOD_LIBRARY NAMES cholmod CHOLMOD PATHS ${SUITESPARSE_LIBRARY_DIR} ) FIND_LIBRARY( UMFPACK_LIBRARY NAMES umfpack UMFPACK PATHS ${SUITESPARSE_LIBRARY_DIR} ) - + FIND_LIBRARY( SUITESPARSE_SPQR_LIBRARY + NAMES spqr SPQR + HINTS $ENV{HOME}/opt/SPQR/lib + PATHS ${SUITESPARSE_LIBRARY_DIR} ) + + FIND_PATH( SUITESPARSE_SPQR_LIBRARY_DIR + NAMES libspqr.so + PATHS /usr/lib /usr/local/lib $ENV{HOME}/opt/SPQR/lib) + + list ( APPEND SUITESPARSE_LIBRARY_DIRS ${SUITESPARSE_SPQR_LIBRARY_DIR} ) + list ( APPEND SUITESPARSE_LIBRARY_DIRS ${SUITESPARSE_LIBRARY_DIR} ) IF(APPLE) list ( APPEND SUITESPARSE_LIBRARIES ${SUITESPARSE_LIBRARY_DIR}/libamd.a ${SUITESPARSE_LIBRARY_DIR}/libbtf.a @@ -90,7 +102,7 @@ else( WIN32 ) ENDIF(APPLE) - list ( APPEND SUITESPARSE_LIBRARIES ${CHOLMOD_LIBRARY} ${UMFPACK_LIBRARY} ) + list ( APPEND SUITESPARSE_LIBRARIES ${CHOLMOD_LIBRARY} ${UMFPACK_LIBRARY} ${SUITESPARSE_SPQR_LIBRARY}) ENDIF( SUITESPARSE_LIBRARY_DIR ) endif( WIN32 ) diff --git a/CoMISo/cmake/FindTAO.cmake b/CoMISo/cmake/FindTAO.cmake new file mode 100644 index 0000000000000000000000000000000000000000..955c9a1f9a41ea0bbf4fba3abf1907a52d51713e --- /dev/null +++ b/CoMISo/cmake/FindTAO.cmake @@ -0,0 +1,58 @@ +if (TAO_INCLUDE_DIRS) + # Already in cache, be silent + SET(TAO_FIND_QUIETLY TRUE) +endif (TAO_INCLUDE_DIRS) + +if (WIN32) + find_path(TAO_INCLUDE_DIR NAMES tao.h + PREFIXES SRC + PATHS + "C:\\libs\\gurobi45" + ${TAO_DIR}/include + ) + + find_library( TAO_LIBRARY_RELEASE + SuperLU + PATHS "C:\\libs\\gurobi45\\lib" ) + find_library( TAO_LIBRARY_DEBUG + SuperLUd + PATHS "C:\\libs\\gurobi45\\lib" ) + + + set ( TAO_LIBRARY "optimized;${TAO_LIBRARY_RELEASE};debug;${TAO_LIBRARY_DEBUG}" CACHE STRING "TAO Libraries" ) + +ELSEIF(APPLE) + + find_path(TAO_INCLUDE_DIR NAMES gurobi_c++.h + PATHS "${CMAKE_SOURCE_DIR}/MacOS/Libs/gurobi40" + ${TAO_INCLUDE_PATH} + ) + + find_library( TAO_LIBRARY + SuperLU + PATHS "${CMAKE_SOURCE_DIR}/MacOS/Libs/gurobi40") + +ELSE( WIN32 ) +find_path(TAO_INCLUDE_DIR NAMES "include/tao.h" + PATHS "$ENV{TAO_DIR}" + /usr/include/tao + ) + +# MESSAGE(STATUS "$ENV{TAO_HOME}/include") + IF(TAO_INCLUDE_DIR) + SET(TAO_FOUND TRUE) + SET(TAO_INCLUDE_DIRS "${TAO_INCLUDE_DIR}/include;${TAO_INCLUDE_DIR}") + SET(TAO_INCLUDE_DIR ${TAO_INCLUDE_DIR}/include;${TAO_INCLUDE_DIR} CACHE PATH "Path to TAO Includes") + SET(TAO_LIBRARY_DIR "$ENV{TAO_DIR}/lib/$ENV{PETSC_ARCH}/" CACHE PATH "Path to TAO Library") + SET(TAO_LIBRARY "tao;taopetsc;taofortran" CACHE STRING "TAO Libraries") +# MESSAGE(STATUS "${TAO_LIBRARY_DIR}") +# MESSAGE(STATUS "${TAO_LIBRARY}") + ELSE(TAO_INCLUDE_DIR) + SET(TAO_FOUND FALSE) + SET(TAO_INCLUDE_DIR ${TAO_INCLUDE_DIR}) + ENDIF(TAO_INCLUDE_DIR) + + #find_library( TAO_LIBRARY + # gurobi + # PATHS "${TAO_HOME}/lib" ) +ENDIF() \ No newline at end of file