refactor(util/lp): use Lean exception
This commit is contained in:
parent
8fbf66d01a
commit
d9acf90f7b
8 changed files with 235 additions and 259 deletions
|
@ -261,7 +261,7 @@ class lar_solver {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw "unexpected";
|
lean_unreachable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,7 +338,7 @@ class lar_solver {
|
||||||
case at_upper_bound: return upper_bound[j];
|
case at_upper_bound: return upper_bound[j];
|
||||||
case free_of_bounds: return zero_of_type<V>();
|
case free_of_bounds: return zero_of_type<V>();
|
||||||
default:
|
default:
|
||||||
throw "unexpected type";
|
lean_unreachable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,10 +421,8 @@ public:
|
||||||
case GE: return left_side_val >= constr.m_right_side;
|
case GE: return left_side_val >= constr.m_right_side;
|
||||||
case GT: return left_side_val >= constr.m_right_side;
|
case GT: return left_side_val >= constr.m_right_side;
|
||||||
case EQ: return left_side_val == constr.m_right_side;
|
case EQ: return left_side_val == constr.m_right_side;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw "unexpected";
|
lean_unreachable();
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -833,8 +831,7 @@ public:
|
||||||
return abs(left_side_val - norm_constr.m_right_side);
|
return abs(left_side_val - norm_constr.m_right_side);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw "unexpected";
|
lean_unreachable();
|
||||||
return numeric_traits<mpq>::zero();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -748,7 +748,7 @@ public:
|
||||||
case upper_bound:
|
case upper_bound:
|
||||||
return at_upper_bound;
|
return at_upper_bound;
|
||||||
default:
|
default:
|
||||||
throw "unexpected column type";
|
lean_unreachable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1159,8 +1159,7 @@ public: // todo : move public lower ; it is for debug only
|
||||||
slope_at_entering += delta;
|
slope_at_entering += delta;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw 1;
|
lean_unreachable();
|
||||||
lean_assert(false); // such a type does not exist
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1222,9 +1221,7 @@ public: // todo : move public lower ; it is for debug only
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
lean_assert(false);
|
lean_unreachable();
|
||||||
throw "cannot be here";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -340,8 +340,7 @@ public:
|
||||||
for (auto it : this->m_columns) {
|
for (auto it : this->m_columns) {
|
||||||
auto sol_it = solution.find(it.second->get_name());
|
auto sol_it = solution.find(it.second->get_name());
|
||||||
if (sol_it == solution.end()) {
|
if (sol_it == solution.end()) {
|
||||||
std::cout << "cannot find column " << it.first << " in solution " << std::endl;
|
throw exception(sstream() << "cannot find column " << it.first << " in solutio");
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!it.second->bounds_hold(sol_it->second)) {
|
if (!it.second->bounds_hold(sol_it->second)) {
|
||||||
|
@ -356,8 +355,7 @@ public:
|
||||||
T get_row_value(unsigned i, std::unordered_map<std::string, T> const & solution, bool print) {
|
T get_row_value(unsigned i, std::unordered_map<std::string, T> const & solution, bool print) {
|
||||||
auto it = this->m_A_values.find(i);
|
auto it = this->m_A_values.find(i);
|
||||||
if (it == this->m_A_values.end()) {
|
if (it == this->m_A_values.end()) {
|
||||||
std::cout << "cannot find row " << i << std::endl;
|
throw exception(sstream() << "cannot find row " << i);
|
||||||
throw "get_row_value";
|
|
||||||
}
|
}
|
||||||
T ret = numeric_traits<T>::zero();
|
T ret = numeric_traits<T>::zero();
|
||||||
for (auto & pair : it->second) {
|
for (auto & pair : it->second) {
|
||||||
|
@ -414,8 +412,7 @@ public:
|
||||||
}
|
}
|
||||||
return true;;
|
return true;;
|
||||||
}
|
}
|
||||||
std::cout << "throw in row_constraint_holds " << std::endl;
|
lean_unreachable();
|
||||||
throw "wrong case";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool row_constraints_hold(std::unordered_map<std::string, T> const & solution) {
|
bool row_constraints_hold(std::unordered_map<std::string, T> const & solution) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ inline std::string column_type_to_string(column_type t) {
|
||||||
case free_column:
|
case free_column:
|
||||||
return std::string("free_column");
|
return std::string("free_column");
|
||||||
default:
|
default:
|
||||||
throw "unexpected";
|
lean_unreachable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,8 +70,7 @@ inline const char* lp_status_to_string(lp_status status) {
|
||||||
case EMPTY: return "EMPTY";
|
case EMPTY: return "EMPTY";
|
||||||
case UNSTABLE: return "UNSTABLE";
|
case UNSTABLE: return "UNSTABLE";
|
||||||
default:
|
default:
|
||||||
std::cout << "throwing in lp_status_to_string " << std::endl;
|
lean_unreachable();
|
||||||
throw "lp_status_to_string";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,8 +84,7 @@ inline lp_status lp_status_from_string(std::string status) {
|
||||||
if (status == "TIME_EXHAUSTED") return lp_status::TIME_EXHAUSTED;
|
if (status == "TIME_EXHAUSTED") return lp_status::TIME_EXHAUSTED;
|
||||||
if (status == "ITERATIONS_EXHAUSTED") return lp_status::ITERATIONS_EXHAUSTED;
|
if (status == "ITERATIONS_EXHAUSTED") return lp_status::ITERATIONS_EXHAUSTED;
|
||||||
if (status == "EMPTY") return lp_status::EMPTY;
|
if (status == "EMPTY") return lp_status::EMPTY;
|
||||||
std::cout << "unexpected status " << status << std::endl;
|
lean_unreachable();
|
||||||
throw "wrong status in a test file";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum non_basic_column_value_position { at_low_bound, at_upper_bound, at_fixed, free_of_bounds };
|
enum non_basic_column_value_position { at_low_bound, at_upper_bound, at_fixed, free_of_bounds };
|
||||||
|
|
|
@ -6,15 +6,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "util/lp/lp_settings.h"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
#include "util/exception.h"
|
||||||
|
#include "util/sstream.h"
|
||||||
|
#include "util/lp/lp_settings.h"
|
||||||
#include "util/lp/column_info.h"
|
#include "util/lp/column_info.h"
|
||||||
#include "util/lp/static_matrix.h"
|
#include "util/lp/static_matrix.h"
|
||||||
#include <algorithm>
|
|
||||||
#include "util/lp/lp_core_solver_base.h"
|
#include "util/lp/lp_core_solver_base.h"
|
||||||
#include <vector>
|
|
||||||
#include "util/lp/scaler.h"
|
#include "util/lp/scaler.h"
|
||||||
namespace lean {
|
namespace lean {
|
||||||
enum lp_relation {
|
enum lp_relation {
|
||||||
|
@ -109,8 +110,7 @@ public:
|
||||||
T get_column_value_by_name(std::string name) const {
|
T get_column_value_by_name(std::string name) const {
|
||||||
auto it = m_names_to_columns.find(name);
|
auto it = m_names_to_columns.find(name);
|
||||||
if (it == m_names_to_columns.end()) {
|
if (it == m_names_to_columns.end()) {
|
||||||
std::cout << "throwing in get_column_value_by_name" << std::endl;
|
throw exception(sstream() << "get_column_value_by_name " << name);
|
||||||
throw "get_column_value_by_name";
|
|
||||||
}
|
}
|
||||||
return get_column_value(it -> second);
|
return get_column_value(it -> second);
|
||||||
}
|
}
|
||||||
|
@ -435,11 +435,9 @@ protected:
|
||||||
case lp_relation::Less_or_equal:
|
case lp_relation::Less_or_equal:
|
||||||
return row_le_is_obsolete(row, row_index);
|
return row_le_is_obsolete(row, row_index);
|
||||||
}
|
}
|
||||||
|
lean_unreachable();
|
||||||
throw "unexpected relation";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void remove_fixed_or_zero_columns() {
|
void remove_fixed_or_zero_columns() {
|
||||||
for (auto & i_row : m_A_values) {
|
for (auto & i_row : m_A_values) {
|
||||||
remove_fixed_or_zero_columns_from_row(i_row.first, i_row.second);
|
remove_fixed_or_zero_columns_from_row(i_row.first, i_row.second);
|
||||||
|
@ -515,8 +513,7 @@ protected:
|
||||||
for (auto & row : m_A_values) {
|
for (auto & row : m_A_values) {
|
||||||
for (auto & col : row.second) {
|
for (auto & col : row.second) {
|
||||||
if (col.second == numeric_traits<T>::zero() || m_columns[col.first]->is_fixed()) {
|
if (col.second == numeric_traits<T>::zero() || m_columns[col.first]->is_fixed()) {
|
||||||
std::cout << "found fixed column " << std::endl;
|
throw exception("found fixed column");
|
||||||
throw "map_external_columns_to_core_solver_columns";
|
|
||||||
}
|
}
|
||||||
unsigned j = col.first;
|
unsigned j = col.first;
|
||||||
auto j_place = m_external_columns_to_core_solver_columns.find(j);
|
auto j_place = m_external_columns_to_core_solver_columns.find(j);
|
||||||
|
@ -615,7 +612,7 @@ protected:
|
||||||
|
|
||||||
auto row = this->m_A_values.find(i);
|
auto row = this->m_A_values.find(i);
|
||||||
if (row == this->m_A_values.end()) {
|
if (row == this->m_A_values.end()) {
|
||||||
throw "cannot find row ";
|
throw exception("cannot find row");
|
||||||
}
|
}
|
||||||
for (auto col : row->second) {
|
for (auto col : row->second) {
|
||||||
ret += col.second * this->m_columns[col.first]->get_shift();
|
ret += col.second * this->m_columns[col.first]->get_shift();
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
Author: Lev Nachmanson
|
Author: Lev Nachmanson
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -12,228 +11,227 @@
|
||||||
#include "util/numerics/double.h"
|
#include "util/numerics/double.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::string T_to_string(const T & t); // forward definition
|
std::string T_to_string(const T & t); // forward definition
|
||||||
|
|
||||||
template <typename X, typename Y>
|
template <typename X, typename Y>
|
||||||
struct convert_struct {
|
struct convert_struct {
|
||||||
static X convert(const Y & y){ return X(y);}
|
static X convert(const Y & y){ return X(y);}
|
||||||
static bool is_epsilon_small(const X & x, const double & y) { return abs(get_double(x)) < y; }
|
static bool is_epsilon_small(const X & x, const double & y) { return abs(get_double(x)) < y; }
|
||||||
static bool below_bound_numeric(const X &, const X &, const Y &) { throw "don't call";}
|
static bool below_bound_numeric(const X &, const X &, const Y &) { lean_unreachable(); }
|
||||||
static bool above_bound_numeric(const X &, const X &, const Y &) { throw "don't call";}
|
static bool above_bound_numeric(const X &, const X &, const Y &) { lean_unreachable(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct convert_struct<double, mpq> {
|
struct convert_struct<double, mpq> {
|
||||||
static double convert(const mpq & q) {return q.get_double();}
|
static double convert(const mpq & q) {return q.get_double();}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct numeric_pair {
|
struct numeric_pair {
|
||||||
T x;
|
T x;
|
||||||
T y;
|
T y;
|
||||||
// empty constructor
|
// empty constructor
|
||||||
numeric_pair() {}
|
numeric_pair() {}
|
||||||
// another constructor
|
// another constructor
|
||||||
|
|
||||||
numeric_pair(T xp, T yp) : x(xp), y(yp) {}
|
numeric_pair(T xp, T yp) : x(xp), y(yp) {}
|
||||||
template <typename X, typename Y> numeric_pair(X xp, Y yp) : numeric_pair(convert_struct<T, X>::convert(xp), convert_struct<T, Y>::convert(yp)) {}
|
template <typename X, typename Y> numeric_pair(X xp, Y yp) : numeric_pair(convert_struct<T, X>::convert(xp), convert_struct<T, Y>::convert(yp)) {}
|
||||||
|
|
||||||
bool operator<(const numeric_pair& a) const {
|
bool operator<(const numeric_pair& a) const {
|
||||||
return x < a.x || (x == a.x && y < a.y);
|
return x < a.x || (x == a.x && y < a.y);
|
||||||
}
|
|
||||||
|
|
||||||
bool operator>(const numeric_pair& a) const {
|
|
||||||
return x > a.x || (x == a.x && y > a.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const numeric_pair& a) const {
|
|
||||||
return a.x == x && a.y == y;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const numeric_pair& a) const {
|
|
||||||
return !(*this == a);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator<=(const numeric_pair& a) const {
|
|
||||||
return *this < a || *this == a;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator>=(const numeric_pair& a) const {
|
|
||||||
return *this > a || a == *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
numeric_pair operator*(const T & a) const {
|
|
||||||
return numeric_pair(a * x, a * y);
|
|
||||||
}
|
|
||||||
|
|
||||||
numeric_pair operator/(const T & a) const {
|
|
||||||
T a_as_T(a);
|
|
||||||
return numeric_pair(x / a_as_T, y / a_as_T);
|
|
||||||
}
|
|
||||||
|
|
||||||
numeric_pair operator/(const numeric_pair &) const {
|
|
||||||
throw "should not be called";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
numeric_pair operator+(const numeric_pair & a) const {
|
|
||||||
return numeric_pair(a.x + x, a.y + y);
|
|
||||||
}
|
|
||||||
|
|
||||||
numeric_pair operator*(const numeric_pair & /*a*/) const {
|
|
||||||
throw "should not be called";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
numeric_pair& operator+=(const numeric_pair & a) {
|
|
||||||
x += a.x;
|
|
||||||
y += a.y;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
numeric_pair& operator-=(const numeric_pair & a) {
|
|
||||||
x -= a.x;
|
|
||||||
y -= a.y;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
numeric_pair& operator/=(const T & a) {
|
|
||||||
x /= a;
|
|
||||||
y /= a;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
numeric_pair& operator*=(const T & a) {
|
|
||||||
x *= a;
|
|
||||||
y *= a;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
numeric_pair operator-(const numeric_pair & a) const {
|
|
||||||
return numeric_pair(x - a.x, y - a.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
numeric_pair operator-() const {
|
|
||||||
return numeric_pair(-x, -y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool precize() { return numeric_traits<T>::precize();}
|
|
||||||
|
|
||||||
std::string to_string() const { return std::string("(") + T_to_string(x) + ", " + T_to_string(y) + ")"; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
std::ostream& operator<<(std::ostream& os, numeric_pair<T> const & obj) {
|
|
||||||
os << obj.to_string();
|
|
||||||
return os;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename X>
|
bool operator>(const numeric_pair& a) const {
|
||||||
numeric_pair<T> operator*(const X & a, const numeric_pair<T> & r) {
|
return x > a.x || (x == a.x && y > a.y);
|
||||||
return numeric_pair<T>(a * r.x, a * r.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename X>
|
bool operator==(const numeric_pair& a) const {
|
||||||
numeric_pair<T> operator*(const numeric_pair<T> & r, const X & a) {
|
return a.x == x && a.y == y;
|
||||||
return numeric_pair<T>(a * r.x, a * r.y);
|
}
|
||||||
|
|
||||||
|
bool operator!=(const numeric_pair& a) const {
|
||||||
|
return !(*this == a);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<=(const numeric_pair& a) const {
|
||||||
|
return *this < a || *this == a;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator>=(const numeric_pair& a) const {
|
||||||
|
return *this > a || a == *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
numeric_pair operator*(const T & a) const {
|
||||||
|
return numeric_pair(a * x, a * y);
|
||||||
|
}
|
||||||
|
|
||||||
|
numeric_pair operator/(const T & a) const {
|
||||||
|
T a_as_T(a);
|
||||||
|
return numeric_pair(x / a_as_T, y / a_as_T);
|
||||||
|
}
|
||||||
|
|
||||||
|
numeric_pair operator/(const numeric_pair &) const {
|
||||||
|
lean_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
numeric_pair operator+(const numeric_pair & a) const {
|
||||||
|
return numeric_pair(a.x + x, a.y + y);
|
||||||
|
}
|
||||||
|
|
||||||
|
numeric_pair operator*(const numeric_pair & /*a*/) const {
|
||||||
|
lean_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
numeric_pair& operator+=(const numeric_pair & a) {
|
||||||
|
x += a.x;
|
||||||
|
y += a.y;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
numeric_pair& operator-=(const numeric_pair & a) {
|
||||||
|
x -= a.x;
|
||||||
|
y -= a.y;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
numeric_pair& operator/=(const T & a) {
|
||||||
|
x /= a;
|
||||||
|
y /= a;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
numeric_pair& operator*=(const T & a) {
|
||||||
|
x *= a;
|
||||||
|
y *= a;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
numeric_pair operator-(const numeric_pair & a) const {
|
||||||
|
return numeric_pair(x - a.x, y - a.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
numeric_pair operator-() const {
|
||||||
|
return numeric_pair(-x, -y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool precize() { return numeric_traits<T>::precize();}
|
||||||
|
|
||||||
|
std::string to_string() const { return std::string("(") + T_to_string(x) + ", " + T_to_string(y) + ")"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// template <numeric_pair, typename T> bool precise() { return numeric_traits<T>::precise();}
|
template <typename T>
|
||||||
template <typename T> double get_double(const numeric_pair<T> & ) { throw "do not call"; }
|
std::ostream& operator<<(std::ostream& os, numeric_pair<T> const & obj) {
|
||||||
template <typename T>
|
os << obj.to_string();
|
||||||
class numeric_traits<numeric_pair<T>> {
|
return os;
|
||||||
public:
|
}
|
||||||
static bool precise() { return numeric_traits<T>::precise();}
|
|
||||||
static numeric_pair<T> zero() { return numeric_pair<T>(numeric_traits<T>::zero(), numeric_traits<T>::zero()); }
|
template <typename T, typename X>
|
||||||
static bool is_zero(const numeric_pair<T> & v) { return numeric_traits<T>::is_zero(v.x) && numeric_traits<T>::is_zero(v.y); }
|
numeric_pair<T> operator*(const X & a, const numeric_pair<T> & r) {
|
||||||
static double get_double(const numeric_pair<T> & v){ return numeric_traits<T>::get_double(v.x); } // just return the double of the first coordinate
|
return numeric_pair<T>(a * r.x, a * r.y);
|
||||||
static double one() { throw "do not call"; }
|
}
|
||||||
};
|
|
||||||
template <>
|
template <typename T, typename X>
|
||||||
struct convert_struct<double, numeric_pair<double>> {
|
numeric_pair<T> operator*(const numeric_pair<T> & r, const X & a) {
|
||||||
static double convert(const numeric_pair<double> & q) {return q.x;}
|
return numeric_pair<T>(a * r.x, a * r.y);
|
||||||
};
|
}
|
||||||
|
|
||||||
template <typename X> bool is_epsilon_small(const X & v, const double& eps); // forward definition { return convert_struct<X, double>::is_epsilon_small(v, eps);}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct convert_struct<numeric_pair<T>, double> {
|
// template <numeric_pair, typename T> bool precise() { return numeric_traits<T>::precise();}
|
||||||
static numeric_pair<T> convert(const double & q) {
|
template <typename T> double get_double(const numeric_pair<T> & ) { lean_unreachable(); }
|
||||||
return numeric_pair<T>(convert_struct<T, double>::convert(q), zero_of_type<T>());
|
template <typename T>
|
||||||
}
|
class numeric_traits<numeric_pair<T>> {
|
||||||
static bool is_epsilon_small(const numeric_pair<T> & p, const double & eps) {
|
public:
|
||||||
return convert_struct<T, double>::is_epsilon_small(p.x, eps) && convert_struct<T, double>::is_epsilon_small(p.y, eps);
|
static bool precise() { return numeric_traits<T>::precise();}
|
||||||
}
|
static numeric_pair<T> zero() { return numeric_pair<T>(numeric_traits<T>::zero(), numeric_traits<T>::zero()); }
|
||||||
static bool below_bound_numeric(const numeric_pair<T> &, const numeric_pair<T> &, const double &) {
|
static bool is_zero(const numeric_pair<T> & v) { return numeric_traits<T>::is_zero(v.x) && numeric_traits<T>::is_zero(v.y); }
|
||||||
throw "do not call";
|
static double get_double(const numeric_pair<T> & v){ return numeric_traits<T>::get_double(v.x); } // just return the double of the first coordinate
|
||||||
}
|
static double one() { lean_unreachable(); }
|
||||||
static bool above_bound_numeric(const numeric_pair<T> &, const numeric_pair<T> &, const double &) {
|
};
|
||||||
throw "do not call";
|
template <>
|
||||||
}
|
struct convert_struct<double, numeric_pair<double>> {
|
||||||
};
|
static double convert(const numeric_pair<double> & q) {return q.x;}
|
||||||
|
};
|
||||||
template <>
|
|
||||||
struct convert_struct<numeric_pair<double>, double> {
|
template <typename X> bool is_epsilon_small(const X & v, const double& eps); // forward definition { return convert_struct<X, double>::is_epsilon_small(v, eps);}
|
||||||
static numeric_pair<double> convert(const double & q) {
|
|
||||||
return numeric_pair<double>(q, 0.0);
|
template <typename T>
|
||||||
}
|
struct convert_struct<numeric_pair<T>, double> {
|
||||||
static bool is_epsilon_small(const numeric_pair<double> & p, const double & eps) {
|
static numeric_pair<T> convert(const double & q) {
|
||||||
return std::abs(p.x) < eps && std::abs(p.y) < eps;
|
return numeric_pair<T>(convert_struct<T, double>::convert(q), zero_of_type<T>());
|
||||||
}
|
}
|
||||||
|
static bool is_epsilon_small(const numeric_pair<T> & p, const double & eps) {
|
||||||
static int compare_on_coord(const double & x, const double & bound, const double eps) {
|
return convert_struct<T, double>::is_epsilon_small(p.x, eps) && convert_struct<T, double>::is_epsilon_small(p.y, eps);
|
||||||
lean_assert(eps > 0);
|
}
|
||||||
if (bound == 0) return (x < - eps)? -1: (x > eps? 1 : 0); // it is an important special case
|
static bool below_bound_numeric(const numeric_pair<T> &, const numeric_pair<T> &, const double &) {
|
||||||
double relative = (bound > 0)? - eps: eps;
|
lean_unreachable();
|
||||||
return (x < bound * (1.0 + relative) - eps)? -1 : ((x > bound * (1.0 - relative) + eps)? 1 : 0);
|
}
|
||||||
}
|
static bool above_bound_numeric(const numeric_pair<T> &, const numeric_pair<T> &, const double &) {
|
||||||
|
lean_unreachable();
|
||||||
static bool below_bound_numeric(const numeric_pair<double> & x, const numeric_pair<double> & bound, const double & eps) {
|
}
|
||||||
int r = compare_on_coord(x.x, bound.x, eps);
|
};
|
||||||
if (r == 1) return false;
|
|
||||||
if (r == -1) return true;
|
template <>
|
||||||
// the first coordinates are almost the same
|
struct convert_struct<numeric_pair<double>, double> {
|
||||||
lean_assert(r == 0);
|
static numeric_pair<double> convert(const double & q) {
|
||||||
return compare_on_coord(x.y, bound.y, eps) == -1;
|
return numeric_pair<double>(q, 0.0);
|
||||||
}
|
}
|
||||||
|
static bool is_epsilon_small(const numeric_pair<double> & p, const double & eps) {
|
||||||
static bool above_bound_numeric(const numeric_pair<double> & x, const numeric_pair<double> & bound, const double & eps) {
|
return std::abs(p.x) < eps && std::abs(p.y) < eps;
|
||||||
int r = compare_on_coord(x.x, bound.x, eps);
|
}
|
||||||
if (r == -1) return false;
|
|
||||||
if (r == 1) return true;
|
static int compare_on_coord(const double & x, const double & bound, const double eps) {
|
||||||
// the first coordinates are almost the same
|
lean_assert(eps > 0);
|
||||||
lean_assert(r == 0);
|
if (bound == 0) return (x < - eps)? -1: (x > eps? 1 : 0); // it is an important special case
|
||||||
return compare_on_coord(x.y, bound.y, eps) == 1;
|
double relative = (bound > 0)? - eps: eps;
|
||||||
}
|
return (x < bound * (1.0 + relative) - eps)? -1 : ((x > bound * (1.0 - relative) + eps)? 1 : 0);
|
||||||
};
|
}
|
||||||
|
|
||||||
template <>
|
static bool below_bound_numeric(const numeric_pair<double> & x, const numeric_pair<double> & bound, const double & eps) {
|
||||||
struct convert_struct<double, double> {
|
int r = compare_on_coord(x.x, bound.x, eps);
|
||||||
static bool is_epsilon_small(const double& x, const double & eps) {
|
if (r == 1) return false;
|
||||||
return x < eps && x > -eps;
|
if (r == -1) return true;
|
||||||
}
|
// the first coordinates are almost the same
|
||||||
static double convert(const double & y){ return y;}
|
lean_assert(r == 0);
|
||||||
static bool below_bound_numeric(const double & x, const double & bound, const double & eps) {
|
return compare_on_coord(x.y, bound.y, eps) == -1;
|
||||||
lean_assert(eps > 0);
|
}
|
||||||
if (bound == 0) return x < - eps;
|
|
||||||
double relative = (bound > 0)? - eps: eps;
|
static bool above_bound_numeric(const numeric_pair<double> & x, const numeric_pair<double> & bound, const double & eps) {
|
||||||
return x < bound * (1.0 + relative) - eps;
|
int r = compare_on_coord(x.x, bound.x, eps);
|
||||||
}
|
if (r == -1) return false;
|
||||||
static bool above_bound_numeric(const double & x, const double & bound, const double & eps) {
|
if (r == 1) return true;
|
||||||
lean_assert(eps > 0);
|
// the first coordinates are almost the same
|
||||||
if (bound == 0) return x > eps;
|
lean_assert(r == 0);
|
||||||
double relative = (bound > 0)? eps: - eps;
|
return compare_on_coord(x.y, bound.y, eps) == 1;
|
||||||
return x > bound * (1.0 + relative) + eps;
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
template <>
|
||||||
template <typename X> bool is_epsilon_small(const X & v, const double &eps) { return convert_struct<X, double>::is_epsilon_small(v, eps);}
|
struct convert_struct<double, double> {
|
||||||
template <typename X> bool below_bound_numeric(const X & x, const X & bound, const double& eps) { return convert_struct<X, double>::below_bound_numeric(x, bound, eps);}
|
static bool is_epsilon_small(const double& x, const double & eps) {
|
||||||
template <typename X> bool above_bound_numeric(const X & x, const X & bound, const double& eps) { return convert_struct<X, double>::above_bound_numeric(x, bound, eps);}
|
return x < eps && x > -eps;
|
||||||
|
}
|
||||||
|
static double convert(const double & y){ return y;}
|
||||||
|
static bool below_bound_numeric(const double & x, const double & bound, const double & eps) {
|
||||||
|
lean_assert(eps > 0);
|
||||||
|
if (bound == 0) return x < - eps;
|
||||||
|
double relative = (bound > 0)? - eps: eps;
|
||||||
|
return x < bound * (1.0 + relative) - eps;
|
||||||
|
}
|
||||||
|
static bool above_bound_numeric(const double & x, const double & bound, const double & eps) {
|
||||||
|
lean_assert(eps > 0);
|
||||||
|
if (bound == 0) return x > eps;
|
||||||
|
double relative = (bound > 0)? eps: - eps;
|
||||||
|
return x > bound * (1.0 + relative) + eps;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename X> bool is_epsilon_small(const X & v, const double &eps) { return convert_struct<X, double>::is_epsilon_small(v, eps);}
|
||||||
|
template <typename X> bool below_bound_numeric(const X & x, const X & bound, const double& eps) { return convert_struct<X, double>::below_bound_numeric(x, bound, eps);}
|
||||||
|
template <typename X> bool above_bound_numeric(const X & x, const X & bound, const double& eps) { return convert_struct<X, double>::above_bound_numeric(x, bound, eps);}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
#include "util/numerics/numeric_traits.h"
|
#include "util/numerics/numeric_traits.h"
|
||||||
#include "util/numerics/xnumeral.h"
|
#include "util/numerics/xnumeral.h"
|
||||||
#include "util/numerics/mpq.h"
|
#include "util/numerics/mpq.h"
|
||||||
|
@ -15,10 +18,7 @@
|
||||||
#include "util/numerics/double.h"
|
#include "util/numerics/double.h"
|
||||||
#include "util/numerics/float.h"
|
#include "util/numerics/float.h"
|
||||||
#include "util/numerics/mpfp.h"
|
#include "util/numerics/mpfp.h"
|
||||||
#include <set>
|
|
||||||
#include "util/lp/sparse_vector.h"
|
#include "util/lp/sparse_vector.h"
|
||||||
#include <unordered_map>
|
|
||||||
#include <utility>
|
|
||||||
#include "util/lp/matrix_domain.h"
|
#include "util/lp/matrix_domain.h"
|
||||||
#include "util/lp/indexed_vector.h"
|
#include "util/lp/indexed_vector.h"
|
||||||
|
|
||||||
|
@ -48,9 +48,7 @@ private:
|
||||||
T m_value;
|
T m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// each assignment for this matrix should be issued only once!!!
|
||||||
|
|
||||||
// each assignment for this matrix should be issued only once!!!
|
|
||||||
template <typename T, typename X>
|
template <typename T, typename X>
|
||||||
class static_matrix
|
class static_matrix
|
||||||
#ifdef LEAN_DEBUG
|
#ifdef LEAN_DEBUG
|
||||||
|
@ -461,15 +459,9 @@ public:
|
||||||
virtual void set_number_of_rows(unsigned /*m*/) { }
|
virtual void set_number_of_rows(unsigned /*m*/) { }
|
||||||
virtual void set_number_of_columns(unsigned /*n*/) { }
|
virtual void set_number_of_columns(unsigned /*n*/) { }
|
||||||
#endif
|
#endif
|
||||||
// const T & get_value_of_column_cell(column_cell<T> const & cc) const {
|
|
||||||
// lean_assert(cc.m_i < m_rows.size());
|
|
||||||
// lean_assert(cc.m_offset < m_rows[cc.m_i].size());
|
|
||||||
// return m_rows[cc.m_i][cc.m_offset].get_val();
|
|
||||||
// }
|
|
||||||
|
|
||||||
T get_max_val_in_row(unsigned i) const {
|
T get_max_val_in_row(unsigned i) const {
|
||||||
lean_assert(false);
|
lean_unreachable();
|
||||||
throw 0;// not implemented
|
|
||||||
}
|
}
|
||||||
|
|
||||||
T get_balance() const {
|
T get_balance() const {
|
||||||
|
|
Loading…
Reference in a new issue