diff --git a/dune/xt/common/CMakeLists.txt b/dune/xt/common/CMakeLists.txt index 8cc305f60aa93643b3a91a0e6a5ad8744c6a8d9b..457813d58bd920e83a12c43f7f63e1903074af04 100644 --- a/dune/xt/common/CMakeLists.txt +++ b/dune/xt/common/CMakeLists.txt @@ -22,6 +22,7 @@ set(lib_dune_xt_common_sources localization-study.cc logging.cc logstreams.cc + lpsolve.cc math.cc memory.cc misc.cc diff --git a/dune/xt/common/lpsolve.cc b/dune/xt/common/lpsolve.cc new file mode 100644 index 0000000000000000000000000000000000000000..a82dfb1c3747f94403ccdbb36ab1860bc8063087 --- /dev/null +++ b/dune/xt/common/lpsolve.cc @@ -0,0 +1,261 @@ +// This file is part of the dune-xt-common project: +// https://github.com/dune-community/dune-xt-common +// Copyright 2009-2018 dune-xt-common developers and contributors. All rights reserved. +// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause) +// or GPL-2.0+ (http://opensource.org/licenses/gpl-license) +// with "runtime exception" (http://www.dune-project.org/license.html) +// Authors: +// Felix Schindler (2017 - 2018) +// Rene Milk (2018) +// Tobias Leibner (2018) + +#include "config.h" + +#if HAVE_LPSOLVE +#include <dune/xt/common/disable_warnings.hh> +#include <lpsolve/lp_lib.h> +#include <dune/xt/common/reenable_warnings.hh> +#endif + +#include <dune/common/unused.hh> + +#include <dune/xt/common/exceptions.hh> + +#include "lpsolve.hh" + +namespace Dune { +namespace XT { +namespace Common { +namespace lp_solve { + + +#if HAVE_LPSOLVE +struct LinearProgram +{ + LinearProgram(int rows, int cols) + : lp_(::make_lp(rows, cols)) + { + if (!lp_) + DUNE_THROW(Dune::MathError, "Couldn't construct linear program"); + } + + ~LinearProgram() + { + ::delete_lp(lp_); + } + + lprec* data() + { + return lp_; + } + +private: + lprec* lp_; +}; +#else // HAVE_LPSOLVE +struct LinearProgram +{ + LinearProgram(int /*rows*/, int /*cols*/) + { + DUNE_THROW(Exceptions::dependency_missing, "You are missing lp_solve, check available() first!"); + } +}; +#endif // HAVE_LPSOLVE + +bool available() +{ +#if HAVE_LPSOLVE + return true; +#else + return false; +#endif +} + + +int eq() +{ +#if HAVE_LPSOLVE + return EQ; +#else + DUNE_THROW(Exceptions::dependency_missing, "You are missing lp_solve, check available() first!"); + return 1; +#endif +} + + +int important() +{ +#if HAVE_LPSOLVE + return IMPORTANT; +#else + DUNE_THROW(Exceptions::dependency_missing, "You are missing lp_solve, check available() first!"); + return 1; +#endif +} + + +int optimal() +{ +#if HAVE_LPSOLVE + return OPTIMAL; +#else + DUNE_THROW(Exceptions::dependency_missing, "You are missing lp_solve, check available() first!"); + return 1; +#endif +} + + +double get_objective(LinearProgram& lp) +{ +#if HAVE_LPSOLVE + return ::get_objective(lp.data()); +#else + DUNE_UNUSED_PARAMETER(lp); + DUNE_THROW(Exceptions::dependency_missing, "You are missing lp_solve, check available() first!"); + return 1; +#endif +} + + +std::unique_ptr<LinearProgram> make_lp(int rows, int cols) +{ + return std::make_unique<LinearProgram>(rows, cols); +} + + +bool set_bounds(LinearProgram& lp, int colnr, double lower, double upper) +{ +#if HAVE_LPSOLVE + auto ret = ::set_bounds(lp.data(), colnr, lower, upper); + assert(ret == 0 || ret == 1); + return static_cast<bool>(ret); +#else + DUNE_UNUSED_PARAMETER(lp); + DUNE_UNUSED_PARAMETER(colnr); + DUNE_UNUSED_PARAMETER(lower); + DUNE_UNUSED_PARAMETER(upper); + DUNE_THROW(Exceptions::dependency_missing, "You are missing lp_solve, check available() first!"); + return 1; +#endif +} + + +bool set_col_name(LinearProgram& lp, int colnr, std::string& colname) +{ +#if HAVE_LPSOLVE + auto ret = ::set_col_name(lp.data(), colnr, &colname[0]); + assert(ret == 0 || ret == 1); + return static_cast<bool>(ret); +#else + DUNE_UNUSED_PARAMETER(lp); + DUNE_UNUSED_PARAMETER(colnr); + DUNE_UNUSED_PARAMETER(colname); + DUNE_THROW(Exceptions::dependency_missing, "You are missing lp_solve, check available() first!"); + return 1; +#endif +} + + +bool set_column(LinearProgram& lp, int colnr, double* column) +{ +#if HAVE_LPSOLVE + auto ret = ::set_column(lp.data(), colnr, column); + assert(ret == 0 || ret == 1); + return static_cast<bool>(ret); +#else + DUNE_UNUSED_PARAMETER(lp); + DUNE_UNUSED_PARAMETER(colnr); + DUNE_UNUSED_PARAMETER(column); + DUNE_THROW(Exceptions::dependency_missing, "You are missing lp_solve, check available() first!"); + return 1; +#endif +} + + +bool set_constr_type(LinearProgram& lp, int rownr, int con_type) +{ +#if HAVE_LPSOLVE + auto ret = ::set_constr_type(lp.data(), rownr, con_type); + assert(ret == 0 || ret == 1); + return static_cast<bool>(ret); +#else + DUNE_UNUSED_PARAMETER(lp); + DUNE_UNUSED_PARAMETER(rownr); + DUNE_UNUSED_PARAMETER(con_type); + DUNE_THROW(Exceptions::dependency_missing, "You are missing lp_solve, check available() first!"); + return 1; +#endif +} + + +bool set_rh(LinearProgram& lp, int rownr, double column) +{ +#if HAVE_LPSOLVE + auto ret = ::set_rh(lp.data(), rownr, column); + assert(ret == 0 || ret == 1); + return static_cast<bool>(ret); +#else + DUNE_UNUSED_PARAMETER(lp); + DUNE_UNUSED_PARAMETER(rownr); + DUNE_UNUSED_PARAMETER(column); + DUNE_THROW(Exceptions::dependency_missing, "You are missing lp_solve, check available() first!"); + return 1; +#endif +} + + +void set_rh_vec(LinearProgram& lp, double* rh) +{ +#if HAVE_LPSOLVE + ::set_rh_vec(lp.data(), rh); +#else + DUNE_UNUSED_PARAMETER(lp); + DUNE_UNUSED_PARAMETER(rh); + DUNE_THROW(Exceptions::dependency_missing, "You are missing lp_solve, check available() first!"); +#endif +} + + +void set_verbose(LinearProgram& lp, int verbose) +{ +#if HAVE_LPSOLVE + ::set_verbose(lp.data(), verbose); +#else + DUNE_UNUSED_PARAMETER(lp); + DUNE_UNUSED_PARAMETER(verbose); + DUNE_THROW(Exceptions::dependency_missing, "You are missing lp_solve, check available() first!"); +#endif +} + + +int solve(LinearProgram& lp) +{ +#if HAVE_LPSOLVE + return ::solve(lp.data()); +#else + DUNE_UNUSED_PARAMETER(lp); + DUNE_THROW(Exceptions::dependency_missing, "You are missing lp_solve, check available() first!"); + return 1; +#endif +} + + +bool write_LP(LinearProgram& lp, FILE* output) +{ +#if HAVE_LPSOLVE + auto ret = ::write_LP(lp.data(), output); + assert(ret == 0 || ret == 1); + return static_cast<bool>(ret); +#else + DUNE_UNUSED_PARAMETER(lp); + DUNE_UNUSED_PARAMETER(output); + DUNE_THROW(Exceptions::dependency_missing, "You are missing lp_solve, check available() first!"); + return 1; +#endif +} + + +} // namespace lp_solve +} // namespace Common +} // namespace XT +} // namespace Dune diff --git a/dune/xt/common/lpsolve.hh b/dune/xt/common/lpsolve.hh new file mode 100644 index 0000000000000000000000000000000000000000..d5ba8ec3e7b51b0094d488a537acffb4325196a8 --- /dev/null +++ b/dune/xt/common/lpsolve.hh @@ -0,0 +1,125 @@ +// This file is part of the dune-xt-common project: +// https://github.com/dune-community/dune-xt-common +// Copyright 2009-2018 dune-xt-common developers and contributors. All rights reserved. +// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause) +// or GPL-2.0+ (http://opensource.org/licenses/gpl-license) +// with "runtime exception" (http://www.dune-project.org/license.html) +// Authors: +// Felix Schindler (2012 - 2014, 2016 - 2018) +// Rene Milk (2011 - 2012, 2015 - 2016, 2018) +// Tobias Leibner (2017 - 2018) + +#ifndef DUNE_XT_COMMON_LPSOLVE_HH +#define DUNE_XT_COMMON_LPSOLVE_HH + +#include <stdio.h> + +#include <complex> +#include <memory> + +namespace Dune { +namespace XT { +namespace Common { +namespace lp_solve { + + +// forward declaration +struct LinearProgram; + + +/** + * \brief If true, calling any of the other methods makes sense. + */ +bool available(); + + +/** + * \brief Wrapper around lp_solve's EQ + */ +int eq(); + + +/** + * \brief Wrapper around lp_solve's IMPORTANT + */ +int important(); + + +/** + * \brief Wrapper around lp_solve's OPTIMAL + */ +int optimal(); + + +/** + * \brief Wrapper around lp_solve's get_objective + */ +double get_objective(LinearProgram& lp); + + +/** + * \brief Create a LinearProgram object (wrapper around lpsolve's lprec) + */ +std::unique_ptr<LinearProgram> make_lp(int rows, int cols); + + +/** + * \brief Wrapper around lp_solve's set_bounds + */ +bool set_bounds(LinearProgram& lp, int colnr, double lower, double upper); + + +/** + * \brief Wrapper around lp_solve's set_col_name + */ +bool set_col_name(LinearProgram& lp, int colnr, std::string& colname); + + +/** + * \brief Wrapper around lp_solve's set_column + */ +bool set_column(LinearProgram& lp, int colnr, double* column); + + +/** + * \brief Wrapper around lp_solve's set_constr_type + */ +bool set_constr_type(LinearProgram& lp, int rownr, int con_type); + + +/** + * \brief Wrapper around lp_solve's set_rh + */ +bool set_rh(LinearProgram& lp, int rownr, double column); + + +/** + * \brief Wrapper around lp_solve's set_rh_vec + */ +void set_rh_vec(LinearProgram& lp, double* rh); + + +/** + * \brief Wrapper around lp_solve's set_verbose + */ +void set_verbose(LinearProgram& lp, int verbose); + + +/** + * \brief Wrapper around lp_solve's solve + */ +int solve(LinearProgram& lp); + + +/** + * \brief Wrapper around lp_solve's write_LP + */ +bool write_LP(LinearProgram& lp, FILE* output); + + +} // namespace lp_solve +} // namespace Common +} // namespace XT +} // namespace Dune + +#endif // DUNE_XT_COMMON_LPSOLVE_HH diff --git a/dune/xt/common/parallel/threadmanager.cc b/dune/xt/common/parallel/threadmanager.cc index 385aff210971c6aac296e692a50b75bda41ebab5..ff5b7a81e5f545b7724cc3d12ac7e54982c168c0 100644 --- a/dune/xt/common/parallel/threadmanager.cc +++ b/dune/xt/common/parallel/threadmanager.cc @@ -71,7 +71,7 @@ size_t Dune::XT::Common::ThreadManager::current_threads() template <typename Key, typename T, typename MapType> std::pair<typename MapType::iterator, bool> tbb_map_emplace(MapType& map_in, Key key, T value) { -#if BOOST_CLANG +#if defined(BOOST_CLANG) && BOOST_CLANG return map_in.insert(typename MapType::value_type(key, value)); #else return map_in.emplace(key, value); diff --git a/dune/xt/common/parallel/threadstorage.hh b/dune/xt/common/parallel/threadstorage.hh index 69cce9ac549dc3632566a272ec84beba3bd0ebf8..1dca7cc97f95dd84f0b29231f9d9efb543fe93b3 100644 --- a/dune/xt/common/parallel/threadstorage.hh +++ b/dune/xt/common/parallel/threadstorage.hh @@ -92,7 +92,7 @@ public: auto& get_pointer() { - return values_[threadManager().thread()]; + return values_[threadManager().thread()]; } template <class BinaryOperation>