mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-20 03:16:10 +00:00
- added CoMISo library
This commit is contained in:
parent
c05bd3fd1f
commit
7e09115bca
38
src/external/CoMISo/CHANGELOG
vendored
Normal file
38
src/external/CoMISo/CHANGELOG
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
#============================================================================================
|
||||
|
||||
CoMISo 1.0-rc1:
|
||||
- Initial release
|
||||
|
||||
CoMISo 1.1:
|
||||
- Only 2 external dependencies: header libraries GMM++ and Eigen3
|
||||
- Efficient re-solve with updated (system and/or constraints) right hand sides
|
||||
|
||||
|
||||
Features:
|
||||
- /NSolver -- simple non-linear solver c++ interfaces:
|
||||
* Gurobi [1],
|
||||
* IPOPT [2],
|
||||
* TAO/PETSc [3],
|
||||
* CPLEX [4],
|
||||
* an the inhouse Newton Solver and more!
|
||||
|
||||
- /EigenSolver -- interface for large-scale eigenvalue problems ARPACK [5]
|
||||
|
||||
- /Solver -- several interfaces for common linear system solvers:
|
||||
* sparse Cholesky (Cholmod, LDLT)
|
||||
* SparseQR [6]
|
||||
* TAUCS [7]
|
||||
* UMFPACK [8]
|
||||
and of course the Constrained and Constrained Mixed Integer Solvers (CoMISo)
|
||||
|
||||
|
||||
|
||||
References:
|
||||
[1] www.gurobi.com
|
||||
[2] https://projects.coin-or.org/Ipopt
|
||||
[3] http://www.mcs.anl.gov/research/projects/tao/
|
||||
[4] http://www-01.ibm.com/software/integration/optimization/cplex-optimizer/
|
||||
[5] http://www.caam.rice.edu/software/ARPACK/
|
||||
[6] http://www.cise.ufl.edu/research/sparse/SPQR/
|
||||
[7] http://www.tau.ac.il/~stoledo/taucs/
|
||||
[8] http://www.cise.ufl.edu/research/sparse/umfpack/
|
||||
371
src/external/CoMISo/CMakeLists.txt
vendored
Normal file
371
src/external/CoMISo/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,371 @@
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
|
||||
project(CoMISo)
|
||||
|
||||
# add our macro directory to cmake search path
|
||||
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
|
||||
|
||||
include (ACGCommon)
|
||||
|
||||
acg_qt4 ()
|
||||
# change to 0 if QT should not be used
|
||||
set( WANT_COMISO_QT 1 )
|
||||
if( QT4_FOUND)
|
||||
#message( WARNING " QT4 FOUND" )
|
||||
if( WANT_COMISO_QT )
|
||||
add_definitions (-DQT4_FOUND)
|
||||
# message( WARNING " USING QT4" )
|
||||
endif ()
|
||||
set (COMISO_QT4_CONFIG_FILE_SETTINGS "#define COMISO_QT4_AVAILABLE 1" )
|
||||
else()
|
||||
set (COMISO_QT4_CONFIG_FILE_SETTINGS "#define COMISO_QT4_AVAILABLE 0" )
|
||||
endif ()
|
||||
|
||||
acg_get_version ()
|
||||
|
||||
include (ACGOutput)
|
||||
|
||||
set(COMISO_INCLUDE_DIRECTORIES "")
|
||||
set(COMISO_LINK_DIRECTORIES "")
|
||||
set(COMISO_LINK_LIBRARIES "")
|
||||
|
||||
FIND_PACKAGE( Boost 1.42.0 COMPONENTS system filesystem regex )
|
||||
if(Boost_FOUND)
|
||||
set (COMISO_BOOST_CONFIG_FILE_SETTINGS "#define COMISO_BOOST_AVAILABLE 1" )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIRS} )
|
||||
# list( APPEND COMISO_LINK_DIRECTORIES ${Boost_LIBRARY_DIR} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${Boost_LIBRARIES} )
|
||||
else()
|
||||
set (COMISO_BOOST_CONFIG_FILE_SETTINGS "#define COMISO_BOOST_AVAILABLE 0" )
|
||||
message (STATUS "Boost not found!")
|
||||
endif ()
|
||||
|
||||
|
||||
find_package (GMM)
|
||||
if (GMM_FOUND)
|
||||
set (COMISO_GMM_CONFIG_FILE_SETTINGS "#define COMISO_GMM_AVAILABLE 1" )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${GMM_INCLUDE_DIR} )
|
||||
else()
|
||||
set (COMISO_GMM_CONFIG_FILE_SETTINGS "#define COMISO_GMM_AVAILABLE 0" )
|
||||
message (FATAL_ERROR "GMM not found!")
|
||||
endif ()
|
||||
|
||||
# We require cgal with its blas on windows
|
||||
find_package(CGAL)
|
||||
if (CGAL_FOUND)
|
||||
set (COMISO_CGAL_CONFIG_FILE_SETTINGS "#define COMISO_CGAL_AVAILABLE 1" )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${CGAL_INCLUDE_DIR} )
|
||||
list( APPEND COMISO_LINK_DIRECTORIES ${CGAL_LIBRARY_DIR} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${CGAL_LIBRARIES} )
|
||||
else()
|
||||
set (COMISO_CGAL_CONFIG_FILE_SETTINGS "#define COMISO_CGAL_AVAILABLE 0" )
|
||||
message (STATUS "CGAL not found!")
|
||||
endif()
|
||||
|
||||
|
||||
find_package (BLAS)
|
||||
if (BLAS_FOUND )
|
||||
set (COMISO_BLAS_CONFIG_FILE_SETTINGS "#define COMISO_BLAS_AVAILABLE 1" )
|
||||
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${BLAS_INCLUDE_DIRS} )
|
||||
list( APPEND COMISO_LINK_DIRECTORIES ${BLAS_LIBRARY_DIRS} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${BLAS_LIBRARIES} )
|
||||
else()
|
||||
set (COMISO_BLAS_CONFIG_FILE_SETTINGS "#define COMISO_BLAS_AVAILABLE 0" )
|
||||
message (STATUS "BLAS not found!")
|
||||
endif ()
|
||||
|
||||
find_package (ADOLC)
|
||||
if (ADOLC_FOUND)
|
||||
set (COMISO_ADOLC_CONFIG_FILE_SETTINGS "#define COMISO_ADOLC_AVAILABLE 1" )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${ADOLC_INCLUDE_DIR} )
|
||||
list( APPEND COMISO_LINK_DIRECTORIES ${ADOLC_LIBRARY_DIR} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${ADOLC_LIBRARIES} )
|
||||
else ()
|
||||
set (COMISO_ADOLC_CONFIG_FILE_SETTINGS "#define COMISO_ADOLC_AVAILABLE 0" )
|
||||
message (STATUS "ADOLC not found!")
|
||||
endif ()
|
||||
|
||||
find_package (SUITESPARSE)
|
||||
if (SUITESPARSE_FOUND )
|
||||
set (COMISO_SUITESPARSE_CONFIG_FILE_SETTINGS "#define COMISO_SUITESPARSE_AVAILABLE 1" )
|
||||
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${SUITESPARSE_INCLUDE_DIRS} )
|
||||
list( APPEND COMISO_LINK_DIRECTORIES ${SUITESPARSE_LIBRARY_DIRS} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${SUITESPARSE_LIBRARIES} )
|
||||
else ()
|
||||
message (STATUS "SUITESPARSE not found!")
|
||||
set (COMISO_SUITESPARSE_CONFIG_FILE_SETTINGS "#define COMISO_SUITESPARSE_AVAILABLE 0" )
|
||||
endif ()
|
||||
# special handling, since spqr is incorrect in several distributions
|
||||
if(SUITESPARSE_SPQR_VALID)
|
||||
set (COMISO_SUITESPARSE_SPQR_CONFIG_FILE_SETTINGS "#define COMISO_SUITESPARSE_SPQR_AVAILABLE 1" )
|
||||
else()
|
||||
message (STATUS "SUITESPARSE SPQR seems to be invalid!")
|
||||
set (COMISO_SUITESPARSE_SPQR_CONFIG_FILE_SETTINGS "#define COMISO_SUITESPARSE_SPQR_AVAILABLE 0" )
|
||||
endif()
|
||||
|
||||
find_package (MPI)
|
||||
if (MPI_FOUND )
|
||||
set (COMISO_MPI_CONFIG_FILE_SETTINGS "#define COMISO_MPI_AVAILABLE 1" )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${MPI_INCLUDE_PATH} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${MPI_CXX_LIBRARIES} )
|
||||
else ()
|
||||
message (STATUS "MPI not found!")
|
||||
set (COMISO_MPI_CONFIG_FILE_SETTINGS "#define COMISO_MPI_AVAILABLE 0" )
|
||||
endif ()
|
||||
|
||||
find_package (PETSC)
|
||||
if (PETSC_FOUND AND MPI_FOUND)
|
||||
set (COMISO_PETSC_CONFIG_FILE_SETTINGS "#define COMISO_PETSC_AVAILABLE 1" )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${PETSC_INCLUDE_DIRS} )
|
||||
list( APPEND COMISO_LINK_DIRECTORIES ${PETSC_LIBRARY_DIR} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${PETSC_LIBRARY} )
|
||||
else ()
|
||||
message (STATUS "PETSC or dependency not found!")
|
||||
set (COMISO_PETSC_CONFIG_FILE_SETTINGS "#define COMISO_PETSC_AVAILABLE 0" )
|
||||
endif ()
|
||||
|
||||
|
||||
find_package (TAO)
|
||||
if (TAO_FOUND AND PETSC_FOUND AND MPI_FOUND)
|
||||
set (COMISO_TAO_CONFIG_FILE_SETTINGS "#define COMISO_TAO_AVAILABLE 1" )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${TAO_INCLUDE_DIRS} )
|
||||
list( APPEND COMISO_LINK_DIRECTORIES ${TAO_LIBRARY_DIR} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${TAO_LIBRARY} )
|
||||
else ()
|
||||
message (STATUS "TAO or dependency not found!")
|
||||
set (COMISO_TAO_CONFIG_FILE_SETTINGS "#define COMISO_TAO_AVAILABLE 0" )
|
||||
endif ()
|
||||
|
||||
find_package (METIS)
|
||||
if (METIS_FOUND )
|
||||
set (COMISO_METIS_CONFIG_FILE_SETTINGS "#define COMISO_METIS_AVAILABLE 1" )
|
||||
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${METIS_INCLUDE_DIRS} )
|
||||
list( APPEND COMISO_LINK_DIRECTORIES ${METIS_LIBRARY_DIRS} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${METIS_LIBRARIES} )
|
||||
else()
|
||||
set (COMISO_METIS_CONFIG_FILE_SETTINGS "#define COMISO_METIS_AVAILABLE 0" )
|
||||
message (STATUS "METIS not found!")
|
||||
endif ()
|
||||
|
||||
find_package (MUMPS)
|
||||
if (MUMPS_FOUND )
|
||||
set (COMISO_MUMPS_CONFIG_FILE_SETTINGS "#define COMISO_MUMPS_AVAILABLE 1" )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${MUMPS_INCLUDE_DIR} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${MUMPS_LIBRARY} )
|
||||
else ()
|
||||
message (STATUS "MUMPS not found!")
|
||||
set (COMISO_MUMPS_CONFIG_FILE_SETTINGS "#define COMISO_MUMPS_AVAILABLE 0" )
|
||||
endif ()
|
||||
|
||||
find_package (IPOPT)
|
||||
if (IPOPT_FOUND)
|
||||
set (COMISO_IPOPT_CONFIG_FILE_SETTINGS "#define COMISO_IPOPT_AVAILABLE 1" )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${IPOPT_INCLUDE_DIR} )
|
||||
list( APPEND COMISO_LINK_DIRECTORIES ${IPOPT_LIBRARY_DIR} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${IPOPT_LIBRARY} )
|
||||
if ( IPOPT_HSL_LIBRARY_DIR )
|
||||
set (COMISO_HSL_CONFIG_FILE_SETTINGS "#define COMISO_HSL_AVAILABLE 1" )
|
||||
else ()
|
||||
set (COMISO_HSL_CONFIG_FILE_SETTINGS "#define COMISO_HSL_AVAILABLE 0" )
|
||||
endif()
|
||||
else ()
|
||||
message (STATUS "IPOPT or dependency not found!")
|
||||
set (COMISO_IPOPT_CONFIG_FILE_SETTINGS "#define COMISO_IPOPT_AVAILABLE 0" )
|
||||
set (COMISO_HSL_CONFIG_FILE_SETTINGS "#define COMISO_HSL_AVAILABLE 0" )
|
||||
endif ()
|
||||
|
||||
find_package (EIGEN3)
|
||||
if (EIGEN3_FOUND )
|
||||
set (COMISO_EIGEN3_CONFIG_FILE_SETTINGS "#define COMISO_EIGEN3_AVAILABLE 1" )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${EIGEN3_INCLUDE_DIR} )
|
||||
else ()
|
||||
message (STATUS "EIGEN3 not found!")
|
||||
set (COMISO_EIGEN3_CONFIG_FILE_SETTINGS "#define COMISO_EIGEN3_AVAILABLE 0" )
|
||||
endif ()
|
||||
|
||||
find_package (Taucs)
|
||||
if (TAUCS_FOUND )
|
||||
set (COMISO_TAUCS_CONFIG_FILE_SETTINGS "#define COMISO_TAUCS_AVAILABLE 1" )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${TAUCS_INCLUDE_DIR} )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${LAPACK_INCLUDE_DIR} )
|
||||
list( APPEND COMISO_LINK_DIRECTORIES ${LAPACK_LIBRARY_DIR} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${TAUCS_LIBRARY} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${LAPACK_LIBRARIES} )
|
||||
else ()
|
||||
message (STATUS "TAUCS not found!")
|
||||
set (COMISO_TAUCS_CONFIG_FILE_SETTINGS "#define COMISO_TAUCS_AVAILABLE 0" )
|
||||
endif ()
|
||||
|
||||
find_package (GUROBI)
|
||||
if (GUROBI_FOUND )
|
||||
set (COMISO_GUROBI_CONFIG_FILE_SETTINGS "#define COMISO_GUROBI_AVAILABLE 1" )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${GUROBI_INCLUDE_DIRS} )
|
||||
# list( APPEND COMISO_LINK_DIRECTORIES ${GUROBI_LIBRARY_DIR} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${GUROBI_LIBRARIES} )
|
||||
else ()
|
||||
message (STATUS "GUROBI not found!")
|
||||
set (COMISO_GUROBI_CONFIG_FILE_SETTINGS "#define COMISO_GUROBI_AVAILABLE 0" )
|
||||
endif ()
|
||||
|
||||
find_package (ARPACK)
|
||||
if (ARPACK_FOUND )
|
||||
set (COMISO_ARPACK_CONFIG_FILE_SETTINGS "#define COMISO_ARPACK_AVAILABLE 1" )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${ARPACK_INCLUDE_DIR} )
|
||||
# list( APPEND COMISO_LINK_DIRECTORIES ${ARPACK_LIBRARY_DIR} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${ARPACK_LIBRARY} )
|
||||
else ()
|
||||
message (STATUS "ARPACK not found!")
|
||||
set (COMISO_ARPACK_CONFIG_FILE_SETTINGS "#define COMISO_ARPACK_AVAILABLE 0" )
|
||||
endif ()
|
||||
|
||||
find_package (CPLEX)
|
||||
if (CPLEX_FOUND )
|
||||
set (COMISO_CPLEX_CONFIG_FILE_SETTINGS "#define COMISO_CPLEX_AVAILABLE 1" )
|
||||
list( APPEND COMISO_INCLUDE_DIRECTORIES ${CPLEX_INCLUDE_DIRS} )
|
||||
list( APPEND COMISO_LINK_LIBRARIES ${CPLEX_LIBRARIES} )
|
||||
|
||||
#enable c++ support
|
||||
add_definitions(-DIL_STD)
|
||||
else ()
|
||||
message (STATUS "CPLEX not found!")
|
||||
set (COMISO_CPLEX_CONFIG_FILE_SETTINGS "#define COMISO_CPLEX_AVAILABLE 0" )
|
||||
endif ()
|
||||
|
||||
include_directories (
|
||||
..
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${COMISO_INCLUDE_DIRECTORIES}
|
||||
)
|
||||
|
||||
# generate dllexport macros on windows
|
||||
if (WIN32)
|
||||
add_definitions(-DCOMISODLL)
|
||||
add_definitions(-D_SCL_SECURE_NO_DEPRECATE)
|
||||
endif ()
|
||||
|
||||
|
||||
link_directories (
|
||||
${COMISO_LINK_DIRECTORIES}
|
||||
)
|
||||
|
||||
# source code directories
|
||||
set (directories
|
||||
.
|
||||
Solver
|
||||
NSolver
|
||||
EigenSolver
|
||||
Config
|
||||
Utils
|
||||
QtWidgets
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
add_definitions(
|
||||
-D_USE_MATH_DEFINES -DNOMINMAX
|
||||
)
|
||||
endif ()
|
||||
|
||||
# collect all header,source and ui files
|
||||
acg_append_files (headers "*.hh" ${directories})
|
||||
acg_append_files (sources "*.cc" ${directories})
|
||||
acg_append_files (ui "*.ui" ${directories})
|
||||
|
||||
|
||||
macro (of_list_filter _list)
|
||||
if (WIN32)
|
||||
foreach (_element ${${_list}})
|
||||
if (_element MATCHES "gnuplot_i\\.(cc|hh)$")
|
||||
list (REMOVE_ITEM ${_list} ${_element})
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
endmacro ()
|
||||
|
||||
of_list_filter ( headers )
|
||||
of_list_filter ( sources )
|
||||
|
||||
|
||||
# remove template cc files from source file list
|
||||
acg_drop_templates (sources)
|
||||
|
||||
if( QT4_FOUND)
|
||||
# genereate uic and moc targets
|
||||
acg_qt4_autouic (uic_targets ${ui})
|
||||
acg_qt4_automoc (moc_targets ${headers})
|
||||
endif()
|
||||
acg_add_library (CoMISo SHARED ${uic_targets} ${sources} ${headers} ${moc_targets})
|
||||
|
||||
if (NOT APPLE)
|
||||
target_link_libraries (CoMISo
|
||||
${QT_LIBRARIES}
|
||||
${COMISO_LINK_LIBRARIES}
|
||||
)
|
||||
else(NOT APPLE)
|
||||
target_link_libraries (CoMISo
|
||||
${QT_LIBRARIES}
|
||||
${COMISO_LINK_LIBRARIES}
|
||||
)
|
||||
endif(NOT APPLE)
|
||||
|
||||
# display results
|
||||
acg_print_configure_header (COMISO "CoMISo")
|
||||
|
||||
# write config file
|
||||
configure_file ("${CMAKE_CURRENT_SOURCE_DIR}/Config/config.hh.in"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Config/config.hh" @ONLY IMMEDIATE)
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# Configure the examples last to be sure, that all configure files
|
||||
# of the library are already there
|
||||
#######################################################################
|
||||
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/factored_solver/CMakeLists.txt" )
|
||||
add_subdirectory (Examples/factored_solver)
|
||||
endif()
|
||||
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/quadratic_solver/CMakeLists.txt" )
|
||||
add_subdirectory (Examples/quadratic_solver)
|
||||
endif()
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/test2/CMakeLists.txt" )
|
||||
add_subdirectory (Examples/test2)
|
||||
endif()
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/small_quadratic_example/CMakeLists.txt" )
|
||||
add_subdirectory (Examples/small_quadratic_example)
|
||||
endif()
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/small_factored_example/CMakeLists.txt" )
|
||||
add_subdirectory (Examples/small_factored_example)
|
||||
endif()
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/super_sparse_matrix/CMakeLists.txt" )
|
||||
add_subdirectory (Examples/super_sparse_matrix)
|
||||
endif()
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/eigen_solver/CMakeLists.txt" )
|
||||
add_subdirectory (Examples/eigen_solver)
|
||||
endif()
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/small_nsolver/CMakeLists.txt" )
|
||||
add_subdirectory (Examples/small_nsolver)
|
||||
endif()
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/small_eigenproblem/CMakeLists.txt" )
|
||||
add_subdirectory (Examples/small_eigenproblem)
|
||||
endif()
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/small_miqp/CMakeLists.txt" )
|
||||
add_subdirectory (Examples/small_miqp)
|
||||
endif()
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/small_nleast_squares/CMakeLists.txt" )
|
||||
add_subdirectory (Examples/small_nleast_squares)
|
||||
endif()
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/small_sparseqr/CMakeLists.txt" )
|
||||
add_subdirectory (Examples/small_sparseqr)
|
||||
endif()
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/small_quadratic_resolve_example/CMakeLists.txt" )
|
||||
add_subdirectory (Examples/small_quadratic_resolve_example)
|
||||
endif()
|
||||
if( EXISTS "${CMAKE_SOURCE_DIR}/Examples/small_cplex_soc/CMakeLists.txt" )
|
||||
add_subdirectory (Examples/small_cplex_soc)
|
||||
endif()
|
||||
675
src/external/CoMISo/COPYING
vendored
Normal file
675
src/external/CoMISo/COPYING
vendored
Normal file
@ -0,0 +1,675 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
|
||||
2
src/external/CoMISo/CoMISo.cmake
vendored
Normal file
2
src/external/CoMISo/CoMISo.cmake
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# add our macro directory to cmake search path
|
||||
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
|
||||
48
src/external/CoMISo/Config/CoMISoDefines.hh
vendored
Normal file
48
src/external/CoMISo/Config/CoMISoDefines.hh
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#ifndef COMISODLLEXPORT
|
||||
#ifdef WIN32
|
||||
#ifdef COMISODLL
|
||||
#ifdef USECOMISO
|
||||
#define COMISODLLEXPORT __declspec(dllimport)
|
||||
#define COMISODLLEXPORTONLY
|
||||
#else
|
||||
#define COMISODLLEXPORT __declspec(dllexport)
|
||||
#define COMISODLLEXPORTONLY __declspec(dllexport)
|
||||
#endif
|
||||
#else
|
||||
#define COMISODLLEXPORT
|
||||
#define COMISODLLEXPORTONLY
|
||||
#endif
|
||||
#else
|
||||
#define COMISODLLEXPORT
|
||||
#define COMISODLLEXPORTONLY
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
|
||||
24
src/external/CoMISo/Config/config.hh.in
vendored
Normal file
24
src/external/CoMISo/Config/config.hh.in
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
// Build time dependencies for CoMiso
|
||||
|
||||
@COMISO_QT4_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_BOOST_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_BLAS_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_GMM_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_ADOLC_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_SUITESPARSE_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_SUITESPARSE_SPQR_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_MPI_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_HSL_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_PETSC_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_TAO_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_IPOPT_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_MUMPS_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_METIS_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_CGAL_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_TAUCS_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_GUROBI_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_ARPACK_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_CPLEX_CONFIG_FILE_SETTINGS@
|
||||
@COMISO_EIGEN3_CONFIG_FILE_SETTINGS@
|
||||
|
||||
|
||||
131
src/external/CoMISo/EigenSolver/ArpackSolver.cc
vendored
Normal file
131
src/external/CoMISo/EigenSolver/ArpackSolver.cc
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS ArpackSolver - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define COMISO_ARPACKSOLVER_C
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "ArpackSolver.hh"
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#if (COMISO_ARPACK_AVAILABLE && COMISO_SUITESPARSE_AVAILABLE && COMISO_EIGEN3_AVAILABLE)
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
template<class MatrixT,class MatrixT2>
|
||||
void
|
||||
ArpackSolver::
|
||||
solve(const MatrixT& _A,
|
||||
std::vector<double>& _eigenvalues,
|
||||
MatrixT2& _eigenvectors,
|
||||
const int _n_eigvalues,
|
||||
const char* _which_eigs )
|
||||
{
|
||||
Matrix A(_A);
|
||||
// ARSymStdEig<double, Matrix> eig_prob(A.matrix().cols(), _n_eigvalues, &A, &Matrix::mult_Mv, (char*)_which_eigs,
|
||||
// 0, 0.0, 2000);
|
||||
|
||||
ARSymStdEig<double, Matrix> eig_prob(A.matrix().cols(), _n_eigvalues, &A, &Matrix::mult_Mv, (char*)_which_eigs,
|
||||
0, 0.0, 100000);
|
||||
|
||||
int n_converged = eig_prob.FindEigenvectors();
|
||||
|
||||
// store result
|
||||
_eigenvalues.resize(n_converged);
|
||||
_eigenvectors.resize(A.matrix().rows(),n_converged);
|
||||
|
||||
for( int i=0; i<n_converged; ++i)
|
||||
{
|
||||
_eigenvalues[i] = eig_prob.Eigenvalue(i);
|
||||
for(int j = 0; j<A.matrix().rows(); ++j)
|
||||
_eigenvectors.coeffRef(j,i) = eig_prob.RawEigenvector(i)[j];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template<class MatrixT,class MatrixT2>
|
||||
void
|
||||
ArpackSolver::
|
||||
solve_inverse(const MatrixT& _A,
|
||||
std::vector<double>& _eigenvalues,
|
||||
MatrixT2& _eigenvectors,
|
||||
const int _n_eigvalues,
|
||||
const char* _which_eigs)
|
||||
{
|
||||
Matrix A(_A,true);
|
||||
ARSymStdEig<double, Matrix> eig_prob(A.matrix().cols(), _n_eigvalues, &A, &Matrix::mult_M_inv_v, (char*)_which_eigs,
|
||||
0, 0.0, 2000);
|
||||
|
||||
// ARSymStdEig(int np, int nevp, ARFOP* objOPp,
|
||||
// void (ARFOP::* MultOPxp)(ARFLOAT[], ARFLOAT[]),
|
||||
// char* whichp = "LM", int ncvp = 0, ARFLOAT tolp = 0.0,
|
||||
// int maxitp = 0, ARFLOAT* residp = NULL, bool ishiftp = true);
|
||||
|
||||
int n_converged = eig_prob.FindEigenvectors();
|
||||
|
||||
// store result
|
||||
_eigenvalues.resize(n_converged);
|
||||
_eigenvectors.resize(A.matrix().rows(),n_converged);
|
||||
|
||||
for( int i=0; i<n_converged; ++i)
|
||||
{
|
||||
_eigenvalues[i] = eig_prob.Eigenvalue(i);
|
||||
for(int j = 0; j<A.matrix().rows(); ++j)
|
||||
_eigenvectors.coeffRef(j,i) = eig_prob.RawEigenvector(i)[j];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template<class MatrixT,class MatrixT2>
|
||||
void
|
||||
ArpackSolver::
|
||||
check_result(const MatrixT& _A, std::vector<double>& _eigenvalues, MatrixT2& _eigenvectors)
|
||||
{
|
||||
int n=_eigenvectors.rows();
|
||||
|
||||
if(n<20)
|
||||
std::cerr << _A << std::endl;
|
||||
|
||||
for(unsigned int i=0; i<_eigenvalues.size(); ++i)
|
||||
{
|
||||
std::cerr << "eigenvalue " << i << ": " << _eigenvalues[i] << ", ";
|
||||
if(n < 20)
|
||||
{
|
||||
std::cerr << "eigenvector: ";
|
||||
for(int j=0; j<n; ++j)
|
||||
{
|
||||
std::cerr << _eigenvectors.coeffRef(j,i) << ", ";
|
||||
}
|
||||
}
|
||||
|
||||
// compute residuum
|
||||
Eigen::Matrix<double, Eigen::Dynamic, 1> v = _eigenvectors.block(0,i,n,1);
|
||||
std::cerr << "residuum norm: " << (_A*v - _eigenvalues[i]*v).norm() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
|
||||
//=============================================================================
|
||||
#endif // COMISO_SUITESPARSE_AVAILABLE
|
||||
//=============================================================================
|
||||
98
src/external/CoMISo/EigenSolver/ArpackSolver.hh
vendored
Normal file
98
src/external/CoMISo/EigenSolver/ArpackSolver.hh
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS ArpackSolver
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_ARPACKSOLVER_HH
|
||||
#define COMISO_ARPACKSOLVER_HH
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if (COMISO_ARPACK_AVAILABLE && COMISO_SUITESPARSE_AVAILABLE && COMISO_EIGEN3_AVAILABLE)
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
|
||||
#include <Eigen/Eigen>
|
||||
#include "EigenArpackMatrixT.hh"
|
||||
|
||||
#include <arpack++/arssym.h>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
|
||||
/** \class ArpackSolver ArpackSolver.hh <COMISO/.../ArpackSolver.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
|
||||
|
||||
class COMISODLLEXPORT ArpackSolver
|
||||
{
|
||||
public:
|
||||
|
||||
// sparse matrix type
|
||||
typedef EigenArpackMatrixT<double,Eigen::SparseMatrix<double,Eigen::ColMajor> > Matrix;
|
||||
|
||||
|
||||
/// Constructor
|
||||
ArpackSolver() {}
|
||||
|
||||
/// Destructor
|
||||
~ArpackSolver() {}
|
||||
|
||||
// solve eigenproblem
|
||||
// number of desired eigenvalues -> _n_eigenvalues
|
||||
// which eigenvalues -> one of {LA (largest algebraic), SA (smalles algebraic), LM (largest magnitude), SM(smallest magnitued), BE(both ends)}
|
||||
template<class MatrixT,class MatrixT2>
|
||||
void solve(const MatrixT& _A,
|
||||
std::vector<double>& _eigenvalues,
|
||||
MatrixT2& _eigenvectors,
|
||||
const int _n_eigvalues = 1,
|
||||
const char* _which_eigs = "SM");
|
||||
|
||||
// solve eigenproblem
|
||||
// number of desired eigenvalues -> _n_eigenvalues
|
||||
// which eigenvalues -> one of {LA (largest algebraic), SA (smalles algebraic), LM (largest magnitude), SM(smallest magnitued), BE(both ends)}
|
||||
template<class MatrixT,class MatrixT2>
|
||||
void solve_inverse(const MatrixT& _A,
|
||||
std::vector<double>& _eigenvalues,
|
||||
MatrixT2& _eigenvectors,
|
||||
const int _n_eigvalues = 1,
|
||||
const char* _which_eigs = "LM");
|
||||
|
||||
|
||||
// check resulting eigenvalues/eigenvectors
|
||||
template<class MatrixT,class MatrixT2>
|
||||
void check_result(const MatrixT& _A, std::vector<double>& _eigenvalues, MatrixT2& _eigenvectors);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace ACG
|
||||
//=============================================================================
|
||||
#if defined(INCLUDE_TEMPLATES) && !defined(COMISO_ARPACKSOLVER_C)
|
||||
#define COMISO_ARPACKSOLVER_TEMPLATES
|
||||
#include "ArpackSolver.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // COMISO_SUITESPARSE_AVAILABLE
|
||||
//=============================================================================
|
||||
#endif // ACG_ARPACKSOLVER_HH defined
|
||||
//=============================================================================
|
||||
|
||||
35
src/external/CoMISo/EigenSolver/EigenArpackMatrixT.cc
vendored
Normal file
35
src/external/CoMISo/EigenSolver/EigenArpackMatrixT.cc
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS EigenArpackMatrixT - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define COMISO_EIGENARPACKMATRIXT_C
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_SUITESPARSE_AVAILABLE
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "EigenArpackMatrixT.hh"
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace ACG
|
||||
//=============================================================================
|
||||
#endif // COMISO_SUITESPARSE_AVAILABLE
|
||||
//=============================================================================
|
||||
126
src/external/CoMISo/EigenSolver/EigenArpackMatrixT.hh
vendored
Normal file
126
src/external/CoMISo/EigenSolver/EigenArpackMatrixT.hh
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS EigenArpackMatrixT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_EIGENARPACKMATRIXT_HH
|
||||
#define COMISO_EIGENARPACKMATRIXT_HH
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if (COMISO_SUITESPARSE_AVAILABLE && COMISO_EIGEN3_AVAILABLE)
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <iostream>
|
||||
#include <Eigen/Eigen>
|
||||
|
||||
#if EIGEN_VERSION_AT_LEAST(3,1,0)
|
||||
#include <Eigen/CholmodSupport>
|
||||
#else
|
||||
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
|
||||
#include <unsupported/Eigen/CholmodSupport>
|
||||
#endif
|
||||
#include <Eigen/Sparse>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/** \class EigenArpackMatrixT EigenArpackMatrixT.hh <COMISO/.../EigenArpackMatrixT.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
|
||||
template <class RealT,class MatrixT>
|
||||
class EigenArpackMatrixT
|
||||
{
|
||||
public:
|
||||
|
||||
typedef MatrixT Matrix;
|
||||
typedef RealT Real;
|
||||
|
||||
/// Constructor
|
||||
template<class MatrixT2>
|
||||
EigenArpackMatrixT(const MatrixT2& _m, bool _use_inverse = false)
|
||||
{
|
||||
mat_ = _m;
|
||||
|
||||
if(_use_inverse)
|
||||
{
|
||||
sllt_.compute(mat_);
|
||||
|
||||
#if EIGEN_VERSION_AT_LEAST(3,1,0)
|
||||
if ( !sllt_.info() != Eigen::Success )
|
||||
#else
|
||||
if ( !sllt_.succeeded() )
|
||||
#endif
|
||||
std::cout << "[ERROR] EigenArpackMatrix(): Could not compute llt factorization." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
~EigenArpackMatrixT() {}
|
||||
|
||||
// get reference on matrix
|
||||
Matrix& matrix() { return mat_; }
|
||||
|
||||
// matrix-vector multiplication _w = mat_*_v
|
||||
void mult_Mv(Real* _v, Real* _w)
|
||||
{
|
||||
Eigen::Map<Eigen::Matrix<Real, Eigen::Dynamic, 1> > v(_v,mat_.rows()); // uses v as a ArrayXf object
|
||||
Eigen::Map<Eigen::Matrix<Real, Eigen::Dynamic, 1> > w(_w,mat_.cols()); // uses w as a ArrayXf object
|
||||
|
||||
w = mat_*v;
|
||||
}
|
||||
|
||||
// matrix-vector multiplication _w = mat_*_v
|
||||
void mult_M_inv_v(Real* _v, Real* _w)
|
||||
{
|
||||
Eigen::Map<Eigen::Matrix<Real, Eigen::Dynamic, 1> > v(_v,mat_.rows()); // uses v as a ArrayXf object
|
||||
Eigen::Map<Eigen::Matrix<Real, Eigen::Dynamic, 1> > w(_w,mat_.cols()); // uses w as a ArrayXf object
|
||||
|
||||
w = sllt_.solve(v);
|
||||
|
||||
// std::cerr << "input:" << std::endl;
|
||||
// std::cerr << v << std::endl;
|
||||
// std::cerr << "output:" << std::endl;
|
||||
// std::cerr << w << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Matrix mat_;
|
||||
|
||||
#if EIGEN_VERSION_AT_LEAST(3,1,0)
|
||||
Eigen::CholmodSupernodalLLT<Eigen::SparseMatrix<Real> > sllt_;
|
||||
#else
|
||||
Eigen::SparseLLT<Eigen::SparseMatrix<Real>, Eigen::Cholmod> sllt_;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#if defined(INCLUDE_TEMPLATES) && !defined(COMISO_EIGENARPACKMATRIXT_C)
|
||||
#define COMISO_EIGENARPACKMATRIXT_TEMPLATES
|
||||
#include "EigenArpackMatrixT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // COMISO_SUITESPARSE_AVAILABLE
|
||||
//=============================================================================
|
||||
#endif // COMISO_EIGENARPACKMATRIXT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
15
src/external/CoMISo/Examples/factored_solver/CMakeLists.txt
vendored
Normal file
15
src/external/CoMISo/Examples/factored_solver/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
include (CoMISoExample)
|
||||
|
||||
if (WIN32)
|
||||
acg_add_executable (factored_solver WIN32 ${sources} ${headers} )
|
||||
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
|
||||
${COMISO_LINK_LIBRARIES}
|
||||
)
|
||||
193
src/external/CoMISo/Examples/factored_solver/main.cc
vendored
Normal file
193
src/external/CoMISo/Examples/factored_solver/main.cc
vendored
Normal file
@ -0,0 +1,193 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <gmm/gmm.h>
|
||||
#include <vector>
|
||||
#include <CoMISo/Solver/ConstrainedSolver.hh>
|
||||
#include <CoMISo/Solver/MISolver.hh>
|
||||
#include <CoMISo/Solver/GMM_Tools.hh>
|
||||
|
||||
/// function to setup a random sparse row matrix of dimension _m x _n
|
||||
/// for the simplicity of this example only integer valued entries are used
|
||||
template<class MatrixT>
|
||||
void random_sparse_row_matrix( MatrixT& _B, int _m, int _n, double _density = 0.7)
|
||||
{
|
||||
gmm::resize(_B, _m, _n);
|
||||
|
||||
for( int i=0; i<_m; ++i)
|
||||
for( int j=0; j<_n; ++j)
|
||||
if( (rand()-1.0*_density*RAND_MAX)/RAND_MAX> 0) // for sparseness
|
||||
_B(i,j) = round(((rand()-0.4*RAND_MAX)/RAND_MAX)*10.0);
|
||||
}
|
||||
|
||||
/// function to setup a random sparse constraint row matrix of dimension _c x _n
|
||||
/// for the simplicity of the example only -1, 0, 1 constraints are used
|
||||
template<class MatrixT>
|
||||
void simple_constraint_row_matrix( MatrixT& _C, int _c, int _n, double _distribution = 0.2)
|
||||
{
|
||||
gmm::resize( _C, _c, _n);
|
||||
for( int i=0; i<_c; ++i)
|
||||
for( int j=0; j<_n; ++j)
|
||||
{
|
||||
double randnum = (double(rand())/double(RAND_MAX));
|
||||
if ( randnum < _distribution)
|
||||
_C( i,j) = -1;
|
||||
else if( randnum > (1.0-_distribution))
|
||||
_C( i,j) = 1;
|
||||
else
|
||||
_C( i,j) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// function to print the equations corresponding to the matrices of an equation system
|
||||
template<class MatrixT>
|
||||
void print_equations( const MatrixT& _B)
|
||||
{
|
||||
int m = gmm::mat_nrows( _B);
|
||||
int n = gmm::mat_ncols( _B);
|
||||
for( int i = 0; i < m; ++i)
|
||||
{
|
||||
for( int j = 0; j < n-1; ++j)
|
||||
{
|
||||
if( _B(i,j) != 0.0)
|
||||
std::cout << _B(i,j) << "*x" << j;
|
||||
else
|
||||
std::cout << " 0 ";
|
||||
if( j < n-2 ) std::cout << " + ";
|
||||
}
|
||||
std::cout << " = " << _B(i, n-1) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Example main
|
||||
int main(void)
|
||||
{
|
||||
std::cout << "---------- 1) setup an (m x n) sparse row matrix B (i.e. the B in the system ((Bx)^T)Bx)" << std::endl;
|
||||
int m = 9;
|
||||
int n = 5+1;
|
||||
gmm::row_matrix< gmm::wsvector< double > > B;
|
||||
random_sparse_row_matrix( B, m, n, 0.85);
|
||||
std::cout << B << std::endl << std::endl;
|
||||
//gmm::inspect_matrix( B );
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "---------- 2) define a set of linear constraints as an (c x n) row matrix C" << std::endl;
|
||||
int c = 2;
|
||||
gmm::row_matrix< gmm::wsvector< double > > C;
|
||||
simple_constraint_row_matrix( C, c, n);
|
||||
std::cout << C << std::endl;
|
||||
std::cout << "corresponding to the following linear equations : " << std::endl;
|
||||
print_equations( C );
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "---------- 3) we now explicitly carry out the steps performed internally by the constrained solver and compare the two results at the end..." << std::endl;
|
||||
// copy the matrices
|
||||
gmm::row_matrix< gmm::wsvector< double > > Bcpy( B );
|
||||
gmm::row_matrix< gmm::wsvector< double > > Ccpy( C );
|
||||
|
||||
// create a constrained solver
|
||||
COMISO::ConstrainedSolver cs;
|
||||
// vector of indices to round (this is the mixed-integer part)
|
||||
std::vector< int > ids_to_round;
|
||||
// lets say we want to round the third variable
|
||||
ids_to_round.push_back(2);
|
||||
|
||||
// vector of independent variables to be eliminated (computed by the make_constraints_independent function)
|
||||
std::vector< int > ids_to_elim;
|
||||
|
||||
std::cout << "---------- ---------- 3.1) make the constraints independent (gauss elimination on C)" << std::endl;
|
||||
print_equations( Ccpy );
|
||||
cs.make_constraints_independent( Ccpy, ids_to_round, ids_to_elim);
|
||||
std::cout << " constraints after gauss elimination..." << std::endl;
|
||||
std::cout << Ccpy << std::endl;
|
||||
std::cout << " the variables to be eliminated are: " << std::endl;
|
||||
std::cout << ids_to_elim << std::endl << std::endl;
|
||||
|
||||
std::cout << "---------- ---------- 3.2) eliminate constraints from system matrix B" << std::endl;
|
||||
// this is the column matrix later used by the solver, it is setup by the eliminate_constraints function
|
||||
gmm::col_matrix< gmm::wsvector< double > > Bcol;
|
||||
|
||||
// this re-indexing is also used by the solver, to know which variables are still there (!=-1) and which have been eliminated (=-1) it is setup by eliminate_constraints
|
||||
std::vector< int > new_idx;
|
||||
|
||||
cs.eliminate_constraints( Ccpy, Bcpy, ids_to_round, ids_to_elim, new_idx, Bcol);
|
||||
std::cout << " B matrix after elimination of constraints..." << std::endl;
|
||||
std::cout << Bcol << std::endl;
|
||||
|
||||
std::cout << "---------- ---------- 3.3) setup the linear system Ax=b, where by forming B^TB and extracting the right hand side" << std::endl;
|
||||
|
||||
// this is the solution vector x
|
||||
std::vector< double > x;
|
||||
|
||||
int new_n = gmm::mat_ncols( Bcol);
|
||||
// set up B transposed
|
||||
gmm::col_matrix< gmm::wsvector< double > > Bt( new_n, m);
|
||||
gmm::copy( gmm::transposed( Bcol), Bt);
|
||||
|
||||
// setup BtB
|
||||
gmm::col_matrix< gmm::wsvector< double > > BtB( new_n, new_n);
|
||||
gmm::mult( Bt, Bcol, BtB);
|
||||
|
||||
// extract rhs
|
||||
std::vector< double > rhs( new_n);
|
||||
gmm::copy( gmm::scaled(gmm::mat_const_col( BtB, new_n - 1),-1.0), rhs);
|
||||
rhs.resize( new_n - 1);
|
||||
|
||||
// resize BtB to only contain the actual system matrix (and not the rhs)
|
||||
gmm::resize( BtB, new_n - 1, new_n - 1);
|
||||
x.resize( new_n - 1);
|
||||
|
||||
// BtB -> CSC
|
||||
gmm::csc_matrix<double> BtBCSC;
|
||||
BtBCSC.init_with_good_format( BtB);
|
||||
|
||||
std::cout << " the linear system now looks like..." << std::endl;
|
||||
std::cout << " Matrix A\n " << BtBCSC << std::endl;
|
||||
std::cout << " Right hand side b\n" << rhs << std::endl << std::endl;
|
||||
|
||||
std::cout << "---------- ---------- 3.4) solve the system using the mixed-integer solver..." << std::endl;
|
||||
// create solver
|
||||
COMISO::MISolver miso;
|
||||
// miso solve
|
||||
miso.solve( BtBCSC, x, rhs, ids_to_round);
|
||||
std::cout << " solution vector x is\n" << x << std::endl << std::endl;
|
||||
|
||||
std::cout << "---------- ---------- 3.5) now the solution must be re-indexed to the expected/original form/size...." << std::endl;
|
||||
cs.restore_eliminated_vars( Ccpy, x, ids_to_elim, new_idx);
|
||||
std::cout << " fullsize solution vector x is\n" << x << std::endl << std::endl;
|
||||
|
||||
std::cout << "---------- ---------- 4) the same result is obtained by one call to the constrained solver, which takes care of re-indexing etc. internally..." << std::endl;
|
||||
// ids_to_round is altered by previous steps...
|
||||
ids_to_round.clear();
|
||||
ids_to_round.push_back(2);
|
||||
cs.solve( C, B, x, ids_to_round, 0.0, false, true);
|
||||
std::cout << " fullsize solution vector x is\n" << x << std::endl << std::endl;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
15
src/external/CoMISo/Examples/quadratic_solver/CMakeLists.txt
vendored
Normal file
15
src/external/CoMISo/Examples/quadratic_solver/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
include (CoMISoExample)
|
||||
|
||||
if (WIN32)
|
||||
acg_add_executable (quadratic_solver WIN32 ${sources} ${headers} )
|
||||
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
|
||||
${COMISO_LINK_LIBRARIES}
|
||||
)
|
||||
199
src/external/CoMISo/Examples/quadratic_solver/main.cc
vendored
Normal file
199
src/external/CoMISo/Examples/quadratic_solver/main.cc
vendored
Normal file
@ -0,0 +1,199 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <gmm/gmm.h>
|
||||
#include <vector>
|
||||
#include <CoMISo/Solver/ConstrainedSolver.hh>
|
||||
#include <CoMISo/Solver/MISolver.hh>
|
||||
#include <CoMISo/Solver/GMM_Tools.hh>
|
||||
|
||||
/// function to setup a random sparse row matrix of dimension _m x _n
|
||||
/// for the simplicity of this example only integer valued entries are used
|
||||
template<class MatrixT>
|
||||
void random_sparse_row_matrix( MatrixT& _B, int _m, int _n, double _density = 0.7)
|
||||
{
|
||||
gmm::resize(_B, _m, _n);
|
||||
|
||||
for( int i=0; i<_m; ++i)
|
||||
for( int j=0; j<_n; ++j)
|
||||
if( (rand()-1.0*_density*RAND_MAX)/RAND_MAX> 0) // for sparseness
|
||||
_B(i,j) = round(((rand()-0.4*RAND_MAX)/RAND_MAX)*10.0);
|
||||
}
|
||||
|
||||
/// function to extract the actual system Ax=b of linear equation from a B^tB matrix
|
||||
template<class RMatrixT, class CMatrixT>
|
||||
void extract_Axb( const RMatrixT& _B, CMatrixT& _A, std::vector< double >& _b)
|
||||
{
|
||||
int dimm = gmm::mat_nrows(_B);
|
||||
int dimn = gmm::mat_ncols(_B);
|
||||
gmm::col_matrix< gmm::wsvector< double > > Btcol;
|
||||
gmm::col_matrix< gmm::wsvector< double > > Bcol;
|
||||
gmm::resize( Btcol, dimn, dimm);
|
||||
gmm::resize( Bcol, dimm, dimn);
|
||||
gmm::resize( _A, dimn, dimn);
|
||||
gmm::copy( _B, Bcol);
|
||||
gmm::copy( gmm::transposed( Bcol), Btcol);
|
||||
gmm::mult( Btcol, Bcol, _A);
|
||||
_b.resize( dimn);
|
||||
gmm::copy( _A.col(dimn-1), _b);
|
||||
_b.resize( dimn-1);
|
||||
gmm::resize( _A, dimn-1, dimn-1);
|
||||
gmm::scale(_b, -1.0);
|
||||
}
|
||||
|
||||
/// function to setup a random sparse constraint row matrix of dimension _c x _n
|
||||
/// for the simplicity of the example only -1, 0, 1 constraints are used
|
||||
template<class MatrixT>
|
||||
void simple_constraint_row_matrix( MatrixT& _C, int _c, int _n, double _distribution = 0.2)
|
||||
{
|
||||
gmm::resize( _C, _c, _n);
|
||||
for( int i=0; i<_c; ++i)
|
||||
for( int j=0; j<_n; ++j)
|
||||
{
|
||||
double randnum = (double(rand())/double(RAND_MAX));
|
||||
if ( randnum < _distribution)
|
||||
_C( i,j) = -1;
|
||||
else if( randnum > (1.0-_distribution))
|
||||
_C( i,j) = 1;
|
||||
else
|
||||
_C( i,j) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// function to print the equations corresponding to the matrices of an equation system
|
||||
template<class MatrixT>
|
||||
void print_equations( const MatrixT& _B)
|
||||
{
|
||||
int m = gmm::mat_nrows( _B);
|
||||
int n = gmm::mat_ncols( _B);
|
||||
for( int i = 0; i < m; ++i)
|
||||
{
|
||||
for( int j = 0; j < n-1; ++j)
|
||||
{
|
||||
if( _B(i,j) != 0.0)
|
||||
std::cout << _B(i,j) << "*x" << j;
|
||||
else
|
||||
std::cout << " 0 ";
|
||||
if( j < n-2 ) std::cout << " + ";
|
||||
}
|
||||
std::cout << " = " << _B(i, n-1) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Example main
|
||||
int main(void)
|
||||
{
|
||||
std::cout << "---------- 1) setup an (m x n) sparse row matrix B (i.e. the B in the system ((Bx)^T)Bx)" << std::endl;
|
||||
int m = 9;
|
||||
int n = 5+1;
|
||||
gmm::row_matrix< gmm::wsvector< double > > B;
|
||||
random_sparse_row_matrix( B, m, n, 0.85);
|
||||
std::cout << B << std::endl << std::endl;
|
||||
|
||||
std::cout << "---------- 2) extract the Ax=b equation system, A (n-1 x n-1)" << std::endl;
|
||||
gmm::col_matrix< gmm::wsvector< double > > A;
|
||||
std::vector< double > b;
|
||||
extract_Axb( B, A, b);
|
||||
std::cout << " A " << std::endl;
|
||||
std::cout << A << " " << b << std::endl;
|
||||
|
||||
//gmm::inspect_matrix( B );
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "---------- 3) define a set of linear constraints as an (c x n) row matrix C" << std::endl;
|
||||
int c = 2;
|
||||
gmm::row_matrix< gmm::wsvector< double > > C;
|
||||
simple_constraint_row_matrix( C, c, n);
|
||||
std::cout << C << std::endl;
|
||||
std::cout << "corresponding to the following linear equations : " << std::endl;
|
||||
print_equations( C );
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "---------- 4) we now explicitly carry out the steps performed internally by the constrained solver and compare the two results at the end..." << std::endl;
|
||||
// copy the matrices
|
||||
gmm::col_matrix< gmm::wsvector< double > > Acpy( A );
|
||||
|
||||
// create a constrained solver
|
||||
COMISO::ConstrainedSolver cs;
|
||||
// vector of indices to round (this is the mixed-integer part)
|
||||
std::vector< int > ids_to_round;
|
||||
// lets say we want to round the third variable
|
||||
ids_to_round.push_back(2);
|
||||
|
||||
// vector of independent variables to be eliminated (computed by the make_constraints_independent function)
|
||||
std::vector< int > ids_to_elim;
|
||||
|
||||
std::cout << "---------- ---------- 4.1) make the constraints independent (gauss elimination on C)" << std::endl;
|
||||
print_equations( C );
|
||||
cs.make_constraints_independent( C, ids_to_round, ids_to_elim);
|
||||
std::cout << " constraints after gauss elimination..." << std::endl;
|
||||
std::cout << C << std::endl;
|
||||
std::cout << " the variables to be eliminated are: " << std::endl;
|
||||
std::cout << ids_to_elim << std::endl << std::endl;
|
||||
gmm::row_matrix< gmm::wsvector< double > > Ccpy( C );
|
||||
|
||||
|
||||
std::cout << "---------- ---------- 4.2) eliminate constraints from system matrix A" << std::endl;
|
||||
|
||||
// CSC matrix later initialized and used by solver
|
||||
gmm::csc_matrix< double > Acsc;
|
||||
|
||||
// this re-indexing is also used by the solver, to know which variables are still there (!=-1) and which have been eliminated (=-1) it is setup by eliminate_constraints
|
||||
std::vector< int > new_idx;
|
||||
|
||||
std::vector< double > x(b.size());
|
||||
std::vector< double > b_cpy(b);
|
||||
|
||||
cs.eliminate_constraints( Ccpy, Acpy, x, b, ids_to_round, ids_to_elim, new_idx, Acsc);
|
||||
std::cout << " A matrix after elimination of constraints..." << std::endl;
|
||||
std::cout << Acsc << std::endl;
|
||||
|
||||
|
||||
std::cout << "---------- ---------- 4.3) solve the system using the mixed-integer solver..." << std::endl;
|
||||
// create solver
|
||||
COMISO::MISolver miso;
|
||||
// miso solve
|
||||
miso.solve( Acsc, x, b, ids_to_round);
|
||||
std::cout << " solution vector x is\n" << x << std::endl << std::endl;
|
||||
|
||||
|
||||
std::cout << "---------- ---------- 4.4) now the solution must be re-indexed to the expected/original form/size...." << std::endl;
|
||||
cs.restore_eliminated_vars( Ccpy, x, ids_to_elim, new_idx);
|
||||
std::cout << " fullsize solution vector x is\n" << x << std::endl << std::endl;
|
||||
|
||||
|
||||
std::cout << "---------- ---------- 5) the same result is obtained by one call to the constrained solver, which takes care of re-indexing etc. internally..." << std::endl;
|
||||
// ids_to_round is altered by previous steps...
|
||||
ids_to_round.clear();
|
||||
ids_to_round.push_back(2);
|
||||
x.resize(gmm::mat_nrows(A));
|
||||
b.resize(gmm::mat_nrows(A));
|
||||
cs.solve( C, A, x, b_cpy, ids_to_round, 0.0, false, true);
|
||||
std::cout << " fullsize solution vector x is\n" << x << std::endl << std::endl;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
15
src/external/CoMISo/Examples/small_cplex_soc/CMakeLists.txt
vendored
Normal file
15
src/external/CoMISo/Examples/small_cplex_soc/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
include (CoMISoExample)
|
||||
|
||||
if (WIN32)
|
||||
acg_add_executable (small_cplex_soc WIN32 ${sources} ${headers} )
|
||||
else ()
|
||||
acg_add_executable (small_cplex_soc ${sources} ${headers} )
|
||||
endif ()
|
||||
|
||||
# enable rpath linking
|
||||
set_target_properties(small_cplex_soc PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1)
|
||||
|
||||
target_link_libraries (small_cplex_soc
|
||||
CoMISo
|
||||
${COMISO_LINK_LIBRARIES}
|
||||
)
|
||||
124
src/external/CoMISo/Examples/small_cplex_soc/main.cc
vendored
Normal file
124
src/external/CoMISo/Examples/small_cplex_soc/main.cc
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#include <CoMISo/Config/config.hh>
|
||||
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <vector>
|
||||
#include <CoMISo/NSolver/LeastSquaresProblem.hh>
|
||||
#include <CoMISo/NSolver/LinearConstraint.hh>
|
||||
#include <CoMISo/NSolver/NPDerivativeChecker.hh>
|
||||
#include <CoMISo/NSolver/CPLEXSolver.hh>
|
||||
#include <CoMISo/NSolver/IPOPTSolver.hh>
|
||||
|
||||
// solve least squares problem for x=1, y=2 and x-2y+z = 1
|
||||
// with hard constraints x =-3, z>=3, z^2 >= x^2+y^2
|
||||
|
||||
|
||||
// Example main
|
||||
int main(void)
|
||||
{
|
||||
std::cout << "---------- 1) Problem description..." << std::endl;
|
||||
std::cout << "Least squares terms: x=1, y=2 and x-2y+z = 1" << std::endl;
|
||||
std::cout << "Constraints : x =-3, z>=3, z^2 >= x^2+y^2" << std::endl;
|
||||
|
||||
std::cout << "---------- 1) Get an instance of a LeastSquaresProblem..." << std::endl;
|
||||
// number of unknowns
|
||||
const int n = 3;
|
||||
COMISO::LeastSquaresProblem lsqp(n);
|
||||
|
||||
// term0
|
||||
COMISO::LinearConstraint::SVectorNC coeffs0(n);
|
||||
coeffs0.coeffRef(0) = 1.0;
|
||||
COMISO::LinearConstraint term0(coeffs0,-1.0,COMISO::NConstraintInterface::NC_EQUAL);
|
||||
lsqp.add_term(&term0);
|
||||
|
||||
// term1
|
||||
COMISO::LinearConstraint::SVectorNC coeffs1(n);
|
||||
coeffs1.coeffRef(1) = 1.0;
|
||||
COMISO::LinearConstraint term1(coeffs1,-2.0,COMISO::NConstraintInterface::NC_EQUAL);
|
||||
lsqp.add_term(&term1);
|
||||
|
||||
// term2
|
||||
COMISO::LinearConstraint::SVectorNC coeffs2(n);
|
||||
coeffs2.coeffRef(0) = 1.0;
|
||||
coeffs2.coeffRef(1) = -2.0;
|
||||
coeffs2.coeffRef(2) = 1.0;
|
||||
COMISO::LinearConstraint term2(coeffs2,-1.0,COMISO::NConstraintInterface::NC_EQUAL);
|
||||
lsqp.add_term(&term2);
|
||||
|
||||
std::cout << "---------- 2) set up constraints" << std::endl;
|
||||
|
||||
// set x = -3.0
|
||||
COMISO::LinearConstraint lc;
|
||||
lc.coeffs().coeffRef(0) = 1.0;
|
||||
lc.b() = 3.0;
|
||||
|
||||
// set z>=3 (cone constraint requires that z>=0 !!!)
|
||||
COMISO::BoundConstraint bc(2,3,3,COMISO::NConstraintInterface::NC_GREATER_EQUAL);
|
||||
|
||||
// set z^2 >= x^2+y^2
|
||||
COMISO::ConeConstraint cc;
|
||||
cc.resize(3);
|
||||
cc.i() = 2;
|
||||
cc.c() = 4.0;
|
||||
cc.Q()(0,0) = 2.0;
|
||||
cc.Q()(1,1) = 4.0;
|
||||
cc.Q()(0,1) = 1.0;
|
||||
cc.Q()(1,0) = 1.0;
|
||||
|
||||
// fill constraint vector
|
||||
std::vector<COMISO::NConstraintInterface*> constraints;
|
||||
constraints.push_back(&lc);
|
||||
constraints.push_back(&bc);
|
||||
constraints.push_back(&cc);
|
||||
|
||||
// check if CPLEX solver available in current configuration
|
||||
#if( COMISO_CPLEX_AVAILABLE)
|
||||
std::cout << "---------- 3) Solve with CPLEX solver... " << std::endl;
|
||||
|
||||
COMISO::CPLEXSolver cplx;
|
||||
cplx.solve(&lsqp, constraints);
|
||||
#endif
|
||||
|
||||
std::cout << "---------- 4) Print solution CPLEX..." << std::endl;
|
||||
for( int i=0; i<n; ++i)
|
||||
std::cerr << "x_" << i << " = " << lsqp.x()[i] << std::endl;
|
||||
|
||||
// check if IPOPT solver available in current configuration
|
||||
#if( COMISO_IPOPT_AVAILABLE)
|
||||
std::cout << "---------- 5) Solve with IPOPT solver... " << std::endl;
|
||||
|
||||
COMISO::IPOPTSolver ipopt;
|
||||
ipopt.app().Options()->SetStringValue("derivative_test", "second-order");
|
||||
ipopt.solve(&lsqp, constraints);
|
||||
#endif
|
||||
|
||||
std::cout << "---------- 6) Print solution..." << std::endl;
|
||||
for( int i=0; i<n; ++i)
|
||||
std::cerr << "x_" << i << " = " << lsqp.x()[i] << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
15
src/external/CoMISo/Examples/small_eigenproblem/CMakeLists.txt
vendored
Normal file
15
src/external/CoMISo/Examples/small_eigenproblem/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
include (CoMISoExample)
|
||||
|
||||
if (WIN32)
|
||||
acg_add_executable (small_eigenproblem WIN32 ${sources} ${headers} )
|
||||
else ()
|
||||
acg_add_executable (small_eigenproblem ${sources} ${headers} )
|
||||
endif ()
|
||||
|
||||
# enable rpath linking
|
||||
set_target_properties(small_eigenproblem PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1)
|
||||
|
||||
target_link_libraries (small_eigenproblem
|
||||
CoMISo
|
||||
${COMISO_LINK_LIBRARIES}
|
||||
)
|
||||
107
src/external/CoMISo/Examples/small_eigenproblem/main.cc
vendored
Normal file
107
src/external/CoMISo/Examples/small_eigenproblem/main.cc
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if (COMISO_ARPACK_AVAILABLE && COMISO_SUITESPARSE_AVAILABLE && COMISO_EIGEN3_AVAILABLE)
|
||||
//=============================================================================
|
||||
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <vector>
|
||||
#include <CoMISo/EigenSolver/ArpackSolver.hh>
|
||||
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
|
||||
#include <Eigen/Sparse>
|
||||
#include <Eigen/Dense>
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Example main
|
||||
int main(void)
|
||||
{
|
||||
// matrix types
|
||||
#if EIGEN_VERSION_AT_LEAST(3,1,0)
|
||||
typedef Eigen::SparseMatrix<double,Eigen::ColMajor> SMatrix;
|
||||
#else
|
||||
typedef Eigen::DynamicSparseMatrix<double,Eigen::ColMajor> SMatrix;
|
||||
#endif
|
||||
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> Matrix;
|
||||
|
||||
std::cout << "---------- 1) Setting up matrix..." << std::endl;
|
||||
unsigned int n=5;
|
||||
SMatrix A(n,n);
|
||||
// 1D Laplacian
|
||||
for(unsigned int i=0; i<n; ++i)
|
||||
{
|
||||
int count = 0;
|
||||
if( i > 0)
|
||||
{
|
||||
A.coeffRef(i,i-1) = -1.0;
|
||||
++count;
|
||||
}
|
||||
if(i<n-1)
|
||||
{
|
||||
A.coeffRef(i,i+1) = -1.0;
|
||||
++count;
|
||||
}
|
||||
|
||||
A.coeffRef(i,i) = count;
|
||||
}
|
||||
|
||||
|
||||
std::cout << "---------- 2) Solving for m smallest eigenvalues and eigenvectors..." << std::endl;
|
||||
unsigned int m=3;
|
||||
COMISO::ArpackSolver arsolv;
|
||||
std::vector<double> evals;
|
||||
Matrix evects;
|
||||
arsolv.solve(A, evals, evects, m);
|
||||
|
||||
std::cout << "---------- 3) printing results..." << std::endl;
|
||||
std::cerr << "********* eigenvalues: ";
|
||||
for(unsigned int i=0; i<evals.size(); ++i)
|
||||
std::cerr << evals[i] << ", ";
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::cerr <<"********* eigenvectors:" << std::endl;
|
||||
std::cerr << evects << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
#else
|
||||
//=============================================================================
|
||||
|
||||
// Example main
|
||||
int main(void)
|
||||
{
|
||||
std::cerr << "Info: required dependencies are missing, abort...\n";
|
||||
return 0;
|
||||
}
|
||||
//=============================================================================
|
||||
#endif // COMISO_SUITESPARSE_AVAILABLE
|
||||
//=============================================================================
|
||||
15
src/external/CoMISo/Examples/small_factored_example/CMakeLists.txt
vendored
Normal file
15
src/external/CoMISo/Examples/small_factored_example/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
include (CoMISoExample)
|
||||
|
||||
if (WIN32)
|
||||
acg_add_executable (small_factored_solver WIN32 ${sources} ${headers} )
|
||||
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
|
||||
${COMISO_LINK_LIBRARIES}
|
||||
)
|
||||
119
src/external/CoMISo/Examples/small_factored_example/main.cc
vendored
Normal file
119
src/external/CoMISo/Examples/small_factored_example/main.cc
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <gmm/gmm.h>
|
||||
#include <vector>
|
||||
#include <CoMISo/Solver/ConstrainedSolver.hh>
|
||||
#include <CoMISo/Solver/MISolver.hh>
|
||||
#include <CoMISo/Solver/GMM_Tools.hh>
|
||||
|
||||
|
||||
/// function to initialize a simple row matrix of equations
|
||||
template<class MatrixT>
|
||||
void init_fac( MatrixT& _B )
|
||||
{
|
||||
_B(0,0) = 0 ; _B(0,1) = 4 ; _B(0,2) = -2 ; _B(0,3) = 0 ; _B(0,4) = -1;
|
||||
_B(1,0) = 0 ; _B(1,1) = 0 ; _B(1,2) = 0 ; _B(1,3) = 0 ; _B(1,4) = 0 ;
|
||||
_B(2,0) = 5 ; _B(2,1) = 0 ; _B(2,2) = -3 ; _B(2,3) = 0 ; _B(2,4) = 0 ;
|
||||
_B(3,0) = 0 ; _B(3,1) = 0 ; _B(3,2) = -2 ; _B(3,3) = 0 ; _B(3,4) = 0 ;
|
||||
_B(4,0) = 0 ; _B(4,1) = -2; _B(4,2) = 0 ; _B(4,3) = 2 ; _B(4,4) = 0 ;
|
||||
}
|
||||
|
||||
/// function to print the equations corresponding to the matrices of an equation system
|
||||
template<class MatrixT>
|
||||
void print_equations( const MatrixT& _B)
|
||||
{
|
||||
int m = gmm::mat_nrows( _B);
|
||||
int n = gmm::mat_ncols( _B);
|
||||
for( int i = 0; i < m; ++i)
|
||||
{
|
||||
for( int j = 0; j < n-1; ++j)
|
||||
{
|
||||
if( _B(i,j) != 0.0)
|
||||
std::cout << _B(i,j) << "*x" << j;
|
||||
else
|
||||
std::cout << " 0 ";
|
||||
if( j < n-2 ) std::cout << " + ";
|
||||
}
|
||||
std::cout << " = " << _B(i, n-1) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Example main
|
||||
int main(void)
|
||||
{
|
||||
std::cout << "---------- 1) Setup a number of equations (i.e. the B matrix of a factored system of linear equations B^tB)..." << std::endl;
|
||||
int n = 4;
|
||||
gmm::row_matrix< gmm::wsvector< double > > B(n+1,n+1);
|
||||
std::vector< double > x(n);
|
||||
|
||||
init_fac( B );
|
||||
|
||||
// create an empty constraint matrix (will be used later)
|
||||
gmm::row_matrix< gmm::wsvector< double > > constraints(0,n+1); //n+1 because of right hand side
|
||||
// create an empty vector of variable indices to be rounded (will be used later)
|
||||
std::vector< int > ids_to_round;
|
||||
|
||||
std::cout << B << std::endl << std::endl;
|
||||
|
||||
|
||||
std::cout << "---------- 2) The original solution to this system is..." << std::endl;
|
||||
|
||||
COMISO::ConstrainedSolver cs;
|
||||
// void solve( RMatrixT& _constraints, RMatrixT& _B, VectorT& _x, VectorIT& _idx_to_round, double _reg_factor = 0.0, bool _show_miso_settings = true, bool _show_timings = true );
|
||||
//_show_miso_settings requires a QT context and hence must be false in this example
|
||||
cs.solve( constraints, B, x, ids_to_round, 0.0, false, true);
|
||||
// copy this solution for later
|
||||
std::vector< double > org_x( x);
|
||||
std::cout << x << std::endl;
|
||||
|
||||
|
||||
std::cout << "---------- 3) Rounding: forcing the second variable to lie on an integer, changes the solution to..." << std::endl;
|
||||
// reset system
|
||||
init_fac( B );
|
||||
ids_to_round.push_back(1);
|
||||
cs.solve( constraints, B, x, ids_to_round, 0.0, false, true);
|
||||
std::cout << x << std::endl;
|
||||
|
||||
|
||||
std::cout << "---------- 4) Constraining: forcing the first variable to equal the second changes the solution to..." << std::endl;
|
||||
// reset system
|
||||
init_fac( B );
|
||||
ids_to_round.clear();
|
||||
ids_to_round.push_back(1);
|
||||
// setup constraint x0*1+x1*0+x2*(-1)+x3*0=0
|
||||
gmm::resize( constraints, 1, n+1);
|
||||
constraints( 0, 0 ) = 1.0;
|
||||
constraints( 0, 1 ) = -1.0;
|
||||
std::cout << " the constraint equation looks like this:" << std::endl;
|
||||
print_equations( constraints);
|
||||
cs.solve( constraints, B, x, ids_to_round, 0.0, false, true);
|
||||
std::cout << x << std::endl;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
15
src/external/CoMISo/Examples/small_miqp/CMakeLists.txt
vendored
Normal file
15
src/external/CoMISo/Examples/small_miqp/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
include (CoMISoExample)
|
||||
|
||||
if (WIN32)
|
||||
acg_add_executable (small_miqp WIN32 ${sources} ${headers} )
|
||||
else ()
|
||||
acg_add_executable (small_miqp ${sources} ${headers} )
|
||||
endif ()
|
||||
|
||||
# enable rpath linking
|
||||
set_target_properties(small_miqp PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1)
|
||||
|
||||
target_link_libraries (small_miqp
|
||||
CoMISo
|
||||
${COMISO_LINK_LIBRARIES}
|
||||
)
|
||||
156
src/external/CoMISo/Examples/small_miqp/main.cc
vendored
Normal file
156
src/external/CoMISo/Examples/small_miqp/main.cc
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#include <CoMISo/Config/config.hh>
|
||||
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <vector>
|
||||
#include <CoMISo/NSolver/NProblemInterface.hh>
|
||||
#include <CoMISo/NSolver/NPDerivativeChecker.hh>
|
||||
#include <CoMISo/NSolver/GUROBISolver.hh>
|
||||
#include <CoMISo/NSolver/CPLEXSolver.hh>
|
||||
#include <CoMISo/NSolver/LinearConstraint.hh>
|
||||
#include <CoMISo/NSolver/VariableType.hh>
|
||||
|
||||
|
||||
// generate an instance of a nonlinear problem by deriving from base class NProblemInterface
|
||||
// implement all virtual functions in order to solve this problem by any of the solvers located
|
||||
// in CoMISo/NSolver
|
||||
|
||||
class SmallNProblem : public COMISO::NProblemInterface
|
||||
{
|
||||
public:
|
||||
|
||||
// Sparse Matrix Type
|
||||
// typedef Eigen::DynamicSparseMatrix<double,Eigen::ColMajor> SMatrixNP;
|
||||
|
||||
|
||||
// specify a function which has several local minima
|
||||
// f(x,y)=(x-2y+1)^2 + (x-5)^2
|
||||
|
||||
// number of unknown variables, here x and y = 2
|
||||
virtual int n_unknowns ( )
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
// initial value where the optimization should start from
|
||||
virtual void initial_x ( double* _x )
|
||||
{
|
||||
_x[0] = 0.0;
|
||||
_x[1] = 0.0;
|
||||
}
|
||||
|
||||
// function evaluation at location _x
|
||||
virtual double eval_f ( const double* _x )
|
||||
{
|
||||
double term = _x[0] - 2.0*_x[1] + 1.0;
|
||||
double term2 = _x[0] - 5.0;
|
||||
|
||||
return term*term + term2*term2;
|
||||
}
|
||||
|
||||
// gradient evaluation at location _x
|
||||
virtual void eval_gradient( const double* _x, double* _g)
|
||||
{
|
||||
double term = _x[0] - 2.0*_x[1] + 1.0;
|
||||
double term2 = _x[0] - 5.0;
|
||||
|
||||
_g[0] = 2.0*term + 2.0*term2;
|
||||
_g[1] = -4.0*term;
|
||||
}
|
||||
|
||||
// hessian matrix evaluation at location _x
|
||||
virtual void eval_hessian ( const double* _x, SMatrixNP& _H)
|
||||
{
|
||||
_H.resize(n_unknowns(), n_unknowns());
|
||||
_H.setZero();
|
||||
|
||||
_H.coeffRef(0,0) = 4.0;
|
||||
_H.coeffRef(1,0) = -4.0;
|
||||
_H.coeffRef(0,1) = -4.0;
|
||||
_H.coeffRef(1,1) = 8.0;
|
||||
}
|
||||
|
||||
// print result
|
||||
virtual void store_result ( const double* _x )
|
||||
{
|
||||
std::cerr << "Energy: " << eval_f(_x) << std::endl;
|
||||
std::cerr << "(x,y) = (" << _x[0] << "," << _x[1] << ")" << std::endl;
|
||||
}
|
||||
|
||||
// advanced properties
|
||||
virtual bool constant_hessian() { return true; }
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Example main
|
||||
int main(void)
|
||||
{
|
||||
std::cout << "---------- 1) Get an instance of a NProblem..." << std::endl;
|
||||
SmallNProblem snp;
|
||||
|
||||
std::cout << "---------- 2) (optional for debugging) Check derivatives of problem..." << std::endl;
|
||||
COMISO::NPDerivativeChecker npd;
|
||||
npd.check_all(&snp);
|
||||
|
||||
std::cout << "---------- 3) setup list of integer variables..." << std::endl;
|
||||
std::vector<COMISO::PairIndexVtype> discrete_variables;
|
||||
discrete_variables.push_back( COMISO::PairIndexVtype(0,COMISO::Integer) );
|
||||
|
||||
std::cout << "---------- 4) setup constraints..." << std::endl;
|
||||
std::vector<COMISO::NConstraintInterface*> constraints;
|
||||
// setup constraint x+y <= 6.5
|
||||
COMISO::LinearConstraint::SVectorNC coeffs(2);
|
||||
coeffs.coeffRef(0) = 1.0;
|
||||
coeffs.coeffRef(1) = 1.0;
|
||||
COMISO::LinearConstraint lc(coeffs, -6.5, COMISO::LinearConstraint::NC_LESS_EQUAL);
|
||||
constraints.push_back(&lc);
|
||||
|
||||
|
||||
// check if IPOPT solver available in current configuration
|
||||
#if( COMISO_GUROBI_AVAILABLE)
|
||||
std::cout << "---------- 5) Get GUROBI solver... " << std::endl;
|
||||
COMISO::GUROBISolver gsol;
|
||||
|
||||
std::cout << "---------- 4) Solve..." << std::endl;
|
||||
|
||||
gsol.solve(&snp, constraints, discrete_variables);
|
||||
#endif
|
||||
|
||||
// check if TAO solver available in current configuration
|
||||
#if( COMISO_CPLEX_AVAILABLE)
|
||||
std::cout << "---------- 5) Solve with CPLEX solver... " << std::endl;
|
||||
COMISO::CPLEXSolver csol;
|
||||
|
||||
std::cout << "---------- 4) Solve..." << std::endl;
|
||||
|
||||
csol.solve(&snp, constraints, discrete_variables);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
15
src/external/CoMISo/Examples/small_nleast_squares/CMakeLists.txt
vendored
Normal file
15
src/external/CoMISo/Examples/small_nleast_squares/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
include (CoMISoExample)
|
||||
|
||||
if (WIN32)
|
||||
acg_add_executable (small_nleast_squares WIN32 ${sources} ${headers} )
|
||||
else ()
|
||||
acg_add_executable (small_nleast_squares ${sources} ${headers} )
|
||||
endif ()
|
||||
|
||||
# enable rpath linking
|
||||
set_target_properties(small_nleast_squares PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1)
|
||||
|
||||
target_link_libraries (small_nleast_squares
|
||||
CoMISo
|
||||
${COMISO_LINK_LIBRARIES}
|
||||
)
|
||||
85
src/external/CoMISo/Examples/small_nleast_squares/main.cc
vendored
Normal file
85
src/external/CoMISo/Examples/small_nleast_squares/main.cc
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#include <CoMISo/Config/config.hh>
|
||||
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <vector>
|
||||
#include <CoMISo/NSolver/LeastSquaresProblem.hh>
|
||||
#include <CoMISo/NSolver/LinearConstraint.hh>
|
||||
#include <CoMISo/NSolver/NPDerivativeChecker.hh>
|
||||
#include <CoMISo/NSolver/IPOPTSolver.hh>
|
||||
|
||||
|
||||
// solve least squares problem for x=1, y=2 and x-2y = 1
|
||||
|
||||
// Example main
|
||||
int main(void)
|
||||
{
|
||||
std::cout << "---------- 1) Get an instance of a LeastSquaresProblem..." << std::endl;
|
||||
// number of unknowns
|
||||
const int n = 2;
|
||||
COMISO::LeastSquaresProblem lsqp(n);
|
||||
|
||||
// term0
|
||||
COMISO::LinearConstraint::SVectorNC coeffs0(n);
|
||||
coeffs0.coeffRef(0) = 1.0;
|
||||
COMISO::LinearConstraint term0(coeffs0,-1.0,COMISO::NConstraintInterface::NC_EQUAL);
|
||||
lsqp.add_term(&term0);
|
||||
|
||||
// term1
|
||||
COMISO::LinearConstraint::SVectorNC coeffs1(n);
|
||||
coeffs1.coeffRef(1) = 1.0;
|
||||
COMISO::LinearConstraint term1(coeffs1,-2.0,COMISO::NConstraintInterface::NC_EQUAL);
|
||||
lsqp.add_term(&term1);
|
||||
|
||||
// term2
|
||||
COMISO::LinearConstraint::SVectorNC coeffs2(n);
|
||||
coeffs2.coeffRef(0) = 1.0;
|
||||
coeffs2.coeffRef(1) = -2.0;
|
||||
COMISO::LinearConstraint term2(coeffs2,-1.0,COMISO::NConstraintInterface::NC_EQUAL);
|
||||
lsqp.add_term(&term2);
|
||||
|
||||
std::cout << "---------- 2) (optional for debugging) Check derivatives of problem..." << std::endl;
|
||||
COMISO::NPDerivativeChecker npd;
|
||||
npd.check_all(&lsqp);
|
||||
|
||||
// check if IPOPT solver available in current configuration
|
||||
#if( COMISO_IPOPT_AVAILABLE)
|
||||
std::cout << "---------- 3) Get IPOPT solver... " << std::endl;
|
||||
COMISO::IPOPTSolver ipsol;
|
||||
|
||||
std::cout << "---------- 4) Solve..." << std::endl;
|
||||
// there are no constraints -> provide an empty vector
|
||||
std::vector<COMISO::NConstraintInterface*> constraints;
|
||||
ipsol.solve(&lsqp, constraints);
|
||||
#endif
|
||||
|
||||
std::cout << "---------- 5) Print solution..." << std::endl;
|
||||
for( int i=0; i<n; ++i)
|
||||
std::cerr << "x_" << i << " = " << lsqp.x()[i] << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
15
src/external/CoMISo/Examples/small_nsolver/CMakeLists.txt
vendored
Normal file
15
src/external/CoMISo/Examples/small_nsolver/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
include (CoMISoExample)
|
||||
|
||||
if (WIN32)
|
||||
acg_add_executable (small_nsolver WIN32 ${sources} ${headers} )
|
||||
else ()
|
||||
acg_add_executable (small_nsolver ${sources} ${headers} )
|
||||
endif ()
|
||||
|
||||
# enable rpath linking
|
||||
set_target_properties(small_nsolver PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1)
|
||||
|
||||
target_link_libraries (small_nsolver
|
||||
CoMISo
|
||||
${COMISO_LINK_LIBRARIES}
|
||||
)
|
||||
85
src/external/CoMISo/Examples/small_nsolver/main.cc
vendored
Normal file
85
src/external/CoMISo/Examples/small_nsolver/main.cc
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#include <CoMISo/Config/config.hh>
|
||||
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <vector>
|
||||
#include <CoMISo/NSolver/LeastSquaresProblem.hh>
|
||||
#include <CoMISo/NSolver/LinearConstraint.hh>
|
||||
#include <CoMISo/NSolver/NPDerivativeChecker.hh>
|
||||
#include <CoMISo/NSolver/IPOPTSolver.hh>
|
||||
|
||||
|
||||
// solve least squares problem for x=1, y=2 and x-2y = 1
|
||||
|
||||
// Example main
|
||||
int main(void)
|
||||
{
|
||||
std::cout << "---------- 1) Get an instance of a LeastSquaresProblem..." << std::endl;
|
||||
// number of unknowns
|
||||
const int n = 2;
|
||||
COMISO::LeastSquaresProblem lsqp(n);
|
||||
|
||||
// term0
|
||||
COMISO::LinearConstraint::SVectorNC coeffs0(n);
|
||||
coeffs0.coeffRef(0) = 1.0;
|
||||
COMISO::LinearConstraint term0(coeffs0,-1.0,COMISO::NConstraintInterface::NC_EQUAL);
|
||||
lsqp.add_term(&term0);
|
||||
|
||||
// term1
|
||||
COMISO::LinearConstraint::SVectorNC coeffs1(n);
|
||||
coeffs1.coeffRef(1) = 1.0;
|
||||
COMISO::LinearConstraint term1(coeffs1,-2.0,COMISO::NConstraintInterface::NC_EQUAL);
|
||||
lsqp.add_term(&term1);
|
||||
|
||||
// term2
|
||||
COMISO::LinearConstraint::SVectorNC coeffs2(n);
|
||||
coeffs2.coeffRef(0) = 1.0;
|
||||
coeffs2.coeffRef(1) = -2.0;
|
||||
COMISO::LinearConstraint term2(coeffs2,-1.0,COMISO::NConstraintInterface::NC_EQUAL);
|
||||
lsqp.add_term(&term2);
|
||||
|
||||
std::cout << "---------- 2) (optional for debugging) Check derivatives of problem..." << std::endl;
|
||||
COMISO::NPDerivativeChecker npd;
|
||||
npd.check_all(&lsqp);
|
||||
|
||||
// check if IPOPT solver available in current configuration
|
||||
#if( COMISO_IPOPT_AVAILABLE)
|
||||
std::cout << "---------- 3) Get IPOPT solver... " << std::endl;
|
||||
COMISO::IPOPTSolver ipsol;
|
||||
|
||||
std::cout << "---------- 4) Solve..." << std::endl;
|
||||
// there are no constraints -> provide an empty vector
|
||||
std::vector<COMISO::NConstraintInterface*> constraints;
|
||||
ipsol.solve(&lsqp, constraints);
|
||||
#endif
|
||||
|
||||
std::cout << "---------- 5) Print solution..." << std::endl;
|
||||
for( int i=0; i<n; ++i)
|
||||
std::cerr << "x_" << i << " = " << lsqp.x()[i] << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
15
src/external/CoMISo/Examples/small_quadratic_example/CMakeLists.txt
vendored
Normal file
15
src/external/CoMISo/Examples/small_quadratic_example/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
include (CoMISoExample)
|
||||
|
||||
if (WIN32)
|
||||
acg_add_executable (small_quadratic_solver WIN32 ${sources} ${headers} )
|
||||
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
|
||||
${COMISO_LINK_LIBRARIES}
|
||||
)
|
||||
122
src/external/CoMISo/Examples/small_quadratic_example/main.cc
vendored
Normal file
122
src/external/CoMISo/Examples/small_quadratic_example/main.cc
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <gmm/gmm.h>
|
||||
#include <vector>
|
||||
#include <CoMISo/Solver/ConstrainedSolver.hh>
|
||||
#include <CoMISo/Solver/MISolver.hh>
|
||||
#include <CoMISo/Solver/GMM_Tools.hh>
|
||||
|
||||
|
||||
/// function to initialize a simple system of linear equations
|
||||
template<class MatrixT>
|
||||
void init_les( MatrixT& _A, std::vector< double >& _b)
|
||||
{
|
||||
_A(0,0) = 25 ; _A(0,1) = 0 ; _A(0,2) = -15; _A(0,3) = 0 ;
|
||||
_A(1,0) = 0 ; _A(1,1) = 20; _A(1,2) = -8 ; _A(1,3) = -4;
|
||||
_A(2,0) = -15 ; _A(2,1) = -8; _A(2,2) = 17 ; _A(2,3) = 0 ;
|
||||
_A(3,0) = 0 ; _A(3,1) = -4; _A(3,2) = 0 ; _A(3,3) = 4 ;
|
||||
|
||||
_b[0] = 0; _b[1] = 4; _b[2] = -2; _b[3] = 0;
|
||||
}
|
||||
|
||||
/// function to print the equations corresponding to the matrices of an equation system
|
||||
template<class MatrixT>
|
||||
void print_equations( const MatrixT& _B)
|
||||
{
|
||||
int m = gmm::mat_nrows( _B);
|
||||
int n = gmm::mat_ncols( _B);
|
||||
for( int i = 0; i < m; ++i)
|
||||
{
|
||||
for( int j = 0; j < n-1; ++j)
|
||||
{
|
||||
if( _B(i,j) != 0.0)
|
||||
std::cout << _B(i,j) << "*x" << j;
|
||||
else
|
||||
std::cout << " 0 ";
|
||||
if( j < n-2 ) std::cout << " + ";
|
||||
}
|
||||
std::cout << " = " << _B(i, n-1) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Example main
|
||||
int main(void)
|
||||
{
|
||||
std::cout << "---------- 1) Setup small (symmetric) test equation system Ax=b..." << std::endl;
|
||||
int n = 4;
|
||||
gmm::col_matrix< gmm::wsvector< double > > A(n,n);
|
||||
std::vector< double > x(n);
|
||||
std::vector< double > b(n);
|
||||
|
||||
init_les( A, b);
|
||||
|
||||
// create an empty constraint matrix (will be used later)
|
||||
gmm::row_matrix< gmm::wsvector< double > > constraints(0,n+1); //n+1 because of right hand side
|
||||
// create an empty vector of variable indices to be rounded (will be used later)
|
||||
std::vector< int > ids_to_round;
|
||||
|
||||
std::cout << A << std::endl << b << std::endl;
|
||||
|
||||
|
||||
std::cout << "---------- 2) The original solution to this system is..." << std::endl;
|
||||
|
||||
COMISO::ConstrainedSolver cs;
|
||||
//void solve( RMatrixT& _constraints, CMatrixT& _A, VectorT& _x, VectorT& _rhs, VectorIT& _idx_to_round, double _reg_factor = 0.0, bool _show_miso_settings = true, bool _show_timings = true );
|
||||
//_show_miso_settings requires a QT context and hence must be false in this example
|
||||
cs.solve( constraints, A, x, b, ids_to_round, 0.0, false, true);
|
||||
// copy this solution for later
|
||||
std::vector< double > org_x( x);
|
||||
std::cout << x << std::endl;
|
||||
|
||||
|
||||
std::cout << "---------- 3) Rounding: forcing the second variable to lie on an integer, changes the solution to..." << std::endl;
|
||||
// reset system
|
||||
init_les( A, b);
|
||||
ids_to_round.push_back(1);
|
||||
cs.solve( constraints, A, x, b, ids_to_round, 0.0, false, true);
|
||||
std::cout << x << std::endl;
|
||||
|
||||
|
||||
std::cout << "---------- 4) Constraining: forcing the first variable to equal the second changes the solution to..." << std::endl;
|
||||
// reset system
|
||||
init_les( A, b);
|
||||
ids_to_round.clear();
|
||||
ids_to_round.push_back(1);
|
||||
// setup constraint x0*1+x1*0+x2*(-1)+x3*0=0
|
||||
gmm::resize( constraints, 1, n+1);
|
||||
constraints( 0, 0 ) = 1.0;
|
||||
constraints( 0, 1 ) = -1.0;
|
||||
std::cout << " the constraint equation looks like this:" << std::endl;
|
||||
print_equations( constraints);
|
||||
cs.solve( constraints, A, x, b, ids_to_round, 0.0, false, true);
|
||||
std::cout << x << std::endl;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
15
src/external/CoMISo/Examples/small_quadratic_resolve_example/CMakeLists.txt
vendored
Normal file
15
src/external/CoMISo/Examples/small_quadratic_resolve_example/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
include (CoMISoExample)
|
||||
|
||||
if (WIN32)
|
||||
acg_add_executable (small_quadratic_resolve WIN32 ${sources} ${headers} )
|
||||
else ()
|
||||
acg_add_executable (small_quadratic_resolve ${sources} ${headers} )
|
||||
endif ()
|
||||
|
||||
# enable rpath linking
|
||||
set_target_properties(small_quadratic_resolve PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1)
|
||||
|
||||
target_link_libraries (small_quadratic_resolve
|
||||
CoMISo
|
||||
${COMISO_LINK_LIBRARIES}
|
||||
)
|
||||
146
src/external/CoMISo/Examples/small_quadratic_resolve_example/main.cc
vendored
Normal file
146
src/external/CoMISo/Examples/small_quadratic_resolve_example/main.cc
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <gmm/gmm.h>
|
||||
#include <vector>
|
||||
#include <CoMISo/Solver/ConstrainedSolver.hh>
|
||||
#include <CoMISo/Solver/MISolver.hh>
|
||||
#include <CoMISo/Solver/GMM_Tools.hh>
|
||||
|
||||
|
||||
/// function to initialize a simple system of linear equations
|
||||
template<class MatrixT>
|
||||
void init_les( MatrixT& _A, std::vector< double >& _b)
|
||||
{
|
||||
_A(0,0) = 25 ; _A(0,1) = 0 ; _A(0,2) = -15; _A(0,3) = 0 ;
|
||||
_A(1,0) = 0 ; _A(1,1) = 20; _A(1,2) = -8 ; _A(1,3) = -4;
|
||||
_A(2,0) = -15 ; _A(2,1) = -8; _A(2,2) = 17 ; _A(2,3) = 0 ;
|
||||
_A(3,0) = 0 ; _A(3,1) = -4; _A(3,2) = 0 ; _A(3,3) = 4 ;
|
||||
|
||||
_b[0] = 0; _b[1] = 4; _b[2] = -2; _b[3] = 0;
|
||||
}
|
||||
|
||||
/// function to print the equations corresponding to the matrices of an equation system
|
||||
template<class MatrixT>
|
||||
void print_equations( const MatrixT& _B)
|
||||
{
|
||||
int m = gmm::mat_nrows( _B);
|
||||
int n = gmm::mat_ncols( _B);
|
||||
for( int i = 0; i < m; ++i)
|
||||
{
|
||||
for( int j = 0; j < n-1; ++j)
|
||||
{
|
||||
if( _B(i,j) != 0.0)
|
||||
std::cout << _B(i,j) << "*x" << j;
|
||||
else
|
||||
std::cout << " 0 ";
|
||||
if( j < n-2 ) std::cout << " + ";
|
||||
}
|
||||
std::cout << " = " << -_B(i, n-1) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Example main
|
||||
int main(void)
|
||||
{
|
||||
std::cout << "---------- 1) Setup small (symmetric) test equation system Ax=b..." << std::endl;
|
||||
int n = 4;
|
||||
gmm::col_matrix< gmm::wsvector< double > > A(n,n);
|
||||
std::vector< double > x(n);
|
||||
std::vector< double > b(n);
|
||||
|
||||
std::vector<double> x_bak;
|
||||
|
||||
std::cout << "---------- 1) Set up problem..." << std::endl;
|
||||
|
||||
init_les( A, b);
|
||||
|
||||
// create an empty constraint matrix (will be used later)
|
||||
gmm::row_matrix< gmm::wsvector< double > > constraints(0,n+1); //n+1 because of right hand side
|
||||
// create an empty vector of variable indices to be rounded (will be used later)
|
||||
std::vector< int > ids_to_round;
|
||||
|
||||
std::cout << A << std::endl << b << std::endl;
|
||||
|
||||
// setup constraints
|
||||
gmm::resize( constraints, 3, n+1);
|
||||
constraints( 0, 0 ) = 1.0;
|
||||
constraints( 0, 1 ) = -1.0;
|
||||
constraints( 0, n ) = 2.0;
|
||||
constraints( 1, 3 ) = 1.0;
|
||||
constraints( 1, n ) = -1.0;
|
||||
// add one redundant constraint (this will be filtered out during Gaussian elimination)
|
||||
constraints( 2, 0 ) = 1.0;
|
||||
constraints( 2, 1 ) = -1.0;
|
||||
constraints( 2, n ) = 2.0;
|
||||
std::cout << " the constraint equations looks like this:" << std::endl;
|
||||
print_equations( constraints);
|
||||
|
||||
std::cout << "---------- 2) Solve full ..." << std::endl;
|
||||
COMISO::ConstrainedSolver cs;
|
||||
cs.solve_const( constraints, A, x, b, ids_to_round, 0.0, false, true);
|
||||
x_bak = x;
|
||||
|
||||
// first test: resolve with identical rhs's
|
||||
std::vector<double> constraint_rhs(3);
|
||||
std::vector<double> b_new = b;
|
||||
constraint_rhs[0] = -2.0;
|
||||
constraint_rhs[1] = 1.0;
|
||||
constraint_rhs[2] = -2.0;
|
||||
|
||||
std::cout << "---------- 2) Solve same rhs pre-factorized ..." << std::endl;
|
||||
cs.resolve(x, &constraint_rhs, &b_new);
|
||||
std::cout << "orig result: " << x_bak << std::endl;
|
||||
std::cout << "resolve result: " << x << std::endl;
|
||||
|
||||
// second test: resolve with changed rhs
|
||||
constraint_rhs[0] = 4.0;
|
||||
constraint_rhs[1] = -2.0;
|
||||
constraint_rhs[2] = 4.0;
|
||||
b_new[0] = 1.0;
|
||||
b_new[1] = -2.0;
|
||||
b_new[2] = 3.0;
|
||||
b_new[3] = -5.0;
|
||||
|
||||
std::cout << "---------- 3) Solve different rhs pre-factorized ..." << std::endl;
|
||||
cs.resolve(x, &constraint_rhs, &b_new);
|
||||
|
||||
|
||||
// solve with new factorization
|
||||
constraints( 0, n ) = -4.0;
|
||||
constraints( 1, n ) = 2.0;
|
||||
constraints( 2, n ) = -4.0;
|
||||
std::cout << "---------- 4) Solve different rhs full ..." << std::endl;
|
||||
cs.solve_const( constraints, A, x_bak, b_new, ids_to_round, 0.0, false, true);
|
||||
|
||||
std::cout << "orig result (with different rhs's): " << x_bak << std::endl;
|
||||
std::cout << "resolve result (with different rhs's): " << x << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
15
src/external/CoMISo/Examples/small_sparseqr/CMakeLists.txt
vendored
Normal file
15
src/external/CoMISo/Examples/small_sparseqr/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
include (CoMISoExample)
|
||||
|
||||
if (WIN32)
|
||||
acg_add_executable (small_sparseqr WIN32 ${sources} ${headers} )
|
||||
else ()
|
||||
acg_add_executable (small_sparseqr ${sources} ${headers} )
|
||||
endif ()
|
||||
|
||||
# enable rpath linking
|
||||
set_target_properties(small_sparseqr PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1)
|
||||
|
||||
target_link_libraries (small_sparseqr
|
||||
CoMISo
|
||||
${COMISO_LINK_LIBRARIES}
|
||||
)
|
||||
176
src/external/CoMISo/Examples/small_sparseqr/main.cc
vendored
Normal file
176
src/external/CoMISo/Examples/small_sparseqr/main.cc
vendored
Normal file
@ -0,0 +1,176 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
#if COMISO_SUITESPARSE_SPQR_AVAILABLE // additional spqr library required
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <Eigen/Sparse>
|
||||
#include <CoMISo/Solver/SparseQRSolver.hh>
|
||||
#include <CoMISo/Solver/Eigen_Tools.hh>
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Example main
|
||||
int main(void)
|
||||
{
|
||||
std::cout << "---------- 0) Using Sparse QR for solving underdetermined equations and computing Null spaces " << std::endl;
|
||||
|
||||
typedef Eigen::SparseMatrix< double > SpMatrix;
|
||||
typedef Eigen::MatrixXd DenMatrix;
|
||||
typedef Eigen::Triplet< double > Triplet;
|
||||
|
||||
int dimr(4+1);
|
||||
int dimc(4+2);
|
||||
|
||||
std::cout << "---------- 1) Creating matrix " << std::endl;
|
||||
std::vector< Triplet > triplets;
|
||||
for( int i = 0; i < dimc*dimr/2; ++i)
|
||||
{
|
||||
int x( rand()%(dimr-1));
|
||||
int y( rand()%dimc);
|
||||
double val( rand()%10);
|
||||
//std::cerr << " setting (" << x << ", " << y << ") to " << val << std::endl;
|
||||
triplets.push_back( Triplet( x, y, val));
|
||||
}
|
||||
SpMatrix A(dimr,dimc);
|
||||
A.setFromTriplets(triplets.begin(), triplets.end());
|
||||
|
||||
std::cerr << DenMatrix(A) << std::endl;
|
||||
int m = dimr;
|
||||
int n = dimc;
|
||||
|
||||
if( m < n )
|
||||
{
|
||||
std::swap( m,n);
|
||||
std::cerr << " ... m < n -> form transposed ..." << std::endl;
|
||||
A = SpMatrix(A.transpose());
|
||||
// test make also row -rank-deficinet
|
||||
A.middleCols(n-1,1) = A.middleCols(0,1);
|
||||
A.middleCols(0,1) = A.middleCols(n-2,1);
|
||||
std::cerr << DenMatrix(A) << std::endl;
|
||||
}
|
||||
|
||||
|
||||
std::cerr << " ... m = " << m << "; n = " << n << std::endl;
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::cout << "---------- 2) Sparse QR " << std::endl;
|
||||
COMISO::SparseQRSolver spqr;
|
||||
SpMatrix Q,R;
|
||||
std::vector< size_t > P;
|
||||
int rank = spqr.factorize_system_eigen( A, Q, R, P);
|
||||
int nullity(dimc-rank);
|
||||
// setup permutation matrix
|
||||
SpMatrix Pm( n, n);
|
||||
if( !P.empty())
|
||||
{
|
||||
for( size_t i = 0; i < P.size(); ++i)
|
||||
{
|
||||
Pm.coeffRef( i, P[i]) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "---------- 3) Result " << std::endl;
|
||||
std::cerr << " Q " << std::endl << DenMatrix(Q) << std::endl;
|
||||
std::cerr << " R " << std::endl << DenMatrix(R) << std::endl;
|
||||
std::cerr << " P " << std::endl << P << std::endl;
|
||||
std::cerr << " P matrix " << std::endl << DenMatrix(Pm) << std::endl;
|
||||
std::cerr << " Rank " << rank << std::endl;
|
||||
std::cerr << " Nullity " << nullity << std::endl;
|
||||
// extract nullspace
|
||||
SpMatrix NullSpace( Q.middleCols( std::max( 0, m-nullity), nullity));
|
||||
std::cerr << " Nullspace " << std::endl << DenMatrix(NullSpace) << std::endl;
|
||||
// non nullspace part of R
|
||||
//// assuming superflous column in R is the last (if A is also row deficient)
|
||||
//SpMatrix Rtmp(R.middleCols(0,std::min(n,n-(n-rank))).transpose());
|
||||
//SpMatrix R1( R.transpose().middleCols(0, m-nullity));
|
||||
SpMatrix Rtmp(R.transpose());
|
||||
SpMatrix R1t( Rtmp.middleCols(0,m-nullity));
|
||||
SpMatrix R1( R1t.transpose());
|
||||
std::cerr << " Non-Nullspace R " << std::endl << DenMatrix(R1) << std::endl;
|
||||
|
||||
|
||||
|
||||
std::cout << "---------- 4) Verification " << std::endl;
|
||||
SpMatrix reconstructedA(Q*R*Pm.transpose());
|
||||
std::cerr << " Q orthogonal? \t " << ((fabs((Q.transpose()*Q).squaredNorm()-m) < 1e-8)?"yes":"no") << std::endl;
|
||||
std::cerr << " A = QR? \t " << (((reconstructedA-A).squaredNorm() < 1e-8)? "yes":"no") << std::endl;
|
||||
|
||||
|
||||
std::cerr << std::endl << std::endl;
|
||||
std::cout << "---------- 5) Solving Ax=b (with x without nullspace component)" << std::endl;
|
||||
// NOTE: A was transposed above to be m>n
|
||||
SpMatrix b(n,1);
|
||||
SpMatrix x(m,1);
|
||||
for( int i = 0; i < n; ++i)
|
||||
b.coeffRef(i,0) = rand()%10;
|
||||
std::cerr << " ... System Ax = b .. \n";
|
||||
std::cerr << " A " << std::endl << DenMatrix(A.transpose()) << " x " << std::endl << DenMatrix(x) << " b " << std::endl << DenMatrix(b) << std::endl;
|
||||
|
||||
std::cout << "---------- 5.1) test: solve using sparse QR solving .." << std::endl;
|
||||
SpMatrix At(A.transpose());
|
||||
spqr.solve_system_eigen( At, b, x);
|
||||
|
||||
std::cerr << " ... solution x .. " << std::endl;
|
||||
std::cerr << DenMatrix(x) << std::endl;
|
||||
|
||||
std::cerr << " ... test: is a solution ? " << (((A.transpose()*x-b).squaredNorm()<1e-8)?"yes":"no") << std::endl;
|
||||
std::cerr << " ... test: has nullspace component ? " << ((x.transpose()*NullSpace).squaredNorm()<1e-8?"yes":"no") << std::endl;
|
||||
std::cerr << " ... Nullspace projections : " << (x.transpose()*NullSpace) << std::endl;
|
||||
|
||||
std::cout << "---------- 5.2) test: solve without nullspace .." << std::endl;
|
||||
SpMatrix Atnull(At);
|
||||
SpMatrix bnull(b);
|
||||
SpMatrix xnull(m,1);
|
||||
spqr.solve_system_eigen_min2norm( Atnull, bnull, xnull);
|
||||
std::cerr << " ... solution x .. " << std::endl;
|
||||
std::cerr << DenMatrix(xnull) << std::endl;
|
||||
|
||||
std::cerr << " ... test: is a solution ? " << (((A.transpose()*xnull-bnull).squaredNorm()<1e-8)?"yes":"no") << std::endl;
|
||||
std::cerr << " ... test: has nullspace component ? " << ((xnull.transpose()*NullSpace).squaredNorm()<1e-8?"yes":"no") << std::endl;
|
||||
std::cerr << " ... Nullspace projections : " << (xnull.transpose()*NullSpace) << std::endl;
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else // COMISO_SUITESPARSE_SPQR_AVAILABLE
|
||||
|
||||
int main(void)
|
||||
{
|
||||
std::cerr << " SUITESPARSE_SPQR not available, please re-configure!\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // COMISO_SUITESPARSE_SPQR_AVAILABLE
|
||||
|
||||
161
src/external/CoMISo/NSolver/BoundConstraint.cc
vendored
Normal file
161
src/external/CoMISo/NSolver/BoundConstraint.cc
vendored
Normal file
@ -0,0 +1,161 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS BoundConstraint - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "BoundConstraint.hh"
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
BoundConstraint::
|
||||
BoundConstraint(const unsigned int _var_idx, // index of variable for bound constraint
|
||||
const double _bound, // bound: x(_var_idx) #_type, <,=,># _bound
|
||||
const unsigned int _n, // number of unknowns in problem
|
||||
const ConstraintType _type) // type of bound upper, lower or both (equal)
|
||||
: NConstraintInterface(_type), idx_(_var_idx), bound_(_bound), n_(_n)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
BoundConstraint::
|
||||
~BoundConstraint()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
int
|
||||
BoundConstraint::
|
||||
n_unknowns()
|
||||
{
|
||||
return n_;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
double
|
||||
BoundConstraint::
|
||||
eval_constraint ( const double* _x )
|
||||
{
|
||||
return _x[idx_] - bound_;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
BoundConstraint::
|
||||
eval_gradient ( const double* _x, SVectorNC& _g )
|
||||
{
|
||||
_g.resize(n_); _g.coeffRef(idx_) = 1.0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
BoundConstraint::
|
||||
eval_hessian ( const double* _x, SMatrixNC& _h )
|
||||
{
|
||||
_h.clear(); _h.resize(n_,n_);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool
|
||||
BoundConstraint::
|
||||
is_linear() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool
|
||||
BoundConstraint::
|
||||
constant_gradient() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool
|
||||
BoundConstraint::
|
||||
constant_hessian() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
unsigned int&
|
||||
BoundConstraint::
|
||||
idx()
|
||||
{
|
||||
return idx_;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
double&
|
||||
BoundConstraint::
|
||||
bound()
|
||||
{
|
||||
return bound_;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
unsigned int&
|
||||
BoundConstraint::
|
||||
n()
|
||||
{
|
||||
return n_;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
BoundConstraint::
|
||||
resize(const unsigned int _n)
|
||||
{
|
||||
n_ = _n;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
84
src/external/CoMISo/NSolver/BoundConstraint.hh
vendored
Normal file
84
src/external/CoMISo/NSolver/BoundConstraint.hh
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS BoundConstraint
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_BOUNDCONSTRAINT_HH
|
||||
#define COMISO_BOUNDCONSTRAINT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include "NConstraintInterface.hh"
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class BoundConstraint
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
class COMISODLLEXPORT BoundConstraint : public NConstraintInterface
|
||||
{
|
||||
public:
|
||||
|
||||
// inherited from NConstraintInterface
|
||||
// typedef Eigen::SparseVector<double> SVectorNC;
|
||||
// typedef SuperSparseMatrixT<double> SMatrixNC;
|
||||
// // different types of constraints
|
||||
// enum ConstraintType {NC_EQUAL, NC_LESS_EQUAL, NC_GREATER_EQUAL};
|
||||
|
||||
/// Default constructor
|
||||
BoundConstraint(const unsigned int _var_idx = 0, // index of variable for bound constraint
|
||||
const double _bound = 0.0, // bound: x(_var_idx) #_type, <,=,># _bound
|
||||
const unsigned int _n = 0, // number of unknowns in problem
|
||||
const ConstraintType _type = NC_LESS_EQUAL); // type of bound upper, lower or both (equal)
|
||||
|
||||
|
||||
/// Destructor
|
||||
virtual ~BoundConstraint();
|
||||
|
||||
virtual int n_unknowns ( );
|
||||
virtual double eval_constraint ( const double* _x );
|
||||
virtual void eval_gradient ( const double* _x, SVectorNC& _g );
|
||||
virtual void eval_hessian ( const double* _x, SMatrixNC& _h );
|
||||
|
||||
virtual bool is_linear() const;
|
||||
virtual bool constant_gradient() const;
|
||||
virtual bool constant_hessian () const;
|
||||
|
||||
// set/get values
|
||||
unsigned int& idx();
|
||||
double& bound();
|
||||
unsigned int& n();
|
||||
void resize(const unsigned int _n);
|
||||
|
||||
private:
|
||||
// variable idx
|
||||
unsigned int idx_;
|
||||
// variable bound
|
||||
double bound_;
|
||||
// number of unknowns
|
||||
unsigned int n_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // ACG_BOUNDCONSTRAINT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
140
src/external/CoMISo/NSolver/COMISOSolver.cc
vendored
Normal file
140
src/external/CoMISo/NSolver/COMISOSolver.cc
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS COMISOSolver - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
//=============================================================================
|
||||
|
||||
#include <vector>
|
||||
#include "COMISOSolver.hh"
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
// ********** SOLVE **************** //
|
||||
void
|
||||
COMISOSolver::
|
||||
solve(NProblemInterface* _problem,
|
||||
std::vector<NConstraintInterface*>& _constraints,
|
||||
std::vector<PairUiV>& _discrete_constraints,
|
||||
double _reg_factor,
|
||||
bool _show_miso_settings,
|
||||
bool _show_timings )
|
||||
{
|
||||
|
||||
//----------------------------------------------
|
||||
// 1. identify integer variables
|
||||
//----------------------------------------------
|
||||
|
||||
// identify integer variables
|
||||
std::vector<int> round_idxs;
|
||||
for(unsigned int i=0; i<_discrete_constraints.size(); ++i)
|
||||
switch(_discrete_constraints[i].second)
|
||||
{
|
||||
case Binary :
|
||||
case Integer:
|
||||
round_idxs.push_back(_discrete_constraints[i].first); break;
|
||||
default : break;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
// 2. setup constraints
|
||||
//----------------------------------------------
|
||||
int n = _problem->n_unknowns();
|
||||
gmm::row_matrix< gmm::wsvector< double > > C(_constraints.size(), n+1);
|
||||
int n_constraints = 0;
|
||||
|
||||
// get zero vector
|
||||
std::vector<double> x(n, 0.0);
|
||||
|
||||
for(unsigned int i=0; i<_constraints.size(); ++i)
|
||||
if(_constraints[i]->constraint_type() == NConstraintInterface::NC_EQUAL)
|
||||
{
|
||||
if(!_constraints[i]->is_linear())
|
||||
std::cerr << "Warning: COMISOSolver received a problem with non-linear constraints!!!" << std::endl;
|
||||
|
||||
// get linear part
|
||||
NConstraintInterface::SVectorNC gc;
|
||||
_constraints[i]->eval_gradient(P(x), gc);
|
||||
|
||||
NConstraintInterface::SVectorNC::InnerIterator v_it(gc);
|
||||
for(; v_it; ++v_it)
|
||||
C(n_constraints, v_it.index()) = v_it.value();
|
||||
|
||||
// get constant part
|
||||
C(n_constraints, n) = _constraints[i]->eval_constraint(P(x));
|
||||
|
||||
// move to next constraint
|
||||
++n_constraints;
|
||||
}
|
||||
|
||||
// resize matrix to final number of constraints
|
||||
gmm::resize(C,n_constraints, n+1);
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
// 3. setup energy
|
||||
//----------------------------------------------
|
||||
|
||||
if(!_problem->constant_hessian())
|
||||
std::cerr << "Warning: COMISOSolver received a problem with non-constant hessian!!!" << std::endl;
|
||||
|
||||
|
||||
// get hessian matrix
|
||||
gmm::col_matrix< gmm::wsvector< double > > A(n,n);
|
||||
NProblemInterface::SMatrixNP H;
|
||||
_problem->eval_hessian(P(x), H);
|
||||
for( int i=0; i<H.outerSize(); ++i)
|
||||
for (NProblemInterface::SMatrixNP::InnerIterator it(H,i); it; ++it)
|
||||
A(it.row(),it.col()) = it.value();
|
||||
|
||||
|
||||
// get negative gradient
|
||||
std::vector<double> rhs(_problem->n_unknowns());
|
||||
_problem->eval_gradient(P(x), P(rhs));
|
||||
for(unsigned int i=0; i<rhs.size(); ++i)
|
||||
rhs[i] = -rhs[i];
|
||||
|
||||
// // add constant part
|
||||
// objective += _problem->eval_f(P(x));
|
||||
|
||||
//----------------------------------------------
|
||||
// 4. solve problem
|
||||
//----------------------------------------------
|
||||
|
||||
cs_.solve(C,A,x,rhs,round_idxs,
|
||||
_reg_factor, _show_miso_settings, _show_timings);
|
||||
|
||||
// void solve(
|
||||
// RMatrixT& _constraints,
|
||||
// CMatrixT& _A,
|
||||
// VectorT& _x,
|
||||
// VectorT& _rhs,
|
||||
// VectorIT& _idx_to_round,
|
||||
// double _reg_factor = 0.0,
|
||||
// bool _show_miso_settings = true,
|
||||
// bool _show_timings = true );
|
||||
|
||||
//----------------------------------------------
|
||||
// 5. store result
|
||||
//----------------------------------------------
|
||||
|
||||
_problem->store_result(P(x));
|
||||
|
||||
// std::cout << "COMISO Objective: " << model.get(GRB_DoubleAttr_ObjVal) << std::endl;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
85
src/external/CoMISo/NSolver/COMISOSolver.hh
vendored
Normal file
85
src/external/CoMISo/NSolver/COMISOSolver.hh
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS COMISOSolver
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_COMISOSOLVER_HH
|
||||
#define COMISO_COMISOSOLVER_HH
|
||||
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include <CoMISo/Solver/ConstrainedSolver.hh>
|
||||
#include <vector>
|
||||
#include "NProblemInterface.hh"
|
||||
#include "NConstraintInterface.hh"
|
||||
#include "VariableType.hh"
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class NewtonSolver GUROBISolver.hh
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
class COMISODLLEXPORT COMISOSolver
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::pair<unsigned int, VariableType> PairUiV;
|
||||
|
||||
/// Default constructor
|
||||
COMISOSolver() {}
|
||||
|
||||
/// Destructor
|
||||
~COMISOSolver() {}
|
||||
|
||||
// ********** SOLVE **************** //
|
||||
void solve(NProblemInterface* _problem, // problem instance
|
||||
std::vector<NConstraintInterface*>& _constraints, // linear constraints
|
||||
std::vector<PairUiV>& _discrete_constraints, // discrete constraint
|
||||
double _reg_factor = 0.0, // reguluarization factor
|
||||
bool _show_miso_settings = true, // show settings dialog
|
||||
bool _show_timings = true ); // show timings
|
||||
|
||||
|
||||
// get reference to ConstrainedSolver to manipulate parameters
|
||||
ConstrainedSolver& solver() { return cs_;}
|
||||
|
||||
protected:
|
||||
double* P(std::vector<double>& _v)
|
||||
{
|
||||
if( !_v.empty())
|
||||
return ((double*)&_v[0]);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
ConstrainedSolver cs_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // ACG_GUROBISOLVER_HH defined
|
||||
//=============================================================================
|
||||
|
||||
68
src/external/CoMISo/NSolver/CPLEXSolver.cc
vendored
Normal file
68
src/external/CoMISo/NSolver/CPLEXSolver.cc
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS CPLEXSolver - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include "CPLEXSolver.hh"
|
||||
#if COMISO_CPLEX_AVAILABLE
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
|
||||
CPLEXSolver::
|
||||
CPLEXSolver()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//void
|
||||
//CPLEXSolver::
|
||||
//set_problem_output_path( const std::string &_problem_output_path)
|
||||
//{
|
||||
// problem_output_path_ = _problem_output_path;
|
||||
//}
|
||||
//
|
||||
//
|
||||
////-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//void
|
||||
//CPLEXSolver::
|
||||
//set_problem_env_output_path( const std::string &_problem_env_output_path)
|
||||
//{
|
||||
// problem_env_output_path_ = _problem_env_output_path;
|
||||
//}
|
||||
//
|
||||
//
|
||||
////-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//void
|
||||
//CPLEXSolver::
|
||||
//set_solution_input_path(const std::string &_solution_input_path)
|
||||
//{
|
||||
// solution_input_path_ = _solution_input_path;
|
||||
//}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // COMISO_CPLEX_AVAILABLE
|
||||
//=============================================================================
|
||||
117
src/external/CoMISo/NSolver/CPLEXSolver.hh
vendored
Normal file
117
src/external/CoMISo/NSolver/CPLEXSolver.hh
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS CPLEXSolver
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_CPLEXSOLVER_HH
|
||||
#define COMISO_CPLEXSOLVER_HH
|
||||
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_CPLEX_AVAILABLE
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "NProblemInterface.hh"
|
||||
#include "NConstraintInterface.hh"
|
||||
#include "VariableType.hh"
|
||||
|
||||
#include <ilcplex/ilocplex.h>
|
||||
ILOSTLBEGIN
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class NewtonSolver CPLEXSolver.hh
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
class COMISODLLEXPORT CPLEXSolver
|
||||
{
|
||||
public:
|
||||
|
||||
/// Default constructor
|
||||
CPLEXSolver();
|
||||
|
||||
/// Destructor
|
||||
~CPLEXSolver() { /*env_.end();*/}
|
||||
|
||||
// ********** SOLVE **************** //
|
||||
// this function has to be inline due to static linking issues
|
||||
inline bool solve(NProblemInterface* _problem, // problem instance
|
||||
std::vector<NConstraintInterface*>& _constraints, // linear constraints
|
||||
std::vector<PairIndexVtype>& _discrete_constraints, // discrete constraints
|
||||
const double _time_limit = 60,
|
||||
const bool _silent = false); // time limit in seconds
|
||||
|
||||
// same as above but without discrete constraints (for convenience)
|
||||
inline bool solve(NProblemInterface* _problem, // problem instance
|
||||
std::vector<NConstraintInterface*>& _constraints, // linear constraints
|
||||
const double _time_limit = 60,
|
||||
const bool _silent = false) // time limit in seconds
|
||||
{ std::vector<PairIndexVtype> dc; return solve(_problem, _constraints, dc, _time_limit, _silent);}
|
||||
|
||||
// with handling of cone constrints
|
||||
inline bool solve2(NProblemInterface* _problem, // problem instance
|
||||
std::vector<NConstraintInterface*>& _constraints, // linear constraints
|
||||
std::vector<PairIndexVtype>& _discrete_constraints, // discrete constraints
|
||||
const double _time_limit = 60,
|
||||
const bool _silent = false); // time limit in seconds
|
||||
|
||||
|
||||
// void set_problem_output_path ( const std::string &_problem_output_path);
|
||||
// void set_problem_env_output_path( const std::string &_problem_env_output_path);
|
||||
// void set_solution_input_path ( const std::string &_solution_input_path);
|
||||
|
||||
protected:
|
||||
double* P(std::vector<double>& _v)
|
||||
{
|
||||
if( !_v.empty())
|
||||
return ((double*)&_v[0]);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// CPLEX environment
|
||||
// IloEnv env_;
|
||||
|
||||
// filenames for exporting/importing gurobi solutions
|
||||
// if string is empty nothing is imported or exported
|
||||
// std::string problem_output_path_;
|
||||
// std::string problem_env_output_path_;
|
||||
// std::string solution_input_path_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
|
||||
//=============================================================================
|
||||
#endif // COMISO_CPLEX_AVAILABLE
|
||||
//=============================================================================
|
||||
#if defined(INCLUDE_TEMPLATES) && !defined(COMISO_CPLEXSOLVER_C)
|
||||
#define COMISO_CPLEXSOLVER_TEMPLATES
|
||||
#include "CPLEXSolverT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // ACG_CPLEXSOLVER_HH defined
|
||||
//=============================================================================
|
||||
|
||||
574
src/external/CoMISo/NSolver/CPLEXSolverT.cc
vendored
Normal file
574
src/external/CoMISo/NSolver/CPLEXSolverT.cc
vendored
Normal file
@ -0,0 +1,574 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS GCPLEXSolver - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define COMISO_CPLEXSOLVER_C
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include "CPLEXSolver.hh"
|
||||
#include "LinearConstraint.hh"
|
||||
#include "BoundConstraint.hh"
|
||||
#include "ConeConstraint.hh"
|
||||
|
||||
#if COMISO_CPLEX_AVAILABLE
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
|
||||
// ********** SOLVE **************** //
|
||||
bool
|
||||
CPLEXSolver::
|
||||
solve2(NProblemInterface* _problem,
|
||||
std::vector<NConstraintInterface*>& _constraints,
|
||||
std::vector<PairIndexVtype>& _discrete_constraints,
|
||||
const double _time_limit,
|
||||
const bool _silent)
|
||||
{
|
||||
try
|
||||
{
|
||||
//----------------------------------------------
|
||||
// 0. set up environment
|
||||
//----------------------------------------------
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> get environment...\n";
|
||||
IloEnv env_;
|
||||
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> get model...\n";
|
||||
IloModel model(env_);
|
||||
// model.getEnv().set(GRB_DoubleParam_TimeLimit, _time_limit);
|
||||
|
||||
//----------------------------------------------
|
||||
// 1. allocate variables
|
||||
//----------------------------------------------
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> allocate variables...\n";
|
||||
// determine variable types: 0->real, 1->integer, 2->bool
|
||||
std::vector<char> vtypes(_problem->n_unknowns(),0);
|
||||
for(unsigned int i=0; i<_discrete_constraints.size(); ++i)
|
||||
if(_discrete_constraints[i].first < vtypes.size())
|
||||
{
|
||||
switch(_discrete_constraints[i].second)
|
||||
{
|
||||
case Integer: vtypes[_discrete_constraints[i].first] = 1; break;
|
||||
case Binary : vtypes[_discrete_constraints[i].first] = 2; break;
|
||||
default : break;
|
||||
}
|
||||
}
|
||||
else
|
||||
std::cerr << "ERROR: requested a discrete variable which is above the total number of variables"
|
||||
<< _discrete_constraints[i].first << " vs " << vtypes.size() << std::endl;
|
||||
|
||||
// CPLEX variables
|
||||
std::vector<IloNumVar> vars;
|
||||
// first all
|
||||
for( int i=0; i<_problem->n_unknowns(); ++i)
|
||||
switch(vtypes[i])
|
||||
{
|
||||
case 0 : vars.push_back( IloNumVar(env_,-IloInfinity, IloInfinity, IloNumVar::Float) ); break;
|
||||
case 1 : vars.push_back( IloNumVar(env_, -IloIntMax, IloIntMax, IloNumVar::Int) ); break;
|
||||
case 2 : vars.push_back( IloNumVar(env_, 0, 1, IloNumVar::Bool) ); break;
|
||||
}
|
||||
|
||||
|
||||
// Integrate new variables
|
||||
// model.update();
|
||||
|
||||
//----------------------------------------------
|
||||
// 2. setup constraints
|
||||
//----------------------------------------------
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> setup constraints...\n";
|
||||
|
||||
// get zero vector
|
||||
std::vector<double> x(_problem->n_unknowns(), 0.0);
|
||||
|
||||
for(unsigned int i=0; i<_constraints.size(); ++i)
|
||||
{
|
||||
if(!_constraints[i]->is_linear())
|
||||
std::cerr << "Warning: CPLEXSolver received a problem with non-linear constraints!!!" << std::endl;
|
||||
|
||||
IloExpr lin_expr(env_);
|
||||
NConstraintInterface::SVectorNC gc;
|
||||
_constraints[i]->eval_gradient(P(x), gc);
|
||||
|
||||
NConstraintInterface::SVectorNC::InnerIterator v_it(gc);
|
||||
for(; v_it; ++v_it)
|
||||
lin_expr += vars[v_it.index()]*v_it.value();
|
||||
|
||||
double b = _constraints[i]->eval_constraint(P(x));
|
||||
|
||||
|
||||
switch(_constraints[i]->constraint_type())
|
||||
{
|
||||
case NConstraintInterface::NC_EQUAL : model.add(lin_expr + b == 0); break;
|
||||
case NConstraintInterface::NC_LESS_EQUAL : model.add(lin_expr + b <= 0); break;
|
||||
case NConstraintInterface::NC_GREATER_EQUAL : model.add(lin_expr + b >= 0); break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// model.update();
|
||||
|
||||
//----------------------------------------------
|
||||
// 3. setup energy
|
||||
//----------------------------------------------
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> setup energy...\n";
|
||||
|
||||
if(!_problem->constant_hessian())
|
||||
std::cerr << "Warning: CPLEXSolver received a problem with non-constant hessian!!!" << std::endl;
|
||||
|
||||
// GRBQuadExpr objective;
|
||||
IloExpr objective(env_);
|
||||
|
||||
// add quadratic part
|
||||
NProblemInterface::SMatrixNP H;
|
||||
_problem->eval_hessian(P(x), H);
|
||||
for( int i=0; i<H.outerSize(); ++i)
|
||||
for (NProblemInterface::SMatrixNP::InnerIterator it(H,i); it; ++it)
|
||||
objective += 0.5*it.value()*vars[it.row()]*vars[it.col()];
|
||||
|
||||
|
||||
// add linear part
|
||||
std::vector<double> g(_problem->n_unknowns());
|
||||
_problem->eval_gradient(P(x), P(g));
|
||||
for(unsigned int i=0; i<g.size(); ++i)
|
||||
objective += g[i]*vars[i];
|
||||
|
||||
// add constant part
|
||||
objective += _problem->eval_f(P(x));
|
||||
|
||||
model.add(IloMinimize(env_,objective));
|
||||
|
||||
// model.set(GRB_IntAttr_ModelSense, 1);
|
||||
// model.setObjective(objective);
|
||||
// model.update();
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
// 4. solve problem
|
||||
//----------------------------------------------
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> generate model...\n";
|
||||
IloCplex cplex(model);
|
||||
cplex.setParam(IloCplex::TiLim, _time_limit);
|
||||
{ // hack
|
||||
// 0 [CPX_NODESEL_DFS] Depth-first search
|
||||
// 1 [CPX_NODESEL_BESTBOUND] Best-bound search
|
||||
// 2 [CPX_NODESEL_BESTEST] Best-estimate search
|
||||
// 3 [CPX_NODESEL_BESTEST_ALT] Alternative best-estimate search
|
||||
// cplex.setParam(IloCplex::NodeSel , 0);
|
||||
}
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> solve...\n";
|
||||
|
||||
// silent mode?
|
||||
if(_silent)
|
||||
cplex.setOut(env_.getNullStream());
|
||||
|
||||
IloBool solution_found = cplex.solve();
|
||||
|
||||
|
||||
// if (solution_input_path_.empty())
|
||||
// {
|
||||
// if (!problem_env_output_path_.empty())
|
||||
// {
|
||||
// std::cout << "Writing problem's environment into file \"" << problem_env_output_path_ << "\"." << std::endl;
|
||||
// model.getEnv().writeParams(problem_env_output_path_);
|
||||
// }
|
||||
// if (!problem_output_path_.empty())
|
||||
// {
|
||||
// std::cout << "Writing problem into file \"" << problem_output_path_ << "\"." << std::endl;
|
||||
// GurobiHelper::outputModelToMpsGz(model, problem_output_path_);
|
||||
// }
|
||||
//
|
||||
// model.optimize();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// std::cout << "Reading solution from file \"" << solution_input_path_ << "\"." << std::endl;
|
||||
// }
|
||||
//
|
||||
//----------------------------------------------
|
||||
// 5. store result
|
||||
//----------------------------------------------
|
||||
|
||||
if(solution_found != IloFalse)
|
||||
{
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> store result...\n";
|
||||
// store computed result
|
||||
for(unsigned int i=0; i<vars.size(); ++i)
|
||||
x[i] = cplex.getValue(vars[i]);
|
||||
|
||||
_problem->store_result(P(x));
|
||||
}
|
||||
|
||||
/*
|
||||
if (solution_input_path_.empty())
|
||||
{
|
||||
// store computed result
|
||||
for(unsigned int i=0; i<vars.size(); ++i)
|
||||
x[i] = vars[i].get(GRB_DoubleAttr_X);
|
||||
}
|
||||
*/
|
||||
// else
|
||||
// {
|
||||
// std::cout << "Loading stored solution from \"" << solution_input_path_ << "\"." << std::endl;
|
||||
// // store loaded result
|
||||
// const size_t oldSize = x.size();
|
||||
// x.clear();
|
||||
// GurobiHelper::readSolutionVectorFromSOL(x, solution_input_path_);
|
||||
// if (oldSize != x.size()) {
|
||||
// std::cerr << "oldSize != x.size() <=> " << oldSize << " != " << x.size() << std::endl;
|
||||
// throw std::runtime_error("Loaded solution vector doesn't have expected dimension.");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// _problem->store_result(P(x));
|
||||
//
|
||||
// // ObjVal is only available if the optimize was called.
|
||||
// if (solution_input_path_.empty())
|
||||
// std::cout << "GUROBI Objective: " << model.get(GRB_DoubleAttr_ObjVal) << std::endl;
|
||||
return solution_found;
|
||||
}
|
||||
catch (IloException& e)
|
||||
{
|
||||
cerr << "Concert exception caught: " << e << endl;
|
||||
return false;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "Unknown exception caught" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
CPLEXSolver::
|
||||
solve(NProblemInterface* _problem,
|
||||
std::vector<NConstraintInterface*>& _constraints,
|
||||
std::vector<PairIndexVtype>& _discrete_constraints,
|
||||
const double _time_limit,
|
||||
const bool _silent)
|
||||
{
|
||||
try
|
||||
{
|
||||
//----------------------------------------------
|
||||
// 0. set up environment
|
||||
//----------------------------------------------
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> get environment...\n";
|
||||
IloEnv env_;
|
||||
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> get model...\n";
|
||||
IloModel model(env_);
|
||||
// model.getEnv().set(GRB_DoubleParam_TimeLimit, _time_limit);
|
||||
|
||||
//----------------------------------------------
|
||||
// 1. allocate variables and initialize limits
|
||||
//----------------------------------------------
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> allocate variables...\n";
|
||||
// determine variable types: 0->real, 1->integer, 2->bool
|
||||
std::vector<char> vtypes (_problem->n_unknowns(),0);
|
||||
|
||||
for(unsigned int i=0; i<_discrete_constraints.size(); ++i)
|
||||
if(_discrete_constraints[i].first < vtypes.size())
|
||||
{
|
||||
switch(_discrete_constraints[i].second)
|
||||
{
|
||||
case Integer: vtypes [_discrete_constraints[i].first] = 1;
|
||||
break;
|
||||
case Binary : vtypes[_discrete_constraints[i].first] = 2;
|
||||
break;
|
||||
default : break;
|
||||
}
|
||||
}
|
||||
else
|
||||
std::cerr << "ERROR: requested a discrete variable which is above the total number of variables"
|
||||
<< _discrete_constraints[i].first << " vs " << vtypes.size() << std::endl;
|
||||
|
||||
// CPLEX variables
|
||||
std::vector<IloNumVar> vars; vars.reserve(_problem->n_unknowns());
|
||||
// first all
|
||||
for( int i=0; i<_problem->n_unknowns(); ++i)
|
||||
switch(vtypes[i])
|
||||
{
|
||||
case 0 : vars.push_back( IloNumVar(env_,-IloInfinity, IloInfinity, IloNumVar::Float) ); break;
|
||||
case 1 : vars.push_back( IloNumVar(env_, -IloIntMax, IloIntMax, IloNumVar::Int) ); break;
|
||||
case 2 : vars.push_back( IloNumVar(env_, 0, 1, IloNumVar::Bool) ); break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Integrate new variables
|
||||
// model.update();
|
||||
|
||||
//----------------------------------------------
|
||||
// 2. setup constraints
|
||||
//----------------------------------------------
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> setup constraints...\n";
|
||||
|
||||
// get zero vector
|
||||
std::vector<double> x(_problem->n_unknowns(), 0.0);
|
||||
|
||||
// handle constraints depending on their tyep
|
||||
for(unsigned int i=0; i<_constraints.size(); ++i)
|
||||
{
|
||||
// is linear constraint?
|
||||
LinearConstraint* lin_ptr = dynamic_cast<LinearConstraint*>(_constraints[i]);
|
||||
if(lin_ptr)
|
||||
{
|
||||
IloExpr lin_expr(env_);
|
||||
NConstraintInterface::SVectorNC gc;
|
||||
_constraints[i]->eval_gradient(P(x), gc);
|
||||
|
||||
NConstraintInterface::SVectorNC::InnerIterator v_it(gc);
|
||||
for(; v_it; ++v_it)
|
||||
lin_expr += vars[v_it.index()]*v_it.value();
|
||||
|
||||
double b = _constraints[i]->eval_constraint(P(x));
|
||||
|
||||
|
||||
switch(_constraints[i]->constraint_type())
|
||||
{
|
||||
case NConstraintInterface::NC_EQUAL : model.add(lin_expr + b == 0); break;
|
||||
case NConstraintInterface::NC_LESS_EQUAL : model.add(lin_expr + b <= 0); break;
|
||||
case NConstraintInterface::NC_GREATER_EQUAL : model.add(lin_expr + b >= 0); break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BoundConstraint* bnd_ptr = dynamic_cast<BoundConstraint*>(_constraints[i]);
|
||||
if(bnd_ptr)
|
||||
{
|
||||
switch(bnd_ptr->constraint_type())
|
||||
{
|
||||
case NConstraintInterface::NC_EQUAL : vars[bnd_ptr->idx()].setBounds(bnd_ptr->bound(), bnd_ptr->bound()); break;
|
||||
case NConstraintInterface::NC_LESS_EQUAL : vars[bnd_ptr->idx()].setUB(bnd_ptr->bound()); break;
|
||||
case NConstraintInterface::NC_GREATER_EQUAL : vars[bnd_ptr->idx()].setLB(bnd_ptr->bound()); break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConeConstraint* cone_ptr = dynamic_cast<ConeConstraint*>(_constraints[i]);
|
||||
if(cone_ptr)
|
||||
{
|
||||
IloExpr soc_lhs(env_);
|
||||
IloExpr soc_rhs(env_);
|
||||
|
||||
soc_rhs= 0.5*cone_ptr->c()*vars[cone_ptr->i()]*vars[cone_ptr->i()];
|
||||
|
||||
NConstraintInterface::SMatrixNC::iterator q_it = cone_ptr->Q().begin();
|
||||
for(; q_it != cone_ptr->Q().end(); ++q_it)
|
||||
{
|
||||
soc_lhs += 0.5*(*q_it)*vars[q_it.col()]*vars[q_it.row()];
|
||||
}
|
||||
|
||||
model.add(soc_lhs <= soc_rhs);
|
||||
}
|
||||
else
|
||||
std::cerr << "Warning: CPLEXSolver received a constraint of unknow type!!! -> skipping it" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
// model.update();
|
||||
|
||||
//----------------------------------------------
|
||||
// 3. setup energy
|
||||
//----------------------------------------------
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> setup energy...\n";
|
||||
|
||||
if(!_problem->constant_hessian())
|
||||
std::cerr << "Warning: CPLEXSolver received a problem with non-constant hessian!!!" << std::endl;
|
||||
|
||||
// GRBQuadExpr objective;
|
||||
IloExpr objective(env_);
|
||||
|
||||
// add quadratic part
|
||||
NProblemInterface::SMatrixNP H;
|
||||
_problem->eval_hessian(P(x), H);
|
||||
for( int i=0; i<H.outerSize(); ++i)
|
||||
for (NProblemInterface::SMatrixNP::InnerIterator it(H,i); it; ++it)
|
||||
objective += 0.5*it.value()*vars[it.row()]*vars[it.col()];
|
||||
|
||||
|
||||
// add linear part
|
||||
std::vector<double> g(_problem->n_unknowns());
|
||||
_problem->eval_gradient(P(x), P(g));
|
||||
for(unsigned int i=0; i<g.size(); ++i)
|
||||
objective += g[i]*vars[i];
|
||||
|
||||
// add constant part
|
||||
objective += _problem->eval_f(P(x));
|
||||
|
||||
model.add(IloMinimize(env_,objective));
|
||||
|
||||
// model.set(GRB_IntAttr_ModelSense, 1);
|
||||
// model.setObjective(objective);
|
||||
// model.update();
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
// 4. solve problem
|
||||
//----------------------------------------------
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> generate model...\n";
|
||||
IloCplex cplex(model);
|
||||
cplex.setParam(IloCplex::TiLim, _time_limit);
|
||||
{ // hack
|
||||
// 0 [CPX_NODESEL_DFS] Depth-first search
|
||||
// 1 [CPX_NODESEL_BESTBOUND] Best-bound search
|
||||
// 2 [CPX_NODESEL_BESTEST] Best-estimate search
|
||||
// 3 [CPX_NODESEL_BESTEST_ALT] Alternative best-estimate search
|
||||
// cplex.setParam(IloCplex::NodeSel , 0);
|
||||
}
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> solve...\n";
|
||||
|
||||
// silent mode?
|
||||
if(_silent)
|
||||
cplex.setOut(env_.getNullStream());
|
||||
|
||||
IloBool solution_found = cplex.solve();
|
||||
|
||||
|
||||
// if (solution_input_path_.empty())
|
||||
// {
|
||||
// if (!problem_env_output_path_.empty())
|
||||
// {
|
||||
// std::cout << "Writing problem's environment into file \"" << problem_env_output_path_ << "\"." << std::endl;
|
||||
// model.getEnv().writeParams(problem_env_output_path_);
|
||||
// }
|
||||
// if (!problem_output_path_.empty())
|
||||
// {
|
||||
// std::cout << "Writing problem into file \"" << problem_output_path_ << "\"." << std::endl;
|
||||
// GurobiHelper::outputModelToMpsGz(model, problem_output_path_);
|
||||
// }
|
||||
//
|
||||
// model.optimize();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// std::cout << "Reading solution from file \"" << solution_input_path_ << "\"." << std::endl;
|
||||
// }
|
||||
//
|
||||
//----------------------------------------------
|
||||
// 5. store result
|
||||
//----------------------------------------------
|
||||
|
||||
if(solution_found != IloFalse)
|
||||
{
|
||||
if(!_silent)
|
||||
std::cerr << "cplex -> store result...\n";
|
||||
// store computed result
|
||||
for(unsigned int i=0; i<vars.size(); ++i)
|
||||
x[i] = cplex.getValue(vars[i]);
|
||||
|
||||
_problem->store_result(P(x));
|
||||
}
|
||||
|
||||
/*
|
||||
if (solution_input_path_.empty())
|
||||
{
|
||||
// store computed result
|
||||
for(unsigned int i=0; i<vars.size(); ++i)
|
||||
x[i] = vars[i].get(GRB_DoubleAttr_X);
|
||||
}
|
||||
*/
|
||||
// else
|
||||
// {
|
||||
// std::cout << "Loading stored solution from \"" << solution_input_path_ << "\"." << std::endl;
|
||||
// // store loaded result
|
||||
// const size_t oldSize = x.size();
|
||||
// x.clear();
|
||||
// GurobiHelper::readSolutionVectorFromSOL(x, solution_input_path_);
|
||||
// if (oldSize != x.size()) {
|
||||
// std::cerr << "oldSize != x.size() <=> " << oldSize << " != " << x.size() << std::endl;
|
||||
// throw std::runtime_error("Loaded solution vector doesn't have expected dimension.");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// _problem->store_result(P(x));
|
||||
//
|
||||
// // ObjVal is only available if the optimize was called.
|
||||
// if (solution_input_path_.empty())
|
||||
// std::cout << "GUROBI Objective: " << model.get(GRB_DoubleAttr_ObjVal) << std::endl;
|
||||
return solution_found;
|
||||
}
|
||||
catch (IloException& e)
|
||||
{
|
||||
cerr << "Concert exception caught: " << e << endl;
|
||||
return false;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cerr << "Unknown exception caught" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//void
|
||||
//CPLEXSolver::
|
||||
//set_problem_output_path( const std::string &_problem_output_path)
|
||||
//{
|
||||
// problem_output_path_ = _problem_output_path;
|
||||
//}
|
||||
//
|
||||
//
|
||||
////-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//void
|
||||
//CPLEXSolver::
|
||||
//set_problem_env_output_path( const std::string &_problem_env_output_path)
|
||||
//{
|
||||
// problem_env_output_path_ = _problem_env_output_path;
|
||||
//}
|
||||
//
|
||||
//
|
||||
////-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//void
|
||||
//CPLEXSolver::
|
||||
//set_solution_input_path(const std::string &_solution_input_path)
|
||||
//{
|
||||
// solution_input_path_ = _solution_input_path;
|
||||
//}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // COMISO_CPLEX_AVAILABLE
|
||||
//=============================================================================
|
||||
134
src/external/CoMISo/NSolver/ConeConstraint.cc
vendored
Normal file
134
src/external/CoMISo/NSolver/ConeConstraint.cc
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS ConerConstraint
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_CONECONSTRAINT_CC
|
||||
#define COMISO_CONECONSTRAINT_CC
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include "NConstraintInterface.hh"
|
||||
#include "ConeConstraint.hh"
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== Implementation =========================================================
|
||||
|
||||
|
||||
/// Default constructor
|
||||
ConeConstraint::ConeConstraint()
|
||||
: NConstraintInterface(NConstraintInterface::NC_GREATER_EQUAL)
|
||||
{
|
||||
Q_.clear();
|
||||
i_ = 1.0;
|
||||
c_ = 1.0;
|
||||
}
|
||||
|
||||
// cone constraint of the form -> 0.5*(c_ * x(i_)^2 - x^T Q_ x) >= 0
|
||||
ConeConstraint::ConeConstraint(const double _c, const int _i, const SMatrixNC& _Q)
|
||||
: NConstraintInterface(NConstraintInterface::NC_GREATER_EQUAL),
|
||||
c_(_c), i_(_i), Q_(_Q)
|
||||
{
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
ConeConstraint::~ConeConstraint() {}
|
||||
|
||||
int ConeConstraint::n_unknowns()
|
||||
{
|
||||
return Q_.cols();
|
||||
}
|
||||
|
||||
void ConeConstraint::resize(const unsigned int _n)
|
||||
{
|
||||
Q_.resize(_n,_n);
|
||||
}
|
||||
|
||||
void ConeConstraint::clear()
|
||||
{
|
||||
Q_.clear();
|
||||
}
|
||||
|
||||
|
||||
const ConeConstraint::SMatrixNC& ConeConstraint::Q() const
|
||||
{
|
||||
return Q_;
|
||||
}
|
||||
ConeConstraint::SMatrixNC& ConeConstraint::Q()
|
||||
{
|
||||
return Q_;
|
||||
}
|
||||
|
||||
const int& ConeConstraint::i() const
|
||||
{
|
||||
return i_;
|
||||
}
|
||||
int& ConeConstraint::i()
|
||||
{
|
||||
return i_;
|
||||
}
|
||||
|
||||
const double& ConeConstraint::c() const
|
||||
{
|
||||
return c_;
|
||||
}
|
||||
double& ConeConstraint::c()
|
||||
{
|
||||
return c_;
|
||||
}
|
||||
|
||||
double ConeConstraint::eval_constraint ( const double* _x )
|
||||
{
|
||||
// cone constraint of the form -> 0.5*(c_ * x(i_)^2 - x^T Q_ x) >= 0
|
||||
double v = c_*_x[i_]*_x[i_];
|
||||
|
||||
SMatrixNC::iterator m_it = Q_.begin();
|
||||
SMatrixNC::iterator m_end = Q_.end();
|
||||
|
||||
for(; m_it != m_end; ++m_it)
|
||||
{
|
||||
v -= (*m_it)*_x[m_it.row()]*_x[m_it.col()];
|
||||
}
|
||||
|
||||
return 0.5*v;
|
||||
}
|
||||
|
||||
void ConeConstraint::eval_gradient( const double* _x, SVectorNC& _g )
|
||||
{
|
||||
_g.setZero();
|
||||
_g.resize(Q_.rows());
|
||||
|
||||
SMatrixNC::iterator m_it = Q_.begin();
|
||||
SMatrixNC::iterator m_end = Q_.end();
|
||||
|
||||
for(; m_it != m_end; ++m_it)
|
||||
{
|
||||
_g.coeffRef(m_it.row()) -= (*m_it)*_x[m_it.col()];
|
||||
}
|
||||
|
||||
_g.coeffRef(i_) += c_*_x[i_];
|
||||
}
|
||||
|
||||
void ConeConstraint::eval_hessian ( const double* _x, SMatrixNC& _h )
|
||||
{
|
||||
_h = Q_;
|
||||
_h.scale(-1.0);
|
||||
_h(i_,i_) += c_;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // ACG_ConeConstraint_HH defined
|
||||
//=============================================================================
|
||||
|
||||
90
src/external/CoMISo/NSolver/ConeConstraint.hh
vendored
Normal file
90
src/external/CoMISo/NSolver/ConeConstraint.hh
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS ConeConstraint
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_CONECONSTRAINT_HH
|
||||
#define COMISO_CONECONSTRAINT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include "NConstraintInterface.hh"
|
||||
#include <Eigen/StdVector>
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
class COMISODLLEXPORT ConeConstraint : public NConstraintInterface
|
||||
{
|
||||
public:
|
||||
|
||||
// sparse vector type
|
||||
typedef NConstraintInterface::SVectorNC SVectorNC;
|
||||
typedef NConstraintInterface::SMatrixNC SMatrixNC;
|
||||
|
||||
/// Default constructor
|
||||
ConeConstraint();
|
||||
|
||||
// cone constraint of the form -> 0.5*(c_ * x(i_)^2 - x^T Q_ x) >= 0
|
||||
ConeConstraint(const double _c, const int _i, const SMatrixNC& _Q);
|
||||
|
||||
/// Destructor
|
||||
virtual ~ConeConstraint();
|
||||
|
||||
virtual int n_unknowns();
|
||||
|
||||
// resize coefficient vector = #unknowns
|
||||
void resize(const unsigned int _n);
|
||||
|
||||
// clear to zero constraint 0 =_type 0
|
||||
void clear();
|
||||
|
||||
const double& c() const;
|
||||
double& c();
|
||||
|
||||
const int& i() const;
|
||||
int& i();
|
||||
|
||||
const SMatrixNC& Q() const;
|
||||
SMatrixNC& Q();
|
||||
|
||||
|
||||
virtual double eval_constraint ( const double* _x );
|
||||
|
||||
virtual void eval_gradient( const double* _x, SVectorNC& _g );
|
||||
|
||||
virtual void eval_hessian ( const double* _x, SMatrixNC& _h );
|
||||
|
||||
virtual bool is_linear() const { return false;}
|
||||
virtual bool constant_gradient() const { return false;}
|
||||
virtual bool constant_hessian () const { return true;}
|
||||
|
||||
private:
|
||||
|
||||
// cone constraint of the form -> 0.5*(c_ * x(i_)^2 - x^T Q_ x) >= 0
|
||||
double c_;
|
||||
int i_;
|
||||
SMatrixNC Q_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
// support std vectors
|
||||
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(COMISO::ConeConstraint);
|
||||
//=============================================================================
|
||||
#endif // ACG_CONECONSTRAINT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
254
src/external/CoMISo/NSolver/GUROBISolver.cc
vendored
Normal file
254
src/external/CoMISo/NSolver/GUROBISolver.cc
vendored
Normal file
@ -0,0 +1,254 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS GUROBISolver - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_GUROBI_AVAILABLE
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#include "GUROBISolver.hh"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
|
||||
GUROBISolver::
|
||||
GUROBISolver()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// ********** SOLVE **************** //
|
||||
bool
|
||||
GUROBISolver::
|
||||
solve(NProblemInterface* _problem,
|
||||
std::vector<NConstraintInterface*>& _constraints,
|
||||
std::vector<PairIndexVtype>& _discrete_constraints,
|
||||
const double _time_limit)
|
||||
{
|
||||
try
|
||||
{
|
||||
//----------------------------------------------
|
||||
// 0. set up environment
|
||||
//----------------------------------------------
|
||||
|
||||
GRBEnv env = GRBEnv();
|
||||
GRBModel model = GRBModel(env);
|
||||
|
||||
model.getEnv().set(GRB_DoubleParam_TimeLimit, _time_limit);
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
// 1. allocate variables
|
||||
//----------------------------------------------
|
||||
|
||||
// determine variable types: 0->real, 1->integer, 2->bool
|
||||
std::vector<char> vtypes(_problem->n_unknowns(),0);
|
||||
for(unsigned int i=0; i<_discrete_constraints.size(); ++i)
|
||||
switch(_discrete_constraints[i].second)
|
||||
{
|
||||
case Integer: vtypes[_discrete_constraints[i].first] = 1; break;
|
||||
case Binary : vtypes[_discrete_constraints[i].first] = 2; break;
|
||||
default : break;
|
||||
}
|
||||
|
||||
// GUROBI variables
|
||||
std::vector<GRBVar> vars;
|
||||
// first all
|
||||
for( int i=0; i<_problem->n_unknowns(); ++i)
|
||||
switch(vtypes[i])
|
||||
{
|
||||
case 0 : vars.push_back( model.addVar(-GRB_INFINITY, GRB_INFINITY, 0.0, GRB_CONTINUOUS) ); break;
|
||||
case 1 : vars.push_back( model.addVar(-GRB_INFINITY, GRB_INFINITY, 0.0, GRB_INTEGER ) ); break;
|
||||
case 2 : vars.push_back( model.addVar(-GRB_INFINITY, GRB_INFINITY, 0.0, GRB_BINARY ) ); break;
|
||||
}
|
||||
|
||||
|
||||
// Integrate new variables
|
||||
model.update();
|
||||
|
||||
//----------------------------------------------
|
||||
// 2. setup constraints
|
||||
//----------------------------------------------
|
||||
|
||||
// get zero vector
|
||||
std::vector<double> x(_problem->n_unknowns(), 0.0);
|
||||
|
||||
for(unsigned int i=0; i<_constraints.size(); ++i)
|
||||
{
|
||||
if(!_constraints[i]->is_linear())
|
||||
std::cerr << "Warning: GUROBISolver received a problem with non-linear constraints!!!" << std::endl;
|
||||
|
||||
GRBLinExpr lin_expr;
|
||||
NConstraintInterface::SVectorNC gc;
|
||||
_constraints[i]->eval_gradient(P(x), gc);
|
||||
|
||||
NConstraintInterface::SVectorNC::InnerIterator v_it(gc);
|
||||
for(; v_it; ++v_it)
|
||||
// lin_expr += v_it.value()*vars[v_it.index()];
|
||||
lin_expr = lin_expr + vars[v_it.index()]*v_it.value();
|
||||
|
||||
double b = _constraints[i]->eval_constraint(P(x));
|
||||
|
||||
switch(_constraints[i]->constraint_type())
|
||||
{
|
||||
case NConstraintInterface::NC_EQUAL : model.addConstr(lin_expr + b == 0); break;
|
||||
case NConstraintInterface::NC_LESS_EQUAL : model.addConstr(lin_expr + b <= 0); break;
|
||||
case NConstraintInterface::NC_GREATER_EQUAL : model.addConstr(lin_expr + b >= 0); break;
|
||||
}
|
||||
}
|
||||
model.update();
|
||||
|
||||
//----------------------------------------------
|
||||
// 3. setup energy
|
||||
//----------------------------------------------
|
||||
|
||||
if(!_problem->constant_hessian())
|
||||
std::cerr << "Warning: GUROBISolver received a problem with non-constant hessian!!!" << std::endl;
|
||||
|
||||
GRBQuadExpr objective;
|
||||
|
||||
// add quadratic part
|
||||
NProblemInterface::SMatrixNP H;
|
||||
_problem->eval_hessian(P(x), H);
|
||||
for( int i=0; i<H.outerSize(); ++i)
|
||||
for (NProblemInterface::SMatrixNP::InnerIterator it(H,i); it; ++it)
|
||||
objective += 0.5*it.value()*vars[it.row()]*vars[it.col()];
|
||||
|
||||
|
||||
// add linear part
|
||||
std::vector<double> g(_problem->n_unknowns());
|
||||
_problem->eval_gradient(P(x), P(g));
|
||||
for(unsigned int i=0; i<g.size(); ++i)
|
||||
objective += g[i]*vars[i];
|
||||
|
||||
// add constant part
|
||||
objective += _problem->eval_f(P(x));
|
||||
|
||||
model.set(GRB_IntAttr_ModelSense, 1);
|
||||
model.setObjective(objective);
|
||||
model.update();
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
// 4. solve problem
|
||||
//----------------------------------------------
|
||||
|
||||
|
||||
if (solution_input_path_.empty())
|
||||
{
|
||||
if (!problem_env_output_path_.empty())
|
||||
{
|
||||
std::cout << "Writing problem's environment into file \"" << problem_env_output_path_ << "\"." << std::endl;
|
||||
model.getEnv().writeParams(problem_env_output_path_);
|
||||
}
|
||||
if (!problem_output_path_.empty())
|
||||
{
|
||||
std::cout << "Writing problem into file \"" << problem_output_path_ << "\"." << std::endl;
|
||||
GurobiHelper::outputModelToMpsGz(model, problem_output_path_);
|
||||
}
|
||||
|
||||
model.optimize();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Reading solution from file \"" << solution_input_path_ << "\"." << std::endl;
|
||||
}
|
||||
|
||||
//----------------------------------------------
|
||||
// 5. store result
|
||||
//----------------------------------------------
|
||||
|
||||
if (solution_input_path_.empty())
|
||||
{
|
||||
// store computed result
|
||||
for(unsigned int i=0; i<vars.size(); ++i)
|
||||
x[i] = vars[i].get(GRB_DoubleAttr_X);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Loading stored solution from \"" << solution_input_path_ << "\"." << std::endl;
|
||||
// store loaded result
|
||||
const size_t oldSize = x.size();
|
||||
x.clear();
|
||||
GurobiHelper::readSolutionVectorFromSOL(x, solution_input_path_);
|
||||
if (oldSize != x.size()) {
|
||||
std::cerr << "oldSize != x.size() <=> " << oldSize << " != " << x.size() << std::endl;
|
||||
throw std::runtime_error("Loaded solution vector doesn't have expected dimension.");
|
||||
}
|
||||
}
|
||||
|
||||
_problem->store_result(P(x));
|
||||
|
||||
// ObjVal is only available if the optimize was called.
|
||||
if (solution_input_path_.empty())
|
||||
std::cout << "GUROBI Objective: " << model.get(GRB_DoubleAttr_ObjVal) << std::endl;
|
||||
return true;
|
||||
}
|
||||
catch(GRBException& e)
|
||||
{
|
||||
std::cout << "Error code = " << e.getErrorCode() << std::endl;
|
||||
std::cout << e.getMessage() << std::endl;
|
||||
return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cout << "Exception during optimization" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
GUROBISolver::
|
||||
set_problem_output_path( const std::string &_problem_output_path)
|
||||
{
|
||||
problem_output_path_ = _problem_output_path;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
GUROBISolver::
|
||||
set_problem_env_output_path( const std::string &_problem_env_output_path)
|
||||
{
|
||||
problem_env_output_path_ = _problem_env_output_path;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
GUROBISolver::
|
||||
set_solution_input_path(const std::string &_solution_input_path)
|
||||
{
|
||||
solution_input_path_ = _solution_input_path;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // COMISO_GUROBI_AVAILABLE
|
||||
//=============================================================================
|
||||
92
src/external/CoMISo/NSolver/GUROBISolver.hh
vendored
Normal file
92
src/external/CoMISo/NSolver/GUROBISolver.hh
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS GUROBISolver
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_GUROBISOLVER_HH
|
||||
#define COMISO_GUROBISOLVER_HH
|
||||
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_GUROBI_AVAILABLE
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "NProblemInterface.hh"
|
||||
#include "NConstraintInterface.hh"
|
||||
#include "VariableType.hh"
|
||||
#include "GurobiHelper.hh"
|
||||
|
||||
#include <gurobi_c++.h>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class NewtonSolver GUROBISolver.hh
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
class COMISODLLEXPORT GUROBISolver
|
||||
{
|
||||
public:
|
||||
|
||||
/// Default constructor
|
||||
GUROBISolver();
|
||||
|
||||
/// Destructor
|
||||
~GUROBISolver() {}
|
||||
|
||||
// ********** SOLVE **************** //
|
||||
bool solve(NProblemInterface* _problem, // problem instance
|
||||
std::vector<NConstraintInterface*>& _constraints, // linear constraints
|
||||
std::vector<PairIndexVtype>& _discrete_constraints, // discrete constraints
|
||||
const double _time_limit = 60 ); // time limit in seconds
|
||||
|
||||
void set_problem_output_path ( const std::string &_problem_output_path);
|
||||
void set_problem_env_output_path( const std::string &_problem_env_output_path);
|
||||
void set_solution_input_path ( const std::string &_solution_input_path);
|
||||
|
||||
protected:
|
||||
double* P(std::vector<double>& _v)
|
||||
{
|
||||
if( !_v.empty())
|
||||
return ((double*)&_v[0]);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// filenames for exporting/importing gurobi solutions
|
||||
// if string is empty nothing is imported or exported
|
||||
std::string problem_output_path_;
|
||||
std::string problem_env_output_path_;
|
||||
std::string solution_input_path_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
|
||||
//=============================================================================
|
||||
#endif // COMISO_GUROBI_AVAILABLE
|
||||
//=============================================================================
|
||||
#endif // ACG_GUROBISOLVER_HH defined
|
||||
//=============================================================================
|
||||
|
||||
175
src/external/CoMISo/NSolver/GurobiHelper.cc
vendored
Normal file
175
src/external/CoMISo/NSolver/GurobiHelper.cc
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* GurobiHelper.cc
|
||||
*
|
||||
* Created on: Jan 4, 2012
|
||||
* Author: ebke
|
||||
*/
|
||||
|
||||
#include "GurobiHelper.hh"
|
||||
|
||||
#if (COMISO_GUROBI_AVAILABLE && COMISO_BOOST_AVAILABLE)
|
||||
|
||||
#include <QTemporaryFile>
|
||||
#include <QFileInfo>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#define OUTPUT_UNCOMPRESSED_WITH_CONSTANT_COMMENT 0
|
||||
#define OUTPUT_CONSTANT_AS_CONT 1
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
/**
|
||||
* Helper class that ensures exception safe deletion
|
||||
* of a temporary file.
|
||||
*/
|
||||
class TempFileGuard {
|
||||
public:
|
||||
TempFileGuard(const std::string &_filePath) : filePath_(_filePath) {
|
||||
}
|
||||
|
||||
~TempFileGuard() {
|
||||
if (boost::filesystem::exists(filePath_))
|
||||
boost::filesystem::remove(filePath_);
|
||||
}
|
||||
|
||||
const boost::filesystem::path &filePath() const { return filePath_; };
|
||||
|
||||
private:
|
||||
boost::filesystem::path filePath_;
|
||||
};
|
||||
|
||||
static void moveConstantTermIntoConstrainedVariable(GRBModel &model) {
|
||||
const double constantTerm = model.getObjective().getLinExpr().getConstant();
|
||||
//tmpModel.getObjective().addConstant(-constantTerm);
|
||||
model.getObjective() -= constantTerm;
|
||||
#if OUTPUT_CONSTANT_AS_CONT
|
||||
model.addVar(constantTerm, constantTerm, 1, GRB_CONTINUOUS, "MIQ_synthetic_constant");
|
||||
#else
|
||||
model.addVar(1, 1, constantTerm, GRB_INTEGER, "MIQ_synthetic_constant");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void copyFile(const char *from, const char *to) {
|
||||
FILE *inF = fopen(from, "r");
|
||||
FILE *outF = fopen(to, "w");
|
||||
|
||||
const int bufsize = 4096;
|
||||
unsigned char buffer[bufsize];
|
||||
|
||||
do {
|
||||
size_t readBytes = fread(buffer, 1, bufsize, inF);
|
||||
fwrite(buffer, 1, readBytes, outF);
|
||||
} while(!feof(inF));
|
||||
|
||||
fclose(inF);
|
||||
fclose(outF);
|
||||
}
|
||||
|
||||
/**
|
||||
* WARNING: Never call outputModelToMpsGz and importInitialSolutionIntoModel
|
||||
* on the same model. Both try to move the constant term into a variable and
|
||||
* consequently, the second attempt to do so will fail.
|
||||
*/
|
||||
void GurobiHelper::outputModelToMpsGz(GRBModel &model, const std::string &problem_output_path_) {
|
||||
#if OUTPUT_UNCOMPRESSED_WITH_CONSTANT_COMMENT
|
||||
boost::scoped_ptr<TempFileGuard> tempFileGuard;
|
||||
{
|
||||
QTemporaryFile tempFile("XXXXXX.mps");
|
||||
tempFile.setAutoRemove(false);
|
||||
tempFile.open();
|
||||
|
||||
// In order to minimize the likelihood of race conditions,
|
||||
// we initialize tempFileGuard right here.
|
||||
tempFileGuard.reset(new TempFileGuard(QFileInfo(tempFile).absoluteFilePath().toStdString()));
|
||||
tempFile.close();
|
||||
}
|
||||
|
||||
const std::string fileName = tempFileGuard->filePath().string();
|
||||
|
||||
model.write(fileName);
|
||||
const double constantTerm = model.getObjective().getLinExpr().getConstant();
|
||||
|
||||
FILE *inF = fopen(fileName.c_str(), "r");
|
||||
FILE *outF = fopen(problem_output_path_.c_str(), "w");
|
||||
|
||||
fprintf(outF, "* Constant Term: %.16e\n", constantTerm);
|
||||
const int bufsize = 4096;
|
||||
unsigned char buffer[bufsize];
|
||||
int readBytes;
|
||||
do {
|
||||
readBytes = fread(buffer, 1, bufsize, inF);
|
||||
fwrite(buffer, 1, readBytes, outF);
|
||||
} while(!feof(inF));
|
||||
fclose(inF);
|
||||
fclose(outF);
|
||||
#else
|
||||
GRBModel tmpModel(model);
|
||||
|
||||
moveConstantTermIntoConstrainedVariable(tmpModel);
|
||||
|
||||
tmpModel.update();
|
||||
tmpModel.write(problem_output_path_);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* WARNING: Never call outputModelToMpsGz and importInitialSolutionIntoModel
|
||||
* on the same model. Both try to move the constant term into a variable and
|
||||
* consequently, the second attempt to do so will fail.
|
||||
*/
|
||||
void GurobiHelper::importInitialSolutionIntoModel(GRBModel &model, const std::string &solution_path_) {
|
||||
boost::scoped_ptr<TempFileGuard> tempFileGuard;
|
||||
{
|
||||
QTemporaryFile tempFile("XXXXXX.mst");
|
||||
tempFile.setAutoRemove(false);
|
||||
tempFile.open();
|
||||
|
||||
// In order to minimize the likelihood of race conditions,
|
||||
// we initialize tempFileGuard right here.
|
||||
tempFileGuard.reset(new TempFileGuard(QFileInfo(tempFile).absoluteFilePath().toStdString()));
|
||||
tempFile.close();
|
||||
}
|
||||
|
||||
const std::string fileName = tempFileGuard->filePath().string();
|
||||
|
||||
copyFile(solution_path_.c_str(), fileName.c_str());
|
||||
|
||||
//moveConstantTermIntoConstrainedVariable(model);
|
||||
const double constantTerm = model.getObjective().getLinExpr().getConstant();
|
||||
model.addVar(constantTerm, constantTerm, 0, GRB_CONTINUOUS, "MIQ_synthetic_constant");
|
||||
|
||||
model.update();
|
||||
model.read(fileName);
|
||||
model.update();
|
||||
}
|
||||
|
||||
void GurobiHelper::readSolutionVectorFromSOL(std::vector<double> &out_solution_, const std::string &fileName_) {
|
||||
std::ifstream solFile(fileName_.c_str());
|
||||
//if (!solFile.good())
|
||||
// throw std::runtime_error("Unable to open file \"" + fileName + "\".");
|
||||
|
||||
static const boost::regex commentRe("\\s*#", boost::regex_constants::perl);
|
||||
static const boost::regex variableRe("\\s*(\\S+)\\s+([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?)", boost::regex_constants::perl);
|
||||
|
||||
std::string line;
|
||||
while (solFile) {
|
||||
std::getline(solFile, line);
|
||||
if (boost::regex_search(line, commentRe, boost::match_continuous)) continue;
|
||||
boost::smatch match;
|
||||
if (boost::regex_search(line, match, variableRe, boost::match_continuous) && match[1] != "MIQ_synthetic_constant") {
|
||||
out_solution_.push_back(boost::lexical_cast<double>(match[2]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace COMISO */
|
||||
|
||||
#endif
|
||||
51
src/external/CoMISo/NSolver/GurobiHelper.hh
vendored
Normal file
51
src/external/CoMISo/NSolver/GurobiHelper.hh
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* GurobiHelper.hh
|
||||
*
|
||||
* Created on: Jan 4, 2012
|
||||
* Author: ebke
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GUROBIHELPER_HH_
|
||||
#define GUROBIHELPER_HH_
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if (COMISO_GUROBI_AVAILABLE && COMISO_BOOST_AVAILABLE)
|
||||
//=============================================================================
|
||||
|
||||
#include <gurobi_c++.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
class GurobiHelper {
|
||||
public:
|
||||
|
||||
/**
|
||||
* WARNING: Never call outputModelToMpsGz and importInitialSolutionIntoModel
|
||||
* on the same model. Both try to move the constant term into a variable and
|
||||
* consequently, the second attempt to do so will fail.
|
||||
*/
|
||||
static void outputModelToMpsGz(GRBModel &model, const std::string &problem_output_path_);
|
||||
|
||||
/**
|
||||
* WARNING: Never call outputModelToMpsGz and importInitialSolutionIntoModel
|
||||
* on the same model. Both try to move the constant term into a variable and
|
||||
* consequently, the second attempt to do so will fail.
|
||||
*/
|
||||
static void importInitialSolutionIntoModel(GRBModel &model, const std::string &solution_path_);
|
||||
|
||||
/**
|
||||
* Reads the solution vector from a SOL file and appends it to
|
||||
* out_solution_.
|
||||
*/
|
||||
static void readSolutionVectorFromSOL(std::vector<double> &out_solution_, const std::string &fileName_);
|
||||
};
|
||||
|
||||
} /* namespace COMISO */
|
||||
#endif /* COMISO_GUROBI_AVAILABLE */
|
||||
#endif /* GUROBIHELPER_HH_ */
|
||||
|
||||
|
||||
1153
src/external/CoMISo/NSolver/IPOPTSolver.cc
vendored
Normal file
1153
src/external/CoMISo/NSolver/IPOPTSolver.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
402
src/external/CoMISo/NSolver/IPOPTSolver.hh
vendored
Normal file
402
src/external/CoMISo/NSolver/IPOPTSolver.hh
vendored
Normal file
@ -0,0 +1,402 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS IPOPTSolver
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_IPOPTSOLVER_HH
|
||||
#define COMISO_IPOPTSOLVER_HH
|
||||
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_IPOPT_AVAILABLE
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <gmm/gmm.h>
|
||||
#include "NProblemGmmInterface.hh"
|
||||
#include "NProblemInterface.hh"
|
||||
#include "NConstraintInterface.hh"
|
||||
#include "BoundConstraint.hh"
|
||||
#include <IpTNLP.hpp>
|
||||
#include <IpIpoptApplication.hpp>
|
||||
#include <IpSolveStatistics.hpp>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class NewtonSolver NewtonSolver.hh <ACG/.../NewtonSolver.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
class COMISODLLEXPORT IPOPTSolver
|
||||
{
|
||||
public:
|
||||
|
||||
/// Default constructor -> set up IpOptApplication
|
||||
IPOPTSolver();
|
||||
|
||||
/// Destructor
|
||||
~IPOPTSolver() {}
|
||||
|
||||
// ********** SOLVE **************** //
|
||||
// solve -> returns ipopt status code
|
||||
//------------------------------------------------------
|
||||
// enum ApplicationReturnStatus
|
||||
// {
|
||||
// Solve_Succeeded=0,
|
||||
// Solved_To_Acceptable_Level=1,
|
||||
// Infeasible_Problem_Detected=2,
|
||||
// Search_Direction_Becomes_Too_Small=3,
|
||||
// Diverging_Iterates=4,
|
||||
// User_Requested_Stop=5,
|
||||
// Feasible_Point_Found=6,
|
||||
//
|
||||
// Maximum_Iterations_Exceeded=-1,
|
||||
// Restoration_Failed=-2,
|
||||
// Error_In_Step_Computation=-3,
|
||||
// Maximum_CpuTime_Exceeded=-4,
|
||||
// Not_Enough_Degrees_Of_Freedom=-10,
|
||||
// Invalid_Problem_Definition=-11,
|
||||
// Invalid_Option=-12,
|
||||
// Invalid_Number_Detected=-13,
|
||||
//
|
||||
// Unrecoverable_Exception=-100,
|
||||
// NonIpopt_Exception_Thrown=-101,
|
||||
// Insufficient_Memory=-102,
|
||||
// Internal_Error=-199
|
||||
// };
|
||||
//------------------------------------------------------
|
||||
|
||||
int solve(NProblemInterface* _problem, const std::vector<NConstraintInterface*>& _constraints);
|
||||
|
||||
// same as above with additional lazy constraints that are only added iteratively to the problem if not satisfied
|
||||
int solve(NProblemInterface* _problem,
|
||||
const std::vector<NConstraintInterface*>& _constraints,
|
||||
const std::vector<NConstraintInterface*>& _lazy_constraints,
|
||||
const double _almost_infeasible = 0.5,
|
||||
const int _max_passes = 5 );
|
||||
|
||||
|
||||
// for convenience, if no constraints are given
|
||||
int solve(NProblemInterface* _problem);
|
||||
|
||||
// deprecated interface for backwards compatibility
|
||||
int solve(NProblemGmmInterface* _problem, std::vector<NConstraintInterface*>& _constraints);
|
||||
|
||||
// ********* CONFIGURATION ********************* //
|
||||
// access the ipopt-application (for setting parameters etc.)
|
||||
// example: app().Options()->SetIntegerValue("max_iter", 100);
|
||||
Ipopt::IpoptApplication& app() {return (*app_); }
|
||||
|
||||
|
||||
protected:
|
||||
double* P(std::vector<double>& _v)
|
||||
{
|
||||
if( !_v.empty())
|
||||
return ((double*)&_v[0]);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// smart pointer to IpoptApplication to set options etc.
|
||||
Ipopt::SmartPtr<Ipopt::IpoptApplication> app_;
|
||||
};
|
||||
|
||||
|
||||
//== CLASS DEFINITION PROBLEM INSTANCE=========================================================
|
||||
|
||||
|
||||
class NProblemIPOPT : public Ipopt::TNLP
|
||||
{
|
||||
public:
|
||||
|
||||
// Ipopt Types
|
||||
typedef Ipopt::Number Number;
|
||||
typedef Ipopt::Index Index;
|
||||
typedef Ipopt::SolverReturn SolverReturn;
|
||||
typedef Ipopt::IpoptData IpoptData;
|
||||
typedef Ipopt::IpoptCalculatedQuantities IpoptCalculatedQuantities;
|
||||
|
||||
// sparse matrix and vector types
|
||||
typedef NConstraintInterface::SVectorNC SVectorNC;
|
||||
typedef NConstraintInterface::SMatrixNC SMatrixNC;
|
||||
typedef NProblemInterface::SMatrixNP SMatrixNP;
|
||||
|
||||
/** default constructor */
|
||||
NProblemIPOPT(NProblemInterface* _problem, const std::vector<NConstraintInterface*>& _constraints)
|
||||
: problem_(_problem), store_solution_(false) { split_constraints(_constraints); analyze_special_properties(_problem, _constraints);}
|
||||
|
||||
/** default destructor */
|
||||
virtual ~NProblemIPOPT() {};
|
||||
|
||||
/**@name Overloaded from TNLP */
|
||||
//@{
|
||||
/** Method to return some info about the nlp */
|
||||
virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
|
||||
Index& nnz_h_lag, IndexStyleEnum& index_style);
|
||||
|
||||
/** Method to return the bounds for my problem */
|
||||
virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u,
|
||||
Index m, Number* g_l, Number* g_u);
|
||||
|
||||
/** Method to return the starting point for the algorithm */
|
||||
virtual bool get_starting_point(Index n, bool init_x, Number* x,
|
||||
bool init_z, Number* z_L, Number* z_U,
|
||||
Index m, bool init_lambda,
|
||||
Number* lambda);
|
||||
|
||||
/** Method to return the objective value */
|
||||
virtual bool eval_f(Index n, const Number* x, bool new_x, Number& obj_value);
|
||||
|
||||
/** Method to return the gradient of the objective */
|
||||
virtual bool eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f);
|
||||
|
||||
/** Method to return the constraint residuals */
|
||||
virtual bool eval_g(Index n, const Number* x, bool new_x, Index m, Number* g);
|
||||
|
||||
/** Method to return:
|
||||
* 1) The structure of the jacobian (if "values" is NULL)
|
||||
* 2) The values of the jacobian (if "values" is not NULL)
|
||||
*/
|
||||
virtual bool eval_jac_g(Index n, const Number* x, bool new_x,
|
||||
Index m, Index nele_jac, Index* iRow, Index *jCol,
|
||||
Number* values);
|
||||
|
||||
/** Method to return:
|
||||
* 1) The structure of the hessian of the lagrangian (if "values" is NULL)
|
||||
* 2) The values of the hessian of the lagrangian (if "values" is not NULL)
|
||||
*/
|
||||
virtual bool eval_h(Index n, const Number* x, bool new_x,
|
||||
Number obj_factor, Index m, const Number* lambda,
|
||||
bool new_lambda, Index nele_hess, Index* iRow,
|
||||
Index* jCol, Number* values);
|
||||
|
||||
//@}
|
||||
|
||||
/** @name Solution Methods */
|
||||
//@{
|
||||
/** This method is called when the algorithm is complete so the TNLP can store/write the solution */
|
||||
virtual void finalize_solution(SolverReturn status,
|
||||
Index n, const Number* x, const Number* z_L, const Number* z_U,
|
||||
Index m, const Number* g, const Number* lambda,
|
||||
Number obj_value,
|
||||
const IpoptData* ip_data,
|
||||
IpoptCalculatedQuantities* ip_cq);
|
||||
//@}
|
||||
|
||||
// special properties of problem
|
||||
bool hessian_constant() const;
|
||||
bool jac_c_constant() const;
|
||||
bool jac_d_constant() const;
|
||||
|
||||
bool& store_solution() {return store_solution_; }
|
||||
std::vector<double>& solution() {return x_;}
|
||||
|
||||
private:
|
||||
/**@name Methods to block default compiler methods.
|
||||
* The compiler automatically generates the following three methods.
|
||||
* Since the default compiler implementation is generally not what
|
||||
* you want (for all but the most simple classes), we usually
|
||||
* put the declarations of these methods in the private section
|
||||
* and never implement them. This prevents the compiler from
|
||||
* implementing an incorrect "default" behavior without us
|
||||
* knowing. (See Scott Meyers book, "Effective C++")
|
||||
*
|
||||
*/
|
||||
//@{
|
||||
// MyNLP();
|
||||
NProblemIPOPT(const NProblemIPOPT&);
|
||||
NProblemIPOPT& operator=(const NProblemIPOPT&);
|
||||
//@}
|
||||
|
||||
// split user-provided constraints into general-constraints and bound-constraints
|
||||
void split_constraints(const std::vector<NConstraintInterface*>& _constraints);
|
||||
|
||||
// determine if hessian_constant, jac_c_constant or jac_d_constant
|
||||
void analyze_special_properties(const NProblemInterface* _problem, const std::vector<NConstraintInterface*>& _constraints);
|
||||
|
||||
|
||||
protected:
|
||||
double* P(std::vector<double>& _v)
|
||||
{
|
||||
if( !_v.empty())
|
||||
return ((double*)&_v[0]);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// pointer to problem instance
|
||||
NProblemInterface* problem_;
|
||||
// reference to constraints vector
|
||||
std::vector<NConstraintInterface*> constraints_;
|
||||
std::vector<BoundConstraint*> bound_constraints_;
|
||||
|
||||
bool hessian_constant_;
|
||||
bool jac_c_constant_;
|
||||
bool jac_d_constant_;
|
||||
|
||||
bool store_solution_;
|
||||
std::vector<double> x_;
|
||||
};
|
||||
|
||||
|
||||
//== CLASS DEFINITION PROBLEM INSTANCE=========================================================
|
||||
|
||||
|
||||
class NProblemGmmIPOPT : public Ipopt::TNLP
|
||||
{
|
||||
public:
|
||||
|
||||
// Ipopt Types
|
||||
typedef Ipopt::Number Number;
|
||||
typedef Ipopt::Index Index;
|
||||
typedef Ipopt::SolverReturn SolverReturn;
|
||||
typedef Ipopt::IpoptData IpoptData;
|
||||
typedef Ipopt::IpoptCalculatedQuantities IpoptCalculatedQuantities;
|
||||
|
||||
// sparse matrix and vector types
|
||||
typedef NConstraintInterface::SVectorNC SVectorNC;
|
||||
typedef NConstraintInterface::SMatrixNC SMatrixNC;
|
||||
typedef gmm::wsvector<double> SVectorNP;
|
||||
typedef NProblemGmmInterface::SMatrixNP SMatrixNP;
|
||||
|
||||
typedef gmm::array1D_reference< double* > VectorPT;
|
||||
typedef gmm::array1D_reference< const double* > VectorPTC;
|
||||
|
||||
typedef gmm::array1D_reference< Index* > VectorPTi;
|
||||
typedef gmm::array1D_reference< const Index* > VectorPTCi;
|
||||
|
||||
typedef gmm::linalg_traits<SVectorNP>::const_iterator SVectorNP_citer;
|
||||
typedef gmm::linalg_traits<SVectorNP>::iterator SVectorNP_iter;
|
||||
|
||||
/** default constructor */
|
||||
NProblemGmmIPOPT(NProblemGmmInterface* _problem, std::vector<NConstraintInterface*>& _constraints)
|
||||
: problem_(_problem), constraints_(_constraints), nnz_jac_g_(0), nnz_h_lag_(0)
|
||||
{}
|
||||
|
||||
/** default destructor */
|
||||
virtual ~NProblemGmmIPOPT() {};
|
||||
|
||||
/**@name Overloaded from TNLP */
|
||||
//@{
|
||||
/** Method to return some info about the nlp */
|
||||
virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
|
||||
Index& nnz_h_lag, IndexStyleEnum& index_style);
|
||||
|
||||
/** Method to return the bounds for my problem */
|
||||
virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u,
|
||||
Index m, Number* g_l, Number* g_u);
|
||||
|
||||
/** Method to return the starting point for the algorithm */
|
||||
virtual bool get_starting_point(Index n, bool init_x, Number* x,
|
||||
bool init_z, Number* z_L, Number* z_U,
|
||||
Index m, bool init_lambda,
|
||||
Number* lambda);
|
||||
|
||||
/** Method to return the objective value */
|
||||
virtual bool eval_f(Index n, const Number* x, bool new_x, Number& obj_value);
|
||||
|
||||
/** Method to return the gradient of the objective */
|
||||
virtual bool eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f);
|
||||
|
||||
/** Method to return the constraint residuals */
|
||||
virtual bool eval_g(Index n, const Number* x, bool new_x, Index m, Number* g);
|
||||
|
||||
/** Method to return:
|
||||
* 1) The structure of the jacobian (if "values" is NULL)
|
||||
* 2) The values of the jacobian (if "values" is not NULL)
|
||||
*/
|
||||
virtual bool eval_jac_g(Index n, const Number* x, bool new_x,
|
||||
Index m, Index nele_jac, Index* iRow, Index *jCol,
|
||||
Number* values);
|
||||
|
||||
/** Method to return:
|
||||
* 1) The structure of the hessian of the lagrangian (if "values" is NULL)
|
||||
* 2) The values of the hessian of the lagrangian (if "values" is not NULL)
|
||||
*/
|
||||
virtual bool eval_h(Index n, const Number* x, bool new_x,
|
||||
Number obj_factor, Index m, const Number* lambda,
|
||||
bool new_lambda, Index nele_hess, Index* iRow,
|
||||
Index* jCol, Number* values);
|
||||
|
||||
//@}
|
||||
|
||||
/** @name Solution Methods */
|
||||
//@{
|
||||
/** This method is called when the algorithm is complete so the TNLP can store/write the solution */
|
||||
virtual void finalize_solution(SolverReturn status,
|
||||
Index n, const Number* x, const Number* z_L, const Number* z_U,
|
||||
Index m, const Number* g, const Number* lambda,
|
||||
Number obj_value,
|
||||
const IpoptData* ip_data,
|
||||
IpoptCalculatedQuantities* ip_cq);
|
||||
//@}
|
||||
|
||||
private:
|
||||
/**@name Methods to block default compiler methods.
|
||||
* The compiler automatically generates the following three methods.
|
||||
* Since the default compiler implementation is generally not what
|
||||
* you want (for all but the most simple classes), we usually
|
||||
* put the declarations of these methods in the private section
|
||||
* and never implement them. This prevents the compiler from
|
||||
* implementing an incorrect "default" behavior without us
|
||||
* knowing. (See Scott Meyers book, "Effective C++")
|
||||
*
|
||||
*/
|
||||
//@{
|
||||
// MyNLP();
|
||||
NProblemGmmIPOPT(const NProblemGmmIPOPT&);
|
||||
NProblemGmmIPOPT& operator=(const NProblemGmmIPOPT&);
|
||||
//@}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// pointer to problem instance
|
||||
NProblemGmmInterface* problem_;
|
||||
// reference to constraints vector
|
||||
std::vector<NConstraintInterface*>& constraints_;
|
||||
|
||||
int nnz_jac_g_;
|
||||
int nnz_h_lag_;
|
||||
|
||||
// constant structure of jacobian_of_constraints and hessian_of_lagrangian
|
||||
std::vector<Index> jac_g_iRow_;
|
||||
std::vector<Index> jac_g_jCol_;
|
||||
std::vector<Index> h_lag_iRow_;
|
||||
std::vector<Index> h_lag_jCol_;
|
||||
|
||||
// Sparse Matrix of problem (don't initialize every time!!!)
|
||||
SMatrixNP HP_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
|
||||
//=============================================================================
|
||||
#endif // COMISO_IPOPT_AVAILABLE
|
||||
//=============================================================================
|
||||
#endif // ACG_IPOPTSOLVER_HH defined
|
||||
//=============================================================================
|
||||
|
||||
212
src/external/CoMISo/NSolver/LeastSquaresProblem.cc
vendored
Normal file
212
src/external/CoMISo/NSolver/LeastSquaresProblem.cc
vendored
Normal file
@ -0,0 +1,212 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS LeastSquaresProblem - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "LeastSquaresProblem.hh"
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
LeastSquaresProblem::
|
||||
add_term(NConstraintInterface* _term)
|
||||
{
|
||||
terms_.push_back(_term);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
double
|
||||
LeastSquaresProblem::
|
||||
eval_term(const unsigned int _i, const double* _x)
|
||||
{
|
||||
if(_i >= terms_.size())
|
||||
{
|
||||
std::cerr << "ERROR: bad index in LeastSquaresProblem::eval_term" << std::endl;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double vterm = terms_[_i]->eval_constraint(_x);
|
||||
|
||||
return vterm*vterm;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
double
|
||||
LeastSquaresProblem::
|
||||
eval_term(const unsigned int _i)
|
||||
{
|
||||
if(!x_.empty())
|
||||
return eval_term(_i, &(x_[0]));
|
||||
else
|
||||
{
|
||||
std::cerr << "warning: called eval_term with zero unknowns..." << std::endl;
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
int
|
||||
LeastSquaresProblem::
|
||||
n_unknowns ( )
|
||||
{
|
||||
return n_;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
LeastSquaresProblem::
|
||||
initial_x ( double* _x )
|
||||
{
|
||||
for( int i=0; i<this->n_unknowns(); ++i)
|
||||
_x[i] = x_[i];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
double
|
||||
LeastSquaresProblem::
|
||||
eval_f ( const double* _x )
|
||||
{
|
||||
double vtot(0.0);
|
||||
|
||||
for(unsigned int i=0; i<terms_.size(); ++i)
|
||||
{
|
||||
double vterm = terms_[i]->eval_constraint(_x);
|
||||
vtot += vterm*vterm;
|
||||
}
|
||||
|
||||
return vtot;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
LeastSquaresProblem::
|
||||
eval_gradient( const double* _x, double* _g)
|
||||
{
|
||||
// clear gradient
|
||||
for( int i=0; i<this->n_unknowns(); ++i)
|
||||
_g[i] = 0.0;
|
||||
|
||||
for(unsigned int i=0; i<terms_.size(); ++i)
|
||||
{
|
||||
// get local function value
|
||||
double vterm = terms_[i]->eval_constraint(_x);
|
||||
|
||||
// get local gradient
|
||||
NConstraintInterface::SVectorNC gterm;
|
||||
terms_[i]->eval_gradient(_x, gterm);
|
||||
|
||||
// add terms to global gradient
|
||||
NConstraintInterface::SVectorNC::InnerIterator v_it(gterm);
|
||||
for( ; v_it; ++v_it)
|
||||
{
|
||||
_g[v_it.index()] += 2.0*vterm*v_it.value();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
LeastSquaresProblem::
|
||||
eval_hessian ( const double* _x, SMatrixNP& _H)
|
||||
{
|
||||
// clear old data
|
||||
_H.resize(n_unknowns(), n_unknowns());
|
||||
_H.setZero();
|
||||
|
||||
for(unsigned int i=0; i<terms_.size(); ++i)
|
||||
{
|
||||
// get local function value
|
||||
double vterm = terms_[i]->eval_constraint(_x);
|
||||
|
||||
// get local gradient
|
||||
NConstraintInterface::SVectorNC gterm;
|
||||
terms_[i]->eval_gradient(_x, gterm);
|
||||
|
||||
// add terms to global gradient
|
||||
NConstraintInterface::SVectorNC::InnerIterator v_it (gterm);
|
||||
for( ; v_it; ++v_it)
|
||||
{
|
||||
NConstraintInterface::SVectorNC::InnerIterator v_it2(gterm);
|
||||
for( ; v_it2; ++v_it2)
|
||||
_H.coeffRef(v_it.index(), v_it2.index()) += 2.0*v_it.value()*v_it2.value();
|
||||
}
|
||||
|
||||
NConstraintInterface::SMatrixNC Hterm;
|
||||
terms_[i]->eval_hessian(_x, Hterm);
|
||||
|
||||
NConstraintInterface::SMatrixNC::iterator h_it = Hterm.begin();
|
||||
NConstraintInterface::SMatrixNC::iterator h_end = Hterm.end();
|
||||
for(; h_it != h_end; ++h_it)
|
||||
_H.coeffRef(h_it.row(),h_it.col()) += 2.0*vterm*(*h_it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
LeastSquaresProblem::
|
||||
store_result ( const double* _x )
|
||||
{
|
||||
for( int i=0; i<this->n_unknowns(); ++i)
|
||||
x_[i] = _x[i];
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
LeastSquaresProblem::
|
||||
constant_hessian()
|
||||
{
|
||||
for(unsigned int i=0; i<terms_.size(); ++i)
|
||||
{
|
||||
if(!terms_[i]->is_linear())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
84
src/external/CoMISo/NSolver/LeastSquaresProblem.hh
vendored
Normal file
84
src/external/CoMISo/NSolver/LeastSquaresProblem.hh
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS LeastSquaresProblem
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_LeastSquaresProblem_HH
|
||||
#define COMISO_LeastSquaresProblem_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include <CoMISo/NSolver/NProblemInterface.hh>
|
||||
#include <CoMISo/NSolver/NConstraintInterface.hh>
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class newClass newClass.hh
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
class COMISODLLEXPORT LeastSquaresProblem : public NProblemInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/// Default constructor
|
||||
LeastSquaresProblem(const int _n_unknowns) :n_(_n_unknowns), x_(_n_unknowns, 0.0) {}
|
||||
|
||||
/// Destructor
|
||||
~LeastSquaresProblem() {}
|
||||
|
||||
|
||||
void add_term(NConstraintInterface* _term);
|
||||
|
||||
double eval_term(const unsigned int _i, const double* _x);
|
||||
double eval_term(const unsigned int _i);
|
||||
|
||||
// get reference to solution vector
|
||||
const std::vector<double>& x() const {return x_;}
|
||||
std::vector<double>& x() {return x_;}
|
||||
|
||||
// problem definition
|
||||
virtual int n_unknowns ( );
|
||||
virtual void initial_x ( double* _x );
|
||||
virtual double eval_f ( const double* _x );
|
||||
virtual void eval_gradient( const double* _x, double* _g);
|
||||
virtual void eval_hessian ( const double* _x, SMatrixNP& _H);
|
||||
virtual void store_result ( const double* _x );
|
||||
|
||||
// advanced properties
|
||||
virtual bool constant_hessian();
|
||||
|
||||
private:
|
||||
|
||||
// #unknowns
|
||||
int n_;
|
||||
|
||||
// current solution vector
|
||||
std::vector<double> x_;
|
||||
|
||||
// pointer to terms
|
||||
std::vector<NConstraintInterface*> terms_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // COMISO_LeastSquaresProblem_HH defined
|
||||
//=============================================================================
|
||||
|
||||
103
src/external/CoMISo/NSolver/LinearConstraint.cc
vendored
Normal file
103
src/external/CoMISo/NSolver/LinearConstraint.cc
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS LinearConstraint
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_LINEARCONSTRAINT_CC
|
||||
#define COMISO_LINEARCONSTRAINT_CC
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include "NConstraintInterface.hh"
|
||||
#include "LinearConstraint.hh"
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== Implementation =========================================================
|
||||
|
||||
|
||||
/// Default constructor
|
||||
LinearConstraint::LinearConstraint(const ConstraintType _type) : NConstraintInterface(_type)
|
||||
{}
|
||||
|
||||
// linear equation of the form -> coeffs_^T *x + b_=_type= 0
|
||||
LinearConstraint::LinearConstraint(const SVectorNC& _coeffs, const double _b, const ConstraintType _type) : NConstraintInterface(_type)
|
||||
{
|
||||
coeffs_ = _coeffs;
|
||||
b_ = _b;
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
LinearConstraint::~LinearConstraint() {}
|
||||
|
||||
int LinearConstraint::n_unknowns()
|
||||
{
|
||||
return coeffs_.innerSize();
|
||||
}
|
||||
|
||||
void LinearConstraint::resize(const unsigned int _n)
|
||||
{
|
||||
coeffs_.m_size = _n;
|
||||
}
|
||||
|
||||
void LinearConstraint::clear()
|
||||
{
|
||||
coeffs_.setZero();
|
||||
b_ = 0.0;
|
||||
}
|
||||
|
||||
|
||||
const LinearConstraint::SVectorNC& LinearConstraint::coeffs() const
|
||||
{
|
||||
return coeffs_;
|
||||
}
|
||||
LinearConstraint::SVectorNC& LinearConstraint::coeffs()
|
||||
{
|
||||
return coeffs_;
|
||||
}
|
||||
const double& LinearConstraint::b() const
|
||||
{
|
||||
return b_;
|
||||
}
|
||||
double& LinearConstraint::b()
|
||||
{
|
||||
return b_;
|
||||
}
|
||||
|
||||
double LinearConstraint::eval_constraint ( const double* _x )
|
||||
{
|
||||
double v = b_;
|
||||
|
||||
SVectorNC::InnerIterator c_it(coeffs_);
|
||||
for(; c_it; ++c_it)
|
||||
v += c_it.value()*_x[c_it.index()];
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void LinearConstraint::eval_gradient( const double* _x, SVectorNC& _g )
|
||||
{
|
||||
_g = coeffs_;
|
||||
}
|
||||
|
||||
void LinearConstraint::eval_hessian ( const double* _x, SMatrixNC& _h )
|
||||
{
|
||||
_h.clear();
|
||||
_h.resize(coeffs_.innerSize(), coeffs_.innerSize());
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // ACG_LINEARCONSTRAINT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
97
src/external/CoMISo/NSolver/LinearConstraint.hh
vendored
Normal file
97
src/external/CoMISo/NSolver/LinearConstraint.hh
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS LinearConstraint
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_LINEARCONSTRAINT_HH
|
||||
#define COMISO_LINEARCONSTRAINT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include "NConstraintInterface.hh"
|
||||
#include <Eigen/StdVector>
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class NProblemGmmInterface NProblemGmmInterface.hh <ACG/.../NPRoblemGmmInterface.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
class COMISODLLEXPORT LinearConstraint : public NConstraintInterface
|
||||
{
|
||||
public:
|
||||
|
||||
// sparse vector type
|
||||
typedef NConstraintInterface::SVectorNC SVectorNC;
|
||||
|
||||
// different types of constraints
|
||||
// enum ConstraintType {NC_EQUAL, NC_LESS_EQUAL, NC_GREATER_EQUAL};
|
||||
|
||||
/// Default constructor
|
||||
LinearConstraint(const ConstraintType _type = NC_EQUAL);
|
||||
|
||||
// linear equation of the form -> coeffs_^T *x + b_=_type= 0
|
||||
LinearConstraint(const SVectorNC& _coeffs, const double _b, const ConstraintType _type = NC_EQUAL);
|
||||
|
||||
/// Destructor
|
||||
virtual ~LinearConstraint();
|
||||
|
||||
virtual int n_unknowns();
|
||||
|
||||
// resize coefficient vector = #unknowns
|
||||
void resize(const unsigned int _n);
|
||||
|
||||
// clear to zero constraint 0 =_type 0
|
||||
void clear();
|
||||
|
||||
const SVectorNC& coeffs() const;
|
||||
SVectorNC& coeffs();
|
||||
|
||||
const double& b() const;
|
||||
double& b();
|
||||
|
||||
virtual double eval_constraint ( const double* _x );
|
||||
|
||||
virtual void eval_gradient( const double* _x, SVectorNC& _g );
|
||||
|
||||
virtual void eval_hessian ( const double* _x, SMatrixNC& _h );
|
||||
|
||||
virtual bool is_linear() const { return true;}
|
||||
virtual bool constant_gradient() const { return true;}
|
||||
virtual bool constant_hessian () const { return true;}
|
||||
|
||||
// inherited from base
|
||||
// virtual ConstraintType constraint_type ( ) { return type_; }
|
||||
|
||||
private:
|
||||
|
||||
// linear equation of the form -> coeffs_^T * x + b_
|
||||
SVectorNC coeffs_;
|
||||
double b_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
// support std vectors
|
||||
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(COMISO::LinearConstraint);
|
||||
//=============================================================================
|
||||
#endif // ACG_LINEARCONSTRAINT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
254
src/external/CoMISo/NSolver/LinearConstraintHandlerElimination.cc
vendored
Normal file
254
src/external/CoMISo/NSolver/LinearConstraintHandlerElimination.cc
vendored
Normal file
@ -0,0 +1,254 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS LinearConstraintHandlerElimination - IMPLEMENTATION TEMPLATES
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "LinearConstraintHandlerElimination.hh"
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== 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<n_; ++i)
|
||||
{
|
||||
b_[i] = 0.0;
|
||||
Ct_(i,i) = 1.0;
|
||||
C_(i,i) = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
LinearConstraintHandlerElimination::
|
||||
initialize( const std::vector<double>& _c)
|
||||
{
|
||||
if( _c.size() )
|
||||
initialize( (double*) &(_c[0]));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
LinearConstraintHandlerElimination::
|
||||
initialize( double* _c)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
LinearConstraintHandlerElimination::
|
||||
transform_x( const std::vector<double>& _x, std::vector<double>& _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<double>& _xC, std::vector<double>& _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::
|
||||
project_x( const std::vector<double>& _x, std::vector<double>& _xp)
|
||||
{
|
||||
_xp.resize(n_);
|
||||
if( _x.size())
|
||||
project_x((double*)&(_x[0]), &(_xp[0]));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
LinearConstraintHandlerElimination::
|
||||
project_x( double* _x, double* _xp)
|
||||
{
|
||||
if( n_ == n_red_) // special case of no constraints
|
||||
{
|
||||
// just copy
|
||||
gmm::copy(VectorPT(_x, n_), VectorPT(_xp, n_));
|
||||
}
|
||||
else
|
||||
{
|
||||
Vtemp_.resize( n_red_);
|
||||
|
||||
transform_x (_x , &(Vtemp_[0]));
|
||||
inv_transform_x( &(Vtemp_[0]), _xp );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
LinearConstraintHandlerElimination::
|
||||
project_dx( const std::vector<double>& _x, std::vector<double>& _xp)
|
||||
{
|
||||
_xp.resize(n_);
|
||||
if( _x.size())
|
||||
project_dx((double*)&(_x[0]), &(_xp[0]));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
LinearConstraintHandlerElimination::
|
||||
project_dx( double* _x, double* _xp)
|
||||
{
|
||||
if( n_ == n_red_) // special case of no constraints
|
||||
{
|
||||
// just copy
|
||||
gmm::copy(VectorPT(_x, n_), VectorPT(_xp, n_));
|
||||
}
|
||||
else
|
||||
{
|
||||
// idea: C_ is an orthonormal basis of the kernel
|
||||
// -> simply project out the non-constraint part
|
||||
|
||||
Vtemp_.resize( n_red_);
|
||||
|
||||
gmm::mult(Ct_, VectorPT(_x, n_), Vtemp_);
|
||||
gmm::mult(C_, Vtemp_, VectorPT(_xp, n_));
|
||||
|
||||
// // check result
|
||||
// std::cerr << "check result..." << std::endl;
|
||||
// Vtemp_.resize(b_orig_.size());
|
||||
// gmm::mult(A_orig_, VectorPT(_xp, n_), Vtemp_);
|
||||
//// gmm::add(gmm::scaled(b_orig_, -1.0), Vtemp_);
|
||||
// std::cerr << "check constraint update... " << gmm::vect_norm2(Vtemp_) << std::endl;
|
||||
//
|
||||
//// std::cerr << "check constraint update... " << COMISO_GMM::residuum_norm<RMatrix,std::vector<double> >(A_orig_,Vtemp_, b_orig_) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
LinearConstraintHandlerElimination::
|
||||
transform_gradient( const std::vector<double>& _g, std::vector<double>& _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 COMISO
|
||||
//=============================================================================
|
||||
134
src/external/CoMISo/NSolver/LinearConstraintHandlerElimination.hh
vendored
Normal file
134
src/external/CoMISo/NSolver/LinearConstraintHandlerElimination.hh
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS LinearConstraintHandlerElimination
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_LINEARCONSTRAINTHANDLERELIMINATION_HH
|
||||
#define COMISO_LINEARCONSTRAINTHANDLERELIMINATION_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include <iostream>
|
||||
#include <gmm/gmm.h>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
|
||||
/** \class LinearConstraintHandler LinearConstraintHandler.hh <ACG/.../LinearConstraintHandler.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
|
||||
|
||||
class COMISODLLEXPORT 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<double*> VectorPT;
|
||||
|
||||
/// Constructor
|
||||
LinearConstraintHandlerElimination() {initialize_identity(0);}
|
||||
|
||||
// initialize Constructor
|
||||
template<class MatrixT, class VectorT>
|
||||
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<class MatrixT, class VectorT>
|
||||
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<double>& _c);
|
||||
void initialize( double* _c);
|
||||
|
||||
// transform x vector (least squares solution, fulfilling the constraints)
|
||||
void transform_x( const std::vector<double>& _x, std::vector<double>& _xC);
|
||||
void transform_x( double* _x, double* _xC);
|
||||
|
||||
// inverse transform x ( x_reduced -> x)
|
||||
void inv_transform_x( const std::vector<double>& _xC, std::vector<double>& _x);
|
||||
void inv_transform_x( double* _xC, double* _x);
|
||||
|
||||
// project x to closest one fullfilling the constraints: inv_transform_x(transform_x(x))
|
||||
void project_x( const std::vector<double>& _x, std::vector<double>& _xp);
|
||||
void project_x( double* _x, double* _xp);
|
||||
|
||||
// project dx to closest one that A(x0+dx) = b
|
||||
void project_dx( const std::vector<double>& _x, std::vector<double>& _xp);
|
||||
void project_dx( double* _x, double* _xp);
|
||||
|
||||
// transform gradient
|
||||
void transform_gradient( const std::vector<double>& _g, std::vector<double>& _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<double> 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<double> Vtemp_;
|
||||
|
||||
// hack -> store initial linear system
|
||||
RMatrix A_orig_;
|
||||
std::vector<double> b_orig_;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // namespace ACG
|
||||
//=============================================================================
|
||||
#if defined(INCLUDE_TEMPLATES) && !defined(COMISO_LINEARCONSTRAINTHANDLERELIMINATION_C)
|
||||
#define COMISO_LINEARCONSTRAINTHANDLERELIMINATION_TEMPLATES
|
||||
#include "LinearConstraintHandlerEliminationT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // COMISO_LINEARCONSTRAINTHANDLERELIMINATION_HH defined
|
||||
//=============================================================================
|
||||
|
||||
112
src/external/CoMISo/NSolver/LinearConstraintHandlerEliminationT.cc
vendored
Normal file
112
src/external/CoMISo/NSolver/LinearConstraintHandlerEliminationT.cc
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS LinearConstraintHandlerElimination - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define COMISO_LINEARCONSTRAINTHANDLERELIMINATION_C
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "LinearConstraintHandlerElimination.hh"
|
||||
|
||||
#include <CoMISo/Solver/SparseQRSolver.hh>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
template<class MatrixT, class VectorT>
|
||||
void
|
||||
LinearConstraintHandlerElimination::
|
||||
initialize( const MatrixT& _C, const VectorT& _c)
|
||||
{
|
||||
// no constraints?
|
||||
if( gmm::mat_nrows(_C) == 0)
|
||||
{
|
||||
initialize_identity( gmm::mat_ncols(_C));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// require SPQR SOLVER!!!
|
||||
#if(COMISO_SUITESPARSE_SPQR_AVAILABLE)
|
||||
// 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<int> 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_;
|
||||
|
||||
// hack -> store initial system
|
||||
if(0)
|
||||
{
|
||||
gmm::resize(A_orig_, gmm::mat_nrows(_C), gmm::mat_ncols(_C));
|
||||
gmm::resize(b_orig_, _c.size());
|
||||
gmm::copy(_C, A_orig_);
|
||||
gmm::copy(_c, b_orig_);
|
||||
}
|
||||
|
||||
// RMatrix CtC(n_red_, n_red_);
|
||||
// gmm::mult(Ct_,C_, CtC);
|
||||
// std::cerr << "CtC\n";
|
||||
// std::cerr << CtC << std::endl;
|
||||
|
||||
|
||||
/*
|
||||
// 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;
|
||||
#else
|
||||
std::cerr << "ERROR: SQPR-Solver required by LinearConstraintHandlerElimination not available !!!" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
131
src/external/CoMISo/NSolver/LinearConstraintHandlerPenalty.cc
vendored
Normal file
131
src/external/CoMISo/NSolver/LinearConstraintHandlerPenalty.cc
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS LinearConstraintHandlerPenalty - IMPLEMENTATION TEMPLATES
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "LinearConstraintHandlerPenalty.hh"
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
/// Constructor
|
||||
LinearConstraintHandlerPenalty::LinearConstraintHandlerPenalty() : penalty_(10000) {}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// Destructor
|
||||
LinearConstraintHandlerPenalty::~LinearConstraintHandlerPenalty()
|
||||
{}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// penalty weight
|
||||
double& LinearConstraintHandlerPenalty::penalty()
|
||||
{ return penalty_; }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// number of variables
|
||||
int LinearConstraintHandlerPenalty::n()
|
||||
{return n_;}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// number of linearly independent constraints (n-n_reduced)
|
||||
int LinearConstraintHandlerPenalty::n_constraints()
|
||||
{ return m_;}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
LinearConstraintHandlerPenalty::
|
||||
initialize( const std::vector<double>& _c)
|
||||
{
|
||||
if( _c.size() )
|
||||
initialize( (double*) &(_c[0]));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
LinearConstraintHandlerPenalty::
|
||||
initialize( double* _c)
|
||||
{
|
||||
for(unsigned int i=0; i<b_.size(); ++i)
|
||||
b_[i] = _c[i];
|
||||
|
||||
penalty_grad_b_.resize(n_);
|
||||
gmm::mult(gmm::transposed(C_), b_, penalty_grad_b_);
|
||||
gmm::scale(penalty_grad_b_, -2.0*penalty_);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
double
|
||||
LinearConstraintHandlerPenalty::
|
||||
add_penalty_f( double* _x, const double _f)
|
||||
{
|
||||
|
||||
temp_.resize(b_.size());
|
||||
gmm::mult(C_, VectorPT(_x, n_), temp_);
|
||||
gmm::add(gmm::scaled(b_, -1.0), temp_);
|
||||
|
||||
double fp = ( penalty_* (gmm::vect_sp(temp_, temp_)) );
|
||||
|
||||
return _f + fp;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
LinearConstraintHandlerPenalty::
|
||||
add_penalty_gradient( const std::vector<double>& _x, std::vector<double>& _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 COMISO
|
||||
//=============================================================================
|
||||
115
src/external/CoMISo/NSolver/LinearConstraintHandlerPenalty.hh
vendored
Normal file
115
src/external/CoMISo/NSolver/LinearConstraintHandlerPenalty.hh
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS LinearConstraintHandlerElimination
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_LINEARCONSTRAINTHANDLERPENALTY_HH
|
||||
#define COMISO_LINEARCONSTRAINTHANDLERPENALTY_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include <iostream>
|
||||
#include <gmm/gmm.h>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
|
||||
/** \class LinearConstraintHandler LinearConstraintHandler.hh <ACG/.../LinearConstraintHandler.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
|
||||
|
||||
class COMISODLLEXPORT 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<double*> VectorPT;
|
||||
|
||||
/// Constructor
|
||||
LinearConstraintHandlerPenalty();
|
||||
|
||||
// initialize Constructor
|
||||
template<class MatrixT, class VectorT>
|
||||
LinearConstraintHandlerPenalty( const MatrixT& _C, const VectorT& _c);
|
||||
|
||||
/// Destructor
|
||||
~LinearConstraintHandlerPenalty();
|
||||
|
||||
// penalty weight
|
||||
double& penalty();
|
||||
|
||||
// number of variables
|
||||
int n();
|
||||
|
||||
// number of linearly independent constraints (n-n_reduced)
|
||||
int n_constraints();
|
||||
|
||||
// initialize new constraints
|
||||
template<class MatrixT, class VectorT>
|
||||
void initialize( const MatrixT& _C, const VectorT& _c);
|
||||
|
||||
// initialize new constraints rhs only
|
||||
void initialize( const std::vector<double>& _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<double>& _x, std::vector<double>& _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<double> b_;
|
||||
|
||||
// precomputed penalty terms
|
||||
RMatrix penalty_H_;
|
||||
std::vector<double> penalty_grad_b_;
|
||||
|
||||
// temp vector
|
||||
std::vector<double> temp_;
|
||||
|
||||
// number of variables
|
||||
int n_;
|
||||
// number of constraints (linear independent)
|
||||
int m_;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#if defined(INCLUDE_TEMPLATES) && !defined(ACG_LINEARCONSTRAINTHANDLERPENALTY_C)
|
||||
#define ACG_LINEARCONSTRAINTHANDLERPENALTY_TEMPLATES
|
||||
#include "LinearConstraintHandlerPenaltyT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // ACG_LINEARCONSTRAINTHANDLERPENALTY_HH defined
|
||||
//=============================================================================
|
||||
|
||||
59
src/external/CoMISo/NSolver/LinearConstraintHandlerPenaltyT.cc
vendored
Normal file
59
src/external/CoMISo/NSolver/LinearConstraintHandlerPenaltyT.cc
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS LinearConstraintHandlerPenalty - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define COMISO_LINEARCONSTRAINTHANDLERPENALTY_C
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "LinearConstraintHandlerPenalty.hh"
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
// initialize Constructor
|
||||
template<class MatrixT, class VectorT>
|
||||
LinearConstraintHandlerPenalty::LinearConstraintHandlerPenalty( const MatrixT& _C, const VectorT& _c) :
|
||||
penalty_(10000)
|
||||
{initialize(_C, _c); }
|
||||
|
||||
template<class MatrixT, class VectorT>
|
||||
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 COMISO
|
||||
//=============================================================================
|
||||
113
src/external/CoMISo/NSolver/NConstraintInterface.hh
vendored
Normal file
113
src/external/CoMISo/NSolver/NConstraintInterface.hh
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS NConstraintInterface
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_NCONSTRAINTINTERFACE_HH
|
||||
#define COMISO_NCONSTRAINTINTERFACE_HH
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_EIGEN3_AVAILABLE
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include "SuperSparseMatrixT.hh"
|
||||
|
||||
|
||||
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
|
||||
#include <Eigen/Sparse>
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class NProblemGmmInterface NProblemGmmInterface.hh <ACG/.../NPRoblemGmmInterface.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
class COMISODLLEXPORT NConstraintInterface
|
||||
{
|
||||
public:
|
||||
|
||||
// define Sparse Datatypes
|
||||
typedef Eigen::SparseVector<double> SVectorNC;
|
||||
typedef SuperSparseMatrixT<double> SMatrixNC;
|
||||
|
||||
// different types of constraints
|
||||
enum ConstraintType {NC_EQUAL, NC_LESS_EQUAL, NC_GREATER_EQUAL};
|
||||
|
||||
/// Default constructor
|
||||
NConstraintInterface(const ConstraintType _type = NC_EQUAL, double _eps = 1e-6) : type_(_type) {}
|
||||
|
||||
/// Destructor
|
||||
virtual ~NConstraintInterface() {}
|
||||
|
||||
virtual int n_unknowns ( ) = 0;
|
||||
virtual double eval_constraint ( const double* _x ) = 0;
|
||||
virtual void eval_gradient ( const double* _x, SVectorNC& _g ) = 0;
|
||||
virtual void eval_hessian ( const double* _x, SMatrixNC& _h ) = 0;
|
||||
|
||||
virtual ConstraintType& constraint_type ( ) { return type_; }
|
||||
|
||||
virtual bool is_satisfied ( const double* _x, double _eps = 1e-6)
|
||||
{
|
||||
switch( type_)
|
||||
{
|
||||
case NC_EQUAL : return (fabs(eval_constraint(_x)) <= _eps); break;
|
||||
case NC_LESS_EQUAL : return ( eval_constraint(_x) <= _eps); break;
|
||||
case NC_GREATER_EQUAL: return ( eval_constraint(_x) >= -_eps); break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// provide special properties
|
||||
virtual bool is_linear() const { return false;}
|
||||
virtual bool constant_gradient() const { return false;}
|
||||
virtual bool constant_hessian () const { return false;}
|
||||
|
||||
virtual double gradient_update_factor( const double* _x, double _eps = 1e-6)
|
||||
{
|
||||
double val = eval_constraint(_x);
|
||||
bool upper_bound_ok = ( val <= _eps);
|
||||
bool lower_bound_ok = ( val >= -_eps);
|
||||
|
||||
if(upper_bound_ok)
|
||||
{
|
||||
if(lower_bound_ok || type_ == NC_LESS_EQUAL) return 0.0;
|
||||
else return 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(lower_bound_ok && type_ == NC_GREATER_EQUAL) return 0.0;
|
||||
else return -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
// constraint type
|
||||
ConstraintType type_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // COMISO_EIGEN3_AVAILABLE
|
||||
//=============================================================================
|
||||
#endif // ACG_NCONSTRAINTINTERFACE_HH defined
|
||||
//=============================================================================
|
||||
|
||||
330
src/external/CoMISo/NSolver/NConstraintInterfaceAD.hpp
vendored
Normal file
330
src/external/CoMISo/NSolver/NConstraintInterfaceAD.hpp
vendored
Normal file
@ -0,0 +1,330 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS NConstraintInterfaceAD
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef COMISO_NCONSTRAINTINTERFACEAD_HH
|
||||
#define COMISO_NCONSTRAINTINTERFACEAD_HH
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_ADOLC_AVAILABLE
|
||||
#if COMISO_EIGEN3_AVAILABLE
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include "SuperSparseMatrixT.hh"
|
||||
|
||||
#include <boost/shared_array.hpp>
|
||||
|
||||
#include <adolc/adolc.h>
|
||||
#include <adolc/adouble.h>
|
||||
#include <adolc/drivers/drivers.h>
|
||||
#include <adolc/sparse/sparsedrivers.h>
|
||||
#include <adolc/taping.h>
|
||||
|
||||
#include "NConstraintInterface.hh"
|
||||
#include "NProblemInterfaceAD.hpp"
|
||||
|
||||
#include "TapeIDSingleton.hh"
|
||||
|
||||
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
|
||||
#include <Eigen/Sparse>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** \class NProblemInterfaceAD NProblemInterfaceAD.hpp
|
||||
|
||||
The problem interface using automatic differentiation.
|
||||
*/
|
||||
class COMISODLLEXPORT NConstraintInterfaceAD : public NConstraintInterface {
|
||||
public:
|
||||
|
||||
// Define Sparse Datatypes
|
||||
typedef NConstraintInterface::SVectorNC SVectorNC;
|
||||
typedef NConstraintInterface::SMatrixNC SMatrixNC;
|
||||
|
||||
typedef NConstraintInterface::ConstraintType ConstraintType;
|
||||
|
||||
/// Default constructor
|
||||
NConstraintInterfaceAD(NProblemInterfaceAD& _problem, int _n_unknowns,
|
||||
const ConstraintType _type = NC_EQUAL, double _eps = 1e-6) :
|
||||
NConstraintInterface(_type, _eps),
|
||||
problem_(_problem),
|
||||
n_unknowns_(_n_unknowns),
|
||||
type_(_type),
|
||||
function_evaluated_(false),
|
||||
use_tape_(true),
|
||||
constant_hessian_evaluated_(false),
|
||||
tape_(static_cast<short int>(TapeIDSingleton::Instance()->requestId())) {
|
||||
|
||||
for(size_t i = 0; i < 11; ++i) tape_stats_[i] = 0;
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
virtual ~NConstraintInterfaceAD() {
|
||||
TapeIDSingleton::Instance()->releaseId(static_cast<size_t>(tape_));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Only override this function
|
||||
*/
|
||||
virtual adouble evaluate(const adouble* _x) = 0;
|
||||
|
||||
public:
|
||||
|
||||
virtual int n_unknowns() {
|
||||
return n_unknowns_;
|
||||
}
|
||||
|
||||
virtual double eval_constraint(const double* _x) {
|
||||
|
||||
double y = 0.0;
|
||||
|
||||
if(!function_evaluated_ || !use_tape_) {
|
||||
|
||||
adouble y_d = 0.0;
|
||||
|
||||
boost::shared_array<adouble> x_d_ptr = problem_.x_d_ptr();
|
||||
|
||||
trace_on(tape_); // Start taping
|
||||
|
||||
// Fill data vector
|
||||
for(int i = 0; i < n_unknowns_; ++i) {
|
||||
x_d_ptr[i] <<= _x[i];
|
||||
}
|
||||
|
||||
// Call virtual function to compute
|
||||
// functional value
|
||||
y_d = evaluate(x_d_ptr.get());
|
||||
|
||||
y_d >>= y;
|
||||
|
||||
trace_off();
|
||||
|
||||
#ifdef ADOLC_STATS
|
||||
tapestats(tape_, tape_stats_);
|
||||
std::cout << "Status values for tape " << tape_ << std::endl;
|
||||
std::cout << "===============================================" << std::endl;
|
||||
std::cout << "Number of independent variables:\t" << tape_stats_[0] << std::endl;
|
||||
std::cout << "Number of dependent variables:\t\t" << tape_stats_[1] << std::endl;
|
||||
std::cout << "Max. number of live active variables:\t" << tape_stats_[2] << std::endl;
|
||||
std::cout << "Size of value stack:\t\t\t" << tape_stats_[3] << std::endl;
|
||||
std::cout << "Buffer size:\t\t\t\t" << tape_stats_[4] << std::endl;
|
||||
std::cout << "Total number of operations recorded:\t" << tape_stats_[5] << std::endl;
|
||||
std::cout << "Other stats [6]:\t\t\t" << tape_stats_[6] << std::endl;
|
||||
std::cout << "Other stats [7]:\t\t\t" << tape_stats_[7] << std::endl;
|
||||
std::cout << "Other stats [8]:\t\t\t" << tape_stats_[8] << std::endl;
|
||||
std::cout << "Other stats [9]:\t\t\t" << tape_stats_[9] << std::endl;
|
||||
std::cout << "Other stats [10]:\t\t\t" << tape_stats_[10] << std::endl;
|
||||
std::cout << "===============================================" << std::endl;
|
||||
#endif
|
||||
|
||||
function_evaluated_ = true;
|
||||
|
||||
} else {
|
||||
|
||||
double ay[1] = {0.0};
|
||||
|
||||
int ec = function(tape_, 1, n_unknowns_, const_cast<double*>(_x), ay);
|
||||
|
||||
#ifdef ADOLC_RET_CODES
|
||||
std::cout << "Info: function() returned code " << ec << std::endl;
|
||||
#endif
|
||||
|
||||
y = ay[0];
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
virtual void eval_gradient(const double* _x, SVectorNC& _g) {
|
||||
|
||||
if(!function_evaluated_ || !use_tape_) {
|
||||
// Evaluate original functional
|
||||
eval_constraint(_x);
|
||||
}
|
||||
|
||||
boost::shared_array<double> grad_p = problem_.grad_ptr();
|
||||
|
||||
_g.resize(n_unknowns_);
|
||||
_g.setZero();
|
||||
|
||||
int ec = gradient(tape_, n_unknowns_, _x, grad_p.get());
|
||||
|
||||
if(ec < 0) {
|
||||
// Retape function if return code indicates discontinuity
|
||||
function_evaluated_ = false;
|
||||
#ifdef ADOLC_RET_CODES
|
||||
std::cout << __FUNCTION__ << " invokes retaping of function due to discontinuity! Return code: " << ec << std::endl;
|
||||
#endif
|
||||
eval_constraint(_x);
|
||||
ec = gradient(tape_, n_unknowns_, _x, grad_p.get());
|
||||
}
|
||||
|
||||
#ifdef ADOLC_RET_CODES
|
||||
std::cout << "Info: gradient() returned code " << ec << std::endl;
|
||||
#endif
|
||||
|
||||
for(int i = 0; i < n_unknowns_; ++i) {
|
||||
_g.coeffRef(i) = grad_p[i];
|
||||
}
|
||||
}
|
||||
|
||||
virtual void eval_hessian(const double* _x, SMatrixNC& _H) {
|
||||
|
||||
_H.resize(n_unknowns_, n_unknowns_);
|
||||
|
||||
if(constant_hessian() && constant_hessian_evaluated_) {
|
||||
_H = constant_hessian_;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!function_evaluated_ || !use_tape_) {
|
||||
// Evaluate original functional
|
||||
eval_constraint(_x);
|
||||
}
|
||||
|
||||
if(sparse_hessian()) {
|
||||
|
||||
int nz = 0;
|
||||
int opt[2] = {0, 0};
|
||||
|
||||
unsigned int* r_ind = NULL;
|
||||
unsigned int* c_ind = NULL;
|
||||
double* val = NULL;
|
||||
|
||||
int ec = sparse_hess(tape_, n_unknowns_, 0, _x, &nz, &r_ind, &c_ind, &val, opt);
|
||||
if(ec < 0) {
|
||||
// Retape function if return code indicates discontinuity
|
||||
function_evaluated_ = false;
|
||||
#ifdef ADOLC_RET_CODES
|
||||
std::cout << __FUNCTION__ << " invokes retaping of function due to discontinuity! Return code: " << ec << std::endl;
|
||||
#endif
|
||||
eval_constraint(_x);
|
||||
ec = sparse_hess(tape_, n_unknowns_, 0, _x, &nz, &r_ind, &c_ind, &val, opt);
|
||||
}
|
||||
|
||||
assert(*nz >= 0);
|
||||
assert(r_ind != NULL);
|
||||
assert(c_ind != NULL);
|
||||
assert(val != NULL);
|
||||
|
||||
#ifdef ADOLC_RET_CODES
|
||||
std::cout << "Info: sparse_hessian() returned code " << ec << std::endl;
|
||||
#endif
|
||||
|
||||
for(int i = 0; i < nz; ++i) {
|
||||
|
||||
_H(r_ind[i], c_ind[i]) = val[i];
|
||||
}
|
||||
|
||||
if(constant_hessian()) {
|
||||
constant_hessian_ = _H;
|
||||
constant_hessian_evaluated_ = true;
|
||||
}
|
||||
|
||||
delete[] r_ind;
|
||||
delete[] c_ind;
|
||||
delete[] val;
|
||||
|
||||
} else {
|
||||
|
||||
double** h_ptr = problem_.dense_hessian_ptr();
|
||||
|
||||
int ec = hessian(tape_, n_unknowns_, const_cast<double*>(_x), h_ptr);
|
||||
|
||||
if(ec < 0) {
|
||||
// Retape function if return code indicates discontinuity
|
||||
function_evaluated_ = false;
|
||||
#ifdef ADOLC_RET_CODES
|
||||
std::cout << __FUNCTION__ << " invokes retaping of function due to discontinuity! Return code: " << ec << std::endl;
|
||||
#endif
|
||||
eval_constraint(_x);
|
||||
ec = hessian(tape_, n_unknowns_, const_cast<double*>(_x), h_ptr);
|
||||
}
|
||||
|
||||
#ifdef ADOLC_RET_CODES
|
||||
std::cout << "Info: hessian() returned code " << ec << std::endl;
|
||||
#endif
|
||||
|
||||
for(int i = 0; i < n_unknowns_; ++i) {
|
||||
for(int j = 0; j <= i; ++j) {
|
||||
|
||||
_H(i, j) = h_ptr[i][j];
|
||||
|
||||
if(i != j) {
|
||||
_H(j, i) = h_ptr[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(constant_hessian()) {
|
||||
constant_hessian_ = _H;
|
||||
constant_hessian_evaluated_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Use tape
|
||||
* Set this to false if the energy functional
|
||||
* is discontinuous (so that the operator tree
|
||||
* has to be re-established at each evaluation)
|
||||
*/
|
||||
bool use_tape() const {
|
||||
return use_tape_;
|
||||
}
|
||||
|
||||
void use_tape(bool _b) {
|
||||
use_tape_ = _b;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Indicate whether the hessian is sparse.
|
||||
* If so, the computations (as well as the memory
|
||||
* consumption) can be performed more efficiently.
|
||||
*/
|
||||
virtual bool sparse_hessian() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Reference to associated objective function
|
||||
NProblemInterfaceAD& problem_;
|
||||
|
||||
// Number of unknowns
|
||||
int n_unknowns_;
|
||||
|
||||
// Constraint type
|
||||
ConstraintType type_;
|
||||
|
||||
size_t tape_stats_[11];
|
||||
|
||||
bool function_evaluated_;
|
||||
bool use_tape_;
|
||||
|
||||
SMatrixNC constant_hessian_;
|
||||
bool constant_hessian_evaluated_;
|
||||
|
||||
const short int tape_;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
}// namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // COMISO_ADOLC_AVAILABLE
|
||||
//=============================================================================
|
||||
#endif // COMISO_EIGEN3_AVAILABLE
|
||||
//=============================================================================
|
||||
#endif // ACG_NCONSTRAINTINTERFACEAD_HH defined
|
||||
//=============================================================================
|
||||
|
||||
223
src/external/CoMISo/NSolver/NPDerivativeChecker.hh
vendored
Normal file
223
src/external/CoMISo/NSolver/NPDerivativeChecker.hh
vendored
Normal file
@ -0,0 +1,223 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS NPDERIVATIVECHECKER
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_NPDERIVATIVECHECKER_HH
|
||||
#define COMISO_NPDERIVATIVECHECKER_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "NProblemGmmInterface.hh"
|
||||
#include "NProblemInterface.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <gmm/gmm.h>
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class NPDerivativeChecker
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
class COMISODLLEXPORT NPDerivativeChecker
|
||||
{
|
||||
public:
|
||||
|
||||
struct Config
|
||||
{
|
||||
Config() : x_min(-1.0), x_max(1.0), n_iters(1), dx(1e-5), eps(1e-3), relativeEps(std::numeric_limits<double>::quiet_NaN())
|
||||
{}
|
||||
|
||||
double x_min;
|
||||
double x_max;
|
||||
int n_iters;
|
||||
double dx;
|
||||
double eps;
|
||||
double relativeEps;
|
||||
};
|
||||
|
||||
/// Default constructor
|
||||
NPDerivativeChecker() {}
|
||||
|
||||
/// Destructor
|
||||
~NPDerivativeChecker() {}
|
||||
|
||||
template<class ProblemInterface>
|
||||
bool check_all(ProblemInterface* _np, double _dx, double _eps)
|
||||
{
|
||||
conf_.dx = _dx;
|
||||
conf_.eps = _eps;
|
||||
return check_all(_np);
|
||||
}
|
||||
|
||||
template<class ProblemInterface>
|
||||
bool check_all(ProblemInterface* _np)
|
||||
{
|
||||
bool d1_ok = check_d1(_np);
|
||||
bool d2_ok = check_d2(_np);
|
||||
|
||||
return ( d1_ok && d2_ok);
|
||||
}
|
||||
|
||||
template<class ProblemInterface>
|
||||
bool check_d1(ProblemInterface* _np)
|
||||
{
|
||||
int n_ok = 0;
|
||||
int n_errors = 0;
|
||||
|
||||
|
||||
int n = _np->n_unknowns();
|
||||
std::vector<double> x(n), g(n);
|
||||
|
||||
for(int i=0; i<conf_.n_iters; ++i)
|
||||
{
|
||||
// get random x
|
||||
get_random_x(x, conf_.x_min, conf_.x_max);
|
||||
// gradient
|
||||
_np->eval_gradient(P(x), P(g));
|
||||
|
||||
for(int j=0; j<n; ++j)
|
||||
{
|
||||
// double fd = finite_difference(_np, x, j);
|
||||
x[j] += conf_.dx;
|
||||
double f1 = _np->eval_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 ((!std::isnan(conf_.relativeEps) && fabs(fd-g[j]) > fmax(fabs(g[j]), 1.0) * conf_.relativeEps) || 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 Summary #############\n";
|
||||
std::cerr << "#ok : " << n_ok << std::endl;
|
||||
std::cerr << "#error: " << n_errors << std::endl;
|
||||
|
||||
return (n_errors == 0);
|
||||
}
|
||||
|
||||
template<class MatrixType>
|
||||
inline double getCoeff(const MatrixType &m, int r, int c);
|
||||
|
||||
template<class ProblemInterface>
|
||||
bool check_d2(ProblemInterface* _np)
|
||||
{
|
||||
int n_ok = 0;
|
||||
int n_errors = 0;
|
||||
|
||||
int n = _np->n_unknowns();
|
||||
std::vector<double> x(n);
|
||||
typename ProblemInterface::SMatrixNP H(n,n);
|
||||
|
||||
for(int i=0; i<conf_.n_iters; ++i)
|
||||
{
|
||||
// get random x
|
||||
get_random_x(x, conf_.x_min, conf_.x_max);
|
||||
// gradient
|
||||
_np->eval_hessian(P(x), H);
|
||||
|
||||
for(int j=0; j<n; ++j)
|
||||
for(int k=0; k<n; ++k)
|
||||
{
|
||||
x[j] += conf_.dx;
|
||||
x[k] += conf_.dx;
|
||||
double f0 = _np->eval_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 ((!std::isnan(conf_.relativeEps) && fabs(fd-H.coeff(j,k)) > fmax(fabs(getCoeff(H, j,k)), 1.0) * conf_.relativeEps) || fabs(fd-getCoeff(H, j,k)) > conf_.eps)
|
||||
{
|
||||
++ n_errors;
|
||||
std::cerr << "Hessian error in component " << j << "," << k << ": " << getCoeff(H, j,k)
|
||||
<< " should be (following FiniteDifferences) " << fd
|
||||
<< " (absolute delta: " << fabs(fd-getCoeff(H, j,k))
|
||||
<< ", relative delta:" << (fabs(fd-getCoeff(H, j,k))/fmax(fabs(getCoeff(H, j,k)), 1.0)) << ")" << std::endl;
|
||||
}
|
||||
else ++ n_ok;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "############## Hessian Checker Summary #############\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<double>& _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<double>& _v)
|
||||
{
|
||||
if( !_v.empty())
|
||||
return ((double*)&_v[0]);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
Config conf_;
|
||||
};
|
||||
|
||||
template<>
|
||||
inline double NPDerivativeChecker::getCoeff(const NProblemInterface::SMatrixNP &m, int r, int c) {
|
||||
return m.coeff(r, c);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline double NPDerivativeChecker::getCoeff(const NProblemGmmInterface::SMatrixNP &m, int r, int c) {
|
||||
return m(r, c);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // ACG_NPDERIVATIVECHECKER defined
|
||||
//=============================================================================
|
||||
|
||||
167
src/external/CoMISo/NSolver/NPLinearConstraints.cc
vendored
Normal file
167
src/external/CoMISo/NSolver/NPLinearConstraints.cc
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS NPLinearConstraints
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "NPLinearConstraints.hh"
|
||||
#include "NProblemGmmInterface.hh"
|
||||
#include "LinearConstraintHandlerElimination.hh"
|
||||
#include "LinearConstraintHandlerPenalty.hh"
|
||||
//#include "LinearConstraintHandlerLagrange.hh"
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/// Default constructor having a pointer to the main problem
|
||||
NPLinearConstraintsElimination::NPLinearConstraintsElimination( NProblemGmmInterface* _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::~NPLinearConstraintsElimination() {}
|
||||
|
||||
// NSolverInterface
|
||||
int NPLinearConstraintsElimination::n_unknowns ()
|
||||
{ return this->n_reduced(); }
|
||||
|
||||
void NPLinearConstraintsElimination::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);
|
||||
}
|
||||
|
||||
double NPLinearConstraintsElimination::eval_f( const double* _x )
|
||||
{
|
||||
update_x(_x);
|
||||
|
||||
return base_->eval_f(P(x_));
|
||||
}
|
||||
|
||||
void NPLinearConstraintsElimination::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);
|
||||
}
|
||||
|
||||
void NPLinearConstraintsElimination::eval_hessian ( const double* _x, SMatrixNP& _H)
|
||||
{
|
||||
update_x(_x);
|
||||
SMatrixNP H;
|
||||
base_->eval_hessian(P(x_), H);
|
||||
this->transform_hessian(H,_H);
|
||||
}
|
||||
|
||||
void NPLinearConstraintsElimination::store_result ( const double* _x )
|
||||
{
|
||||
update_x(_x);
|
||||
|
||||
base_->store_result( P(x_));
|
||||
}
|
||||
|
||||
void NPLinearConstraintsElimination::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; i<this->n_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* NPLinearConstraintsElimination::P(const std::vector<double>& _v)
|
||||
{
|
||||
if(_v.size())
|
||||
return (double*) (&(_v[0]));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/// Default constructor having a pointer to the main problem
|
||||
NPLinearConstraintsPenalty::NPLinearConstraintsPenalty( NProblemGmmInterface* _np) : base_(_np)
|
||||
{ if( !base_) std::cerr << "Warning: initialized NPLinearConstraints with zero pointer...\n"; }
|
||||
|
||||
/// Destructor
|
||||
NPLinearConstraintsPenalty::~NPLinearConstraintsPenalty()
|
||||
{}
|
||||
|
||||
// NSolverInterface
|
||||
int NPLinearConstraintsPenalty::n_unknowns ()
|
||||
{ return base_->n_unknowns(); }
|
||||
|
||||
void NPLinearConstraintsPenalty::initial_x ( double* _x )
|
||||
{
|
||||
base_->initial_x(_x);
|
||||
}
|
||||
|
||||
double NPLinearConstraintsPenalty::eval_f( const double* _x )
|
||||
{
|
||||
return this->add_penalty_f((double*)_x, base_->eval_f(_x));
|
||||
}
|
||||
|
||||
void NPLinearConstraintsPenalty::eval_gradient( const double* _x, double* _g)
|
||||
{
|
||||
base_->eval_gradient( _x, _g);
|
||||
this->add_penalty_gradient((double*)_x, _g);
|
||||
}
|
||||
|
||||
void NPLinearConstraintsPenalty::eval_hessian ( const double* _x, SMatrixNP& _H)
|
||||
{
|
||||
base_->eval_hessian(_x, _H);
|
||||
this->add_penalty_hessian(_H);
|
||||
}
|
||||
|
||||
void NPLinearConstraintsPenalty::store_result ( const double* _x )
|
||||
{
|
||||
base_->store_result( _x);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace ACG
|
||||
//=============================================================================
|
||||
|
||||
|
||||
138
src/external/CoMISo/NSolver/NPLinearConstraints.hh
vendored
Normal file
138
src/external/CoMISo/NSolver/NPLinearConstraints.hh
vendored
Normal file
@ -0,0 +1,138 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS NPLinearConstraints
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_NPLINEARCONSTRAINTS_HH
|
||||
#define COMISO_NPLINEARCONSTRAINTS_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include <gmm/gmm.h>
|
||||
#include "NProblemGmmInterface.hh"
|
||||
#include "LinearConstraintHandlerElimination.hh"
|
||||
#include "LinearConstraintHandlerPenalty.hh"
|
||||
//#include "LinearConstraintHandlerLagrange.hh"
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== 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 COMISODLLEXPORT NPLinearConstraintsElimination : public NProblemGmmInterface, public LinearConstraintHandlerElimination
|
||||
{
|
||||
public:
|
||||
|
||||
// use c-arrays as vectors for gmm
|
||||
typedef gmm::array1D_reference<double*> VectorPT;
|
||||
|
||||
/// Default constructor having a pointer to the main problem
|
||||
NPLinearConstraintsElimination( NProblemGmmInterface* _np);
|
||||
|
||||
/// Destructor
|
||||
~NPLinearConstraintsElimination();
|
||||
|
||||
// initialize constraints
|
||||
template<class MatrixT, class VectorT>
|
||||
void initialize_constraints( const MatrixT& _C, const VectorT& _c);
|
||||
|
||||
|
||||
// NSolverInterface
|
||||
virtual int n_unknowns ();
|
||||
|
||||
virtual void initial_x ( double* _x );
|
||||
|
||||
virtual double eval_f( const double* _x );
|
||||
|
||||
virtual void eval_gradient( const double* _x, double* _g);
|
||||
|
||||
virtual void eval_hessian ( const double* _x, SMatrixNP& _H);
|
||||
|
||||
virtual void store_result ( const double* _x );
|
||||
|
||||
protected:
|
||||
|
||||
void update_x(const double* _xr);
|
||||
|
||||
// convert vector into pointer
|
||||
double* P(const std::vector<double>& _v);
|
||||
|
||||
private:
|
||||
NProblemGmmInterface* base_;
|
||||
|
||||
bool cache_initialized_;
|
||||
|
||||
std::vector<double> x_;
|
||||
std::vector<double> xr_;
|
||||
std::vector<double> vtemp_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
// ConstraintHandler working with Penalty
|
||||
class COMISODLLEXPORT NPLinearConstraintsPenalty : public NProblemGmmInterface, public LinearConstraintHandlerPenalty
|
||||
{
|
||||
public:
|
||||
|
||||
// use c-arrays as vectors for gmm
|
||||
typedef gmm::array1D_reference<double*> VectorPT;
|
||||
|
||||
/// Default constructor having a pointer to the main problem
|
||||
NPLinearConstraintsPenalty( NProblemGmmInterface* _np);
|
||||
|
||||
/// Destructor
|
||||
~NPLinearConstraintsPenalty();
|
||||
|
||||
// initialize constraints
|
||||
template<class MatrixT, class VectorT>
|
||||
void initialize_constraints( const MatrixT& _C, const VectorT& _c);
|
||||
|
||||
// NSolverInterface
|
||||
virtual int n_unknowns ();
|
||||
|
||||
virtual void initial_x ( double* _x );
|
||||
|
||||
virtual double eval_f( const double* _x );
|
||||
|
||||
virtual void eval_gradient( const double* _x, double* _g);
|
||||
|
||||
virtual void eval_hessian ( const double* _x, SMatrixNP& _H);
|
||||
|
||||
virtual void store_result ( const double* _x );
|
||||
|
||||
private:
|
||||
NProblemGmmInterface* base_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace ACG
|
||||
//=============================================================================
|
||||
#if defined(INCLUDE_TEMPLATES) && !defined(COMISO_NSOLVERGMMINTERFACE_C)
|
||||
#define ACG_NSOLVERGMMINTERFACE_TEMPLATES
|
||||
#include "NPLinearConstraintsT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // COMISO_NSOLVERGMMINTERFACE_HH defined
|
||||
//=============================================================================
|
||||
|
||||
49
src/external/CoMISo/NSolver/NPLinearConstraintsT.cc
vendored
Normal file
49
src/external/CoMISo/NSolver/NPLinearConstraintsT.cc
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS NPLinearConstraints
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define COMISO_NSOLVERGMMINTERFACE_C
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include <gmm/gmm.h>
|
||||
#include "NProblemGmmInterface.hh"
|
||||
#include "LinearConstraintHandlerElimination.hh"
|
||||
#include "LinearConstraintHandlerPenalty.hh"
|
||||
//#include "LinearConstraintHandlerLagrange.hh"
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
// initialize constraints
|
||||
template<class MatrixT, class VectorT>
|
||||
void NPLinearConstraintsElimination::initialize_constraints( const MatrixT& _C, const VectorT& _c)
|
||||
{
|
||||
initialize(_C, _c);
|
||||
cache_initialized_ = false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
// initialize constraints
|
||||
template<class MatrixT, class VectorT>
|
||||
void NPLinearConstraintsPenalty::initialize_constraints( const MatrixT& _C, const VectorT& _c)
|
||||
{
|
||||
initialize(_C, _c);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace ACG
|
||||
//=============================================================================
|
||||
|
||||
|
||||
112
src/external/CoMISo/NSolver/NPTiming.cc
vendored
Normal file
112
src/external/CoMISo/NSolver/NPTiming.cc
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS NPTiming
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "NPTiming.hh"
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/// Default constructor
|
||||
NPTiming::NPTiming(NProblemGmmInterface* _base) : base_(_base) {start_timing();}
|
||||
|
||||
/// Destructor
|
||||
NPTiming::~NPTiming() {}
|
||||
|
||||
int NPTiming::n_unknowns ()
|
||||
{
|
||||
return base_->n_unknowns();
|
||||
}
|
||||
|
||||
void NPTiming::initial_x( double* _x )
|
||||
{
|
||||
base_->initial_x(_x);
|
||||
}
|
||||
|
||||
double NPTiming::eval_f( const double* _x )
|
||||
{
|
||||
++n_eval_f_;
|
||||
sw_.start();
|
||||
double f = base_->eval_f(_x);
|
||||
timing_eval_f_ += sw_.stop();
|
||||
return f;
|
||||
}
|
||||
|
||||
void NPTiming::eval_gradient( const double* _x, double* _g)
|
||||
{
|
||||
++n_eval_gradient_;
|
||||
sw_.start();
|
||||
base_->eval_gradient(_x, _g);
|
||||
timing_eval_gradient_ += sw_.stop();
|
||||
}
|
||||
|
||||
void NPTiming::eval_hessian ( const double* _x, SMatrixNP& _H)
|
||||
{
|
||||
++n_eval_hessian_;
|
||||
sw_.start();
|
||||
base_->eval_hessian(_x, _H);
|
||||
timing_eval_hessian_ += sw_.stop();
|
||||
}
|
||||
|
||||
void NPTiming::store_result ( const double* _x )
|
||||
{
|
||||
base_->store_result(_x);
|
||||
print_statistics();
|
||||
}
|
||||
|
||||
void NPTiming::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;
|
||||
}
|
||||
|
||||
|
||||
void NPTiming::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";
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
|
||||
85
src/external/CoMISo/NSolver/NPTiming.hh
vendored
Normal file
85
src/external/CoMISo/NSolver/NPTiming.hh
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS NPTiming
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_NPTIMING_HH
|
||||
#define COMISO_NPTIMING_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <gmm/gmm.h>
|
||||
#include "NProblemGmmInterface.hh"
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class NProblemGmmInterface NProblemGmmInterface.hh <ACG/.../NProblemGmmInterface.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
class COMISODLLEXPORT NPTiming : public NProblemGmmInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/// Default constructor
|
||||
NPTiming(NProblemGmmInterface* _base);
|
||||
|
||||
/// Destructor
|
||||
~NPTiming();
|
||||
|
||||
virtual int n_unknowns ();
|
||||
|
||||
virtual void initial_x( double* _x );
|
||||
|
||||
virtual double eval_f( const double* _x );
|
||||
|
||||
virtual void eval_gradient( const double* _x, double* _g);
|
||||
|
||||
virtual void eval_hessian ( const double* _x, SMatrixNP& _H);
|
||||
|
||||
virtual void store_result ( const double* _x );
|
||||
|
||||
void start_timing();
|
||||
|
||||
protected:
|
||||
|
||||
void print_statistics();
|
||||
|
||||
private:
|
||||
NProblemGmmInterface* 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 COMISO
|
||||
//=============================================================================
|
||||
#endif // COMISO_NPTIMING_HH defined
|
||||
//=============================================================================
|
||||
|
||||
64
src/external/CoMISo/NSolver/NProblemGmmInterface.hh
vendored
Normal file
64
src/external/CoMISo/NSolver/NProblemGmmInterface.hh
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS NProblemGmmInterface
|
||||
// **************** DEPRECATED -> Please use NProblemInterface ***************//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_NPROBLEMGMMINTERFACE_HH
|
||||
#define COMISO_NPROBLEMGMMINTERFACE_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <gmm/gmm.h>
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class NProblemGmmInterface NProblemGmmInterface.hh <ACG/.../NPRoblemGmmInterface.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
|
||||
// *** This class is DEPRECATED -> Please use NProblemInterface ***//
|
||||
class COMISODLLEXPORT NProblemGmmInterface
|
||||
{
|
||||
public:
|
||||
|
||||
// ToDo: appropriate MatrixType ???
|
||||
typedef gmm::row_matrix< gmm::wsvector<double> > SMatrixNP;
|
||||
|
||||
/// Default constructor
|
||||
NProblemGmmInterface()
|
||||
{std::cerr << "Warning: NProblemGmmInterface is deprecated -> use NProblemInterface instead!!!" << std::endl;}
|
||||
|
||||
/// Destructor
|
||||
~NProblemGmmInterface() {}
|
||||
|
||||
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, SMatrixNP& _H) = 0;
|
||||
virtual void store_result ( const double* _x ) = 0;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // COMISO_NPROBLEMGMMINTERFACE_HH defined
|
||||
//=============================================================================
|
||||
|
||||
11
src/external/CoMISo/NSolver/NProblemInterface.cc
vendored
Normal file
11
src/external/CoMISo/NSolver/NProblemInterface.cc
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
#include "NProblemInterface.hh"
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
NProblemInterface::NProblemInterface() {
|
||||
}
|
||||
|
||||
NProblemInterface::~NProblemInterface() {
|
||||
}
|
||||
|
||||
}
|
||||
82
src/external/CoMISo/NSolver/NProblemInterface.hh
vendored
Normal file
82
src/external/CoMISo/NSolver/NProblemInterface.hh
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS NProblemGmmInterface
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_NPROBLEMINTERFACE_HH
|
||||
#define COMISO_NPROBLEMINTERFACE_HH
|
||||
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_EIGEN3_AVAILABLE
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
#include <Eigen/Eigen>
|
||||
#if !(EIGEN_VERSION_AT_LEAST(3,1,0))
|
||||
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
|
||||
#endif
|
||||
#include <Eigen/Sparse>
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class NProblemGmmInterface NProblemGmmInterface.hh <ACG/.../NPRoblemGmmInterface.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
class COMISODLLEXPORT NProblemInterface
|
||||
{
|
||||
public:
|
||||
|
||||
// Sparse Matrix Type
|
||||
#if EIGEN_VERSION_AT_LEAST(3,1,0)
|
||||
typedef Eigen::SparseMatrix<double,Eigen::ColMajor> SMatrixNP;
|
||||
#else
|
||||
typedef Eigen::DynamicSparseMatrix<double,Eigen::ColMajor> SMatrixNP;
|
||||
#endif
|
||||
|
||||
/// Default constructor
|
||||
NProblemInterface();
|
||||
|
||||
/// Destructor
|
||||
virtual ~NProblemInterface();
|
||||
|
||||
// problem definition
|
||||
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, SMatrixNP& _H) = 0;
|
||||
virtual void store_result ( const double* _x ) = 0;
|
||||
|
||||
// advanced properties
|
||||
virtual bool constant_gradient() const { return false; }
|
||||
virtual bool constant_hessian() const { return false; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // COMISO_EIGEN3_AVAILABLE
|
||||
//=============================================================================
|
||||
#endif // COMISO_NPROBLEMGMMINTERFACE_HH defined
|
||||
//=============================================================================
|
||||
|
||||
362
src/external/CoMISo/NSolver/NProblemInterfaceAD.hpp
vendored
Normal file
362
src/external/CoMISo/NSolver/NProblemInterfaceAD.hpp
vendored
Normal file
@ -0,0 +1,362 @@
|
||||
/*
|
||||
* NProblemInterfaceAD.hpp
|
||||
*
|
||||
* Created on: Nov 30, 2012
|
||||
* Author: kremer
|
||||
*/
|
||||
|
||||
#ifndef NPROBLEMINTERFACEAD_HPP_
|
||||
#define NPROBLEMINTERFACEAD_HPP_
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_ADOLC_AVAILABLE
|
||||
#if COMISO_EIGEN3_AVAILABLE
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/shared_array.hpp>
|
||||
|
||||
#include <adolc/adolc.h>
|
||||
#include <adolc/adouble.h>
|
||||
#include <adolc/drivers/drivers.h>
|
||||
#include <adolc/sparse/sparsedrivers.h>
|
||||
#include <adolc/taping.h>
|
||||
|
||||
#include <Eigen/Eigen>
|
||||
#if !(EIGEN_VERSION_AT_LEAST(3,1,0))
|
||||
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
|
||||
#endif
|
||||
#include <Eigen/Sparse>
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
|
||||
#include "TapeIDSingleton.hh"
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** \class NProblemmInterfaceAD NProblemInterfaceAD.hpp <ACG/.../NProblemInterfaceAD.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
Extend the problem interface with auto differentiation using ADOL-C
|
||||
*/
|
||||
class COMISODLLEXPORT NProblemInterfaceAD : public NProblemInterface
|
||||
{
|
||||
public:
|
||||
|
||||
// Sparse Matrix Type
|
||||
#if EIGEN_VERSION_AT_LEAST(3,1,0)
|
||||
typedef Eigen::SparseMatrix<double,Eigen::ColMajor> SMatrixNP;
|
||||
#else
|
||||
typedef Eigen::DynamicSparseMatrix<double,Eigen::ColMajor> SMatrixNP;
|
||||
#endif
|
||||
|
||||
/// Default constructor
|
||||
NProblemInterfaceAD(int _n_unknowns) :
|
||||
n_unknowns_(_n_unknowns),
|
||||
dense_hessian_(NULL),
|
||||
function_evaluated_(false),
|
||||
use_tape_(true),
|
||||
tape_(static_cast<short int>(TapeIDSingleton::Instance()->requestId())) {
|
||||
|
||||
for(size_t i = 0; i < 11; ++i) tape_stats_[i] = 0;
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
virtual ~NProblemInterfaceAD() {
|
||||
|
||||
if(dense_hessian_ != NULL) {
|
||||
for(int i = 0; i < n_unknowns_; ++i) {
|
||||
delete[] dense_hessian_[i];
|
||||
}
|
||||
delete[] dense_hessian_;
|
||||
}
|
||||
|
||||
TapeIDSingleton::Instance()->releaseId(static_cast<size_t>(tape_));
|
||||
}
|
||||
|
||||
// ================================================
|
||||
// Override these three methods
|
||||
// ================================================
|
||||
|
||||
virtual void initial_x(double* _x) = 0;
|
||||
|
||||
virtual adouble evaluate(const adouble* _x) = 0;
|
||||
|
||||
virtual void store_result(const double* _x) = 0;
|
||||
|
||||
// ================================================
|
||||
// Optionally override these methods, too
|
||||
// ================================================
|
||||
|
||||
/**
|
||||
* \brief Indicate whether the hessian is sparse.
|
||||
* If so, the computations (as well as the memory
|
||||
* consumption) can be performed more efficiently.
|
||||
*/
|
||||
virtual bool sparse_hessian() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ================================================
|
||||
|
||||
virtual int n_unknowns() {
|
||||
|
||||
return n_unknowns_;
|
||||
}
|
||||
|
||||
virtual double eval_f(const double* _x) {
|
||||
|
||||
double y = 0.0;
|
||||
|
||||
if(!function_evaluated_ || !use_tape_) {
|
||||
|
||||
adouble y_d = 0.0;
|
||||
|
||||
boost::shared_array<adouble> x_d = x_d_ptr();
|
||||
|
||||
trace_on(tape_); // Start taping
|
||||
|
||||
// Fill data vector
|
||||
for(int i = 0; i < n_unknowns_; ++i) {
|
||||
x_d[i] <<= _x[i];
|
||||
}
|
||||
|
||||
// Call virtual function to compute
|
||||
// functional value
|
||||
y_d = evaluate(x_d.get());
|
||||
|
||||
y_d >>= y;
|
||||
|
||||
trace_off();
|
||||
|
||||
#ifdef ADOLC_STATS
|
||||
tapestats(tape_, tape_stats_);
|
||||
std::cout << "Status values for tape " << tape_ << std::endl;
|
||||
std::cout << "===============================================" << std::endl;
|
||||
std::cout << "Number of independent variables:\t" << tape_stats_[0] << std::endl;
|
||||
std::cout << "Number of dependent variables:\t\t" << tape_stats_[1] << std::endl;
|
||||
std::cout << "Max. number of live active variables:\t" << tape_stats_[2] << std::endl;
|
||||
std::cout << "Size of value stack:\t\t\t" << tape_stats_[3] << std::endl;
|
||||
std::cout << "Buffer size:\t\t\t\t" << tape_stats_[4] << std::endl;
|
||||
std::cout << "Total number of operations recorded:\t" << tape_stats_[5] << std::endl;
|
||||
std::cout << "Other stats [6]:\t\t\t" << tape_stats_[6] << std::endl;
|
||||
std::cout << "Other stats [7]:\t\t\t" << tape_stats_[7] << std::endl;
|
||||
std::cout << "Other stats [8]:\t\t\t" << tape_stats_[8] << std::endl;
|
||||
std::cout << "Other stats [9]:\t\t\t" << tape_stats_[9] << std::endl;
|
||||
std::cout << "Other stats [10]:\t\t\t" << tape_stats_[10] << std::endl;
|
||||
std::cout << "===============================================" << std::endl;
|
||||
#endif
|
||||
|
||||
function_evaluated_ = true;
|
||||
|
||||
} else {
|
||||
|
||||
double ay[1] = {0.0};
|
||||
|
||||
int ec = function(tape_, 1, n_unknowns_, const_cast<double*>(_x), ay);
|
||||
|
||||
#ifdef ADOLC_RET_CODES
|
||||
std::cout << "Info: function() returned code " << ec << std::endl;
|
||||
#endif
|
||||
|
||||
y = ay[0];
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
virtual void eval_gradient(const double* _x, double* _g) {
|
||||
|
||||
if(!function_evaluated_ || !use_tape_) {
|
||||
// Evaluate original functional
|
||||
eval_f(_x);
|
||||
}
|
||||
|
||||
int ec = gradient(tape_, n_unknowns_, _x, _g);
|
||||
|
||||
if(ec < 0) {
|
||||
// Retape function if return code indicates discontinuity
|
||||
function_evaluated_ = false;
|
||||
#ifdef ADOLC_RET_CODES
|
||||
std::cout << __FUNCTION__ << " invokes retaping of function due to discontinuity! Return code: " << ec << std::endl;
|
||||
#endif
|
||||
eval_f(_x);
|
||||
ec = gradient(tape_, n_unknowns_, _x, _g);
|
||||
}
|
||||
|
||||
#ifdef ADOLC_RET_CODES
|
||||
std::cout << "Info: gradient() returned code " << ec << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void eval_hessian(const double* _x, SMatrixNP& _H) {
|
||||
|
||||
_H.resize(n_unknowns_, n_unknowns_);
|
||||
_H.setZero();
|
||||
|
||||
if(!function_evaluated_ || !use_tape_) {
|
||||
// Evaluate original functional
|
||||
eval_f(_x);
|
||||
}
|
||||
|
||||
if(sparse_hessian()) {
|
||||
|
||||
int nz = 0;
|
||||
int opt[2] = {0, 0};
|
||||
|
||||
unsigned int* r_ind_p = NULL;
|
||||
unsigned int* c_ind_p = NULL;
|
||||
double* val_p = NULL;
|
||||
|
||||
int ec = sparse_hess(tape_, n_unknowns_, 0, _x, &nz, &r_ind_p, &c_ind_p, &val_p, opt);
|
||||
|
||||
if(ec < 0) {
|
||||
// Retape function if return code indicates discontinuity
|
||||
function_evaluated_ = false;
|
||||
#ifdef ADOLC_RET_CODES
|
||||
std::cout << __FUNCTION__ << " invokes retaping of function due to discontinuity! Return code: " << ec << std::endl;
|
||||
#endif
|
||||
eval_f(_x);
|
||||
ec = sparse_hess(tape_, n_unknowns_, 0, _x, &nz, &r_ind_p, &c_ind_p, &val_p, opt);
|
||||
}
|
||||
|
||||
assert(*nz >= 0);
|
||||
assert(r_ind_p != NULL);
|
||||
assert(c_ind_p != NULL);
|
||||
assert(val_p != NULL);
|
||||
|
||||
#ifdef ADOLC_RET_CODES
|
||||
std::cout << "Info: sparse_hessian() returned code " << ec << std::endl;
|
||||
#endif
|
||||
|
||||
for(int i = 0; i < nz; ++i) {
|
||||
|
||||
_H.coeffRef(r_ind_p[i], c_ind_p[i]) = val_p[i];
|
||||
}
|
||||
|
||||
delete[] r_ind_p;
|
||||
delete[] c_ind_p;
|
||||
delete[] val_p;
|
||||
|
||||
} else {
|
||||
|
||||
// Dense hessian data
|
||||
double** h_ptr = dense_hessian_ptr();
|
||||
|
||||
int ec = hessian(tape_, n_unknowns_, const_cast<double*>(_x), h_ptr);
|
||||
|
||||
if(ec < 0) {
|
||||
// Retape function if return code indicates discontinuity
|
||||
function_evaluated_ = false;
|
||||
#ifdef ADOLC_RET_CODES
|
||||
std::cout << __FUNCTION__ << " invokes retaping of function due to discontinuity! Return code: " << ec << std::endl;
|
||||
#endif
|
||||
eval_f(_x);
|
||||
ec = hessian(tape_, n_unknowns_, const_cast<double*>(_x), h_ptr);
|
||||
}
|
||||
|
||||
#ifdef ADOLC_RET_CODES
|
||||
std::cout << "Info: hessian() returned code " << ec << std::endl;
|
||||
#endif
|
||||
|
||||
for(int i = 0; i < n_unknowns_; ++i) {
|
||||
for(int j = 0; j <= i; ++j) {
|
||||
|
||||
_H.coeffRef(i, j) = h_ptr[i][j];
|
||||
|
||||
if(i != j) {
|
||||
_H.coeffRef(j, i) = h_ptr[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool use_tape() const {
|
||||
return use_tape_;
|
||||
}
|
||||
|
||||
/** \brief Use tape
|
||||
* Set this to false if the energy functional
|
||||
* is discontinuous (so that the operator tree
|
||||
* has to be re-established at each evaluation)
|
||||
*/
|
||||
void use_tape(bool _b) {
|
||||
use_tape_ = _b;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get sample point vector's address
|
||||
*
|
||||
* The objective function class allocates the
|
||||
* memory for this vector at construction.
|
||||
* Get the pointer to this vector and inject it
|
||||
* into the constraint classes in order to
|
||||
* prevent them from allocating their own vectors
|
||||
* (which can be inefficient in terms of memory
|
||||
* consumption in case there are many constraints)
|
||||
*/
|
||||
|
||||
boost::shared_array<adouble> x_d_ptr() {
|
||||
if(x_d_.get() == NULL) {
|
||||
x_d_.reset(new adouble[n_unknowns_]);
|
||||
}
|
||||
return x_d_;
|
||||
}
|
||||
|
||||
boost::shared_array<double> grad_ptr() {
|
||||
if(grad_.get() == NULL) {
|
||||
grad_.reset(new double[n_unknowns_]);
|
||||
}
|
||||
return grad_;
|
||||
}
|
||||
|
||||
double** dense_hessian_ptr() {
|
||||
if(dense_hessian_ == NULL) {
|
||||
dense_hessian_ = new double*[n_unknowns_];
|
||||
for(int i = 0; i < n_unknowns_; ++i) {
|
||||
dense_hessian_[i] = new double[i+1];
|
||||
}
|
||||
}
|
||||
return dense_hessian_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
int n_unknowns_;
|
||||
|
||||
// Shared data
|
||||
boost::shared_array<adouble> x_d_;
|
||||
|
||||
// Gradient vector
|
||||
boost::shared_array<double> grad_;
|
||||
|
||||
// Dense hessian
|
||||
double** dense_hessian_;
|
||||
|
||||
size_t tape_stats_[11];
|
||||
|
||||
bool function_evaluated_;
|
||||
bool use_tape_;
|
||||
|
||||
const short int tape_;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // COMISO_ADOLC_AVAILABLE
|
||||
//=============================================================================
|
||||
#endif // COMISO_EIGEN3_AVAILABLE
|
||||
//=============================================================================
|
||||
#endif /* NPROBLEMINTERFACEAD_HPP_ */
|
||||
122
src/external/CoMISo/NSolver/NewtonSolver.cc
vendored
Normal file
122
src/external/CoMISo/NSolver/NewtonSolver.cc
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS NewtonSolver - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "NewtonSolver.hh"
|
||||
#include <CoMISo/Solver/CholmodSolver.hh>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
// solve
|
||||
int
|
||||
NewtonSolver::
|
||||
solve(NProblemGmmInterface* _problem)
|
||||
{
|
||||
#if COMISO_SUITESPARSE_AVAILABLE
|
||||
|
||||
// get problem size
|
||||
int n = _problem->n_unknowns();
|
||||
|
||||
// hesse matrix
|
||||
NProblemGmmInterface::SMatrixNP H;
|
||||
// gradient
|
||||
std::vector<double> 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; i<max_iter_; ++i)
|
||||
{
|
||||
_problem->eval_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; j<n; ++j)
|
||||
H(j,j) += reg_comp;
|
||||
|
||||
// solve linear system
|
||||
bool factorization_ok = false;
|
||||
if(constant_hessian_structure_ && i != 0)
|
||||
factorization_ok = chol.update_system_gmm(H);
|
||||
else
|
||||
factorization_ok = chol.calc_system_gmm(H);
|
||||
|
||||
bool improvement = false;
|
||||
if(factorization_ok)
|
||||
if(chol.solve( dx, g))
|
||||
{
|
||||
gmm::add(x, gmm::scaled(dx,-1.0),x_new);
|
||||
double f_new = _problem->eval_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;
|
||||
|
||||
#else
|
||||
std::cerr << "Warning: NewtonSolver requires not-available CholmodSolver...\n";
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
80
src/external/CoMISo/NSolver/NewtonSolver.hh
vendored
Normal file
80
src/external/CoMISo/NSolver/NewtonSolver.hh
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS NewtonSolver
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_NEWTONSOLVER_HH
|
||||
#define COMISO_NEWTONSOLVER_HH
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include <gmm/gmm.h>
|
||||
#include "NProblemGmmInterface.hh"
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class NewtonSolver NewtonSolver.hh <ACG/.../NewtonSolver.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
class COMISODLLEXPORT NewtonSolver
|
||||
{
|
||||
public:
|
||||
|
||||
/// Default constructor
|
||||
NewtonSolver() : max_iter_(20), convergence_eps_(1e-6), constant_hessian_structure_(false) {}
|
||||
|
||||
/// Destructor
|
||||
~NewtonSolver() {}
|
||||
|
||||
// solve
|
||||
int solve(NProblemGmmInterface* _problem);
|
||||
|
||||
// solve specifying parameters
|
||||
int solve(NProblemGmmInterface* _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<double>& _v)
|
||||
{
|
||||
if( !_v.empty())
|
||||
return ((double*)&_v[0]);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
int max_iter_;
|
||||
double convergence_eps_;
|
||||
bool constant_hessian_structure_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // ACG_NEWTONSOLVER_HH defined
|
||||
//=============================================================================
|
||||
|
||||
27
src/external/CoMISo/NSolver/SuperSparseMatrixT.cc
vendored
Normal file
27
src/external/CoMISo/NSolver/SuperSparseMatrixT.cc
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS SuperSparseMatrixT - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define COMISO_SUPERSPARSEMATRIXT_C
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "SuperSparseMatrixT.hh"
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
201
src/external/CoMISo/NSolver/SuperSparseMatrixT.hh
vendored
Normal file
201
src/external/CoMISo/NSolver/SuperSparseMatrixT.hh
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS SuperSparseMatrixT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_SUPERSPARSEMATRIXT_HH
|
||||
#define COMISO_SUPERSPARSEMATRIXT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <math.h>
|
||||
#include <Eigen/Dense>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
|
||||
/** \class SuperSparseMatrixT SuperSparseMatrixT.hh <COMISO/.../SuperSparseMatrixT.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
|
||||
template <class VType>
|
||||
class SuperSparseMatrixT
|
||||
{
|
||||
public:
|
||||
|
||||
// value type
|
||||
typedef VType VT;
|
||||
typedef std::pair<unsigned int, unsigned int> PII;
|
||||
|
||||
// iterate over elements
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
|
||||
// default constructor
|
||||
iterator() {}
|
||||
// copy constructor
|
||||
iterator(const iterator& _it) { m_it_ = _it.m_it_; }
|
||||
// map iterator constructor
|
||||
iterator(const typename std::map<PII,VType>::iterator& _m_it) { m_it_ = _m_it; }
|
||||
|
||||
// get reference to data
|
||||
VT& operator*() { return m_it_->second; }
|
||||
|
||||
// get row and col of value
|
||||
unsigned int row() {return m_it_->first.first; }
|
||||
unsigned int col() {return m_it_->first.second; }
|
||||
|
||||
// post-increment
|
||||
iterator& operator++() { ++m_it_; return(*this);}
|
||||
iterator operator++(int) { return iterator(++m_it_); }
|
||||
|
||||
bool operator== (const iterator& _it) { return (m_it_ == _it.m_it_);}
|
||||
bool operator!= (const iterator& _it) { return (m_it_ != _it.m_it_);}
|
||||
|
||||
// get raw iterator of map
|
||||
typename std::map<PII,VType>::iterator& map_iterator() {return m_it_;}
|
||||
|
||||
private:
|
||||
typename std::map<PII,VType>::iterator m_it_;
|
||||
};
|
||||
|
||||
/// Constructor
|
||||
SuperSparseMatrixT(const int _n_rows = 0, const int _n_cols = 0)
|
||||
: n_rows_(_n_rows), n_cols_(_n_cols)
|
||||
{}
|
||||
|
||||
/// Destructor
|
||||
~SuperSparseMatrixT() {}
|
||||
|
||||
// iterate over non-zeros
|
||||
iterator begin() { return iterator(data_.begin()); }
|
||||
iterator end() { return iterator(data_.end()); }
|
||||
// erase element
|
||||
void erase( iterator _it) { data_.erase(_it.map_iterator()); }
|
||||
|
||||
// element access
|
||||
VT& operator()(const unsigned int _i, const unsigned int _j)
|
||||
{ return data_[PII(_i,_j)]; }
|
||||
|
||||
// const element access
|
||||
const VT& operator()(const unsigned int _i, const unsigned int _j) const
|
||||
{ return data_[PII(_i,_j)]; }
|
||||
|
||||
// get number of stored elements
|
||||
unsigned int nonZeros() { return data_.size(); }
|
||||
|
||||
// get dimensions
|
||||
unsigned int rows() const { return n_rows_;}
|
||||
unsigned int cols() const { return n_cols_;}
|
||||
|
||||
|
||||
// resize matrix -> delete invalid elements
|
||||
void resize(const unsigned int _n_rows, const unsigned int _n_cols)
|
||||
{
|
||||
n_rows_ = _n_rows;
|
||||
n_cols_ = _n_cols;
|
||||
|
||||
// delete out of range elements
|
||||
typename std::map<PII, VT>::iterator m_it = data_.begin();
|
||||
for(; m_it != data_.end();)
|
||||
{
|
||||
if(m_it->first.first >=n_rows_ || m_it->first.second >= n_cols_)
|
||||
data_.erase(m_it++);
|
||||
else
|
||||
++m_it;
|
||||
}
|
||||
}
|
||||
|
||||
// clear data
|
||||
void clear()
|
||||
{ data_.clear(); }
|
||||
|
||||
|
||||
// removes all values whose absolut value is smaller than _eps
|
||||
void prune(const VT _eps)
|
||||
{
|
||||
typename std::map<PII, VT>::iterator m_it = data_.begin();
|
||||
for(; m_it != data_.end();)
|
||||
{
|
||||
if(fabs(m_it->second) < _eps)
|
||||
data_.erase(m_it++);
|
||||
else
|
||||
++m_it;
|
||||
}
|
||||
}
|
||||
|
||||
// scale matrix by scalar
|
||||
void scale(const VT _s)
|
||||
{
|
||||
typename std::map<PII, VT>::iterator m_it = data_.begin();
|
||||
for(; m_it != data_.end(); ++m_it)
|
||||
m_it->second *=_s;
|
||||
}
|
||||
|
||||
void print()
|
||||
{
|
||||
iterator it = begin();
|
||||
iterator ite = end();
|
||||
|
||||
std::cerr << "######## SuperSparseMatrix ########" << std::endl;
|
||||
std::cerr << "dimension : " << rows() << " x " << cols() << std::endl;
|
||||
std::cerr << "#non-zeros: " << nonZeros() << std::endl;
|
||||
for(; it!=ite; ++it)
|
||||
std::cerr << "(" << it.row() << "," << it.col() << ") -> " << *it << std::endl;
|
||||
}
|
||||
|
||||
void print_eigenvalues()
|
||||
{
|
||||
Eigen::MatrixXd A = Eigen::MatrixXd::Zero(n_rows_, n_cols_);
|
||||
|
||||
iterator it = begin();
|
||||
for(; it != end(); ++it)
|
||||
A(it.row(),it.col()) = *it;
|
||||
|
||||
Eigen::EigenSolver<Eigen::MatrixXd> eigensolver(A);
|
||||
if (eigensolver.info() != Eigen::Success) abort();
|
||||
std::cout << "The eigenvalues of A are:\n" << eigensolver.eigenvalues() << std::endl;
|
||||
// std::cout << "Here's a matrix whose columns are eigenvectors of A \n"
|
||||
// << "corresponding to these eigenvalues:\n"
|
||||
// << eigensolver.eigenvectors() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// dimension of matrix
|
||||
unsigned int n_rows_;
|
||||
unsigned int n_cols_;
|
||||
|
||||
typename std::map<PII, VT> data_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#if defined(INCLUDE_TEMPLATES) && !defined(COMISO_SUPERSPARSEMATRIXT_C)
|
||||
#define COMISO_SUPERSPARSEMATRIXT_TEMPLATES
|
||||
#include "SuperSparseMatrixT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // COMISO_SUPERSPARSEMATRIXT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
999
src/external/CoMISo/NSolver/TAOSolver.cc
vendored
Normal file
999
src/external/CoMISo/NSolver/TAOSolver.cc
vendored
Normal file
@ -0,0 +1,999 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS TAOSolver - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_TAO_AVAILABLE
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "TAOSolver.hh"
|
||||
|
||||
//#include <dlfcn.h>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
// static member initialization
|
||||
bool TAOSolver::initialized_ = false;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// interface of TAO was changed from version 1 to 2 !!!
|
||||
#if (TAO_VERSION_MAJOR < 2)
|
||||
|
||||
int
|
||||
TAOSolver::
|
||||
solve( NProblemGmmInterface* _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::
|
||||
solve( NProblemInterface* _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, objective2, (void*) _base); CHKERRQ(info);
|
||||
info = TaoAppSetGradientRoutine (testapp, gradient2 , (void*) _base); CHKERRQ(info);
|
||||
info = TaoAppSetHessianRoutine (testapp, hessian2 , (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)
|
||||
{
|
||||
NProblemGmmInterface* base = (NProblemGmmInterface*) _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)
|
||||
{
|
||||
NProblemGmmInterface* base = (NProblemGmmInterface*) _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)
|
||||
{
|
||||
NProblemGmmInterface* base = (NProblemGmmInterface*) _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
|
||||
NProblemGmmInterface::SMatrixNP H;
|
||||
base->eval_hessian( x, H);
|
||||
|
||||
for (unsigned int i = 0; i < gmm::mat_nrows(H); ++i)
|
||||
{
|
||||
typedef gmm::linalg_traits<NProblemGmmInterface::SMatrixNP>::const_sub_row_type
|
||||
CRow;
|
||||
CRow row = gmm::mat_const_row(H, i);
|
||||
|
||||
gmm::linalg_traits<CRow>::const_iterator it = gmm::vect_const_begin(row);
|
||||
gmm::linalg_traits<CRow>::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;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
int
|
||||
TAOSolver::
|
||||
objective2( TAO_APPLICATION _app, Vec _x, double* _result, void* _base)
|
||||
{
|
||||
NProblemInterface* base = (NProblemInterface*) _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::
|
||||
gradient2(TAO_APPLICATION _app, Vec _x, Vec _g, void* _base)
|
||||
{
|
||||
NProblemInterface* base = (NProblemInterface*) _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::
|
||||
hessian2(TAO_APPLICATION _app, Vec _x, Mat* _H, Mat* _H_pre, MatStructure* _H_struct, void* _base)
|
||||
{
|
||||
NProblemInterface* base = (NProblemInterface*) _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
|
||||
NProblemInterface::SMatrixNP H;
|
||||
base->eval_hessian( x, H);
|
||||
|
||||
for(int i=0; i<H.outerSize(); ++i)
|
||||
{
|
||||
int m = 1;
|
||||
int n = 1;
|
||||
int idxm[1]; idxm[0] = i;
|
||||
int idxn[1];
|
||||
PetscScalar values[1];
|
||||
|
||||
for (NProblemInterface::SMatrixNP::InnerIterator it(H,i); it; ++it)
|
||||
{
|
||||
idxm[0] = it.row();
|
||||
idxn[0] = it.col();
|
||||
values[0] = it.value();
|
||||
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();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
#else // (TAO_VERSION_MAJOR < 2)
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
int
|
||||
TAOSolver::
|
||||
solve( NProblemGmmInterface* _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(PETSC_COMM_SELF,1,"Incorrect number of processors");
|
||||
}
|
||||
|
||||
/* Create TAO solver with desired solution method */
|
||||
TaoSolver tao; /* TaoSolver solver context */
|
||||
TaoCreate(PETSC_COMM_SELF,&tao);
|
||||
TaoSetType(tao,"tao_ntr");
|
||||
|
||||
/* 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);
|
||||
TaoSetInitialVector(tao,x);
|
||||
|
||||
/* Provide TAO routines for function evaluation */
|
||||
TaoSetObjectiveRoutine(tao, objective, (void*) _base);
|
||||
TaoSetGradientRoutine (tao, gradient , (void*) _base);
|
||||
TaoSetHessianRoutine (tao, H, H, hessian , (void*) _base);
|
||||
|
||||
/* SOLVE */
|
||||
TaoSolve(tao);
|
||||
|
||||
/* Get information on termination */
|
||||
TaoSolverTerminationReason reason;
|
||||
TaoGetTerminationReason(tao,&reason);
|
||||
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, PETSC_VIEWER_STDOUT_SELF); CHKERRQ(info);
|
||||
|
||||
// if successfull get and store result
|
||||
// if( reason)
|
||||
{
|
||||
TaoGetSolutionVector(tao, &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 */
|
||||
TaoDestroy(&tao);
|
||||
|
||||
/* Free PETSc data structures */
|
||||
VecDestroy(&x);
|
||||
MatDestroy(&H);
|
||||
|
||||
TaoFinalize();
|
||||
|
||||
return reason;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
int
|
||||
TAOSolver::
|
||||
solve( NProblemInterface* _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(PETSC_COMM_SELF,1,"Incorrect number of processors");
|
||||
}
|
||||
|
||||
/* Create TAO solver with desired solution method */
|
||||
TaoSolver tao; /* TaoSolver solver context */
|
||||
TaoCreate(PETSC_COMM_SELF,&tao);
|
||||
TaoSetType(tao,"tao_ntr");
|
||||
|
||||
/* 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);
|
||||
TaoSetInitialVector(tao,x);
|
||||
|
||||
/* Provide TAO routines for function evaluation */
|
||||
TaoSetObjectiveRoutine(tao, objective2, (void*) _base);
|
||||
TaoSetGradientRoutine (tao, gradient2 , (void*) _base);
|
||||
TaoSetHessianRoutine (tao, H, H, hessian2 , (void*) _base);
|
||||
|
||||
/* SOLVE */
|
||||
TaoSolve(tao);
|
||||
|
||||
/* Get information on termination */
|
||||
TaoSolverTerminationReason reason;
|
||||
TaoGetTerminationReason(tao,&reason);
|
||||
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, PETSC_VIEWER_STDOUT_SELF); CHKERRQ(info);
|
||||
|
||||
// if successfull get and store result
|
||||
// if( reason)
|
||||
{
|
||||
TaoGetSolutionVector(tao, &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 */
|
||||
TaoDestroy(&tao);
|
||||
|
||||
/* Free PETSc data structures */
|
||||
VecDestroy(&x);
|
||||
MatDestroy(&H);
|
||||
|
||||
TaoFinalize();
|
||||
|
||||
return reason;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
int
|
||||
TAOSolver::
|
||||
objective( TaoSolver _tao, Vec _x, double* _result, void* _base)
|
||||
{
|
||||
NProblemGmmInterface* base = (NProblemGmmInterface*) _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(TaoSolver _tao, Vec _x, Vec _g, void* _base)
|
||||
{
|
||||
NProblemGmmInterface* base = (NProblemGmmInterface*) _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(TaoSolver _tao, Vec _x, Mat* _H, Mat* _H_pre, MatStructure* _H_struct, void* _base)
|
||||
{
|
||||
NProblemGmmInterface* base = (NProblemGmmInterface*) _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
|
||||
NProblemGmmInterface::SMatrixNP H;
|
||||
base->eval_hessian( x, H);
|
||||
|
||||
for (unsigned int i = 0; i < gmm::mat_nrows(H); ++i)
|
||||
{
|
||||
typedef gmm::linalg_traits<NProblemGmmInterface::SMatrixNP>::const_sub_row_type
|
||||
CRow;
|
||||
CRow row = gmm::mat_const_row(H, i);
|
||||
|
||||
gmm::linalg_traits<CRow>::const_iterator it = gmm::vect_const_begin(row);
|
||||
gmm::linalg_traits<CRow>::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;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
int
|
||||
TAOSolver::
|
||||
objective2( TaoSolver _tao, Vec _x, double* _result, void* _base)
|
||||
{
|
||||
NProblemInterface* base = (NProblemInterface*) _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::
|
||||
gradient2(TaoSolver _tao, Vec _x, Vec _g, void* _base)
|
||||
{
|
||||
NProblemInterface* base = (NProblemInterface*) _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::
|
||||
hessian2(TaoSolver _tao, Vec _x, Mat* _H, Mat* _H_pre, MatStructure* _H_struct, void* _base)
|
||||
{
|
||||
NProblemInterface* base = (NProblemInterface*) _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
|
||||
NProblemInterface::SMatrixNP H;
|
||||
base->eval_hessian( x, H);
|
||||
|
||||
for(int i=0; i<H.outerSize(); ++i)
|
||||
{
|
||||
int m = 1;
|
||||
int n = 1;
|
||||
int idxm[1]; idxm[0] = i;
|
||||
int idxn[1];
|
||||
PetscScalar values[1];
|
||||
|
||||
for (NProblemInterface::SMatrixNP::InnerIterator it(H,i); it; ++it)
|
||||
{
|
||||
idxm[0] = it.row();
|
||||
idxn[0] = it.col();
|
||||
values[0] = it.value();
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // COMISO_TAO_AVAILABLE
|
||||
|
||||
98
src/external/CoMISo/NSolver/TAOSolver.hh
vendored
Normal file
98
src/external/CoMISo/NSolver/TAOSolver.hh
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS TAOSolver
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_TAOSOLVER_HH
|
||||
#define COMISO_TAOSOLVER_HH
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_TAO_AVAILABLE
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include "NProblemGmmInterface.hh"
|
||||
#include "NProblemInterface.hh"
|
||||
|
||||
#include <mpi.h>
|
||||
#include <tao.h>
|
||||
#include <gmm/gmm.h>
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class TAOSolver TAOSolver.hh <ACG/.../TAOSolver.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
class COMISODLLEXPORT TAOSolver
|
||||
{
|
||||
public:
|
||||
|
||||
/// Default constructor
|
||||
TAOSolver() {}
|
||||
|
||||
|
||||
/// Destructor
|
||||
~TAOSolver() {}
|
||||
|
||||
// solve problem
|
||||
static int solve( NProblemInterface* _base);
|
||||
static int solve( NProblemGmmInterface* _base);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
static void initialize();
|
||||
|
||||
// ToDo: cleanup has to be started automatically
|
||||
static void cleanup();
|
||||
|
||||
#if (TAO_VERSION_MAJOR < 2)
|
||||
// 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*);
|
||||
|
||||
static int objective2(TAO_APPLICATION,Vec,double*,void*);
|
||||
static int gradient2 (TAO_APPLICATION,Vec,Vec ,void*);
|
||||
static int hessian2 (TAO_APPLICATION,Vec,Mat*,Mat*,MatStructure*,void*);
|
||||
#else
|
||||
static PetscErrorCode objective(TaoSolver,Vec,double*,void*);
|
||||
static PetscErrorCode gradient (TaoSolver,Vec,Vec ,void*);
|
||||
static PetscErrorCode hessian (TaoSolver,Vec,Mat*,Mat*,MatStructure*,void*);
|
||||
|
||||
static PetscErrorCode objective2(TaoSolver,Vec,double*,void*);
|
||||
static PetscErrorCode gradient2 (TaoSolver,Vec,Vec ,void*);
|
||||
static PetscErrorCode hessian2 (TaoSolver,Vec,Mat*,Mat*,MatStructure*,void*);
|
||||
#endif
|
||||
|
||||
private:
|
||||
// initialized?
|
||||
static bool initialized_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
|
||||
//=============================================================================
|
||||
#endif // COMISO_TAO_AVAILABLE
|
||||
//=============================================================================
|
||||
#endif // ACG_TAOSOLVER_HH defined
|
||||
//=============================================================================
|
||||
|
||||
10
src/external/CoMISo/NSolver/TapeIDSingleton.cc
vendored
Normal file
10
src/external/CoMISo/NSolver/TapeIDSingleton.cc
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* TapeIDSingleton.cc
|
||||
*
|
||||
* Created on: Jan 4, 2013
|
||||
* Author: kremer
|
||||
*/
|
||||
|
||||
#include "TapeIDSingleton.hh"
|
||||
|
||||
TapeIDSingleton* TapeIDSingleton::reference_ = NULL;
|
||||
57
src/external/CoMISo/NSolver/TapeIDSingleton.hh
vendored
Normal file
57
src/external/CoMISo/NSolver/TapeIDSingleton.hh
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* TapeIDSingleton.hpp
|
||||
*
|
||||
* Created on: Jan 4, 2013
|
||||
* Author: kremer
|
||||
*/
|
||||
|
||||
#ifndef TAPEIDSINGLETON_HPP_
|
||||
#define TAPEIDSINGLETON_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
class TapeIDSingleton {
|
||||
public:
|
||||
static TapeIDSingleton* Instance() {
|
||||
|
||||
if(reference_ == NULL) {
|
||||
reference_ = new TapeIDSingleton();
|
||||
}
|
||||
return reference_;
|
||||
}
|
||||
|
||||
size_t requestId() {
|
||||
|
||||
// Test if previously requested id is available again
|
||||
const size_t n = ids_.size();
|
||||
for(size_t i = 0; i < n; ++i) {
|
||||
if(!ids_[i]) {
|
||||
ids_[i] = true;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// Request new id at the end of array
|
||||
size_t id = ids_.size();
|
||||
ids_.push_back(true);
|
||||
return id;
|
||||
}
|
||||
|
||||
void releaseId(const size_t _i) {
|
||||
|
||||
assert(_i < ids_.size());
|
||||
ids_[_i] = false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
TapeIDSingleton() {}
|
||||
TapeIDSingleton(const TapeIDSingleton&) {}
|
||||
~TapeIDSingleton() {}
|
||||
static TapeIDSingleton* reference_;
|
||||
std::vector<bool> ids_;
|
||||
};
|
||||
|
||||
#endif /* TAPEIDSINGLETON_HPP_ */
|
||||
86
src/external/CoMISo/NSolver/TestInterface.hh
vendored
Normal file
86
src/external/CoMISo/NSolver/TestInterface.hh
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS BaseTaoGmmInterface
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_TESTINTERFACE_HH
|
||||
#define COMISO_TESTINTERFACE_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "NProblemGmmInterface.hh"
|
||||
#include <gmm/gmm.h>
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class BaseTaoGmmInterface BaseTaoGmmInterface.hh <ACG/.../BaseTaoGmmInterface.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
|
||||
class COMISODLLEXPORT TestInterface : public NProblemGmmInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/// Default constructor
|
||||
TestInterface() {}
|
||||
|
||||
/// Destructor
|
||||
~TestInterface() {}
|
||||
|
||||
// minimize (x-2.4)^2
|
||||
|
||||
virtual int n_unknowns ( )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void initial_x ( double* _x )
|
||||
{
|
||||
_x[0] = 100;
|
||||
}
|
||||
|
||||
virtual double eval_f ( const double* _x )
|
||||
{
|
||||
return (_x[0]-2.4)*(_x[0]-2.4);
|
||||
}
|
||||
|
||||
virtual void eval_gradient( const double* _x, double* _g)
|
||||
{
|
||||
_g[0] = 2.0*(_x[0]-2.4);
|
||||
}
|
||||
|
||||
virtual void eval_hessian( const double* _x, SMatrixNP& _H)
|
||||
{
|
||||
gmm::resize(_H,1,1);
|
||||
_H(0,0) = 2.0;
|
||||
}
|
||||
|
||||
virtual void store_result ( const double* _x )
|
||||
{
|
||||
std::cerr << "result: " << _x[0] << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // COMISO_TESTINTERFACE_HH defined
|
||||
//=============================================================================
|
||||
|
||||
34
src/external/CoMISo/NSolver/VariableType.hh
vendored
Normal file
34
src/external/CoMISo/NSolver/VariableType.hh
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// ENUM VariableType
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_VARIABLETYPE_HH
|
||||
#define COMISO_VARIABLETYPE_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
enum VariableType { Real, Integer, Binary};
|
||||
|
||||
typedef std::pair<unsigned int, VariableType> PairIndexVtype;
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // COMISO_VARIABLETYPE_HH defined
|
||||
//=============================================================================
|
||||
|
||||
156
src/external/CoMISo/QtWidgets/MISolverDialogUI.cc
vendored
Normal file
156
src/external/CoMISo/QtWidgets/MISolverDialogUI.cc
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS MISolverDialog - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <CoMISo/Config/config.hh>
|
||||
|
||||
//== BUILD-TIME DEPENDENCIES =================================================================
|
||||
#if(COMISO_QT4_AVAILABLE)
|
||||
//============================================================================================
|
||||
|
||||
|
||||
#include "MISolverDialogUI.hh"
|
||||
|
||||
#include <QtGui>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
MISolverDialog::
|
||||
get_parameters()
|
||||
{
|
||||
// QDoubleSpinBox *localErrorDSB;
|
||||
// QSpinBox *localItersSB;
|
||||
// QDoubleSpinBox *cgErrorDSB;
|
||||
// QSpinBox *cgItersSB;
|
||||
// QDoubleSpinBox *taucsErrorDSB;
|
||||
// QCheckBox *finalTaucsCB;
|
||||
// QCheckBox *initialTaucsCB;
|
||||
// QSpinBox *infoSB;
|
||||
// QCheckBox *directRoundingCB;
|
||||
|
||||
initialFullCB ->setChecked( misolver_.get_inital_full());
|
||||
iterFullCB ->setChecked( misolver_.get_iter_full());
|
||||
finalFullCB ->setChecked( misolver_.get_final_full());
|
||||
directRoundingCB ->setChecked( misolver_.get_direct_rounding());
|
||||
noRoundingCB ->setChecked( misolver_.get_no_rounding());
|
||||
multipleRoundingCB->setChecked( misolver_.get_multiple_rounding());
|
||||
gurobiRoundingCB ->setChecked( misolver_.get_gurobi_rounding());
|
||||
cplexRoundingCB ->setChecked( misolver_.get_cplex_rounding());
|
||||
|
||||
localItersSB ->setValue( misolver_.get_local_iters());
|
||||
localErrorDSB->setValue( log(misolver_.get_local_error())/log(10.0f));
|
||||
|
||||
cgItersSB ->setValue( misolver_.get_cg_iters());
|
||||
cgErrorDSB->setValue( log(misolver_.get_cg_error())/log(10.0f));
|
||||
gurobiMaxTimeDSB->setValue(misolver_.get_gurobi_max_time());
|
||||
|
||||
multipleRoundingDSB->setValue( misolver_.get_multiple_rounding_threshold());
|
||||
|
||||
infoSB->setValue( misolver_.get_noise());
|
||||
solverStatsCheckBox->setChecked( misolver_.get_stats( ));
|
||||
|
||||
use_reordering_cb->setChecked( misolver_.use_constraint_reordering() );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
MISolverDialog::
|
||||
set_parameters()
|
||||
{
|
||||
misolver_.set_inital_full ( initialFullCB ->isChecked() );
|
||||
misolver_.set_iter_full ( iterFullCB ->isChecked() );
|
||||
misolver_.set_final_full ( finalFullCB ->isChecked() );
|
||||
misolver_.set_direct_rounding( directRoundingCB->isChecked());
|
||||
misolver_.set_no_rounding( noRoundingCB->isChecked());
|
||||
misolver_.set_multiple_rounding( multipleRoundingCB->isChecked());
|
||||
misolver_.set_gurobi_rounding( gurobiRoundingCB->isChecked());
|
||||
misolver_.set_cplex_rounding ( cplexRoundingCB->isChecked());
|
||||
|
||||
misolver_.set_local_iters( localItersSB ->value());
|
||||
misolver_.set_local_error( pow(10, localErrorDSB->value()));
|
||||
|
||||
misolver_.set_cg_iters( cgItersSB ->value());
|
||||
misolver_.set_cg_error( pow(10, cgErrorDSB->value()));
|
||||
|
||||
misolver_.set_gurobi_max_time(gurobiMaxTimeDSB->value());
|
||||
|
||||
misolver_.set_multiple_rounding_threshold( multipleRoundingDSB->value());
|
||||
|
||||
misolver_.set_noise( infoSB->value());
|
||||
misolver_.set_stats( solverStatsCheckBox->isChecked());
|
||||
|
||||
misolver_.use_constraint_reordering() = use_reordering_cb->isChecked();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
MISolverDialog::
|
||||
slotOkButton()
|
||||
{
|
||||
set_parameters();
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
MISolverDialog::
|
||||
slotCancelButton()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//== BUILD-TIME DEPENDENCIES ==================================================
|
||||
#endif
|
||||
//=============================================================================
|
||||
113
src/external/CoMISo/QtWidgets/MISolverDialogUI.hh
vendored
Normal file
113
src/external/CoMISo/QtWidgets/MISolverDialogUI.hh
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS MiSolverDialog
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_MISOLVERDIALOG_HH
|
||||
#define COMISO_MISOLVERDIALOG_HH
|
||||
|
||||
|
||||
#include <CoMISo/Config/config.hh>
|
||||
|
||||
//== BUILD-TIME DEPENDENCIES =================================================================
|
||||
#if(COMISO_QT4_AVAILABLE)
|
||||
//============================================================================================
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "ui_QtMISolverDialogBaseUI.hh"
|
||||
|
||||
// ACGMake users have to include
|
||||
// #include "QtMISolverDialogBase.hh"
|
||||
|
||||
|
||||
#include <Solver/MISolver.hh>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO
|
||||
{
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class MISolverDialog MISolverDialog.hh <COMISO/.../MISolverDialog.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
class MISolverDialog
|
||||
: public QDialog, public Ui::QtMISolverDialogBaseUI
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
/// Default constructor
|
||||
MISolverDialog( MISolver& _misolver,
|
||||
QWidget* _parent = 0 ):
|
||||
QDialog( _parent ),
|
||||
Ui::QtMISolverDialogBaseUI(),
|
||||
misolver_( _misolver )
|
||||
{
|
||||
setupUi( this );
|
||||
get_parameters();
|
||||
|
||||
connect( okPB, SIGNAL( clicked() ), this, SLOT( slotOkButton() ) );
|
||||
connect( cancelPB, SIGNAL( clicked() ), this, SLOT( slotCancelButton() ) );
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
~MISolverDialog() {}
|
||||
|
||||
void get_parameters();
|
||||
void set_parameters();
|
||||
|
||||
|
||||
public slots:
|
||||
virtual void slotOkButton();
|
||||
virtual void slotCancelButton();
|
||||
|
||||
private:
|
||||
|
||||
MISolver& misolver_;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#endif // COMISO_MISOLVERDIALOG_HH defined
|
||||
//=============================================================================
|
||||
|
||||
#endif
|
||||
331
src/external/CoMISo/QtWidgets/QtMISolverDialogBaseUI.ui
vendored
Normal file
331
src/external/CoMISo/QtWidgets/QtMISolverDialogBaseUI.ui
vendored
Normal file
@ -0,0 +1,331 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QtMISolverDialogBaseUI</class>
|
||||
<widget class="QDialog" name="QtMISolverDialogBaseUI">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>385</width>
|
||||
<height>273</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="8" column="1">
|
||||
<widget class="QCheckBox" name="cplexRoundingCB">
|
||||
<property name="text">
|
||||
<string>use cplex</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Max Error (1e-x)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Iterations</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Local</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="localErrorDSB">
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-1000000000.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000000000.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>6.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QSpinBox" name="localItersSB">
|
||||
<property name="maximum">
|
||||
<number>1000000000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CG</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="cgErrorDSB">
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-1000000000.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000000000.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>6.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QSpinBox" name="cgItersSB">
|
||||
<property name="maximum">
|
||||
<number>1000000000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Full</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="initialFullCB">
|
||||
<property name="text">
|
||||
<string>initial</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="iterFullCB">
|
||||
<property name="text">
|
||||
<string>iter not converged</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="finalFullCB">
|
||||
<property name="text">
|
||||
<string>final</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Rounding</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="directRoundingCB">
|
||||
<property name="text">
|
||||
<string>direct</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="noRoundingCB">
|
||||
<property name="text">
|
||||
<string>no</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="multipleRoundingCB">
|
||||
<property name="text">
|
||||
<string>multiple</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="multipleRoundingDSB">
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Info Level</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="infoSB"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="solverStatsCheckBox">
|
||||
<property name="text">
|
||||
<string>Output solver statistics</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Constraints</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QCheckBox" name="use_reordering_cb">
|
||||
<property name="text">
|
||||
<string>reordering</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>GUROBI</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QCheckBox" name="gurobiRoundingCB">
|
||||
<property name="text">
|
||||
<string>use gurobi</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QDoubleSpinBox" name="gurobiMaxTimeDSB">
|
||||
<property name="maximum">
|
||||
<double>999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>60.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="3">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>s</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="okPB">
|
||||
<property name="text">
|
||||
<string>Ok</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelPB">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>14</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
63
src/external/CoMISo/README.txt
vendored
Normal file
63
src/external/CoMISo/README.txt
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
CoMISo Version 1.0 rc1
|
||||
www.rwth-graphics.de
|
||||
zimmer@informatik.rwth-aachen.de
|
||||
bommes@informatik.rwth-aachen.de
|
||||
|
||||
Update! Version 1.1
|
||||
-------------------
|
||||
For the CoMISo to work only Eigen3 and GMM++ are needed.
|
||||
|
||||
What is
|
||||
-------
|
||||
This is a short readme file to get you started with the Constrained Mixed-Integer Solver (CoMISo). It shortly overviews the system prerequisites and explains how to build the package. See the examples and the HarmonicExample OpenFlipper plugin for usage examples and ideas.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
Here is an example of what packages were needed to compile CoMISo on a freshly installed Ubuntu 9.04 system
|
||||
# sudo apt-get install g++
|
||||
# sudo apt-get install cmake
|
||||
# sudo apt-get install libgmm-dev
|
||||
# sudo apt-get install libboost-dev
|
||||
# sudo apt-get install libblas-dev
|
||||
# sudo apt-get install libsuitesparse-dev
|
||||
(some other needed libraries such as lapack, are installed as dependencies of the above)
|
||||
|
||||
For Windows and Macintosh systems the corresponding packages need to be downloaded and installed.
|
||||
|
||||
The cmake build system should enable building the CoMISo library under Windows and Macintosh systems, please let me know if this is (not) the case!
|
||||
|
||||
OpenFlipper requirements:
|
||||
-------------------------
|
||||
To build OpenFlipper you additionally need to install all the Qt4 packages libqt4-{dev-dbg, dev, network, gui, opengl, opengl-dev, script, scripttools, ...} and also
|
||||
# sudo apt-get install libglew1.5-dev
|
||||
# sudo apt-get install glutg3-dev
|
||||
|
||||
Building (Stand alone)
|
||||
----------------------
|
||||
Assuming CoMISo was unpacked to the directory SOME_DIRECTORY/CoMISo (where SOME_DIRECTORY should be /PATH_TO_OPENFLIPPER/libs/CoMISo for integration with the OpenFlipper framework) the package is built by creating a build directory, using cmake to create the Makefiles and using make to actually build:
|
||||
|
||||
# cd /SOME_DIRECTORY/CoMISo/
|
||||
# mkdir build
|
||||
# cd build
|
||||
# cmake ..
|
||||
(assuming all needed packages are installed and cmake threw no errors...)
|
||||
# make
|
||||
|
||||
The binaries (examples) and the shared library are found under
|
||||
/SOME_DIRECTORY/CoMISO/build/Build/bin/
|
||||
and
|
||||
/SOME_DIRECTORY/CoMISO/build/Build/lib/CoMISo/
|
||||
|
||||
|
||||
Building (For use with OpenFlipper)
|
||||
-----------------------------------
|
||||
Simply extract/checkout the CoMISo directory to the /PATH_TO_OPENFLIPPER/libs/ directory. The library will be automatically built and you will find the shared library libCoMISo.so under the OpenFlipper build directory.
|
||||
To use the solver in your Plugin add CoMISo to the CMakeLists.txt of the plugin and you are set, see Plugin-HarmonicExample for an example.
|
||||
|
||||
Using
|
||||
-----
|
||||
To use the solver library in your applications have a look at the /SOME_DIRECTORY/CoMISo/Examples/ and the sample OpenFlipper plugin (Plugin-HarmonicExample) downloadable from the CoMISo project homepage.
|
||||
|
||||
Feedback
|
||||
--------
|
||||
We appreciate your feedback! Bugs, comments, questions or patches send them to zimmer@informatik.rwth-aachen.de or bommes@informatik.rwth-aachen.de !
|
||||
262
src/external/CoMISo/Solver/CholmodSolver.cc
vendored
Normal file
262
src/external/CoMISo/Solver/CholmodSolver.cc
vendored
Normal file
@ -0,0 +1,262 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_SUITESPARSE_AVAILABLE
|
||||
//=============================================================================
|
||||
|
||||
#include "CholmodSolver.hh"
|
||||
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
CholmodSolver::CholmodSolver()
|
||||
{
|
||||
mp_cholmodCommon = new cholmod_common;
|
||||
cholmod_start( mp_cholmodCommon );
|
||||
|
||||
mp_L = 0;
|
||||
|
||||
show_timings_ = false;
|
||||
|
||||
mp_cholmodCommon->nmethods = 1;
|
||||
// use AMD ordering
|
||||
mp_cholmodCommon->method[0].ordering = CHOLMOD_AMD ;
|
||||
|
||||
// use METIS ordering
|
||||
// mp_cholmodCommon->method[0].ordering = CHOLMOD_METIS ;
|
||||
|
||||
// try all methods
|
||||
// mp_cholmodCommon->nmethods = 9;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
CholmodSolver::~CholmodSolver()
|
||||
{
|
||||
if( mp_L )
|
||||
{
|
||||
cholmod_free_factor( &mp_L, mp_cholmodCommon );
|
||||
}
|
||||
|
||||
cholmod_finish( mp_cholmodCommon );
|
||||
delete mp_cholmodCommon;
|
||||
mp_cholmodCommon = NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool CholmodSolver::calc_system( const std::vector<int>& _colptr,
|
||||
const std::vector<int>& _rowind,
|
||||
const std::vector<double>& _values)
|
||||
{
|
||||
if(show_timings_) sw_.start();
|
||||
|
||||
colptr_ = _colptr;
|
||||
rowind_ = _rowind;
|
||||
values_ = _values;
|
||||
|
||||
int n = colptr_.size()-1;
|
||||
|
||||
cholmod_sparse matA;
|
||||
|
||||
matA.nrow = n;
|
||||
matA.ncol = n;
|
||||
matA.nzmax = _values.size();
|
||||
|
||||
matA.p = &colptr_[0];
|
||||
matA.i = &rowind_[0];
|
||||
matA.x = &values_[0];
|
||||
matA.nz = 0;
|
||||
matA.z = 0;
|
||||
|
||||
// matA.stype = -1;
|
||||
matA.stype = 1;
|
||||
matA.itype = CHOLMOD_INT;
|
||||
matA.xtype = CHOLMOD_REAL;
|
||||
matA.dtype = CHOLMOD_DOUBLE;
|
||||
matA.sorted = 1;
|
||||
matA.packed = 1;
|
||||
|
||||
|
||||
// clean up
|
||||
if( mp_L )
|
||||
{
|
||||
cholmod_free_factor( &mp_L, mp_cholmodCommon );
|
||||
mp_L = 0;
|
||||
}
|
||||
|
||||
if(show_timings_)
|
||||
{
|
||||
std::cerr << " Cholmod Timing cleanup: " << sw_.stop()/1000.0 << "s\n";
|
||||
sw_.start();
|
||||
}
|
||||
|
||||
if( !(mp_L = cholmod_analyze( &matA, mp_cholmodCommon )) )
|
||||
{
|
||||
std::cout << "cholmod_analyze failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// // show selected ordering method
|
||||
// std::cerr << "best ordering was: " << mp_cholmodCommon->selected << std::endl;
|
||||
// std::cerr << "current ordering was: " << mp_cholmodCommon->current << std::endl;
|
||||
|
||||
|
||||
if(show_timings_)
|
||||
{
|
||||
std::cerr << " Cholmod Timing analyze: " << sw_.stop()/1000.0 << "s\n";
|
||||
sw_.start();
|
||||
}
|
||||
|
||||
if( !cholmod_factorize( &matA, mp_L, mp_cholmodCommon ) )
|
||||
{
|
||||
std::cout << "cholmod_factorize failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(show_timings_)
|
||||
{
|
||||
std::cerr << " Cholmod Timing factorize: " << sw_.stop()/1000.0 << "s\n";
|
||||
sw_.start();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool CholmodSolver::update_system( const std::vector<int>& _colptr,
|
||||
const std::vector<int>& _rowind,
|
||||
const std::vector<double>& _values )
|
||||
{
|
||||
if( !mp_L )
|
||||
return false;
|
||||
|
||||
colptr_ = _colptr;
|
||||
rowind_ = _rowind;
|
||||
values_ = _values;
|
||||
int n = colptr_.size()-1;
|
||||
|
||||
cholmod_sparse matA;
|
||||
|
||||
matA.nrow = n;
|
||||
matA.ncol = n;
|
||||
matA.nzmax = _values.size();
|
||||
|
||||
matA.p = &colptr_[0];
|
||||
matA.i = &rowind_[0];
|
||||
matA.x = &values_[0];
|
||||
matA.nz = 0;
|
||||
matA.z = 0;
|
||||
|
||||
// matA.stype = -1;
|
||||
matA.stype = 1;
|
||||
matA.itype = CHOLMOD_INT;
|
||||
matA.xtype = CHOLMOD_REAL;
|
||||
matA.dtype = CHOLMOD_DOUBLE;
|
||||
matA.sorted = 1;
|
||||
matA.packed = 1;
|
||||
|
||||
|
||||
if( !cholmod_factorize( &matA, mp_L, mp_cholmodCommon ) )
|
||||
{
|
||||
std::cout << "cholmod_factorize failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool CholmodSolver::solve( double * _x, double * _b)
|
||||
{
|
||||
const unsigned int n = colptr_.size() - 1;
|
||||
|
||||
cholmod_dense *x, b;
|
||||
|
||||
|
||||
b.nrow = n;
|
||||
b.ncol = 1;
|
||||
b.nzmax = n;
|
||||
b.d = b.nrow;
|
||||
b.x = _b;
|
||||
b.z = 0;
|
||||
b.xtype = CHOLMOD_REAL;
|
||||
b.dtype = CHOLMOD_DOUBLE;
|
||||
|
||||
if( !(x = cholmod_solve( CHOLMOD_A, mp_L, &b, mp_cholmodCommon )) )
|
||||
{
|
||||
std::cout << "cholmod_solve failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
for( unsigned int i = 0; i < n; ++i )
|
||||
_x[i] = ((double*)x->x)[i];
|
||||
|
||||
cholmod_free_dense( &x, mp_cholmodCommon );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int CholmodSolver::dimension()
|
||||
{
|
||||
return std::max(int(0), (int)(colptr_.size()-1));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool CholmodSolver::
|
||||
solve ( std::vector<double>& _x0, std::vector<double>& _b)
|
||||
{
|
||||
return solve( &(_x0[0]), &(_b[0]));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool& CholmodSolver::
|
||||
show_timings()
|
||||
{
|
||||
return show_timings_;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
#endif // COMISO_SUITESPARSE_AVAILABLE
|
||||
//=============================================================================
|
||||
124
src/external/CoMISo/Solver/CholmodSolver.hh
vendored
Normal file
124
src/external/CoMISo/Solver/CholmodSolver.hh
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS CholmodSolver
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef COMISO_CHOLMOD_SOLVER_HH
|
||||
#define COMISO_CHOLMOD_SOLVER_HH
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_SUITESPARSE_AVAILABLE
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "cholmod.h"
|
||||
|
||||
// typedef struct cholmod_common_struct cholmod_common;
|
||||
// typedef struct cholmod_factor_struct cholmod_factor;
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
class COMISODLLEXPORT CholmodSolver
|
||||
{
|
||||
public:
|
||||
|
||||
// _size is maximal size this instance can handle (smaller problems are possible!!!)
|
||||
CholmodSolver();
|
||||
~CholmodSolver();
|
||||
|
||||
bool calc_system( const std::vector<int>& _colptr,
|
||||
const std::vector<int>& _rowind,
|
||||
const std::vector<double>& _values );
|
||||
|
||||
|
||||
template< class GMM_MatrixT>
|
||||
bool calc_system_gmm( const GMM_MatrixT& _mat);
|
||||
|
||||
template< class Eigen_MatrixT>
|
||||
bool calc_system_eigen( const Eigen_MatrixT& _mat);
|
||||
|
||||
|
||||
bool update_system( const std::vector<int>& _colptr,
|
||||
const std::vector<int>& _rowind,
|
||||
const std::vector<double>& _values );
|
||||
|
||||
|
||||
template< class GMM_MatrixT>
|
||||
bool update_system_gmm( const GMM_MatrixT& _mat);
|
||||
|
||||
template< class Eigen_MatrixT>
|
||||
bool update_system_eigen( const Eigen_MatrixT& _mat);
|
||||
|
||||
|
||||
bool solve ( double * _x0, double * _b);
|
||||
|
||||
bool solve ( std::vector<double>& _x0, std::vector<double>& _b);
|
||||
|
||||
bool& show_timings();
|
||||
|
||||
int dimension();
|
||||
|
||||
private:
|
||||
|
||||
cholmod_common * mp_cholmodCommon;
|
||||
|
||||
cholmod_factor * mp_L;
|
||||
|
||||
std::vector<double> values_;
|
||||
std::vector<int> colptr_;
|
||||
std::vector<int> rowind_;
|
||||
|
||||
bool show_timings_;
|
||||
StopWatch sw_;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#if defined(INCLUDE_TEMPLATES) && !defined(COMISO_CHOLMOD_SOLVER_TEMPLATES_C)
|
||||
#define COMISO_CHOLMOD_SOLVER_TEMPLATES
|
||||
#include "CholmodSolverT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // COMISO_SUITESPARSE_AVAILABLE
|
||||
//=============================================================================
|
||||
#endif // COMISO_CHOLMOD_SOLVER_HH defined
|
||||
//=============================================================================
|
||||
131
src/external/CoMISo/Solver/CholmodSolverT.cc
vendored
Normal file
131
src/external/CoMISo/Solver/CholmodSolverT.cc
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_SUITESPARSE_AVAILABLE
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#define COMISO_CHOLMOD_SOLVER_TEMPLATES_C
|
||||
|
||||
#include <CoMISo/Solver/GMM_Tools.hh>
|
||||
#include <CoMISo/Solver/Eigen_Tools.hh>
|
||||
#include <CoMISo/Solver/CholmodSolver.hh>
|
||||
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
|
||||
template< class GMM_MatrixT>
|
||||
bool CholmodSolver::calc_system_gmm( const GMM_MatrixT& _mat)
|
||||
{
|
||||
// std::vector<int> colptr;
|
||||
// std::vector<int> rowind;
|
||||
// std::vector<double> values;
|
||||
|
||||
|
||||
if(show_timings_) sw_.start();
|
||||
|
||||
COMISO_GMM::get_ccs_symmetric_data( _mat,
|
||||
'u',
|
||||
values_,
|
||||
rowind_,
|
||||
colptr_ );
|
||||
|
||||
if(show_timings_)
|
||||
{
|
||||
std::cerr << "Cholmod Timing GMM convert: " << sw_.stop()/1000.0 << "s\n";
|
||||
std::cerr << "#nnz: " << values_.size() << std::endl;
|
||||
}
|
||||
|
||||
return calc_system( colptr_, rowind_, values_);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template< class GMM_MatrixT>
|
||||
bool CholmodSolver::update_system_gmm( const GMM_MatrixT& _mat)
|
||||
{
|
||||
// std::vector<int> colptr;
|
||||
// std::vector<int> rowind;
|
||||
// std::vector<double> values;
|
||||
|
||||
COMISO_GMM::get_ccs_symmetric_data( _mat,
|
||||
'u',
|
||||
values_,
|
||||
rowind_,
|
||||
colptr_ );
|
||||
|
||||
return update_system( colptr_, rowind_, values_);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class Eigen_MatrixT>
|
||||
bool CholmodSolver::calc_system_eigen( const Eigen_MatrixT& _mat)
|
||||
{
|
||||
if(show_timings_) sw_.start();
|
||||
|
||||
#if COMISO_EIGEN3_AVAILABLE
|
||||
COMISO_EIGEN::get_ccs_symmetric_data( _mat,
|
||||
'u',
|
||||
values_,
|
||||
rowind_,
|
||||
colptr_ );
|
||||
#endif
|
||||
|
||||
if(show_timings_)
|
||||
{
|
||||
std::cerr << "Cholmod Timing EIGEN convert: " << sw_.stop()/1000.0 << "s\n";
|
||||
std::cerr << "#nnz: " << values_.size() << std::endl;
|
||||
}
|
||||
|
||||
return calc_system( colptr_, rowind_, values_);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class Eigen_MatrixT>
|
||||
bool CholmodSolver::update_system_eigen( const Eigen_MatrixT& _mat)
|
||||
{
|
||||
#if COMISO_EIGEN3_AVAILABLE
|
||||
COMISO_EIGEN::get_ccs_symmetric_data( _mat,
|
||||
'u',
|
||||
values_,
|
||||
rowind_,
|
||||
colptr_ );
|
||||
#endif
|
||||
return update_system( colptr_, rowind_, values_);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
#endif // COMISO_SUITESPARSE_AVAILABLE
|
||||
//=============================================================================
|
||||
118
src/external/CoMISo/Solver/ConstrainedSolver.cc
vendored
Normal file
118
src/external/CoMISo/Solver/ConstrainedSolver.cc
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#include "ConstrainedSolver.hh"
|
||||
|
||||
#include <gmm/gmm.h>
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int
|
||||
ConstrainedSolver::
|
||||
find_gcd(std::vector<int>& _v_gcd, int& _n_ints)
|
||||
{
|
||||
bool found_gcd = false;
|
||||
bool done = false;
|
||||
bool all_same = true;
|
||||
int i_gcd = -1;
|
||||
int prev_val = -1;
|
||||
// check integer coefficient pairwise
|
||||
while( !done)
|
||||
{
|
||||
// assume gcd of all pairs is the same
|
||||
all_same = true;
|
||||
for( int k=0; k<_n_ints-1 && !done; ++k)
|
||||
{
|
||||
// use abs(.) to get same sign needed for all_same
|
||||
_v_gcd[k] = abs(gcd(_v_gcd[k],_v_gcd[k+1]));
|
||||
|
||||
if( k>0 && prev_val != _v_gcd[k])
|
||||
all_same = false;
|
||||
|
||||
prev_val = _v_gcd[k];
|
||||
|
||||
// if a 2 was found, all other entries have to be divisible by 2
|
||||
if(_v_gcd[k] == 2)
|
||||
{
|
||||
bool all_ok=true;
|
||||
for( int l=0; l<_n_ints; ++l)
|
||||
if( abs(_v_gcd[l]%2) != 0)
|
||||
{
|
||||
all_ok = false;
|
||||
break;
|
||||
}
|
||||
done = true;
|
||||
if( all_ok )
|
||||
{
|
||||
found_gcd = true;
|
||||
i_gcd = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
found_gcd = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// already done (by successfull "2"-test)?
|
||||
if(!done)
|
||||
{
|
||||
// all gcds the same?
|
||||
// we just need to check one final gcd between first 2 elements
|
||||
if( all_same && _n_ints >1)
|
||||
{
|
||||
_v_gcd[0] = abs(gcd(_v_gcd[0],_v_gcd[1]));
|
||||
// we are done
|
||||
_n_ints = 1;
|
||||
}
|
||||
|
||||
// only one value left, either +-1 or gcd
|
||||
if( _n_ints == 1)
|
||||
{
|
||||
done = true;
|
||||
if( (_v_gcd[0])*(_v_gcd[0]) == 1)
|
||||
{
|
||||
found_gcd = false;
|
||||
//std::cerr << __FUNCTION__ << " Info: No gcd found!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
i_gcd = _v_gcd[0];
|
||||
found_gcd = true;
|
||||
//std::cerr << __FUNCTION__ << " Info: Found gcd = " << i_gcd << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
// we now have n_ints-1 gcds to check next iteration
|
||||
--_n_ints;
|
||||
}
|
||||
return i_gcd;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
463
src/external/CoMISo/Solver/ConstrainedSolver.hh
vendored
Normal file
463
src/external/CoMISo/Solver/ConstrainedSolver.hh
vendored
Normal file
@ -0,0 +1,463 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS ConstrainedSolver
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_CONSTRAINEDSOLVER_HH
|
||||
#define COMISO_CONSTRAINEDSOLVER_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
|
||||
#include "GMM_Tools.hh"
|
||||
#include "MISolver.hh"
|
||||
#include <vector>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== DEFINES ==================================================================
|
||||
#define ROUND(x) ((x)<0?int((x)-0.5):int((x)+0.5))
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/** \class ConstrainedSolver ConstrainedSolver.hh <ACG/.../ConstrainedSolver.hh>
|
||||
|
||||
Takes a linear (symmetric) system of equations and a set of linear constraints and solves it.
|
||||
*/
|
||||
|
||||
class COMISODLLEXPORT ConstrainedSolver
|
||||
{
|
||||
public:
|
||||
typedef gmm::csc_matrix<double> CSCMatrix;
|
||||
typedef gmm::row_matrix< gmm::wsvector< double > > RowMatrix;
|
||||
|
||||
|
||||
/// default Constructor
|
||||
/** _do_gcd specifies if a greatest common devisor correction should be used when no (+-)1-coefficient is found*/
|
||||
ConstrainedSolver( bool _do_gcd = true): do_gcd_(_do_gcd)
|
||||
{ epsilon_ = 1e-8; noisy_ = 1; }
|
||||
|
||||
/// Destructor
|
||||
~ConstrainedSolver() { }
|
||||
|
||||
/** @name Contrained solvers
|
||||
* Functions to solve constrained linear systems of the form Ax=b (stemming from quadratic energies).
|
||||
* The constraints can be linear constraints of the form \f$ x_1*c_1+ \cdots +x_n*c_n=c \f$ as well as integer constraints \f$x_i\in \mathbf{Z}\f$.
|
||||
* The system is then solved with these constraints in mind. For solving the system the Mixed-Integer Solver \a MISolver is used.
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/// Quadratic matrix constrained solver
|
||||
/**
|
||||
* Takes a system of the form Ax=b, a constraint matrix C and a set of variables _to_round to be rounded to integers. \f$ A\in \mathbf{R}^{n\times n}\f$
|
||||
* @param _constraints row matrix with rows of the form \f$ [ c_1, c_2, \cdots, c_n, c_{n+1} ] \f$ corresponding to the linear equation \f$ c_1*x_1+\cdots+c_n*x_n + c_{n+1}=0 \f$.
|
||||
* @param _A nxn-dimensional column matrix of the system
|
||||
* @param _x n-dimensional variable vector
|
||||
* @param _rhs n-dimensional right hand side.
|
||||
* @param _idx_to_round indices i of variables x_i that shall be rounded
|
||||
* @param _reg_factor regularization factor. Helps unstable, low rank system to become solvable. Adds \f$ \_reg\_factor*mean(trace(_A))*Id \f$ to A.
|
||||
* @param _show_miso_settings should the (QT) dialog of the Mixed-Integer solver pop up?
|
||||
* @param _show_timings shall some timings be printed?
|
||||
*/
|
||||
template<class RMatrixT, class CMatrixT, class VectorT, class VectorIT >
|
||||
void solve(
|
||||
RMatrixT& _constraints,
|
||||
CMatrixT& _A,
|
||||
VectorT& _x,
|
||||
VectorT& _rhs,
|
||||
VectorIT& _idx_to_round,
|
||||
double _reg_factor = 0.0,
|
||||
bool _show_miso_settings = true,
|
||||
bool _show_timings = true );
|
||||
|
||||
// const version of above function
|
||||
template<class RMatrixT, class CMatrixT, class VectorT, class VectorIT >
|
||||
void solve_const(
|
||||
const RMatrixT& _constraints,
|
||||
const CMatrixT& _A,
|
||||
VectorT& _x,
|
||||
const VectorT& _rhs,
|
||||
const VectorIT& _idx_to_round,
|
||||
double _reg_factor = 0.0,
|
||||
bool _show_miso_settings = true,
|
||||
bool _show_timings = true );
|
||||
|
||||
// efficent re-solve with modified _constraint_rhs and/or _rhs (if not modified use 0 pointer)
|
||||
// by keeping previous _constraints and _A fixed
|
||||
// _constraint_rhs and _rhs are constant, i.e. not changed
|
||||
template<class VectorT >
|
||||
void resolve(
|
||||
VectorT& _x,
|
||||
VectorT* _constraint_rhs = 0,
|
||||
VectorT* _rhs = 0,
|
||||
bool _show_timings = true );
|
||||
|
||||
|
||||
/// Non-Quadratic matrix constrained solver
|
||||
/**
|
||||
* Same as above, but performs the elimination of the constraints directly on the B matrix of \f$ x^\top B^\top Bx \f$, where B has m rows (equations) and (n+1) columns \f$ [ x_1, x_2, \cdots, x_n, -rhs ] \f$.
|
||||
* \note This function might be more efficient in some cases, but generally the solver for the quadratic matrix above is a safer bet. Needs further testing.
|
||||
* \note Internally the \f$ A=B^\top B \f$ matrix is formed.
|
||||
* @param _constraints row matrix with rows of the form \f$ [ c_1, c_2, \cdots, c_n, c_{n+1} ] \f$ corresponding to the linear equation \f$ c_1*x_1+\cdots+c_n*x_n + c_{n+1}=0 \f$.
|
||||
* @param _B mx(n+1)-dimensional column matrix of the system
|
||||
* @param _x n-dimensional variable vector
|
||||
* @param _idx_to_round indices i of variables x_i that shall be rounded
|
||||
* @param _reg_factor regularization factor. Helps unstable, low rank system to become solvable.
|
||||
* @param _show_miso_settings should the (QT) dialog of the Mixed-Integer solver pop up?
|
||||
* @param _show_timings shall some timings be printed?
|
||||
*/
|
||||
template<class RMatrixT, class VectorT, class VectorIT >
|
||||
void solve(
|
||||
RMatrixT& _constraints,
|
||||
RMatrixT& _B,
|
||||
VectorT& _x,
|
||||
VectorIT& _idx_to_round,
|
||||
double _reg_factor = 0.0,
|
||||
bool _show_miso_settings = true,
|
||||
bool _show_timings = true );
|
||||
|
||||
// const version of above function
|
||||
template<class RMatrixT, class VectorT, class VectorIT >
|
||||
void solve_const(
|
||||
const RMatrixT& _constraints,
|
||||
const RMatrixT& _B,
|
||||
VectorT& _x,
|
||||
const VectorIT& _idx_to_round,
|
||||
double _reg_factor = 0.0,
|
||||
bool _show_miso_settings = true,
|
||||
bool _show_timings = true );
|
||||
|
||||
// efficent re-solve with modified _rhs by keeping previous _constraints and _A fixed
|
||||
// ATTENTION: only the rhs resulting from B^TB can be changed!!! otherwise use solve
|
||||
template<class RMatrixT, class VectorT >
|
||||
void resolve(
|
||||
const RMatrixT& _B,
|
||||
VectorT& _x,
|
||||
VectorT* _constraint_rhs = 0,
|
||||
bool _show_timings = true );
|
||||
|
||||
/*@}*/
|
||||
|
||||
|
||||
/** @name Eliminate constraints
|
||||
* Functions to eliminate (or integrate) linear constraints from an equation system. These functions are used internally by the \a solve functions.
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/// Make constraints independent
|
||||
/**
|
||||
* This function performs a Gauss elimination on the constraint matrix making the constraints easier to eliminate.
|
||||
* \note A certain amount of independence of the constraints is assumed.
|
||||
* \note contradicting constraints will be ignored.
|
||||
* \warning care must be taken when non-trivial constraints occur where some of the variables contain integer-variables (to be rounded) as the optimal result might not always occur.
|
||||
* @param _constraints row matrix with constraints
|
||||
* @param _idx_to_round indices of variables to be rounded (these must be considered.)
|
||||
* @param _c_elim the "returned" vector of variable indices and the order in which the can be eliminated.
|
||||
*/
|
||||
template<class RMatrixT, class VectorIT >
|
||||
void make_constraints_independent(
|
||||
RMatrixT& _constraints,
|
||||
VectorIT& _idx_to_round,
|
||||
std::vector<int>& _c_elim );
|
||||
|
||||
template<class RMatrixT, class VectorIT >
|
||||
void make_constraints_independent_reordering(
|
||||
RMatrixT& _constraints,
|
||||
VectorIT& _idx_to_round,
|
||||
std::vector<int>& _c_elim );
|
||||
|
||||
/// Eliminate constraints on a factored matrix B
|
||||
/**
|
||||
* \note Constraints are assumed to have been made independent by \a make_constraints_independent.
|
||||
* @param _constraints row matrix with constraints (n+1 columns)
|
||||
* @param _B system row matrix mx(n+1)
|
||||
* @param _idx_to_round indices to be rounded
|
||||
* @param _c_elim the indices of the variables to be eliminated.
|
||||
* @param _new_idx the created re-indexing map. new_idx[i] = -1 means x_i eliminated, new_idx[i] = j means x_i is now at index j.
|
||||
* @param _Bcol resulting (smaller) column matrix to be used for future computations. (e.g. convert to CSC and solve)
|
||||
*/
|
||||
template<class SVector1T, class SVector2T, class VectorIT, class SVector3T>
|
||||
void eliminate_constraints(
|
||||
gmm::row_matrix<SVector1T>& _constraints,
|
||||
gmm::row_matrix<SVector2T>& _B,
|
||||
VectorIT& _idx_to_round,
|
||||
std::vector<int>& _c_elim,
|
||||
std::vector<int>& _new_idx,
|
||||
gmm::col_matrix<SVector3T>& _Bcol);
|
||||
|
||||
/// Eliminate constraints on a quadratic matrix A
|
||||
/**
|
||||
* \note Constraints are assumed to have been made independent by \a make_constraints_independent.
|
||||
* \note _x must have correct size (same as _rhs)
|
||||
* @param _constraints row matrix with constraints (n+1 columns)
|
||||
* @param _A system row matrix nxn)
|
||||
* @param _x variable vector
|
||||
* @param _rhs right hand side
|
||||
* @param _idx_to_round indices to be rounded
|
||||
* @param _c_elim the indices of the variables to be eliminated.
|
||||
* @param _new_idx the created re-indexing map. new_idx[i] = -1 means x_i eliminated, new_idx[i] = j means x_i is now at index j.
|
||||
* @param _Acsc resulting (smaller) column (csc) matrix to be used for future computations.
|
||||
*/
|
||||
|
||||
template<class SVector1T, class SVector2T, class VectorIT, class CSCMatrixT>
|
||||
void eliminate_constraints(
|
||||
gmm::row_matrix<SVector1T>& _constraints,
|
||||
gmm::col_matrix<SVector2T>& _A,
|
||||
std::vector<double>& _x,
|
||||
std::vector<double>& _rhs,
|
||||
VectorIT& _idx_to_round,
|
||||
std::vector<int>& _c_elim,
|
||||
std::vector<int>& _new_idx,
|
||||
CSCMatrixT& _Acsc);
|
||||
|
||||
/// Restore a solution vector to the un-eliminated size
|
||||
/**
|
||||
* @param _constraints row matrix with constraints (n+1 columns)
|
||||
* @param _x solution vector to reduced/eliminated system (result will also be written here)
|
||||
* @param _c_elim vector of eliminated indices
|
||||
* @param _new_idx re-indexing vector
|
||||
*/
|
||||
|
||||
template<class RMatrixT, class VectorT >
|
||||
void restore_eliminated_vars( RMatrixT& _constraints,
|
||||
VectorT& _x,
|
||||
std::vector<int>& _c_elim,
|
||||
std::vector<int>& _new_idx);
|
||||
|
||||
|
||||
/*@}*/
|
||||
|
||||
/// Set numerical epsilon for valid constraint coefficient
|
||||
void set_epsilon( double _epsilon) { epsilon_ = _epsilon; }
|
||||
|
||||
/// Set noise-level (how much std output is given) 0 basically none, 1 important stuff (warning/timing, is default), 2+ not so important
|
||||
void set_noisy( int _noisy) { noisy_ = _noisy;}
|
||||
|
||||
// Get/Set whether the constraint reordering is used (default true)
|
||||
bool& use_constraint_reordering() { return miso_.use_constraint_reordering(); }
|
||||
|
||||
/** @name Verify the result.
|
||||
* Functions to verify the result of the constrained solver. Are the constraints met, are the correct variables correctly rounded ...
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
|
||||
template<class RMatrixT, class CMatrixT, class VectorT>
|
||||
double verify_constrained_system(
|
||||
const RMatrixT& _conditions,
|
||||
const CMatrixT& _A,
|
||||
const VectorT& _x,
|
||||
const VectorT& _rhs,
|
||||
double _eps = 1e-9);
|
||||
|
||||
template<class RMatrixT, class CMatrixT, class VectorT, class VectorIT>
|
||||
double verify_constrained_system_round(
|
||||
const RMatrixT& _conditions,
|
||||
const CMatrixT& _A,
|
||||
const VectorT& _x,
|
||||
const VectorT& _rhs,
|
||||
const VectorIT& _idx_to_round,
|
||||
double _eps = 1e-9);
|
||||
|
||||
template<class RMatrixT, class VectorT, class VectorIT>
|
||||
void verify_mi_factored( const RMatrixT& _conditions,
|
||||
const RMatrixT& _B,
|
||||
const VectorT& _x,
|
||||
const VectorIT& _idx_to_round );
|
||||
/*@}*/
|
||||
|
||||
|
||||
/// Access the MISolver (e.g. to change settings)
|
||||
COMISO::MISolver& misolver() { return miso_;}
|
||||
|
||||
private:
|
||||
|
||||
template<class RowT, class MatrixT>
|
||||
void add_row( int _row_i,
|
||||
double _coeff,
|
||||
RowT _row,
|
||||
MatrixT& _mat );
|
||||
|
||||
template<class RowT, class RMatrixT, class CMatrixT>
|
||||
void add_row_simultaneously( int _row_i,
|
||||
double _coeff,
|
||||
RowT _row,
|
||||
RMatrixT& _rmat,
|
||||
CMatrixT& _cmat );
|
||||
|
||||
|
||||
template<class CMatrixT, class VectorT, class VectorIT>
|
||||
double setup_and_solve_system( CMatrixT& _B,
|
||||
VectorT& _x,
|
||||
VectorIT& _idx_to_round,
|
||||
double _reg_factor,
|
||||
bool _show_miso_settings);
|
||||
|
||||
|
||||
// warning: order of replacement not the same as in _columns (internal sort)
|
||||
template<class CMatrixT>
|
||||
void eliminate_columns( CMatrixT& _M,
|
||||
const std::vector< int >& _columns);
|
||||
|
||||
inline int gcd( int _a, int _b)
|
||||
{
|
||||
while( _b != 0)
|
||||
{
|
||||
int t(_b);
|
||||
_b = _a%_b;
|
||||
_a = t;
|
||||
}
|
||||
return _a;
|
||||
}
|
||||
|
||||
int find_gcd(std::vector<int>& _v_gcd, int& _n_ints);
|
||||
// TODO if no gcd correction was possible, at least use a variable divisible by 2 as new elim_j (to avoid in-exactness e.g. 1/3)
|
||||
template<class RMatrixT>
|
||||
bool update_constraint_gcd( RMatrixT& _constraints,
|
||||
int _row_i,
|
||||
int& _elim_j,
|
||||
std::vector<int>& _v_gcd,
|
||||
int& _n_ints);
|
||||
|
||||
private:
|
||||
|
||||
/// Copy constructor (not used)
|
||||
ConstrainedSolver(const ConstrainedSolver& _rhs);
|
||||
|
||||
/// Assignment operator (not used)
|
||||
ConstrainedSolver& operator=(const ConstrainedSolver& _rhs);
|
||||
|
||||
// MISO solver
|
||||
COMISO::MISolver miso_;
|
||||
|
||||
double epsilon_;
|
||||
int noisy_;
|
||||
bool do_gcd_;
|
||||
|
||||
// --------------- Update by Marcel to enable efficient re-solve with changed rhs ----------------------
|
||||
// Store for symbolic elimination information for rhs
|
||||
class rhsUpdateTable {
|
||||
public:
|
||||
|
||||
void append(int _i, double _f, int _j, bool _flag)
|
||||
{
|
||||
// std::cerr << "append " << _i << ", " << _j << ", " << _f << ", " << int(_flag) << std::endl;
|
||||
table_.push_back(rhsUpdateTableEntry(_i, _j, _f, _flag));
|
||||
}
|
||||
void add_elim_id(int _i) { elim_var_ids_.push_back(_i); }
|
||||
void clear() { table_.clear(); elim_var_ids_.clear(); }
|
||||
// apply stored transformations to _rhs
|
||||
void apply(std::vector<double>& _constraint_rhs, std::vector<double>& _rhs)
|
||||
{
|
||||
std::vector<rhsUpdateTableEntry>::const_iterator t_it, t_end;
|
||||
t_end = table_.end();
|
||||
int cur_j = -1;
|
||||
double cur_rhs = 0.0;
|
||||
for(t_it = table_.begin(); t_it != t_end; ++t_it)
|
||||
{
|
||||
if(t_it->rhs_flag)
|
||||
_rhs[t_it->i] += t_it->f*_constraint_rhs[t_it->j];
|
||||
else
|
||||
{
|
||||
if(t_it->j != cur_j) { cur_j = t_it->j; cur_rhs = _rhs[cur_j]; }
|
||||
_rhs[t_it->i] += t_it->f * cur_rhs;
|
||||
}
|
||||
}
|
||||
}
|
||||
// remove eliminated elements from _rhs
|
||||
void eliminate(std::vector<double>& _rhs)
|
||||
{
|
||||
std::vector<int> evar( elim_var_ids_ );
|
||||
std::sort( evar.begin(), evar.end() );
|
||||
evar.push_back( std::numeric_limits<int>::max() );
|
||||
|
||||
int cur_evar_idx=0;
|
||||
unsigned int nc = _rhs.size();
|
||||
for( unsigned int i=0; i<nc; ++i )
|
||||
{
|
||||
unsigned int next_i = evar[cur_evar_idx];
|
||||
|
||||
if ( i != next_i ) _rhs[i-cur_evar_idx] = _rhs[i];
|
||||
else ++cur_evar_idx;
|
||||
}
|
||||
_rhs.resize( nc - cur_evar_idx );
|
||||
}
|
||||
// store transformed constraint matrix and index map to allow for later re-substitution
|
||||
template<class RMatrixT>
|
||||
void store(const RMatrixT& _constraints, const std::vector<int>& _c_elim, const std::vector<int>& _new_idx)
|
||||
{
|
||||
constraints_p_.resize( gmm::mat_nrows(_constraints), gmm::mat_ncols(_constraints));
|
||||
gmm::copy(_constraints, constraints_p_);
|
||||
c_elim_ = _c_elim;
|
||||
new_idx_ = _new_idx;
|
||||
}
|
||||
|
||||
private:
|
||||
class rhsUpdateTableEntry {
|
||||
public:
|
||||
rhsUpdateTableEntry(int _i, int _j, double _f, bool _rhs_flag) : i(_i), j(_j), f(_f), rhs_flag(_rhs_flag) {}
|
||||
int i;
|
||||
int j;
|
||||
double f;
|
||||
bool rhs_flag;
|
||||
};
|
||||
|
||||
std::vector<rhsUpdateTableEntry> table_;
|
||||
std::vector<int> elim_var_ids_;
|
||||
|
||||
public:
|
||||
std::vector<int> c_elim_;
|
||||
std::vector<int> new_idx_;
|
||||
RowMatrix constraints_p_;
|
||||
|
||||
// cache current rhs_ and constraint_rhs_ and linear transformation of constraint_rhs_ D_
|
||||
RowMatrix D_;
|
||||
std::vector<double> cur_rhs_;
|
||||
// constraint_rhs after Gaussian elimination update D*constraint_rhs_orig_
|
||||
std::vector<double> cur_constraint_rhs_;
|
||||
} rhs_update_table_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#if defined(INCLUDE_TEMPLATES) && !defined(COMISO_CONSTRAINEDSOLVER_C)
|
||||
#define COMISO_CONSTRAINEDSOLVER_TEMPLATES
|
||||
#include "ConstrainedSolverT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // COMISO_CONSTRAINEDSOLVER_HH defined
|
||||
//=============================================================================
|
||||
|
||||
1468
src/external/CoMISo/Solver/ConstrainedSolverT.cc
vendored
Normal file
1468
src/external/CoMISo/Solver/ConstrainedSolverT.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
117
src/external/CoMISo/Solver/EigenLDLTSolver.cc
vendored
Normal file
117
src/external/CoMISo/Solver/EigenLDLTSolver.cc
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
#include "EigenLDLTSolver.hh"
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#if (COMISO_EIGEN3_AVAILABLE)
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
EigenLDLTSolver::EigenLDLTSolver() : n_(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
EigenLDLTSolver::~EigenLDLTSolver()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool EigenLDLTSolver::calc_system( const std::vector<int>& _colptr,
|
||||
const std::vector<int>& _rowind,
|
||||
const std::vector<double>& _values)
|
||||
{
|
||||
std::cerr << "Info: EigenLDLTSolver::calc_system( const std::vector<int> ...) not implemented yet..." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool EigenLDLTSolver::update_system( const std::vector<int>& _colptr,
|
||||
const std::vector<int>& _rowind,
|
||||
const std::vector<double>& _values )
|
||||
{
|
||||
std::cerr << "Info: EigenLDLTSolver::update_system( const std::vector<int> ...) not implemented yet..." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool EigenLDLTSolver::solve( double * _x, double * _b)
|
||||
{
|
||||
// map arrays to Eigen-Vectors
|
||||
Eigen::Map<Eigen::VectorXd> x(_x,n_);
|
||||
Eigen::Map<Eigen::VectorXd> b(_b,n_);
|
||||
|
||||
// solve for another right hand side:
|
||||
x = ldlt_.solve(b);
|
||||
|
||||
return (ldlt_.info()==Eigen::Success);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int EigenLDLTSolver::dimension()
|
||||
{
|
||||
return n_;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool EigenLDLTSolver::
|
||||
solve ( std::vector<double>& _x0, std::vector<double>& _b)
|
||||
{
|
||||
return solve( &(_x0[0]), &(_b[0]));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool& EigenLDLTSolver::
|
||||
show_timings()
|
||||
{
|
||||
return show_timings_;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
#endif // COMISO_EIGEN3_AVAILABLE
|
||||
//=============================================================================
|
||||
121
src/external/CoMISo/Solver/EigenLDLTSolver.hh
vendored
Normal file
121
src/external/CoMISo/Solver/EigenLDLTSolver.hh
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS CholmodSolver
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef COMISO_EIGEN_LDLT_SOLVER_HH
|
||||
#define COMISO_EIGEN_LDLT_SOLVER_HH
|
||||
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if (COMISO_EIGEN3_AVAILABLE)
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include <Eigen/Eigen>
|
||||
#include <Eigen/Sparse>
|
||||
#include <Eigen/SparseCholesky>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
class COMISODLLEXPORT EigenLDLTSolver
|
||||
{
|
||||
public:
|
||||
|
||||
// _size is maximal size this instance can handle (smaller problems are possible!!!)
|
||||
EigenLDLTSolver();
|
||||
~EigenLDLTSolver();
|
||||
|
||||
bool calc_system( const std::vector<int>& _colptr,
|
||||
const std::vector<int>& _rowind,
|
||||
const std::vector<double>& _values );
|
||||
|
||||
|
||||
template< class GMM_MatrixT>
|
||||
bool calc_system_gmm( const GMM_MatrixT& _mat);
|
||||
|
||||
template< class Eigen_MatrixT>
|
||||
bool calc_system_eigen( const Eigen_MatrixT& _mat);
|
||||
|
||||
|
||||
bool update_system( const std::vector<int>& _colptr,
|
||||
const std::vector<int>& _rowind,
|
||||
const std::vector<double>& _values );
|
||||
|
||||
|
||||
template< class GMM_MatrixT>
|
||||
bool update_system_gmm( const GMM_MatrixT& _mat);
|
||||
|
||||
template< class Eigen_MatrixT>
|
||||
bool update_system_eigen( const Eigen_MatrixT& _mat);
|
||||
|
||||
|
||||
bool solve ( double * _x0, double * _b);
|
||||
|
||||
bool solve ( std::vector<double>& _x0, std::vector<double>& _b);
|
||||
|
||||
bool& show_timings();
|
||||
|
||||
int dimension();
|
||||
|
||||
private:
|
||||
|
||||
// dimension n_
|
||||
unsigned int n_;
|
||||
|
||||
Eigen::SimplicialLDLT<Eigen::SparseMatrix<double> > ldlt_;
|
||||
|
||||
bool show_timings_;
|
||||
StopWatch sw_;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#if defined(INCLUDE_TEMPLATES) && !defined(COMISO_EIGEN_LDLT_SOLVER_TEMPLATES_C)
|
||||
#define COMISO_EIGEN_LDLT_SOLVER_TEMPLATES
|
||||
#include "EigenLDLTSolverT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // COMISO_EIGEN3_AVAILABLE
|
||||
//=============================================================================
|
||||
#endif // COMISO_EIGEN_LDLT_SOLVER_HH defined
|
||||
//=============================================================================
|
||||
119
src/external/CoMISo/Solver/EigenLDLTSolverT.cc
vendored
Normal file
119
src/external/CoMISo/Solver/EigenLDLTSolverT.cc
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if (COMISO_EIGEN3_AVAILABLE)
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#define COMISO_EIGEN_LDLT_SOLVER_TEMPLATES_C
|
||||
|
||||
#include <CoMISo/Solver/GMM_Tools.hh>
|
||||
#include <CoMISo/Solver/Eigen_Tools.hh>
|
||||
#include <CoMISo/Solver/EigenLDLTSolver.hh>
|
||||
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
|
||||
template< class GMM_MatrixT>
|
||||
bool EigenLDLTSolver::calc_system_gmm( const GMM_MatrixT& _mat)
|
||||
{
|
||||
if(show_timings_) sw_.start();
|
||||
|
||||
Eigen::SparseMatrix<double> E;
|
||||
COMISO_EIGEN::gmm_to_eigen(_mat, E);
|
||||
|
||||
if(show_timings_)
|
||||
{
|
||||
std::cerr << "EigenLDLT Timing GMM convert: " << sw_.stop()/1000.0 << "s\n";
|
||||
std::cerr << "#nnz: " << E.nonZeros() << std::endl;
|
||||
}
|
||||
|
||||
return calc_system_eigen( E);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template< class GMM_MatrixT>
|
||||
bool EigenLDLTSolver::update_system_gmm( const GMM_MatrixT& _mat)
|
||||
{
|
||||
if(show_timings_) sw_.start();
|
||||
|
||||
Eigen::SparseMatrix<double> E;
|
||||
COMISO_EIGEN::gmm_to_eigen(_mat, E);
|
||||
|
||||
if(show_timings_)
|
||||
{
|
||||
std::cerr << "EigenLDLT Timing GMM convert: " << sw_.stop()/1000.0 << "s\n";
|
||||
std::cerr << "#nnz: " << E.nonZeros() << std::endl;
|
||||
}
|
||||
|
||||
return update_system_eigen( E);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class Eigen_MatrixT>
|
||||
bool EigenLDLTSolver::calc_system_eigen( const Eigen_MatrixT& _mat)
|
||||
{
|
||||
n_ = _mat.rows();
|
||||
|
||||
if(show_timings_) sw_.start();
|
||||
|
||||
ldlt_.compute(_mat);
|
||||
|
||||
if(show_timings_)
|
||||
{
|
||||
std::cerr << "EigenLDLT Timing EIGEN compute: " << sw_.stop()/1000.0 << "s\n";
|
||||
}
|
||||
|
||||
return (ldlt_.info()==Eigen::Success);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template< class Eigen_MatrixT>
|
||||
bool EigenLDLTSolver::update_system_eigen( const Eigen_MatrixT& _mat)
|
||||
{
|
||||
if(show_timings_) sw_.start();
|
||||
|
||||
ldlt_.factorize(_mat);
|
||||
|
||||
if(show_timings_)
|
||||
{
|
||||
std::cerr << "EigenLDLT Timing EIGEN factorize: " << sw_.stop()/1000.0 << "s\n";
|
||||
}
|
||||
|
||||
return (ldlt_.info()==Eigen::Success );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
#endif // COMISO_EIGEN3_AVAILABLE
|
||||
//=============================================================================
|
||||
684
src/external/CoMISo/Solver/Eigen_Tools.cc
vendored
Normal file
684
src/external/CoMISo/Solver/Eigen_Tools.cc
vendored
Normal file
@ -0,0 +1,684 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS Eigen_Tools - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_EIGEN3_AVAILABLE
|
||||
|
||||
|
||||
#define COMISO_Eigen_TOOLS_C
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "Eigen_Tools.hh"
|
||||
#include <queue>
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
#include <CoMISo/Utils/VSToolsT.hh>
|
||||
#include <gmm/gmm.h>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO_EIGEN
|
||||
{
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class MatrixT, class REALT, class INTT>
|
||||
void get_ccs_symmetric_data( const MatrixT& _mat,
|
||||
const char _uplo,
|
||||
std::vector<REALT>& _values,
|
||||
std::vector<INTT>& _rowind,
|
||||
std::vector<INTT>& _colptr )
|
||||
{
|
||||
// Assumes col major
|
||||
|
||||
int m = _mat.innerSize();
|
||||
int n = _mat.outerSize();
|
||||
|
||||
_values.resize( 0 );
|
||||
_rowind.resize( 0 );
|
||||
_colptr.resize( 0 );
|
||||
|
||||
INTT iv( 0 );
|
||||
|
||||
typedef typename MatrixT::InnerIterator It;
|
||||
|
||||
switch ( _uplo )
|
||||
{
|
||||
case 'l':
|
||||
case 'L':
|
||||
// for all columns
|
||||
for ( int i=0; i<n; ++i )
|
||||
{
|
||||
_colptr.push_back( iv );
|
||||
|
||||
// row it
|
||||
It it(_mat, i);
|
||||
|
||||
for( ; it; ++it)
|
||||
{
|
||||
if( it.index() >= i )
|
||||
{
|
||||
_values.push_back( it.value());
|
||||
_rowind.push_back( it.index());
|
||||
++iv;
|
||||
}
|
||||
}
|
||||
}
|
||||
_colptr.push_back( iv );
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
case 'U':
|
||||
// for all columns
|
||||
for ( int i=0; i<n; ++i )
|
||||
{
|
||||
_colptr.push_back( iv );
|
||||
|
||||
// row it
|
||||
It it(_mat, i);
|
||||
|
||||
for( ; it; ++it)
|
||||
{
|
||||
if( it.index() <= i )
|
||||
{
|
||||
_values.push_back( it.value());
|
||||
_rowind.push_back( it.index());
|
||||
++iv;
|
||||
}
|
||||
}
|
||||
}
|
||||
_colptr.push_back( iv );
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
// for all columns
|
||||
for ( int i=0; i<n; ++i )
|
||||
{
|
||||
_colptr.push_back( iv );
|
||||
|
||||
// row it
|
||||
It it(_mat, i);
|
||||
|
||||
for( ; it; ++it)
|
||||
{
|
||||
_values.push_back( it.value());
|
||||
_rowind.push_back( it.index());
|
||||
++iv;
|
||||
}
|
||||
}
|
||||
_colptr.push_back( iv );
|
||||
break;
|
||||
|
||||
default:
|
||||
std::cerr << "ERROR: parameter uplo must bei either 'U' or 'L' or 'C'!!!\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// inspect the matrix: dimension, symmetry, zero_rows, zero_cols, nnz, max, min, max_abs, min_abs, NAN, INF
|
||||
template<class MatrixT>
|
||||
void inspect_matrix( const MatrixT& _A)
|
||||
{
|
||||
|
||||
|
||||
std::cerr << "################### INSPECT MATRIX ##################\n";
|
||||
std::cerr << "#outer size : " << _A.outerSize() << std::endl;
|
||||
std::cerr << "#inner size : " << _A.innerSize() << std::endl;
|
||||
std::cerr << "#rows : " << _A.rows() << std::endl;
|
||||
std::cerr << "#cols : " << _A.cols() << std::endl;
|
||||
std::cerr << "#nonzeros : " << _A.nonZeros() << std::endl;
|
||||
std::cerr << "#nonzeros/row: " << (double(_A.nonZeros())/double(_A.rows())) << std::endl;
|
||||
std::cerr << "symmetric : " << is_symmetric( _A) << std::endl;
|
||||
|
||||
MatrixT trans( _A.transpose());
|
||||
|
||||
int zero_rows = 0;
|
||||
int zero_cols = 0;
|
||||
|
||||
for(int i=0; i<_A.outerSize(); ++i)
|
||||
{
|
||||
typename MatrixT::InnerIterator it(_A, i);
|
||||
if( !it) ++zero_rows;
|
||||
}
|
||||
|
||||
for(int i=0; i<trans.outerSize(); ++i)
|
||||
{
|
||||
typename MatrixT::InnerIterator it(trans, i);
|
||||
if( !it) ++zero_cols;
|
||||
}
|
||||
|
||||
std::cerr << "zero rows : " << zero_rows << std::endl;
|
||||
std::cerr << "zero cols : " << zero_cols << std::endl;
|
||||
|
||||
typedef typename MatrixT::Scalar Scalar;
|
||||
Scalar vmin = std::numeric_limits<Scalar>::max();
|
||||
Scalar vmax = std::numeric_limits<Scalar>::min();
|
||||
Scalar vmin_abs = std::numeric_limits<Scalar>::max();
|
||||
Scalar vmax_abs = 0;
|
||||
|
||||
int n_nan = 0;
|
||||
int n_inf = 0;
|
||||
|
||||
// inspect elements
|
||||
for(int i=0; i<_A.outerSize(); ++i)
|
||||
{
|
||||
typename MatrixT::InnerIterator it( _A, i);
|
||||
|
||||
for(; it ; ++it)
|
||||
{
|
||||
if( it.value() < vmin ) vmin = it.value();
|
||||
if( it.value() > vmax ) vmax = it.value();
|
||||
|
||||
if( fabs(it.value()) < vmin_abs) vmin_abs = fabs(it.value());
|
||||
if( fabs(it.value()) > vmax_abs) vmax_abs = fabs(it.value());
|
||||
|
||||
if( std::isnan(it.value())) ++n_nan;
|
||||
if( std::isinf(it.value())) ++n_inf;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "min val : " << vmin << std::endl;
|
||||
std::cerr << "max val : " << vmax << std::endl;
|
||||
std::cerr << "min |val| : " << vmin_abs << std::endl;
|
||||
std::cerr << "max |val| : " << vmax_abs << std::endl;
|
||||
std::cerr << "#nan : " << n_nan << std::endl;
|
||||
std::cerr << "#inf : " << n_inf << std::endl;
|
||||
|
||||
std::cerr << "min eval : " << "..." << std::endl;
|
||||
std::cerr << "max eval : " << "..." << std::endl;
|
||||
std::cerr << "min|eval| : " << "..." << std::endl;
|
||||
std::cerr << "max|eval| : " << "..." << std::endl;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// symmetric ?
|
||||
template<class MatrixT>
|
||||
bool is_symmetric( const MatrixT& _A)
|
||||
{
|
||||
typedef typename MatrixT::InnerIterator It;
|
||||
typedef typename MatrixT::Scalar Scalar;
|
||||
|
||||
int nouter( _A.outerSize());
|
||||
int ninner( _A.innerSize());
|
||||
|
||||
if( nouter != ninner )
|
||||
return false;
|
||||
|
||||
bool symmetric(true);
|
||||
|
||||
for( int c = 0; c < nouter; ++c)
|
||||
{
|
||||
for( It it(_A,c); it; ++it)
|
||||
{
|
||||
int r(it.index());
|
||||
|
||||
Scalar val(it.value());
|
||||
|
||||
// find diagonal partner element
|
||||
bool found(false);
|
||||
for( It dit(_A,r); dit; ++dit)
|
||||
{
|
||||
if( dit.index() < c )
|
||||
{}
|
||||
else if( dit.index() == c)
|
||||
{
|
||||
if( dit.value() == val)
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !found)
|
||||
{
|
||||
symmetric = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return symmetric;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template< class Eigen_MatrixT, class IntT >
|
||||
void permute( const Eigen_MatrixT& _QR, const std::vector< IntT>& _Pvec, Eigen_MatrixT& _A)
|
||||
{
|
||||
#ifdef COMISO_EIGEN3_AVAILABLE
|
||||
typedef typename Eigen_MatrixT::Scalar Scalar;
|
||||
|
||||
int m = _QR.innerSize();
|
||||
int n = _QR.outerSize();
|
||||
|
||||
if( _Pvec.size() == 0)
|
||||
{
|
||||
_A = _QR;
|
||||
return;
|
||||
}
|
||||
|
||||
if( _Pvec.size() != (size_t)_QR.cols() && _Pvec.size() != 0)
|
||||
{
|
||||
std::cerr << __FUNCTION__ << " wrong size of permutation vector, should have #cols length (or zero)" << std::endl;
|
||||
}
|
||||
|
||||
// build sparse permutation matrix
|
||||
typedef Eigen::Triplet< Scalar > Triplet;
|
||||
std::vector< Triplet > triplets;
|
||||
triplets.reserve(_QR.nonZeros());
|
||||
_A = Eigen_MatrixT( m, n);
|
||||
|
||||
typedef typename Eigen_MatrixT::InnerIterator It;
|
||||
|
||||
|
||||
for( int c = 0; c < n; ++c) // cols
|
||||
{
|
||||
for( It it(_QR,c); it; ++it) // rows
|
||||
{
|
||||
int r(it.index());
|
||||
|
||||
Scalar val(it.value());
|
||||
|
||||
int newcol( _Pvec[c]);
|
||||
|
||||
triplets.push_back( Triplet( r, newcol, val));
|
||||
}
|
||||
}
|
||||
_A.setFromTriplets( triplets.begin(), triplets.end());
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if COMISO_SUITESPARSE_AVAILABLE
|
||||
|
||||
/// Eigen to Cholmod_sparse interface
|
||||
template<class MatrixT>
|
||||
void cholmod_to_eigen( const cholmod_sparse& _AC, MatrixT& _A)
|
||||
{
|
||||
#ifdef COMISO_EIGEN3_AVAILABLE
|
||||
// initialize dimensions
|
||||
typedef typename MatrixT::Scalar Scalar;
|
||||
typedef Eigen::Triplet< Scalar > Triplet;
|
||||
size_t nzmax( _AC.nzmax);
|
||||
std::cerr << __FUNCTION__ << " row " << _AC.nrow << " col " << _AC.ncol << " stype " << _AC.stype << std::endl;
|
||||
_A = MatrixT(_AC.nrow, _AC.ncol);
|
||||
std::vector< Triplet > triplets;
|
||||
triplets.reserve(nzmax);
|
||||
|
||||
if(!_AC.packed)
|
||||
{
|
||||
std::cerr << "Warning: " << __FUNCTION__ << " does not support unpacked matrices yet!!!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Pointer to data
|
||||
double* X((double*)_AC.x);
|
||||
|
||||
// complete matrix stored
|
||||
if(_AC.stype == 0)
|
||||
{
|
||||
// which integer type?
|
||||
if(_AC.itype == CHOLMOD_LONG)
|
||||
{
|
||||
UF_long* P((UF_long*)_AC.p);
|
||||
UF_long* I((UF_long*)_AC.i);
|
||||
|
||||
for(UF_long i=0; i<(UF_long)_AC.ncol; ++i)
|
||||
for(UF_long j= P[i]; j< P[i+1]; ++j)
|
||||
//_A( I[j], i) += X[j]; // += really needed?
|
||||
triplets.push_back( Triplet( I[j], i, X[j]));
|
||||
}
|
||||
else
|
||||
{
|
||||
int* P((int*)_AC.p);
|
||||
int* I((int*)_AC.i);
|
||||
|
||||
for(int i=0; i<(int)_AC.ncol; ++i)
|
||||
for(int j= P[i]; j< P[i+1]; ++j)
|
||||
triplets.push_back( Triplet( I[j], i, X[j]));
|
||||
//_A( I[j], i) += X[j];
|
||||
}
|
||||
|
||||
}
|
||||
else // only upper or lower diagonal stored
|
||||
{
|
||||
// which integer type?
|
||||
if(_AC.itype == CHOLMOD_LONG)
|
||||
{
|
||||
UF_long* P((UF_long*)_AC.p);
|
||||
UF_long* I((UF_long*)_AC.i);
|
||||
|
||||
for(UF_long i=0; i<(UF_long)_AC.ncol; ++i)
|
||||
for(UF_long j=P[i]; j<P[i+1]; ++j)
|
||||
{
|
||||
//_A(I[j], i) += X[j];
|
||||
triplets.push_back( Triplet( I[j], i, X[j]));
|
||||
|
||||
// add up symmetric part
|
||||
if( I[j] != i)
|
||||
triplets.push_back( Triplet( i, I[j], X[j]));
|
||||
//_A(i,I[j]) += X[j];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int* P((int*)_AC.p);
|
||||
int* I((int*)_AC.i);
|
||||
|
||||
for(int i=0; i<(int)_AC.ncol; ++i)
|
||||
for(int j=P[i]; j<P[i+1]; ++j)
|
||||
{
|
||||
//_A(I[j], i) += X[j];
|
||||
triplets.push_back( Triplet( I[j], i, X[j]));
|
||||
|
||||
// add up symmetric part
|
||||
if( I[j] != i)
|
||||
// _A(i,I[j]) += X[j];
|
||||
triplets.push_back( Triplet( i, I[j], X[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
_A.setFromTriplets( triplets.begin(), triplets.end());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// GMM to Cholmod_sparse interface
|
||||
template<class MatrixT>
|
||||
void eigen_to_cholmod( const MatrixT& _A, cholmod_sparse* &_AC, cholmod_common* _common, int _sparsity_type, bool _long_int)
|
||||
{
|
||||
/* _sparsity_type
|
||||
* 0: matrix is "unsymmetric": use both upper and lower triangular parts
|
||||
* (the matrix may actually be symmetric in pattern and value, but
|
||||
* both parts are explicitly stored and used). May be square or
|
||||
* rectangular.
|
||||
* >0: matrix is square and symmetric, use upper triangular part.
|
||||
* Entries in the lower triangular part are ignored.
|
||||
* <0: matrix is square and symmetric, use lower triangular part.
|
||||
* Entries in the upper triangular part are ignored. */
|
||||
|
||||
int m = _A.innerSize();
|
||||
int n = _A.outerSize();
|
||||
|
||||
// get upper or lower
|
||||
char uplo = 'c';
|
||||
if(_sparsity_type < 0) uplo = 'l';
|
||||
if(_sparsity_type > 0) uplo = 'u';
|
||||
|
||||
|
||||
if( _long_int) // long int version
|
||||
{
|
||||
std::vector<double> values;
|
||||
std::vector<UF_long> rowind;
|
||||
std::vector<UF_long> colptr;
|
||||
|
||||
// get data of gmm matrix
|
||||
COMISO_EIGEN::get_ccs_symmetric_data( _A, uplo, values, rowind, colptr);
|
||||
|
||||
// allocate cholmod matrix
|
||||
_AC = cholmod_l_allocate_sparse(m,n,values.size(),true,true,_sparsity_type,CHOLMOD_REAL, _common);
|
||||
|
||||
// copy data to cholmod matrix
|
||||
for(UF_long i=0; i<(UF_long)values.size(); ++i)
|
||||
{
|
||||
((double*) (_AC->x))[i] = values[i];
|
||||
((UF_long*)(_AC->i))[i] = rowind[i];
|
||||
}
|
||||
|
||||
for(UF_long i=0; i<(UF_long)colptr.size(); ++i)
|
||||
((UF_long*)(_AC->p))[i] = colptr[i];
|
||||
}
|
||||
else // int version
|
||||
{
|
||||
std::vector<double> values;
|
||||
std::vector<int> rowind;
|
||||
std::vector<int> colptr;
|
||||
|
||||
// get data of gmm matrix
|
||||
COMISO_EIGEN::get_ccs_symmetric_data( _A, uplo, values, rowind, colptr);
|
||||
|
||||
// allocate cholmod matrix
|
||||
_AC = cholmod_allocate_sparse(m,n,values.size(),true,true,_sparsity_type,CHOLMOD_REAL, _common);
|
||||
|
||||
// copy data to cholmod matrix
|
||||
for(unsigned int i=0; i<values.size(); ++i)
|
||||
{
|
||||
((double*)(_AC->x))[i] = values[i];
|
||||
((int*) (_AC->i))[i] = rowind[i];
|
||||
}
|
||||
for(unsigned int i=0; i<colptr.size(); ++i)
|
||||
((int*)(_AC->p))[i] = colptr[i];
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
/// Eigen to Cholmod_dense interface
|
||||
template<class MatrixT>
|
||||
void cholmod_to_eigen_dense( const cholmod_dense& _AC, MatrixT& _A)
|
||||
{
|
||||
// initialize dimensions
|
||||
typedef typename MatrixT::Scalar Scalar;
|
||||
typedef Eigen::Triplet< Scalar > Triplet;
|
||||
size_t nzmax( _AC.nzmax);
|
||||
_A = MatrixT(_AC.nrow, _AC.ncol);
|
||||
std::vector< Triplet > triplets;
|
||||
triplets.reserve(nzmax);
|
||||
|
||||
if(!_AC.packed)
|
||||
{
|
||||
std::cerr << "Warning: " << __FUNCTION__ << " does not support unpacked matrices yet!!!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Pointer to data
|
||||
double* X((double*)_AC.x);
|
||||
|
||||
// complete matrix stored
|
||||
if(_AC.stype == 0)
|
||||
{
|
||||
// which integer type?
|
||||
if(_AC.itype == CHOLMOD_LONG)
|
||||
{
|
||||
UF_long* P((UF_long*)_AC.p);
|
||||
UF_long* I((UF_long*)_AC.i);
|
||||
|
||||
for(UF_long i=0; i<(UF_long)_AC.ncol; ++i)
|
||||
for(UF_long j= P[i]; j< P[i+1]; ++j)
|
||||
//_A( I[j], i) += X[j]; // += really needed?
|
||||
triplets.push_back( Triplet( I[j], i, X[j]));
|
||||
}
|
||||
else
|
||||
{
|
||||
int* P((int*)_AC.p);
|
||||
int* I((int*)_AC.i);
|
||||
|
||||
for(int i=0; i<(int)_AC.ncol; ++i)
|
||||
for(int j= P[i]; j< P[i+1]; ++j)
|
||||
triplets.push_back( Triplet( I[j], i, X[j]));
|
||||
//_A( I[j], i) += X[j];
|
||||
}
|
||||
|
||||
}
|
||||
else // only upper or lower diagonal stored
|
||||
{
|
||||
// which integer type?
|
||||
if(_AC.itype == CHOLMOD_LONG)
|
||||
{
|
||||
UF_long* P((UF_long*)_AC.p);
|
||||
UF_long* I((UF_long*)_AC.i);
|
||||
|
||||
for(UF_long i=0; i<(UF_long)_AC.ncol; ++i)
|
||||
for(UF_long j=P[i]; j<P[i+1]; ++j)
|
||||
{
|
||||
//_A(I[j], i) += X[j];
|
||||
triplets.push_back( Triplet( I[j], i, X[j]));
|
||||
|
||||
// add up symmetric part
|
||||
if( I[j] != i)
|
||||
triplets.push_back( Triplet( i, I[j], X[j]));
|
||||
//_A(i,I[j]) += X[j];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int* P((int*)_AC.p);
|
||||
int* I((int*)_AC.i);
|
||||
|
||||
for(int i=0; i<(int)_AC.ncol; ++i)
|
||||
for(int j=P[i]; j<P[i+1]; ++j)
|
||||
{
|
||||
//_A(I[j], i) += X[j];
|
||||
triplets.push_back( Triplet( I[j], i, X[j]));
|
||||
|
||||
// add up symmetric part
|
||||
if( I[j] != i)
|
||||
// _A(i,I[j]) += X[j];
|
||||
triplets.push_back( Triplet( i, I[j], X[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
_A.setFromTriplets( triplets.begin(), triplets.end());
|
||||
}
|
||||
|
||||
|
||||
/// GMM to Cholmod_sparse interface
|
||||
template<class MatrixT>
|
||||
void eigen_to_cholmod_dense( const MatrixT& _A, cholmod_dense* &_AC, cholmod_common* _common, bool _long_int)
|
||||
{
|
||||
int m = _A.innerSize();
|
||||
int n = _A.outerSize();
|
||||
|
||||
// allocate cholmod matrix
|
||||
_AC = cholmod_l_allocate_sparse(m,n,values.size(),true,true,_sparsity_type,CHOLMOD_REAL, _common);
|
||||
_AC = cholmod_l_allocate_dense (m,n,n, xtype, cc)
|
||||
|
||||
if( _long_int) // long int version
|
||||
{
|
||||
std::vector<double> values;
|
||||
std::vector<UF_long> rowind;
|
||||
std::vector<UF_long> colptr;
|
||||
|
||||
// get data of gmm matrix
|
||||
COMISO_EIGEN::get_ccs_symmetric_data( _A, uplo, values, rowind, colptr);
|
||||
|
||||
// allocate cholmod matrix
|
||||
_AC = cholmod_l_allocate_sparse(m,n,values.size(),true,true,_sparsity_type,CHOLMOD_REAL, _common);
|
||||
|
||||
// copy data to cholmod matrix
|
||||
for(UF_long i=0; i<(UF_long)values.size(); ++i)
|
||||
{
|
||||
((double*) (_AC->x))[i] = values[i];
|
||||
((UF_long*)(_AC->i))[i] = rowind[i];
|
||||
}
|
||||
|
||||
for(UF_long i=0; i<(UF_long)colptr.size(); ++i)
|
||||
((UF_long*)(_AC->p))[i] = colptr[i];
|
||||
}
|
||||
else // int version
|
||||
{
|
||||
std::vector<double> values;
|
||||
std::vector<int> rowind;
|
||||
std::vector<int> colptr;
|
||||
|
||||
// get data of gmm matrix
|
||||
COMISO_EIGEN::get_ccs_symmetric_data( _A, uplo, values, rowind, colptr);
|
||||
|
||||
// allocate cholmod matrix
|
||||
_AC = cholmod_allocate_sparse(m,n,values.size(),true,true,_sparsity_type,CHOLMOD_REAL, _common);
|
||||
|
||||
// copy data to cholmod matrix
|
||||
for(unsigned int i=0; i<values.size(); ++i)
|
||||
{
|
||||
((double*)(_AC->x))[i] = values[i];
|
||||
((int*) (_AC->i))[i] = rowind[i];
|
||||
}
|
||||
for(unsigned int i=0; i<colptr.size(); ++i)
|
||||
((int*)(_AC->p))[i] = colptr[i];
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
// convert a gmm col-sparse matrix into an eigen sparse matrix
|
||||
template<class GMM_MatrixT, class EIGEN_MatrixT>
|
||||
void gmm_to_eigen( const GMM_MatrixT& _G, EIGEN_MatrixT& _E)
|
||||
{
|
||||
#ifdef COMISO_EIGEN3_AVAILABLE
|
||||
typedef typename EIGEN_MatrixT::Scalar Scalar;
|
||||
|
||||
typedef typename gmm::linalg_traits<GMM_MatrixT>::const_sub_col_type ColT;
|
||||
typedef typename gmm::linalg_traits<ColT>::const_iterator CIter;
|
||||
|
||||
// build matrix triplets
|
||||
typedef Eigen::Triplet< Scalar > Triplet;
|
||||
std::vector< Triplet > triplets;
|
||||
triplets.reserve(gmm::nnz(_G));
|
||||
|
||||
for(unsigned int i=0; i<gmm::mat_ncols(_G); ++i)
|
||||
{
|
||||
ColT col = mat_const_col( _G, i );
|
||||
|
||||
CIter it = gmm::vect_const_begin( col );
|
||||
CIter ite = gmm::vect_const_end( col );
|
||||
for ( ; it!=ite; ++it )
|
||||
triplets.push_back( Triplet( it.index(), i, *it));
|
||||
}
|
||||
|
||||
// generate eigen matrix
|
||||
_E = EIGEN_MatrixT( gmm::mat_nrows(_G), gmm::mat_ncols(_G));
|
||||
_E.setFromTriplets( triplets.begin(), triplets.end());
|
||||
#endif
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
|
||||
//=============================================================================
|
||||
#endif // COMISO_EIGEN3_AVAILABLE
|
||||
//=============================================================================
|
||||
129
src/external/CoMISo/Solver/Eigen_Tools.hh
vendored
Normal file
129
src/external/CoMISo/Solver/Eigen_Tools.hh
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#ifndef COMISO_Eigen_TOOLS_HH
|
||||
#define COMISO_Eigen_TOOLS_HH
|
||||
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#if COMISO_EIGEN3_AVAILABLE
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
#include <Eigen/Dense>
|
||||
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
|
||||
#include <Eigen/Sparse>
|
||||
|
||||
#if COMISO_SUITESPARSE_AVAILABLE
|
||||
#include <cholmod.h>
|
||||
#endif
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO_EIGEN
|
||||
{
|
||||
|
||||
/** \class EigenTools Eigen_Tools.hh
|
||||
|
||||
A collection of helper functions for manipulating (Eigen) matrices.
|
||||
*/
|
||||
|
||||
|
||||
//== FUNCTION DEFINITION ======================================================
|
||||
|
||||
/// Get matrix data (CSC matrix format) from matrix
|
||||
/** Used by Cholmod wrapper
|
||||
* @param _mat matrix
|
||||
* @param _c uplo parameter (l, L, u, U, c, C)
|
||||
* @param _values values vector
|
||||
* @param _rowind row indices
|
||||
* @param _colptr column pointer */
|
||||
template<class MatrixT, class REALT, class INTT>
|
||||
void get_ccs_symmetric_data( const MatrixT& _mat,
|
||||
const char _c,
|
||||
std::vector<REALT>& _values,
|
||||
std::vector<INTT>& _rowind,
|
||||
std::vector<INTT>& _colptr );
|
||||
|
||||
/// Inspect the matrix (print)
|
||||
/** Prints useful matrix informations such as, dimension, symmetry, zero_rows, zero_cols, nnz, max, min, max_abs, min_abs, NAN, INF
|
||||
* @param _A matrix */
|
||||
template<class MatrixT>
|
||||
void inspect_matrix( const MatrixT& _A);
|
||||
|
||||
/** checks for symmetry
|
||||
* @param _A matrix
|
||||
* @return symmetric? (bool)*/
|
||||
template<class MatrixT>
|
||||
bool is_symmetric( const MatrixT& _A);
|
||||
|
||||
template< class Eigen_MatrixT, class IntT >
|
||||
void permute( const Eigen_MatrixT& _QR, const std::vector< IntT>& _Pvec, Eigen_MatrixT& _A);
|
||||
|
||||
|
||||
#if COMISO_SUITESPARSE_AVAILABLE
|
||||
|
||||
/// Eigen to Cholmod_sparse interface
|
||||
template<class MatrixT>
|
||||
void cholmod_to_eigen( const cholmod_sparse& _AC, MatrixT& _A);
|
||||
|
||||
template<class MatrixT>
|
||||
void eigen_to_cholmod( const MatrixT& _A,
|
||||
cholmod_sparse* &_AC,
|
||||
cholmod_common* _common,
|
||||
int _sparsity_type = 0,
|
||||
bool _long_int = false);
|
||||
#endif
|
||||
|
||||
// convert a gmm column-sparse matrix into an eigen sparse matrix
|
||||
template<class GMM_MatrixT, class EIGEN_MatrixT>
|
||||
void gmm_to_eigen( const GMM_MatrixT& _G, EIGEN_MatrixT& _E);
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO_Eigen
|
||||
//=============================================================================
|
||||
#if defined(INCLUDE_TEMPLATES) && !defined(COMISO_Eigen_TOOLS_C)
|
||||
#define COMISO_Eigen_TOOLS_TEMPLATES
|
||||
#include "Eigen_Tools.cc"
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
#endif // COMISO_EIGEN3_AVAILABLE
|
||||
//=============================================================================//=============================================================================
|
||||
#endif // Eigen_TOOLS_HH defined
|
||||
//=============================================================================
|
||||
|
||||
1262
src/external/CoMISo/Solver/GMM_Tools.cc
vendored
Normal file
1262
src/external/CoMISo/Solver/GMM_Tools.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
275
src/external/CoMISo/Solver/GMM_Tools.hh
vendored
Normal file
275
src/external/CoMISo/Solver/GMM_Tools.hh
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#ifndef COMISO_GMM_TOOLS_HH
|
||||
#define COMISO_GMM_TOOLS_HH
|
||||
|
||||
|
||||
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
|
||||
#include <CoMISo/Config/config.hh>
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <gmm/gmm.h>
|
||||
|
||||
#if COMISO_SUITESPARSE_AVAILABLE
|
||||
#include <cholmod.h>
|
||||
#endif
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO_GMM
|
||||
{
|
||||
|
||||
/** \class GMMTools GMM_Tools.hh
|
||||
|
||||
A collection of helper functions for manipulating (gmm) matrices.
|
||||
*/
|
||||
|
||||
|
||||
//== FUNCTION DEFINITION ======================================================
|
||||
|
||||
/** @name Variable elimination
|
||||
* These functions are used to eliminate (one or more) variables x_i from an equation system Ax=b. Elimination meaning that x_i has been assigned a value x_i = c and is considered a constant, this changes entries of the matrix which depend on i and finally "eliminates" the ith row and column and updates the rhs. */
|
||||
/*@{*/
|
||||
|
||||
/// Eliminate multiple variables from a CSC matrix.
|
||||
/**
|
||||
* \note eliminate_csc_vars2 is probably more efficient
|
||||
* @param _evar indices of variables to be eliminated
|
||||
* @param _eval values c_i of x_i to be eliminated, x_i = c_i
|
||||
* @param _A CSC Matrix of the equation system
|
||||
* @param _x variable vector of equation system
|
||||
* @param _rhs right-hand side vector of equation system */
|
||||
template<class ScalarT, class VectorT, class RealT, class IntegerT>
|
||||
void eliminate_csc_vars(
|
||||
const std::vector<IntegerT>& _evar,
|
||||
const std::vector<ScalarT>& _eval,
|
||||
typename gmm::csc_matrix<RealT>& _A,
|
||||
VectorT& _x,
|
||||
VectorT& _rhs );
|
||||
|
||||
/// Eliminate variables from a CSC matric.
|
||||
template<class ScalarT, class VectorT, class RealT, class IntegerT>
|
||||
void eliminate_csc_vars2(
|
||||
const std::vector<IntegerT>& _evar,
|
||||
const std::vector<ScalarT>& _eval,
|
||||
typename gmm::csc_matrix<RealT>& _A,
|
||||
VectorT& _x,
|
||||
VectorT& _rhs );
|
||||
|
||||
/// Eliminate only one variable x_i = c (CSC matrices)
|
||||
/** Specialization to eliminating one varaible
|
||||
* @param _j index of variable to be eliminated
|
||||
* @param _value_j value c of x_i to be eliminated, x_i = c
|
||||
* @param _A CSC Matrix of the equation system
|
||||
* @param _x variable vector of equation system
|
||||
* @param _rhs right-hand side vector of equation system */
|
||||
template<class ScalarT, class VectorT, class RealT>
|
||||
void eliminate_var(
|
||||
const unsigned int _j,
|
||||
const ScalarT _value_j,
|
||||
typename gmm::csc_matrix<RealT>& _A,
|
||||
VectorT& _x,
|
||||
VectorT& _rhs );
|
||||
|
||||
|
||||
|
||||
/// eliminate multiple variables from a (NON CSC) linear system by fixin x[j] = _value_j
|
||||
/**
|
||||
* @param _evar indices of variables to be eliminated
|
||||
* @param _eval values c_i of x_i to be eliminated, x_i = c_i
|
||||
* @param _A (non-CSC) Matrix of the equation system
|
||||
* @param _x variable vector of equation system
|
||||
* @param _rhs right-hand side vector of equation system */
|
||||
template<class IntegerT, class ScalarT, class VectorT, class MatrixT>
|
||||
void eliminate_vars(
|
||||
const std::vector<IntegerT>& _evar,
|
||||
const std::vector<ScalarT>& _eval,
|
||||
MatrixT& _A,
|
||||
VectorT& _x,
|
||||
VectorT& _rhs );
|
||||
|
||||
/// Eliminate only one variable x_i = c (non-CSC matrices)
|
||||
/** Specialization to eliminating one varaible
|
||||
* @param _j index of variable to be eliminated
|
||||
* @param _value_j value c of x_i to be eliminated, x_i = c
|
||||
* @param _A (non-CSC) Matrix of the equation system
|
||||
* @param _x variable vector of equation system
|
||||
* @param _rhs right-hand side vector of equation system */
|
||||
template<class ScalarT, class VectorT, class SVT>
|
||||
void eliminate_var(
|
||||
const unsigned int _j,
|
||||
const ScalarT _value_j,
|
||||
gmm::col_matrix<SVT>& _A,
|
||||
VectorT& _x,
|
||||
VectorT& _rhs );
|
||||
|
||||
/// update indices of eliminated variables
|
||||
/**
|
||||
* @param _evar indices of variables that were eliminated
|
||||
* @param _idx index map to be changed.
|
||||
* @param _dummy value to which eliminated entries of _idx are set. */
|
||||
template<class IntegerT, class IntegerT2>
|
||||
void eliminate_vars_idx(
|
||||
const std::vector<IntegerT >& _evar,
|
||||
std::vector<IntegerT2>& _idx,
|
||||
IntegerT2 _dummy = -1,
|
||||
IntegerT2 _range = -1);
|
||||
|
||||
/// update index of eliminated variable
|
||||
/** Specialization to update only one eliminated variable
|
||||
* @param _evar index of variable that was eliminated
|
||||
* @param _idx index map to be changed.
|
||||
* @param _dummy value to which eliminated entry of _idx is set. */
|
||||
template<class IntegerT, class IntegerT2>
|
||||
void eliminate_var_idx(
|
||||
const IntegerT _evar,
|
||||
std::vector<IntegerT2>& _idx,
|
||||
IntegerT2 _dummy = -1 );
|
||||
|
||||
|
||||
/// do in-place elimination in CSC format by setting row and column to zero and
|
||||
/// diagonal entry to zero
|
||||
/**
|
||||
* @param _j index of variable to be eliminated
|
||||
* @param _value_j value c of x_i to be eliminated, x_i = c
|
||||
* @param _A (non-CSC) Matrix of the equation system
|
||||
* @param _x variable vector of equation system
|
||||
* @param _rhs right-hand side vector of equation system */
|
||||
template<class ScalarT, class VectorT, class RealT>
|
||||
void fix_var_csc_symmetric( const unsigned int _j,
|
||||
const ScalarT _value_j,
|
||||
typename gmm::csc_matrix<RealT>& _A,
|
||||
VectorT& _x,
|
||||
VectorT& _rhs );
|
||||
|
||||
|
||||
/*@}*/
|
||||
|
||||
|
||||
/// Get matrix data (CSC matrix format) from matrix
|
||||
/** Used by Cholmod wrapper
|
||||
* @param _mat matrix
|
||||
* @param _c uplo parameter (l, L, u, U, c, C)
|
||||
* @param _values values vector
|
||||
* @param _rowind row indices
|
||||
* @param _colptr column pointer */
|
||||
template<class MatrixT, class REALT, class INTT>
|
||||
void get_ccs_symmetric_data( const MatrixT& _mat,
|
||||
const char _c,
|
||||
std::vector<REALT>& _values,
|
||||
std::vector<INTT>& _rowind,
|
||||
std::vector<INTT>& _colptr );
|
||||
|
||||
/// Regularize matrix
|
||||
/** Makes matrices with rank(_mat)<n solvable.
|
||||
* Add factor*avg(trace(_mat))*Identity to _mat.
|
||||
* @param _mat Matrix to regularize
|
||||
* @param _v factor in factor*avg(trace(_mat))*Identity */
|
||||
template<class MatrixT>
|
||||
void regularize_hack( MatrixT& _mat, double _v = 1e-6 );
|
||||
|
||||
|
||||
/// Local Gauss Seidel update of lin. equation system.
|
||||
/**
|
||||
* Add factor*avg(trace(_mat))*Identity to _mat.
|
||||
* @param _A Matrix of linear system
|
||||
* @param _x variable vector of linear system
|
||||
* @param _rhs right hand side of linear system
|
||||
* @param _max_iter maximum number of iterations
|
||||
* @param _tolerance error tolerance threshold
|
||||
* @return number of iterations performed */
|
||||
template<class MatrixT, class VectorT>
|
||||
int gauss_seidel_local(
|
||||
MatrixT& _A,
|
||||
VectorT& _x,
|
||||
VectorT& _rhs,
|
||||
std::vector<unsigned int> _idxs,
|
||||
int _max_iter = 10000,
|
||||
double _tolerance = 1e-6 );
|
||||
|
||||
|
||||
/// Residuum norm of linear system
|
||||
/** residuum = Ax-b
|
||||
* @param _A Matrix
|
||||
* @param _x Variables
|
||||
* @param _rhs right hand side
|
||||
* @return norm Ax-rhs */
|
||||
template<class MatrixT, class VectorT>
|
||||
double residuum_norm( MatrixT& _A, VectorT& _x, VectorT& _rhs );
|
||||
|
||||
|
||||
/// Convert factored LSE to quadratic representation
|
||||
/** Conversion is done by computing _F^t _F where the last column is the _rhs
|
||||
* @param _F Factored Matrix (input)
|
||||
* @param _Q Quadratic Matrix (output)
|
||||
* @param _rhs right hand side (output) */
|
||||
template<class MatrixT, class MatrixT2, class VectorT>
|
||||
void factored_to_quadratic( MatrixT& _F, MatrixT2& _Q, VectorT& _rhs);
|
||||
|
||||
|
||||
/// Inspect the matrix (print)
|
||||
/** Prints useful matrix informations such as, dimension, symmetry, zero_rows, zero_cols, nnz, max, min, max_abs, min_abs, NAN, INF
|
||||
* @param _A matrix */
|
||||
template<class MatrixT>
|
||||
void inspect_matrix( const MatrixT& _A);
|
||||
|
||||
/// Print the matrix as dense matrix
|
||||
template<class MatrixT>
|
||||
void print_dense( const MatrixT& _A);
|
||||
|
||||
|
||||
#if COMISO_SUITESPARSE_AVAILABLE
|
||||
|
||||
/// GMM to Cholmod_sparse interface
|
||||
template<class MatrixT>
|
||||
void cholmod_to_gmm( const cholmod_sparse& _AC, MatrixT& _A);
|
||||
|
||||
template<class MatrixT>
|
||||
void gmm_to_cholmod( const MatrixT& _A,
|
||||
cholmod_sparse* &_AC,
|
||||
cholmod_common* _common,
|
||||
int _sparsity_type = 0,
|
||||
bool _long_int = false);
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO_GMM
|
||||
//=============================================================================
|
||||
#if defined(INCLUDE_TEMPLATES) && !defined(COMISO_GMM_TOOLS_C)
|
||||
#define COMISO_GMM_TOOLS_TEMPLATES
|
||||
#include "GMM_Tools.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // GMM_GMM_TOOLS_HH defined
|
||||
//=============================================================================
|
||||
|
||||
253
src/external/CoMISo/Solver/IterativeSolverT.cc
vendored
Normal file
253
src/external/CoMISo/Solver/IterativeSolverT.cc
vendored
Normal file
@ -0,0 +1,253 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS IterativeSolverT - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#define COMISO_ITERATIVESOLVERT_C
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include "IterativeSolverT.hh"
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO{
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
template <class RealT>
|
||||
bool
|
||||
IterativeSolverT<RealT>::
|
||||
gauss_seidel_local( typename gmm::csc_matrix<Real>& _A,
|
||||
std::vector<Real>& _x,
|
||||
std::vector<Real>& _rhs,
|
||||
std::vector<unsigned int>& _idxs,
|
||||
int& _max_iter,
|
||||
Real& _tolerance )
|
||||
{
|
||||
if( _max_iter == 0) return false;
|
||||
|
||||
typedef typename gmm::linalg_traits< gmm::csc_matrix<Real> >::const_sub_col_type ColT;
|
||||
typedef typename gmm::linalg_traits<ColT>::const_iterator CIter;
|
||||
|
||||
// clear old data
|
||||
i_temp.clear();
|
||||
q.clear();
|
||||
|
||||
for ( unsigned int i=0; i<_idxs.size(); ++i )
|
||||
q.push_back( _idxs[i] );
|
||||
|
||||
int it_count = 0;
|
||||
|
||||
while ( !q.empty() && it_count < _max_iter )
|
||||
{
|
||||
++it_count;
|
||||
unsigned int cur_i = q.front();
|
||||
q.pop_front();
|
||||
i_temp.clear();
|
||||
|
||||
ColT col = mat_const_col( _A, cur_i );
|
||||
|
||||
CIter it = gmm::vect_const_begin( col );
|
||||
CIter ite = gmm::vect_const_end( col );
|
||||
|
||||
double res_i = -_rhs[cur_i];
|
||||
double x_i_new = _rhs[cur_i];
|
||||
double diag = 1.0;
|
||||
for ( ; it!=ite; ++it )
|
||||
{
|
||||
res_i += ( *it ) * _x[it.index()];
|
||||
x_i_new -= ( *it ) * _x[it.index()];
|
||||
if( it.index() != cur_i)
|
||||
i_temp.push_back( it.index() );
|
||||
else
|
||||
diag = *it;
|
||||
}
|
||||
|
||||
// take inverse of diag
|
||||
diag = 1.0/diag;
|
||||
|
||||
// compare relative residuum normalized by diagonal entry
|
||||
if ( fabs(res_i*diag) > _tolerance )
|
||||
{
|
||||
_x[cur_i] += x_i_new*diag;
|
||||
|
||||
for ( unsigned int j=0; j<i_temp.size(); ++j )
|
||||
q.push_back( i_temp[j] );
|
||||
}
|
||||
}
|
||||
|
||||
// converged?
|
||||
return q.empty();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class RealT>
|
||||
bool
|
||||
IterativeSolverT<RealT>::
|
||||
gauss_seidel_local2( typename gmm::csc_matrix<Real>& _A,
|
||||
std::vector<Real>& _x,
|
||||
std::vector<Real>& _rhs,
|
||||
std::vector<unsigned int>& _idxs,
|
||||
int& _max_iter,
|
||||
Real& _tolerance )
|
||||
{
|
||||
typedef typename gmm::linalg_traits< gmm::csc_matrix<Real> >::const_sub_col_type ColT;
|
||||
typedef typename gmm::linalg_traits<ColT>::const_iterator CIter;
|
||||
|
||||
double t2 = _tolerance*_tolerance;
|
||||
|
||||
// clear old data
|
||||
i_temp.clear();
|
||||
s.clear();
|
||||
|
||||
for ( unsigned int i=0; i<_idxs.size(); ++i )
|
||||
s.insert( _idxs[i] );
|
||||
|
||||
int it_count = 0;
|
||||
|
||||
bool finished = false;
|
||||
|
||||
while ( !finished && it_count < _max_iter )
|
||||
{
|
||||
finished = true;
|
||||
std::set<int>::iterator s_it = s.begin();
|
||||
for(; s_it != s.end(); ++s_it)
|
||||
{
|
||||
++it_count;
|
||||
unsigned int cur_i = *s_it;
|
||||
i_temp.clear();
|
||||
|
||||
ColT col = mat_const_col( _A, cur_i );
|
||||
|
||||
CIter it = gmm::vect_const_begin( col );
|
||||
CIter ite = gmm::vect_const_end( col );
|
||||
|
||||
double res_i = -_rhs[cur_i];
|
||||
double x_i_new = _rhs[cur_i];
|
||||
double diag = 1.0;
|
||||
for ( ; it!=ite; ++it )
|
||||
{
|
||||
res_i += ( *it ) * _x[it.index()];
|
||||
x_i_new -= ( *it ) * _x[it.index()];
|
||||
if( it.index() != cur_i)
|
||||
i_temp.push_back( it.index() );
|
||||
else
|
||||
diag = *it;
|
||||
}
|
||||
|
||||
// compare relative residuum normalized by diagonal entry
|
||||
if ( res_i*res_i/diag > t2 )
|
||||
{
|
||||
_x[cur_i] += x_i_new/_A( cur_i, cur_i );
|
||||
|
||||
for ( unsigned int j=0; j<i_temp.size(); ++j )
|
||||
{
|
||||
finished = false;
|
||||
s.insert( i_temp[j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// converged?
|
||||
return finished;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class RealT>
|
||||
bool
|
||||
IterativeSolverT<RealT>::
|
||||
conjugate_gradient( typename gmm::csc_matrix<Real>& _A,
|
||||
std::vector<Real>& _x,
|
||||
std::vector<Real>& _rhs,
|
||||
int& _max_iter,
|
||||
Real& _tolerance )
|
||||
{
|
||||
Real rho, rho_1(0), a;
|
||||
|
||||
// initialize vectors
|
||||
p_.resize(_x.size());
|
||||
q_.resize(_x.size());
|
||||
r_.resize(_x.size());
|
||||
d_.resize(_x.size());
|
||||
gmm::copy( _x, p_);
|
||||
|
||||
// initialize diagonal (for relative norm)
|
||||
for(unsigned int i=0; i<_x.size(); ++i)
|
||||
d_[i] = 1.0/_A(i,i);
|
||||
|
||||
// start with iteration 0
|
||||
int cur_iter(0);
|
||||
|
||||
gmm::mult(_A, gmm::scaled(_x, Real(-1)), _rhs, r_);
|
||||
rho = gmm::vect_sp( r_, r_);
|
||||
gmm::copy(r_, p_);
|
||||
|
||||
bool not_converged = true;
|
||||
Real res_norm(0);
|
||||
|
||||
// while not converged
|
||||
while( (not_converged = ( (res_norm=vect_norm_rel(r_, d_)) > _tolerance)) &&
|
||||
cur_iter < _max_iter)
|
||||
{
|
||||
// std::cerr << "iter " << cur_iter << " res " << res_norm << std::endl;
|
||||
|
||||
if (cur_iter != 0)
|
||||
{
|
||||
rho = gmm::vect_sp( r_, r_);
|
||||
gmm::add(r_, gmm::scaled(p_, rho / rho_1), p_);
|
||||
}
|
||||
|
||||
gmm::mult(_A, p_, q_);
|
||||
|
||||
a = rho / gmm::vect_sp( q_, p_);
|
||||
gmm::add(gmm::scaled(p_, a), _x);
|
||||
gmm::add(gmm::scaled(q_, -a), r_);
|
||||
rho_1 = rho;
|
||||
|
||||
++cur_iter;
|
||||
}
|
||||
|
||||
_max_iter = cur_iter;
|
||||
_tolerance = res_norm;
|
||||
|
||||
return (!not_converged);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class RealT>
|
||||
typename IterativeSolverT<RealT>::Real
|
||||
IterativeSolverT<RealT>::
|
||||
vect_norm_rel(const std::vector<Real>& _v, const std::vector<Real>& _diag) const
|
||||
{
|
||||
Real res = 0.0;
|
||||
|
||||
for(unsigned int i=0; i<_v.size(); ++i)
|
||||
{
|
||||
res = std::max(fabs(_v[i]*_diag[i]), res);
|
||||
|
||||
// Real cur = fabs(_v[i]*_diag[i]);
|
||||
// if(cur > res)
|
||||
// res = cur;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
104
src/external/CoMISo/Solver/IterativeSolverT.hh
vendored
Normal file
104
src/external/CoMISo/Solver/IterativeSolverT.hh
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS IterativeSolverT
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_ITERATIVESOLVERT_HH
|
||||
#define COMISO_ITERATIVESOLVERT_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <gmm/gmm.h>
|
||||
#include <deque>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
|
||||
/** \class IterativeSolverT IterativeSolverT.hh <COMISO/.../IterativeSolverT.hh>
|
||||
|
||||
Brief Description.
|
||||
|
||||
A more elaborate description follows.
|
||||
*/
|
||||
|
||||
template <class RealT>
|
||||
class IterativeSolverT
|
||||
{
|
||||
public:
|
||||
|
||||
typedef RealT Real;
|
||||
|
||||
/// Constructor
|
||||
IterativeSolverT() {}
|
||||
|
||||
/// Destructor
|
||||
~IterativeSolverT() {}
|
||||
|
||||
|
||||
// local gauss_seidel
|
||||
bool gauss_seidel_local( typename gmm::csc_matrix<Real>& _A,
|
||||
std::vector<Real>& _x,
|
||||
std::vector<Real>& _rhs,
|
||||
std::vector<unsigned int>& _idxs,
|
||||
int& _max_iter,
|
||||
Real& _tolerance );
|
||||
|
||||
// local gauss_seidel
|
||||
bool gauss_seidel_local2( typename gmm::csc_matrix<Real>& _A,
|
||||
std::vector<Real>& _x,
|
||||
std::vector<Real>& _rhs,
|
||||
std::vector<unsigned int>& _idxs,
|
||||
int& _max_iter,
|
||||
Real& _tolerance );
|
||||
|
||||
// conjugate gradient
|
||||
bool conjugate_gradient( typename gmm::csc_matrix<Real>& _A,
|
||||
std::vector<Real>& _x,
|
||||
std::vector<Real>& _rhs,
|
||||
int& _max_iter,
|
||||
Real& _tolerance );
|
||||
|
||||
private:
|
||||
// compute relative norm
|
||||
Real vect_norm_rel(const std::vector<Real>& _v, const std::vector<Real>& _diag) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// helper for conjugate gradient
|
||||
std::vector<Real> p_;
|
||||
std::vector<Real> q_;
|
||||
std::vector<Real> r_;
|
||||
std::vector<Real> d_;
|
||||
|
||||
// helper for local gauss seidel
|
||||
std::vector<unsigned int> i_temp;
|
||||
std::deque<unsigned int> q;
|
||||
std::set<int> s;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#if defined(INCLUDE_TEMPLATES) && !defined(COMISO_ITERATIVESOLVERT_C)
|
||||
#define COMISO_ITERATIVESOLVERT_TEMPLATES
|
||||
#include "IterativeSolverT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // COMISO_ITERATIVESOLVERT_HH defined
|
||||
//=============================================================================
|
||||
|
||||
738
src/external/CoMISo/Solver/MISolver.cc
vendored
Normal file
738
src/external/CoMISo/Solver/MISolver.cc
vendored
Normal file
@ -0,0 +1,738 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#include <CoMISo/Config/config.hh>
|
||||
#include "MISolver.hh"
|
||||
|
||||
#if(COMISO_QT4_AVAILABLE)
|
||||
#include <CoMISo/QtWidgets/MISolverDialogUI.hh>
|
||||
#endif
|
||||
|
||||
#if COMISO_GUROBI_AVAILABLE
|
||||
#include <gurobi_c++.h>
|
||||
#endif
|
||||
|
||||
#include <CoMISo/Utils/StopWatch.hh>
|
||||
|
||||
#include <gmm/gmm.h>
|
||||
#include <float.h>
|
||||
|
||||
// hack for testing only
|
||||
#include "SparseQRSolver.hh"
|
||||
#include "UMFPACKSolver.hh"
|
||||
#include "EigenLDLTSolver.hh"
|
||||
|
||||
#define ROUND(x) ((x)<0?int((x)-0.5):int((x)+0.5))
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
|
||||
|
||||
// Constructor
|
||||
MISolver::MISolver()
|
||||
{
|
||||
// default parameters
|
||||
initial_full_solution_ = true;
|
||||
iter_full_solution_ = true;
|
||||
final_full_solution_ = true;
|
||||
|
||||
direct_rounding_ = false;
|
||||
no_rounding_ = false;
|
||||
multiple_rounding_ = true;
|
||||
gurobi_rounding_ = false;
|
||||
cplex_rounding_ = false;
|
||||
|
||||
max_local_iters_ = 100000;
|
||||
max_local_error_ = 1e-3;
|
||||
max_cg_iters_ = 50;
|
||||
max_cg_error_ = 1e-3;
|
||||
|
||||
multiple_rounding_threshold_ = 0.5;
|
||||
|
||||
gurobi_max_time_ = 60;
|
||||
|
||||
noisy_ = 0;
|
||||
stats_ = true;
|
||||
|
||||
use_constraint_reordering_ = true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
MISolver::solve_no_rounding(
|
||||
CSCMatrix& _A,
|
||||
Vecd& _x,
|
||||
Vecd& _rhs )
|
||||
{
|
||||
direct_solver_.calc_system_gmm(_A);
|
||||
direct_solver_.solve(_x, _rhs);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
MISolver::resolve(
|
||||
Vecd& _x,
|
||||
Vecd& _rhs )
|
||||
{
|
||||
direct_solver_.solve(_x, _rhs);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
MISolver::solve_direct_rounding(
|
||||
CSCMatrix& _A,
|
||||
Vecd& _x,
|
||||
Vecd& _rhs,
|
||||
Veci& _to_round)
|
||||
{
|
||||
Veci to_round(_to_round);
|
||||
// copy to round vector and make it unique
|
||||
std::sort(to_round.begin(), to_round.end());
|
||||
Veci::iterator last_unique;
|
||||
last_unique = std::unique(to_round.begin(), to_round.end());
|
||||
int r = last_unique - to_round.begin();
|
||||
to_round.resize( r);
|
||||
|
||||
// initalize old indices
|
||||
Veci old_idx(_rhs.size());
|
||||
for(unsigned int i=0; i<old_idx.size(); ++i)
|
||||
old_idx[i] = i;
|
||||
direct_solver_.calc_system_gmm(_A);
|
||||
direct_solver_.solve(_x, _rhs);
|
||||
|
||||
// check solver performance (only for testing!!!)
|
||||
{
|
||||
StopWatch sw;
|
||||
|
||||
// hack
|
||||
const bool enable_performance_test = false;
|
||||
|
||||
// performance comparison code
|
||||
#if(COMISO_SUITESPARSE_SPQR_AVAILABLE)
|
||||
if(enable_performance_test)
|
||||
{
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
// performance comparison code
|
||||
#if(COMISO_SUITESPARSE_AVAILABLE)
|
||||
if(enable_performance_test)
|
||||
{
|
||||
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
|
||||
if(enable_performance_test)
|
||||
{
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if(COMISO_EIGEN3_AVAILABLE)
|
||||
// performance comparison code
|
||||
if(enable_performance_test)
|
||||
{
|
||||
sw.start();
|
||||
COMISO::EigenLDLTSolver ldlt;
|
||||
ldlt.calc_system_gmm(_A);
|
||||
std::cerr << "Eigen LDLT factor took: " << sw.stop()/1000.0 << "s\n";
|
||||
Vecd x5(_x);
|
||||
sw.start();
|
||||
ldlt.solve(x5,_rhs);
|
||||
std::cerr << "Eigen LDLT solve took: " << sw.stop()/1000.0 << "s\n";
|
||||
Vecd res(_x);
|
||||
gmm::add(_x,gmm::scaled(x5,-1.0),res);
|
||||
std::cerr << "DIFFERENCE IN RESULT: " << gmm::vect_norm2(res) << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// round and eliminate variables
|
||||
Vecui elim_i;
|
||||
Vecd elim_v;
|
||||
for( unsigned int i=0; i < to_round.size(); ++i)
|
||||
{
|
||||
_x[to_round[i]] = ROUND(_x[to_round[i]]);
|
||||
elim_i.push_back(to_round[i]);
|
||||
elim_v.push_back(_x[to_round[i]]);
|
||||
// update old idx
|
||||
old_idx[to_round[i]] = -1;
|
||||
}
|
||||
|
||||
Veci::iterator new_end = std::remove( old_idx.begin(), old_idx.end(), -1);
|
||||
old_idx.resize( new_end-old_idx.begin());
|
||||
// eliminate vars from linear system
|
||||
Vecd xr(_x);
|
||||
COMISO_GMM::eliminate_csc_vars2( elim_i, elim_v, _A, xr, _rhs);
|
||||
|
||||
// std::cerr << "size A: " << gmm::mat_nrows(_A) << " " << gmm::mat_ncols(_A)
|
||||
// << std::endl;
|
||||
// std::cerr << "size x : " << xr.size() << std::endl;
|
||||
// std::cerr << "size rhs: " << _rhs.size() << std::endl;
|
||||
|
||||
// final full solution
|
||||
if( gmm::mat_ncols( _A) > 0)
|
||||
{
|
||||
// direct_solver_.update_system_gmm(_A);
|
||||
direct_solver_.calc_system_gmm(_A);
|
||||
direct_solver_.solve( xr, _rhs);
|
||||
}
|
||||
|
||||
// store solution values to result vector
|
||||
for(unsigned int i=0; i<old_idx.size(); ++i)
|
||||
{
|
||||
_x[ old_idx[i] ] = xr[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
MISolver::solve_iterative(
|
||||
CSCMatrix& _A,
|
||||
Vecd& _x,
|
||||
Vecd& _rhs,
|
||||
Veci& _to_round,
|
||||
bool _fixed_order )
|
||||
{
|
||||
// StopWatch
|
||||
COMISO::StopWatch sw;
|
||||
double time_search_next_integer = 0;
|
||||
|
||||
// some statistics
|
||||
n_local_ = 0;
|
||||
n_cg_ = 0;
|
||||
n_full_ = 0;
|
||||
|
||||
// reset cholmod step flag
|
||||
cholmod_step_done_ = false;
|
||||
|
||||
Veci to_round(_to_round);
|
||||
// if the order is not fixed, uniquify the indices
|
||||
if( !_fixed_order)
|
||||
{
|
||||
// copy to round vector and make it unique
|
||||
std::sort(to_round.begin(), to_round.end());
|
||||
Veci::iterator last_unique;
|
||||
last_unique = std::unique(to_round.begin(), to_round.end());
|
||||
int r = last_unique - to_round.begin();
|
||||
to_round.resize( r);
|
||||
}
|
||||
|
||||
// initalize old indices
|
||||
Veci old_idx(_rhs.size());
|
||||
for(unsigned int i=0; i<old_idx.size(); ++i)
|
||||
old_idx[i] = i;
|
||||
|
||||
if( initial_full_solution_)
|
||||
{
|
||||
if( noisy_ > 2) std::cerr << "initial full solution" << std::endl;
|
||||
direct_solver_.calc_system_gmm(_A);
|
||||
direct_solver_.solve(_x, _rhs);
|
||||
|
||||
cholmod_step_done_ = true;
|
||||
|
||||
++n_full_;
|
||||
}
|
||||
|
||||
// neighbors for local optimization
|
||||
Vecui neigh_i;
|
||||
|
||||
// Vector for reduced solution
|
||||
Vecd xr(_x);
|
||||
|
||||
// loop until solution computed
|
||||
for(unsigned int i=0; i<to_round.size(); ++i)
|
||||
{
|
||||
if( noisy_ > 0)
|
||||
{
|
||||
std::cerr << "Integer DOF's left: " << to_round.size()-(i+1) << " ";
|
||||
if( noisy_ > 1)
|
||||
std::cerr << "residuum_norm: " << COMISO_GMM::residuum_norm( _A, xr, _rhs) << std::endl;
|
||||
}
|
||||
|
||||
// index to eliminate
|
||||
unsigned int i_best = 0;
|
||||
|
||||
// position in round vector
|
||||
unsigned int tr_best = 0;
|
||||
|
||||
if( _fixed_order ) // if order is fixed, simply get next index from to_round
|
||||
{
|
||||
i_best = to_round[i];
|
||||
}
|
||||
else // else search for best rounding candidate
|
||||
{
|
||||
sw.start();
|
||||
// find index yielding smallest rounding error
|
||||
double r_best = FLT_MAX;
|
||||
for(unsigned int j=0; j<to_round.size(); ++j)
|
||||
{
|
||||
if( to_round[j] != -1)
|
||||
{
|
||||
int cur_idx = to_round[j];
|
||||
double rnd_error = fabs( ROUND(xr[cur_idx]) - xr[cur_idx]);
|
||||
if( rnd_error < r_best)
|
||||
{
|
||||
i_best = cur_idx;
|
||||
r_best = rnd_error;
|
||||
tr_best = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
time_search_next_integer += sw.stop();
|
||||
}
|
||||
|
||||
// store rounded value
|
||||
double rnd_x = ROUND(xr[i_best]);
|
||||
_x[ old_idx[i_best] ] = rnd_x;
|
||||
|
||||
// compute neighbors
|
||||
neigh_i.clear();
|
||||
Col col = gmm::mat_const_col(_A, i_best);
|
||||
ColIter it = gmm::vect_const_begin( col);
|
||||
ColIter ite = gmm::vect_const_end ( col);
|
||||
for(; it!=ite; ++it)
|
||||
if(it.index() != i_best)
|
||||
neigh_i.push_back(it.index());
|
||||
|
||||
// eliminate var
|
||||
COMISO_GMM::fix_var_csc_symmetric(i_best, rnd_x, _A, xr, _rhs);
|
||||
to_round[tr_best] = -1;
|
||||
|
||||
// 3-stage update of solution w.r.t. roundings
|
||||
// local GS / CG / SparseCholesky
|
||||
update_solution( _A, xr, _rhs, neigh_i);
|
||||
}
|
||||
|
||||
// final full solution?
|
||||
if( final_full_solution_)
|
||||
{
|
||||
if( noisy_ > 2) std::cerr << "final full solution" << std::endl;
|
||||
|
||||
if( gmm::mat_ncols( _A) > 0)
|
||||
{
|
||||
if(cholmod_step_done_)
|
||||
direct_solver_.update_system_gmm(_A);
|
||||
else
|
||||
direct_solver_.calc_system_gmm(_A);
|
||||
|
||||
direct_solver_.solve( xr, _rhs);
|
||||
++n_full_;
|
||||
}
|
||||
}
|
||||
|
||||
// store solution values to result vector
|
||||
for(unsigned int i=0; i<old_idx.size(); ++i)
|
||||
{
|
||||
_x[ old_idx[i] ] = xr[i];
|
||||
}
|
||||
|
||||
// output statistics
|
||||
if( stats_)
|
||||
{
|
||||
std::cerr << "\t" << __FUNCTION__ << " *** Statistics of MiSo Solver ***\n";
|
||||
std::cerr << "\t\t Number of CG iterations = " << n_cg_ << std::endl;
|
||||
std::cerr << "\t\t Number of LOCAL iterations = " << n_local_ << std::endl;
|
||||
std::cerr << "\t\t Number of FULL iterations = " << n_full_ << std::endl;
|
||||
std::cerr << "\t\t Number of ROUNDING = " << _to_round.size() << std::endl;
|
||||
std::cerr << "\t\t time searching next integer = " << time_search_next_integer / 1000.0 <<"s\n";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
MISolver::update_solution(
|
||||
CSCMatrix& _A,
|
||||
Vecd& _x,
|
||||
Vecd& _rhs,
|
||||
Vecui& _neigh_i )
|
||||
{
|
||||
// set to not converged
|
||||
bool converged = false;
|
||||
|
||||
// compute new solution
|
||||
if(max_local_iters_ > 0)
|
||||
{
|
||||
if( noisy_ > 2)std::cerr << "use local iteration ";
|
||||
|
||||
int n_its = max_local_iters_;
|
||||
double tolerance = max_local_error_;
|
||||
converged = siter_.gauss_seidel_local(_A, _x, _rhs, _neigh_i, n_its, tolerance);
|
||||
|
||||
++n_local_;
|
||||
}
|
||||
|
||||
|
||||
// conjugate gradient
|
||||
if( !converged && max_cg_iters_ > 0)
|
||||
{
|
||||
if( noisy_ > 2) std::cerr << ", cg ";
|
||||
|
||||
int max_cg_iters = max_cg_iters_;
|
||||
double tolerance = max_cg_error_;
|
||||
converged = siter_.conjugate_gradient(_A, _x,_rhs, max_cg_iters, tolerance);
|
||||
|
||||
if( noisy_ > 3)
|
||||
std::cerr << "( converged " << converged << " "
|
||||
<< " iters " << max_cg_iters << " "
|
||||
<< " res_norm " << tolerance << std::endl;
|
||||
++n_cg_;
|
||||
}
|
||||
|
||||
if(!converged && iter_full_solution_)
|
||||
{
|
||||
if( noisy_ > 2)std::cerr << ", full ";
|
||||
|
||||
if( gmm::mat_ncols( _A) > 0)
|
||||
{
|
||||
if(cholmod_step_done_)
|
||||
direct_solver_.update_system_gmm(_A);
|
||||
else
|
||||
{
|
||||
direct_solver_.calc_system_gmm(_A);
|
||||
cholmod_step_done_ = true;
|
||||
}
|
||||
direct_solver_.solve(_x,_rhs);
|
||||
|
||||
++n_full_;
|
||||
}
|
||||
}
|
||||
|
||||
if( noisy_ > 2)std::cerr << std::endl;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
MISolver::solve_multiple_rounding(
|
||||
CSCMatrix& _A,
|
||||
Vecd& _x,
|
||||
Vecd& _rhs,
|
||||
Veci& _to_round )
|
||||
{
|
||||
// StopWatch
|
||||
COMISO::StopWatch sw;
|
||||
double time_search_next_integer = 0;
|
||||
|
||||
// some statistics
|
||||
n_local_ = 0;
|
||||
n_cg_ = 0;
|
||||
n_full_ = 0;
|
||||
|
||||
// reset cholmod step flag
|
||||
cholmod_step_done_ = false;
|
||||
|
||||
Veci to_round(_to_round);
|
||||
// copy to round vector and make it unique
|
||||
std::sort(to_round.begin(), to_round.end());
|
||||
Veci::iterator last_unique;
|
||||
last_unique = std::unique(to_round.begin(), to_round.end());
|
||||
int r = last_unique - to_round.begin();
|
||||
to_round.resize( r);
|
||||
|
||||
// initalize old indices
|
||||
Veci old_idx(_rhs.size());
|
||||
for(unsigned int i=0; i<old_idx.size(); ++i)
|
||||
old_idx[i] = i;
|
||||
|
||||
if( initial_full_solution_)
|
||||
{
|
||||
if( noisy_ > 2) std::cerr << "initial full solution" << std::endl;
|
||||
direct_solver_.calc_system_gmm(_A);
|
||||
direct_solver_.solve(_x, _rhs);
|
||||
|
||||
cholmod_step_done_ = true;
|
||||
|
||||
++n_full_;
|
||||
}
|
||||
|
||||
// neighbors for local optimization
|
||||
Vecui neigh_i;
|
||||
|
||||
// Vector for reduced solution
|
||||
Vecd xr(_x);
|
||||
|
||||
// loop until solution computed
|
||||
for(unsigned int i=0; i<to_round.size(); ++i)
|
||||
{
|
||||
if( noisy_ > 0)
|
||||
{
|
||||
std::cerr << "Integer DOF's left: " << to_round.size()-(i+1) << " ";
|
||||
if( noisy_ > 1)
|
||||
std::cerr << "residuum_norm: " << COMISO_GMM::residuum_norm( _A, xr, _rhs) << std::endl;
|
||||
}
|
||||
|
||||
// position in round vector
|
||||
std::vector<int> tr_best;
|
||||
|
||||
sw.start();
|
||||
|
||||
RoundingSet rset;
|
||||
rset.set_threshold(multiple_rounding_threshold_);
|
||||
|
||||
// find index yielding smallest rounding error
|
||||
for(unsigned int j=0; j<to_round.size(); ++j)
|
||||
{
|
||||
if( to_round[j] != -1)
|
||||
{
|
||||
int cur_idx = to_round[j];
|
||||
double rnd_error = fabs( ROUND(xr[cur_idx]) - xr[cur_idx]);
|
||||
|
||||
rset.add(j, rnd_error);
|
||||
}
|
||||
}
|
||||
|
||||
rset.get_ids( tr_best);
|
||||
|
||||
time_search_next_integer += sw.stop();
|
||||
|
||||
// nothing more to do?
|
||||
if( tr_best.empty() )
|
||||
break;
|
||||
|
||||
if( noisy_ > 5)
|
||||
std::cerr << "round " << tr_best.size() << " variables simultaneously\n";
|
||||
|
||||
// clear neigh for local update
|
||||
neigh_i.clear();
|
||||
|
||||
for(unsigned int j = 0; j<tr_best.size(); ++j)
|
||||
{
|
||||
int i_cur = to_round[tr_best[j]];
|
||||
|
||||
// store rounded value
|
||||
double rnd_x = ROUND(xr[i_cur]);
|
||||
_x[ old_idx[i_cur] ] = rnd_x;
|
||||
|
||||
// compute neighbors
|
||||
Col col = gmm::mat_const_col(_A, i_cur);
|
||||
ColIter it = gmm::vect_const_begin( col);
|
||||
ColIter ite = gmm::vect_const_end ( col);
|
||||
for(; it!=ite; ++it)
|
||||
if(it.index() != (unsigned int)i_cur)
|
||||
neigh_i.push_back(it.index());
|
||||
|
||||
// eliminate var
|
||||
COMISO_GMM::fix_var_csc_symmetric( i_cur, rnd_x, _A, xr, _rhs);
|
||||
to_round[tr_best[j]] = -1;
|
||||
}
|
||||
|
||||
// 3-stage update of solution w.r.t. roundings
|
||||
// local GS / CG / SparseCholesky
|
||||
update_solution( _A, xr, _rhs, neigh_i);
|
||||
}
|
||||
|
||||
// final full solution?
|
||||
if( final_full_solution_)
|
||||
{
|
||||
if( noisy_ > 2) std::cerr << "final full solution" << std::endl;
|
||||
|
||||
if( gmm::mat_ncols( _A) > 0)
|
||||
{
|
||||
if(cholmod_step_done_)
|
||||
direct_solver_.update_system_gmm(_A);
|
||||
else
|
||||
direct_solver_.calc_system_gmm(_A);
|
||||
|
||||
direct_solver_.solve( xr, _rhs);
|
||||
++n_full_;
|
||||
}
|
||||
}
|
||||
|
||||
// store solution values to result vector
|
||||
for(unsigned int i=0; i<old_idx.size(); ++i)
|
||||
{
|
||||
_x[ old_idx[i] ] = xr[i];
|
||||
}
|
||||
|
||||
// output statistics
|
||||
if( stats_)
|
||||
{
|
||||
std::cerr << "\t" << __FUNCTION__ << " *** Statistics of MiSo Solver ***\n";
|
||||
std::cerr << "\t\t Number of CG iterations = " << n_cg_ << std::endl;
|
||||
std::cerr << "\t\t Number of LOCAL iterations = " << n_local_ << std::endl;
|
||||
std::cerr << "\t\t Number of FULL iterations = " << n_full_ << std::endl;
|
||||
std::cerr << "\t\t Number of ROUNDING = " << _to_round.size() << std::endl;
|
||||
std::cerr << "\t\t time searching next integer = " << time_search_next_integer / 1000.0 <<"s\n";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
MISolver::solve_gurobi(
|
||||
CSCMatrix& _A,
|
||||
Vecd& _x,
|
||||
Vecd& _rhs,
|
||||
Veci& _to_round)
|
||||
{
|
||||
#if COMISO_GUROBI_AVAILABLE
|
||||
|
||||
// get round-indices in set
|
||||
std::set<int> to_round;
|
||||
for(unsigned int i=0; i<_to_round.size();++i)
|
||||
to_round.insert(_to_round[i]);
|
||||
|
||||
try {
|
||||
GRBEnv env = GRBEnv();
|
||||
|
||||
GRBModel model = GRBModel(env);
|
||||
|
||||
// set time limite
|
||||
model.getEnv().set(GRB_DoubleParam_TimeLimit, gurobi_max_time_);
|
||||
|
||||
unsigned int n = _rhs.size();
|
||||
|
||||
// 1. allocate variables
|
||||
std::vector<GRBVar> vars;
|
||||
for( unsigned int i=0; i<n; ++i)
|
||||
if( to_round.count(i))
|
||||
vars.push_back( model.addVar(-GRB_INFINITY, GRB_INFINITY, 0.0, GRB_INTEGER));
|
||||
else
|
||||
vars.push_back( model.addVar(-GRB_INFINITY, GRB_INFINITY, 0.0, GRB_CONTINUOUS));
|
||||
|
||||
// Integrate new variables
|
||||
model.update();
|
||||
|
||||
// 2. setup_energy
|
||||
|
||||
// build objective function from linear system E = x^tAx - 2x^t*rhs
|
||||
GRBQuadExpr objective;
|
||||
|
||||
for(unsigned int i=0; i<_A.nc; ++i)
|
||||
for(unsigned int j=_A.jc[i]; j<_A.jc[i+1]; ++j)
|
||||
{
|
||||
objective += _A.pr[j]*vars[_A.ir[j]]*vars[i];
|
||||
}
|
||||
for(unsigned int i=0; i<n; ++i)
|
||||
objective -= 2*_rhs[i]*vars[i];
|
||||
|
||||
// _A.jc[c+1]
|
||||
// _A.pr[write]
|
||||
// _A.ir[write]
|
||||
// _A.nc
|
||||
// _A.nr
|
||||
|
||||
// minimize
|
||||
model.set(GRB_IntAttr_ModelSense, 1);
|
||||
model.setObjective(objective);
|
||||
|
||||
// 4. solve
|
||||
model.optimize();
|
||||
|
||||
// 5. store result
|
||||
_x.resize(n);
|
||||
for(unsigned int i=0; i<n; ++i)
|
||||
_x[i] = vars[i].get(GRB_DoubleAttr_X);
|
||||
|
||||
std::cout << "GUROBI objective: " << model.get(GRB_DoubleAttr_ObjVal) << std::endl;
|
||||
|
||||
}
|
||||
catch(GRBException& e)
|
||||
{
|
||||
std::cout << "Error code = " << e.getErrorCode() << std::endl;
|
||||
std::cout << e.getMessage() << std::endl;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cout << "Exception during optimization" << std::endl;
|
||||
}
|
||||
|
||||
#else
|
||||
std::cerr << "GUROBI solver is not available, please install it..." << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void
|
||||
MISolver::
|
||||
show_options_dialog()
|
||||
{
|
||||
#if(COMISO_QT4_AVAILABLE)
|
||||
MISolverDialog* pd = new MISolverDialog(*this);
|
||||
pd->exec();
|
||||
#else
|
||||
std::cerr << "Warning: Qt not available to show solver dialog!!!" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// end namespace COMISO
|
||||
}// ----------------------
|
||||
404
src/external/CoMISo/Solver/MISolver.hh
vendored
Normal file
404
src/external/CoMISo/Solver/MISolver.hh
vendored
Normal file
@ -0,0 +1,404 @@
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* CoMISo *
|
||||
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
|
||||
* www.rwth-graphics.de *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of CoMISo. *
|
||||
* *
|
||||
* CoMISo is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* CoMISo is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with CoMISo. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS MISolver
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef COMISO_MISOLVER_HH
|
||||
#define COMISO_MISOLVER_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
#include <CoMISo/Config/CoMISoDefines.hh>
|
||||
#include <CoMISo/Config/config.hh>
|
||||
|
||||
#if COMISO_SUITESPARSE_AVAILABLE
|
||||
#include "CholmodSolver.hh"
|
||||
#elif COMISO_EIGEN3_AVAILABLE
|
||||
#include "EigenLDLTSolver.hh"
|
||||
#else
|
||||
#print "Warning: MISolver requires Suitesparse or Eigen3 support"
|
||||
#endif
|
||||
|
||||
#include "GMM_Tools.hh"
|
||||
#include "IterativeSolverT.hh"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define ROUND_MI(x) ((x)<0?int((x)-0.5):int((x)+0.5))
|
||||
|
||||
|
||||
//== FORWARDDECLARATIONS ======================================================
|
||||
|
||||
|
||||
namespace COMISO {
|
||||
class MISolverDialog;
|
||||
}
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace COMISO {
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
|
||||
/** \class MISolver MISolver.hh
|
||||
|
||||
Mixed-Integer Solver.
|
||||
Approximates the solution of a (mixed-)integer problem
|
||||
by iteratively computing a continuous(real) minimizer x followed by a
|
||||
rounding of the one variable x_i which is subsequently eliminated from the
|
||||
system, and the system is solved again ...
|
||||
*/
|
||||
|
||||
class COMISODLLEXPORT MISolver
|
||||
{
|
||||
public:
|
||||
|
||||
// typedefs
|
||||
typedef gmm::csc_matrix< double > CSCMatrix;
|
||||
typedef std::vector< double > Vecd;
|
||||
typedef std::vector< int > Veci;
|
||||
typedef std::vector< unsigned int > Vecui;
|
||||
|
||||
// gmm Column and ColumnIterator of CSC matrix
|
||||
typedef gmm::linalg_traits< CSCMatrix >::const_sub_col_type Col;
|
||||
typedef gmm::linalg_traits< Col >::const_iterator ColIter;
|
||||
|
||||
|
||||
/// default Constructor
|
||||
MISolver();
|
||||
|
||||
/// Destructor
|
||||
~MISolver() {}
|
||||
|
||||
|
||||
/// Compute greedy approximation to a mixed integer problem.
|
||||
/** @param _A symmetric positive semi-definite CSC matrix (Will be \b destroyed!)
|
||||
* @param _x vector holding solution at the end
|
||||
* @param _rhs right hand side of system Ax=rhs (Will be \b destroyed!)
|
||||
* @param _to_round vector with variable indices to round to integers
|
||||
* @param _fixed_order specifies if _to_round indices shall be rounded in the
|
||||
* given order (\b true) or be greedily selected (\b false)
|
||||
* */
|
||||
inline void solve(
|
||||
CSCMatrix& _A,
|
||||
Vecd& _x,
|
||||
Vecd& _rhs,
|
||||
Veci& _to_round,
|
||||
bool _fixed_order = false );
|
||||
|
||||
void resolve(
|
||||
Vecd& _x,
|
||||
Vecd& _rhs );
|
||||
|
||||
/// Compute greedy approximation to a mixed integer problem.
|
||||
/** @param _B mx(n+1) matrix with (still non-squared) equations of the energy,
|
||||
* including the right hand side (Will be \b destroyed!)
|
||||
* @param _x vector holding solution at the end
|
||||
* @param _to_round vector with variable indices to round to integers
|
||||
* @param _fixed_order specifies if _to_round indices shall be rounded in the
|
||||
* given order (\b true) or be greedily selected (\b false)
|
||||
* */
|
||||
template<class CMatrixT>
|
||||
void solve(
|
||||
CMatrixT& _B,
|
||||
Vecd& _x,
|
||||
Veci& _to_round,
|
||||
bool _fixed_order = false );
|
||||
|
||||
|
||||
/// show Qt-Options-Dialog for setting algorithm parameters
|
||||
/** Requires a Qt Application running and COMISO_GUI to be defined */
|
||||
void show_options_dialog();
|
||||
|
||||
/** @name Get/Set functions for algorithm parameters
|
||||
* Besides being used by the Qt-Dialog these can also be called explicitly
|
||||
* to set parameters of the algorithm. */
|
||||
/*@{*/
|
||||
/// Shall an initial full solution be computed?
|
||||
void set_inital_full( bool _b) { initial_full_solution_=_b;}
|
||||
/// Will an initial full solution be computed?
|
||||
bool get_inital_full() { return initial_full_solution_;}
|
||||
|
||||
/// Shall an full solution be computed if iterative methods did not converged?
|
||||
void set_iter_full( bool _b) { iter_full_solution_=_b;}
|
||||
/// Will an full solution be computed if iterative methods did not converged?
|
||||
bool get_iter_full() { return iter_full_solution_;}
|
||||
|
||||
/// Shall a final full solution be computed?
|
||||
void set_final_full( bool _b) { final_full_solution_=_b;}
|
||||
/// Will a final full solution be computed?
|
||||
bool get_final_full() { return final_full_solution_;}
|
||||
|
||||
/// Shall direct (or greedy) rounding be used?
|
||||
void set_direct_rounding( bool _b) { direct_rounding_=_b;}
|
||||
/// Will direct rounding be used?
|
||||
bool get_direct_rounding() { return direct_rounding_;}
|
||||
|
||||
/// Shall no rounding be performed?
|
||||
void set_no_rounding( bool _b) { no_rounding_=_b;}
|
||||
/// Will no rounding be performed?
|
||||
bool get_no_rounding() { return no_rounding_;}
|
||||
|
||||
/// Shall multiple rounding be performed?
|
||||
void set_multiple_rounding( bool _b) { multiple_rounding_=_b;}
|
||||
/// Will multiple rounding be performed?
|
||||
bool get_multiple_rounding() { return multiple_rounding_;}
|
||||
|
||||
/// Shall gurobi solver be used?
|
||||
void set_gurobi_rounding( bool _b) { gurobi_rounding_=_b;}
|
||||
/// Will gurobi rounding be performed?
|
||||
bool get_gurobi_rounding() { return gurobi_rounding_;}
|
||||
|
||||
/// Shall cplex solver be used?
|
||||
void set_cplex_rounding( bool _b) { cplex_rounding_=_b;}
|
||||
/// Will cplex rounding be performed?
|
||||
bool get_cplex_rounding() { return cplex_rounding_;}
|
||||
|
||||
/// Set number of maximum Gauss-Seidel iterations
|
||||
void set_local_iters( unsigned int _i) { max_local_iters_ = _i;}
|
||||
/// Get number of maximum Gauss-Seidel iterations
|
||||
unsigned int get_local_iters() { return max_local_iters_;}
|
||||
|
||||
/// Set error threshold for Gauss-Seidel solver
|
||||
void set_local_error( double _d) { max_local_error_ = _d;}
|
||||
/// Get error threshold for Gauss-Seidel solver
|
||||
double get_local_error() { return max_local_error_;}
|
||||
|
||||
/// Set number of maximum Conjugate Gradient iterations
|
||||
void set_cg_iters( unsigned int _i) { max_cg_iters_ = _i;}
|
||||
/// Get number of maximum Conjugate Gradient iterations
|
||||
unsigned int get_cg_iters() { return max_cg_iters_;}
|
||||
|
||||
/// Set error threshold for Conjugate Gradient
|
||||
void set_cg_error( double _d) { max_cg_error_ = _d;}
|
||||
/// Get error threshold for Conjugate Gradient
|
||||
double get_cg_error() { return max_cg_error_;}
|
||||
|
||||
/// Set multiple rounding threshold (upper bound of rounding performed in each iteration)
|
||||
void set_multiple_rounding_threshold( double _d) { multiple_rounding_threshold_ = _d;}
|
||||
/// Get multiple rounding threshold (upper bound of rounding performed in each iteration)
|
||||
double get_multiple_rounding_threshold() { return multiple_rounding_threshold_;}
|
||||
|
||||
/// Set noise level of algorithm. 0 - quiet, 1 - more noise, 2 - even more, 100 - all noise
|
||||
void set_noise( unsigned int _i) { noisy_ = _i;}
|
||||
/// Get noise level of algorithm
|
||||
unsigned int get_noise() { return noisy_;}
|
||||
|
||||
/// Set time limit for gurobi solver (in seconds)
|
||||
void set_gurobi_max_time( double _d) { gurobi_max_time_ = _d;}
|
||||
/// Get time limit for gurobi solver (in seconds)
|
||||
double get_gurobi_max_time() { return gurobi_max_time_;}
|
||||
|
||||
/// Set output statistics of solver
|
||||
void set_stats( bool _stats) { stats_ = _stats; }
|
||||
/// Get output statistics of solver
|
||||
bool get_stats( ) { return stats_; }
|
||||
/*@}*/
|
||||
|
||||
/// Set/Get use_constraint_reordering for constraint solver (default = true)
|
||||
bool& use_constraint_reordering() { return use_constraint_reordering_;}
|
||||
|
||||
private:
|
||||
|
||||
// find set of variables for simultaneous rounding
|
||||
class RoundingSet
|
||||
{
|
||||
public:
|
||||
typedef std::pair<double,int> PairDI;
|
||||
|
||||
RoundingSet() : threshold_(0.5), cur_sum_(0.0) {}
|
||||
|
||||
void clear() { rset_.clear(); cur_sum_ = 0.0;}
|
||||
|
||||
bool add( int _id, double _rd_val)
|
||||
{
|
||||
// empty set? -> always add one element
|
||||
if( rset_.empty() || cur_sum_+_rd_val <= threshold_)
|
||||
{
|
||||
rset_.insert( PairDI(_rd_val,_id) );
|
||||
cur_sum_ += _rd_val;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// move to last element
|
||||
std::set<PairDI>::iterator s_it = rset_.end();
|
||||
--s_it;
|
||||
|
||||
if( s_it->first > _rd_val)
|
||||
{
|
||||
cur_sum_ -= s_it->first;
|
||||
rset_.erase(s_it);
|
||||
rset_.insert( PairDI(_rd_val,_id) );
|
||||
cur_sum_ += _rd_val;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void set_threshold( double _thres) { threshold_ = _thres; }
|
||||
|
||||
void get_ids( std::vector<int>& _ids )
|
||||
{
|
||||
_ids.clear();
|
||||
_ids.reserve( rset_.size());
|
||||
std::set<PairDI>::iterator s_it = rset_.begin();
|
||||
for(; s_it != rset_.end(); ++s_it)
|
||||
_ids.push_back( s_it->second);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
double threshold_;
|
||||
double cur_sum_;
|
||||
|
||||
std::set<PairDI> rset_;
|
||||
|
||||
std::set<PairDI> test_;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
void solve_no_rounding(
|
||||
CSCMatrix& _A,
|
||||
Vecd& _x,
|
||||
Vecd& _rhs );
|
||||
|
||||
void solve_direct_rounding(
|
||||
CSCMatrix& _A,
|
||||
Vecd& _x,
|
||||
Vecd& _rhs,
|
||||
Veci& _to_round);
|
||||
|
||||
void solve_multiple_rounding(
|
||||
CSCMatrix& _A,
|
||||
Vecd& _x,
|
||||
Vecd& _rhs,
|
||||
Veci& _to_round );
|
||||
|
||||
void solve_iterative(
|
||||
CSCMatrix& _A,
|
||||
Vecd& _x,
|
||||
Vecd& _rhs,
|
||||
Veci& _to_round,
|
||||
bool _fixed_order );
|
||||
|
||||
void solve_gurobi(
|
||||
CSCMatrix& _A,
|
||||
Vecd& _x,
|
||||
Vecd& _rhs,
|
||||
Veci& _to_round );
|
||||
|
||||
inline void solve_cplex(
|
||||
CSCMatrix& _A,
|
||||
Vecd& _x,
|
||||
Vecd& _rhs,
|
||||
Veci& _to_round );
|
||||
|
||||
|
||||
void update_solution(
|
||||
CSCMatrix& _A,
|
||||
Vecd& _x,
|
||||
Vecd& _rhs,
|
||||
Vecui& _neigh_i );
|
||||
|
||||
private:
|
||||
|
||||
/// Copy constructor (not used)
|
||||
MISolver(const MISolver& _rhs);
|
||||
|
||||
/// Assignment operator (not used)
|
||||
MISolver& operator=(const MISolver& _rhs);
|
||||
|
||||
// parameters used by the MiSo
|
||||
bool initial_full_solution_;
|
||||
bool iter_full_solution_;
|
||||
bool final_full_solution_;
|
||||
|
||||
bool direct_rounding_;
|
||||
bool no_rounding_;
|
||||
bool multiple_rounding_;
|
||||
bool gurobi_rounding_;
|
||||
bool cplex_rounding_;
|
||||
|
||||
double multiple_rounding_threshold_;
|
||||
|
||||
unsigned int max_local_iters_;
|
||||
double max_local_error_;
|
||||
unsigned int max_cg_iters_;
|
||||
double max_cg_error_;
|
||||
double max_full_error_;
|
||||
unsigned int noisy_;
|
||||
bool stats_;
|
||||
|
||||
// time limit for gurobi solver (in seconds)
|
||||
double gurobi_max_time_;
|
||||
|
||||
// flag
|
||||
bool cholmod_step_done_;
|
||||
|
||||
// declar direct solver depending on availability
|
||||
#if COMISO_SUITESPARSE_AVAILABLE
|
||||
COMISO::CholmodSolver direct_solver_;
|
||||
#elif COMISO_EIGEN3_AVAILABLE
|
||||
COMISO::EigenLDLTSolver direct_solver_;
|
||||
#else
|
||||
#print "Warning: MISolver requires Suitesparse or Eigen3 support"
|
||||
#endif
|
||||
|
||||
IterativeSolverT<double> siter_;
|
||||
|
||||
// statistics
|
||||
unsigned int n_local_;
|
||||
unsigned int n_cg_;
|
||||
unsigned int n_full_;
|
||||
|
||||
bool use_constraint_reordering_;
|
||||
|
||||
#if(COMISO_QT4_AVAILABLE)
|
||||
friend class COMISO::MISolverDialog;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace COMISO
|
||||
//=============================================================================
|
||||
#if defined(INCLUDE_TEMPLATES) && !defined(COMISO_MISOLVER_C)
|
||||
#define COMISO_MISOLVER_TEMPLATES
|
||||
#include "MISolverT.cc"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // COMISO_MISOLVER_HH defined
|
||||
//=============================================================================
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user