Commit 5053d79b authored by Henrik Zimmer's avatar Henrik Zimmer

initial CoMISo check in, not release

git-svn-id: http://www.openflipper.org/svnrepo/CoMISo/trunk@2 1355f012-dd97-4b2f-ae87-10fa9f823a57
parent ea66204f
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 ()
endif ()
acg_get_version ()
include (ACGOutput)
find_package (GMM)
if (NOT GMM_FOUND)
message (FATAL_ERROR "GMM not found!")
endif ()
find_package (Boost)
if (NOT Boost_FOUND)
message (FATAL_ERROR "Boost not found!")
endif ()
find_package (BLAS)
if (NOT BLAS_FOUND )
message (FATAL_ERROR "BLAS not found!")
endif ()
#added by CAT
find_package (SUITESPARSE)
if (NOT SUITESPARSE_FOUND )
message (FATAL_ERROR "SUITESPARSE not found!")
endif ()
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()
include_directories (
..
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${Boost_INCLUDE_DIR}
${GMM_INCLUDE_DIR}
${SUITESPARSE_INCLUDE_DIRS}
)
# generate dllexport macros on windows
if (WIN32)
add_definitions(-DCOMISODLL)
endif ()
link_directories (
${SUITESPARSE_LIBRARY_DIRS}
)
# source code directories
set (directories
.
Solver
Config
Utils
QtWidgets
)
# generate dllexport macros on windows
if (WIN32)
add_definitions(-DCOMISODLL)
endif ()
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})
message( WARNING ${ui})
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)
# genereate uic and moc targets
acg_qt4_autouic (uic_targets ${ui})
acg_qt4_automoc (moc_targets ${headers})
message( WARNING ${uic_targets})
acg_add_library (CoMISo SHARED ${uic_targets} ${sources} ${headers} ${moc_targets})
if (NOT APPLE)
target_link_libraries (CoMISo
${QT_LIBRARIES}
${SUITESPARSE_LIBRARIES}
${BLAS_LIBRARIES}
)
else(NOT APPLE)
target_link_libraries (CoMISo
${QT_LIBRARIES}
${SUITESPARSE_LIBRARIES}
${BLAS_LIBRARIES}
)
endif(NOT APPLE)
# display results
acg_print_configure_header (COMISO "CoMISo")
#ifndef COMISODLLEXPORT
#ifdef WIN32
#ifdef COMISOMDLL
#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
include (ACGCommon)
include_directories (
..
${CMAKE_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
link_directories (
# ${CMAKE_CURRENT_BINARY_DIR}/Build/lib/CoMISo
#/data/home1/zimmer/projects/ConstrainedSolver/package/CoMISo/build/Build/lib/CoMISo
)
# source code directories
set (directories
.
)
# 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})
# remove template cc files from source file list
acg_drop_templates (sources)
# genereate uic and moc targets
acg_qt4_autouic (uic_targets ${ui})
acg_qt4_automoc (moc_targets ${headers})
if (WIN32)
acg_add_executable (factored_solver WIN32 ${uic_targets} ${sources} ${headers} ${moc_targets})
elseif (APPLE)
# generate bundle on mac
acg_add_executable (factored_solver MACOSX_BUNDLE ${uic_targets} ${sources} ${headers} ${moc_targets})
else ()
acg_add_executable (factored_solver ${uic_targets} ${sources} ${headers} ${moc_targets})
endif ()
target_link_libraries (factored_solver
CoMISo
${QT_LIBRARIES}
)
if (APPLE)
# create bundle in "Build" directory and set icon
# no install needed here, because the whole bundle will be installed in the
# toplevel CMakeLists.txt
set_target_properties (
Exmaple PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/Build"
MACOSX_BUNDLE_INFO_STRING "CoMISo factored_solver"
)
endif ()
#include <Utils/StopWatch.hh>
#include <gmm/gmm.h>
#include <vector>
#include <Solver/ConstrainedSolver.hh>
#include <Solver/MISolver.hh>
#include <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
ACG::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
ACG::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;
}
include (ACGCommon)
include_directories (
..
${CMAKE_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
link_directories (
# ${CMAKE_CURRENT_BINARY_DIR}/Build/lib/CoMISo
#/data/home1/zimmer/projects/ConstrainedSolver/package/CoMISo/build/Build/lib/CoMISo
)
# source code directories
set (directories
.
)
# 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})
# remove template cc files from source file list
acg_drop_templates (sources)
# genereate uic and moc targets
acg_qt4_autouic (uic_targets ${ui})
acg_qt4_automoc (moc_targets ${headers})
if (WIN32)
acg_add_executable (quadratic_solver WIN32 ${uic_targets} ${sources} ${headers} ${moc_targets})
elseif (APPLE)
# generate bundle on mac
acg_add_executable (quadratic_solver MACOSX_BUNDLE ${uic_targets} ${sources} ${headers} ${moc_targets})
else ()
acg_add_executable (quadratic_solver ${uic_targets} ${sources} ${headers} ${moc_targets})
endif ()
target_link_libraries (quadratic_solver
CoMISo
${QT_LIBRARIES}
)
if (APPLE)
# create bundle in "Build" directory and set icon
# no install needed here, because the whole bundle will be installed in the
# toplevel CMakeLists.txt
set_target_properties (
Exmaple PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/Build"
MACOSX_BUNDLE_INFO_STRING "CoMISo quadratic_solver"
)
endif ()
#include <Utils/StopWatch.hh>
#include <gmm/gmm.h>
#include <vector>
#include <Solver/ConstrainedSolver.hh>
#include <Solver/MISolver.hh>
#include <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
ACG::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
ACG::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;
}
include (ACGCommon)
include_directories (
..
${CMAKE_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
link_directories (
# ${CMAKE_CURRENT_BINARY_DIR}/Build/lib/CoMISo
#/data/home1/zimmer/projects/ConstrainedSolver/package/CoMISo/build/Build/lib/CoMISo
)
# source code directories
set (directories
.
)
# 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})
# remove template cc files from source file list
acg_drop_templates (sources)
# genereate uic and moc targets
acg_qt4_autouic (uic_targets ${ui})
acg_qt4_automoc (moc_targets ${headers})
if (WIN32)
acg_add_executable (small_factored_example WIN32 ${uic_targets} ${sources} ${headers} ${moc_targets})
elseif (APPLE)
# generate bundle on mac
acg_add_executable (small_factored_example MACOSX_BUNDLE ${uic_targets} ${sources} ${headers} ${moc_targets})
else ()
acg_add_executable (small_factored_example ${uic_targets} ${sources} ${headers} ${moc_targets})
endif ()
target_link_libraries (small_factored_example
CoMISo
${QT_LIBRARIES}
)
if (APPLE)
# create bundle in "Build" directory and set icon
# no install needed here, because the whole bundle will be installed in the
# toplevel CMakeLists.txt
set_target_properties (
Exmaple PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/Build"
MACOSX_BUNDLE_INFO_STRING "CoMISo small_factored_example"
)
endif ()
/*===========================================================================*\
* *
* CoMISo *
* Copyright (C) 2008-2009 by Computer Graphics Group, RWTH Aachen *
* www.graphics.rwth-aachen.de *<