Skip to content

Commit

Permalink
Initial revision of the linear_programming openMVG module. openMVG#46
Browse files Browse the repository at this point in the history
  • Loading branch information
pmoulon committed Dec 29, 2013
1 parent b295e1a commit 76c7794
Show file tree
Hide file tree
Showing 12 changed files with 1,357 additions and 0 deletions.
9 changes: 9 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ Setup the required external library.
$ cd openMVG_Build
$ cmake -DCMAKE_BUILD_TYPE=RELEASE . ../openMVG/src/

=> In order to use the MOSEK backend for the linear programming oepnMVG module
- Check that you have an uptodate MOSEK licence, else openMVG MOSEK unit test will fail.

$ cmake -DCMAKE_BUILD_TYPE=RELEASE
-DMOSEK_SEARCH_HEADER="~/Documents/Lib/mosek/6/tools/platform/linux64x86/h"
-DMOSEK_SEARCH_LIB="~/Documents/Lib/mosek/6/tools/platform/linux64x86/bin"
. ../openMVG/src/


If you want have an IDE openable project with codeblocks:
$ cmake -G "CodeBlocks - Unix Makefiles" -DCMAKE_BUILD_TYPE=RELEASE . ../openMVG/src/

Expand Down
30 changes: 30 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,36 @@ IF (UNIX)
ENDIF (EXIV2_FOUND)
ENDIF (UNIX)

#===============================
#---- LINEAR PROGRAMMING SOLVER
#===============================

#- Mosek (linear programming interface)
#===============================================================================
FIND_PACKAGE(Mosek)
IF(MOSEK_FOUND)
ADD_DEFINITIONS(-DOPENMVG_HAVE_MOSEK)
INCLUDE_DIRECTORIES(
${MOSEK_INCLUDE}
./dependencies/osi_clp/Osi/src/OsiMsk/
)
ENDIF(MOSEK_FOUND)

#- osi_clp (linear programming interface)
# ==============================================================================
ADD_SUBDIRECTORY(dependencies/osi_clp)
INCLUDE_DIRECTORIES(
./dependencies/osi_clp/CoinUtils/src/
./dependencies/osi_clp/Clp/src/
./dependencies/osi_clp/Osi/src/Osi/
./dependencies/osi_clp/Clp/src/OsiClp/
)

#===============================
#--END-- LINEAR PROGRAMMING SOLVER
#===============================


# ==============================================================================
# Opencv is not used by openMVG but some samples show how to use openCV
# and openMVG simultaneously
Expand Down
33 changes: 33 additions & 0 deletions src/cmakeFindModules/FindMosek.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

# MOSEK library detection
FIND_PATH(MOSEK_INCLUDE NAMES mosek.h PATHS ${MOSEK_SEARCH_HEADER})
FIND_LIBRARY(MOSEK_LIB NAMES libmosek libmosek.so libmosek64 libmosek64.so PATHS ${MOSEK_SEARCH_LIB})

IF (EXISTS ${MOSEK_INCLUDE} AND EXISTS ${MOSEK_LIB})

SET(MOSEK_FOUND true CACHE BOOL "USE MOSEK library")
MESSAGE("-- Found Mosek header in: ${MOSEK_INCLUDE}")
MESSAGE("-- Found Mosek library: ${MOSEK_LIB}")
# INCLUDE_DIRECTORIES( ${MOSEK_INCLUDE} )

IF (${UNIX})
FIND_PACKAGE(Threads REQUIRED)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_THREAD_LIBS_INIT}")
LIST(APPEND ${MOSEK_LIB} pthread)
ENDIF (${UNIX})

# ADD_DEFINITIONS(-DOPENMVG_HAVE_MOSEK)

ELSE (EXISTS ${MOSEK_INCLUDE} AND EXISTS ${MOSEK_LIB})
MESSAGE("-- Did not find MOSEK header")
IF (NOT EXISTS ${MOSEK_LIB})
MESSAGE("-- Did not find MOSEK library")
ENDIF ()
ENDIF (EXISTS ${MOSEK_INCLUDE} AND EXISTS ${MOSEK_LIB})

IF(NOT MOSEK_FOUND)
MESSAGE(STATUS "Could not find mosek library on this machine.")
ENDIF(NOT MOSEK_FOUND)

MARK_AS_ADVANCED(MOSEK_FOUND)

2 changes: 2 additions & 0 deletions src/openMVG/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ ADD_SUBDIRECTORY(bundle_adjustment)

ADD_SUBDIRECTORY(exif_IO)
ADD_SUBDIRECTORY(split)

ADD_SUBDIRECTORY(linearProgramming)
34 changes: 34 additions & 0 deletions src/openMVG/linearProgramming/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
FILE(
GLOB
linearProgramming_headers
*.hpp
)
FILE(
GLOB
linearProgramming_cpp
*.cpp
)
FILE(GLOB_RECURSE REMOVEFILESUNITTEST *_test.cpp)

SET_SOURCE_FILES_PROPERTIES(${linearProgramming_headers} PROPERTIES LANGUAGE CXX)

#Remove the future main files
LIST(REMOVE_ITEM linearProgramming_cpp ${REMOVEFILESUNITTEST})

ADD_LIBRARY(openMVG_linearProgramming ${linearProgramming_headers} ${linearProgramming_cpp})
TARGET_LINK_LIBRARIES(openMVG_linearProgramming
lib_OsiClpSolver # solver wrapper
lib_CoinUtils # container tools
lib_Osi # generic LP
lib_clp # Solver
)
IF (MOSEK_FOUND)
TARGET_LINK_LIBRARIES(openMVG_linearProgramming
pthread
${MOSEK_LIB}
lib_Osi_Msk # OSI solver wrapper for the Mosek backend
)
ENDIF (MOSEK_FOUND)

UNIT_TEST(openMVG_linearProgramming linearProgramming "openMVG_linearProgramming")

81 changes: 81 additions & 0 deletions src/openMVG/linearProgramming/bisectionLP.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright (c) 2012 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef OPENMVG_LINEAR_PROGRAMMING_BISECTIONLP_H_
#define OPENMVG_LINEAR_PROGRAMMING_BISECTIONLP_H_

#include "openMVG/linearProgramming/linearProgrammingInterface.hpp"
#include <iostream>
#include <iterator>
#include <vector>

namespace openMVG {
namespace linearProgramming {

/// Generic Bisection algorithm via Linear Programming.
/// Use dichotomy or mid-point best parameter that fit the solution.
/// http://en.wikipedia.org/wiki/Bisection_method
/// The bisection algorithm continue as long as
/// precision or max iteration number is not reach.
///
template <typename ConstraintBuilder, typename ConstraintType>
bool BisectionLP(
LP_Solver & solver,
ConstraintBuilder & cstraintBuilder,
std::vector<double> * parameters,
double gammaUp = 1.0, // Upper bound
double gammaLow = 0.0, // lower bound
double eps = 1e-8, // precision that stop dichotomy
const int maxIteration = 20, // max number of iteration
double * bestFeasibleGamma = NULL, // value of best bisection found value
bool bVerbose = false)
{
int k = 0;
bool bModelFound = false;
ConstraintType constraint;
do
{
++k; // One more iteration

double gamma = (gammaLow + gammaUp) / 2.0;

//-- Setup constraint and solver
cstraintBuilder.Build(gamma, constraint);
solver.setup( constraint );
//--
// Solving
bool bFeasible = solver.solve();
//--

if (bFeasible)
{
gammaUp = gamma;
if (bestFeasibleGamma)
*bestFeasibleGamma = gamma;
solver.getSolution(*parameters);
bModelFound = true;

if(bVerbose)
std::cout << "\n" << k<<"/"<<maxIteration
<< "\t gamma " << gamma
<< "\t gammaUp-gammaLow " << gammaUp-gammaLow << std::endl;
}
else
{
gammaLow = gamma;
if(bVerbose)
std::cout << "\nNot feasible with gamma: " << gamma << std::endl;
}
} while (k < maxIteration && gammaUp - gammaLow > eps);

return bModelFound;
}

} // namespace linearProgramming
} // namespace openMVG


#endif // OPENMVG_LINEAR_PROGRAMMING_BISECTIONLP_H_
101 changes: 101 additions & 0 deletions src/openMVG/linearProgramming/linearProgrammingInterface.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright (c) 2012 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef OPENMVG_LINEAR_PROGRAMMING_INTERFACE_H_
#define OPENMVG_LINEAR_PROGRAMMING_INTERFACE_H_

#include <vector>
#include <utility>
#include "openMVG/numeric/numeric.h"

namespace openMVG {
namespace linearProgramming {

/// Generic container for LP (Linear Programming problems).
/// Embed :
/// - objective function
/// - Constraints (coefficients, Sign, objective value),
/// - Bounds over parameter (<=, =, >=).
/// - minimize or maximize
///
struct LP_Constraints
{
enum eLP_SIGN
{
LP_LESS_OR_EQUAL = 1, // (<=)
LP_GREATER_OR_EQUAL = 2, // (>=)
LP_EQUAL = 3, // (=)
LP_FREE = 4 //only supported in MOSEK
};

LP_Constraints() {
_bminimize = false;
}

int _nbParams; // The number of parameter/variable in constraint.
Mat _constraintMat; // Constraint under Matrix form.
Vec _Cst_objective; // Constraint objective value.
std::vector<eLP_SIGN> _vec_sign; // Constraint sign.
std::vector< std::pair<double, double> > _vec_bounds; // parameter/variable bounds.

bool _bminimize; // minimize is true or maximize is false.
std::vector<double> _vec_cost; // Objective function
};

/// Generic Sparse container for LP (Linear Programming problems).
/// Embed :
/// - Constraints (coefficients, Sign, objective value),
/// - Bounds over parameter (<=, =, >=).
/// Implementation differ from LP_Constraints, here constraints are
/// stored as a Sparse matrix.
///
struct LP_Constraints_Sparse
{
LP_Constraints_Sparse() {
_bminimize = false;
}

// Variable part
int _nbParams; // The number of parameter/variable in constraint.
std::vector< std::pair<double, double> > _vec_bounds; // parameter/variable bounds.

// Constraint part
sRMat _constraintMat; // Constraint under Matrix form.
Vec _Cst_objective; // Constraint objective value.
std::vector<LP_Constraints::eLP_SIGN> _vec_sign; // Constraint sign.

bool _bminimize; // minimize is true or maximize is false.
std::vector<double> _vec_cost; // Objective function
};

/// Generic LP solver (Linear Programming)
/// It's an interface to setup constraint and objective of a Linear Program.
/// Embed constraint setup, problem solving, and parameters getter.
class LP_Solver
{
public:

LP_Solver(int nbParams):_nbParams(nbParams){};

/// Setup constraint for the given library.
virtual bool setup(const LP_Constraints & constraints) = 0;
virtual bool setup(const LP_Constraints_Sparse & constraints) = 0;

/// Setup the feasibility and found the solution that best fit the constraint.
virtual bool solve() = 0;

/// Get back solution. Call it after solve.
virtual bool getSolution(std::vector<double> & estimatedParams) = 0;

protected :
int _nbParams; // The number of parameter considered in constraint formulation.
};

} // namespace linearProgramming
} // namespace openMVG


#endif // OPENMVG_LINEAR_PROGRAMMING_INTERFACE_H_
Loading

0 comments on commit 76c7794

Please sign in to comment.