dev(lp): fix build for clang, avoid clang-3.3 bug, cleanup permutation_matrix
Signed-off-by: Lev Nachmanson <levnach@microsoft.com>
This commit is contained in:
parent
2fd5347901
commit
23079a75a7
11 changed files with 88 additions and 88 deletions
|
@ -2449,7 +2449,6 @@ void test_square_dense_submatrix() {
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
int main(int argn, char * const * argv) {
|
||||
initialize_util_module();
|
||||
initialize_numerics_module();
|
||||
|
|
|
@ -195,7 +195,7 @@ class mps_reader {
|
|||
// look for start of the rows
|
||||
read_line();
|
||||
do {
|
||||
if (m_line.find("ROWS") >= 0) {
|
||||
if (static_cast<int>(m_line.find("ROWS")) >= 0) {
|
||||
break;
|
||||
}
|
||||
} while (m_is_OK);
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
#include <utility>
|
||||
#include <functional>
|
||||
#include "util/numerics/mpq.h"
|
||||
#ifdef __CLANG__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wmismatched-tags"
|
||||
#endif
|
||||
namespace std {
|
||||
template<>
|
||||
struct hash<lean::mpq> {
|
||||
|
@ -19,8 +23,7 @@ struct hash<lean::mpq> {
|
|||
|
||||
template <class T>
|
||||
inline void hash_combine(std::size_t & seed, const T & v) {
|
||||
std::hash<T> hasher;
|
||||
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
seed ^= std::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
}
|
||||
|
||||
namespace std {
|
||||
|
@ -33,3 +36,6 @@ template<typename S, typename T> struct hash<pair<S, T>> {
|
|||
}
|
||||
};
|
||||
}
|
||||
#ifdef __CLANG__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
|
|
@ -102,8 +102,9 @@ fill_cb(T * y){
|
|||
|
||||
template <typename T, typename X> void lp_core_solver_base<T, X>::
|
||||
fill_cb(std::vector<T> & y){
|
||||
for (unsigned i = 0; i < m_m; i++)
|
||||
for (unsigned i = 0; i < m_m; i++) {
|
||||
y[i] = m_costs[m_basis[i]];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename X> void lp_core_solver_base<T, X>::
|
||||
|
@ -542,10 +543,11 @@ fill_reduced_costs_from_m_y_by_rows() {
|
|||
while (i--) {
|
||||
const T & y = m_y[i];
|
||||
if (is_zero(y)) continue;
|
||||
for (auto & it : m_A.m_rows[i]) {
|
||||
for (row_cell<T> & it : m_A.m_rows[i]) {
|
||||
j = it.m_j;
|
||||
if (m_factorization->m_basis_heading[j] < 0)
|
||||
if (m_factorization->m_basis_heading[j] < 0) {
|
||||
m_d[j] -= y * it.get_val();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "util/lp/lp_primal_core_solver.h"
|
||||
namespace lean {
|
||||
|
||||
|
||||
// This core solver solves (Ax=b, low_bound_values \leq x \leq upper_bound_values, maximize costs*x )
|
||||
// The right side b is given implicitly by x and the basis
|
||||
template <typename T, typename X>
|
||||
|
@ -242,16 +241,16 @@ template <typename T, typename X> X lp_primal_core_solver<T, X>::get_max_boun
|
|||
}
|
||||
|
||||
// stage1 constructor
|
||||
template <typename T, typename X> lp_primal_core_solver<T, X>:: lp_primal_core_solver(static_matrix<T, X> & A,
|
||||
std::vector<X> & b, // the right side vector
|
||||
std::vector<X> & x, // the number of elements in x needs to be at least as large as the number of columns in A
|
||||
std::vector<unsigned> & basis,
|
||||
std::vector<T> & costs,
|
||||
std::vector<column_type> & column_type_array,
|
||||
std::vector<X> & low_bound_values,
|
||||
std::vector<X> & upper_bound_values,
|
||||
lp_settings & settings,
|
||||
std::unordered_map<unsigned, std::string> const & column_names):
|
||||
template <typename T, typename X> lp_primal_core_solver<T, X>::lp_primal_core_solver(static_matrix<T, X> & A,
|
||||
std::vector<X> & b, // the right side vector
|
||||
std::vector<X> & x, // the number of elements in x needs to be at least as large as the number of columns in A
|
||||
std::vector<unsigned> & basis,
|
||||
std::vector<T> & costs,
|
||||
std::vector<column_type> & column_type_array,
|
||||
std::vector<X> & low_bound_values,
|
||||
std::vector<X> & upper_bound_values,
|
||||
lp_settings & settings,
|
||||
std::unordered_map<unsigned, std::string> const & column_names):
|
||||
lp_core_solver_base<T, X>(A, b,
|
||||
basis,
|
||||
x,
|
||||
|
@ -261,7 +260,8 @@ template <typename T, typename X> lp_primal_core_solver<T, X>:: lp_primal_core
|
|||
column_type_array,
|
||||
low_bound_values,
|
||||
upper_bound_values),
|
||||
m_beta(A.row_count()) {
|
||||
m_beta(A.row_count()),
|
||||
m_converted_harris_eps(convert_struct<T, double>::convert(this->m_settings.harris_feasibility_tolerance)) {
|
||||
this->m_status = UNKNOWN;
|
||||
this->m_column_norm_update_counter = settings.column_norms_update_frequency;
|
||||
}
|
||||
|
@ -286,8 +286,8 @@ lp_primal_core_solver(static_matrix<T, X> & A,
|
|||
column_type_array,
|
||||
m_low_bound_values_dummy,
|
||||
upper_bound_values),
|
||||
m_beta(A.row_count()) {
|
||||
m_converted_harris_eps = convert_struct<T, double>::convert(this->m_settings.harris_feasibility_tolerance);
|
||||
m_beta(A.row_count()),
|
||||
m_converted_harris_eps(convert_struct<T, double>::convert(this->m_settings.harris_feasibility_tolerance)) {
|
||||
lean_assert(initial_x_is_correct());
|
||||
m_low_bound_values_dummy.resize(A.column_count(), zero_of_type<T>());
|
||||
m_enter_price_eps = numeric_traits<T>::precise() ? numeric_traits<T>::zero() : T(1e-5);
|
||||
|
|
|
@ -47,7 +47,8 @@ public:
|
|||
bool m_exit_on_feasible_solution = false;
|
||||
std::vector<T> m_costs_backup;
|
||||
bool m_current_x_is_feasible;
|
||||
T m_converted_harris_eps = convert_struct<T, double>::convert(this->m_settings.harris_feasibility_tolerance);
|
||||
T m_converted_harris_eps;
|
||||
// T m_converted_harris_eps = convert_struct<T, double>::convert(this->m_settings.harris_feasibility_tolerance);
|
||||
std::list<unsigned> m_non_basis_list;
|
||||
void sort_non_basis();
|
||||
int choose_entering_column(unsigned number_of_benefitial_columns_to_go_over);
|
||||
|
|
|
@ -332,6 +332,7 @@ void lu<T, X>::swap_rows(int j, int k) {
|
|||
m_U.swap_rows(j, k);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename X>
|
||||
void lu<T, X>::swap_columns(int j, int pivot_column) {
|
||||
if (j == pivot_column)
|
||||
|
|
|
@ -7,33 +7,33 @@
|
|||
#include <vector>
|
||||
#include "util/lp/permutation_matrix.h"
|
||||
namespace lean {
|
||||
template <typename T, typename X> permutation_matrix<T, X>::permutation_matrix(unsigned length): m_length(length), m_permutation(length), m_rev(length) {
|
||||
unsigned i = m_length;
|
||||
while (i--)
|
||||
template <typename T, typename X> permutation_matrix<T, X>::permutation_matrix(unsigned length): m_permutation(length), m_rev(length) {
|
||||
lean_assert(length > 0);
|
||||
for (unsigned i = 0; i < length; i++) { // do not change the direction of the loop because of the vectorization bug in clang3.3
|
||||
m_permutation[i] = m_rev[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename X> permutation_matrix<T, X>::permutation_matrix(unsigned length, std::vector<unsigned> const & values): m_length(length), m_permutation(length), m_rev(length) {
|
||||
template <typename T, typename X> permutation_matrix<T, X>::permutation_matrix(unsigned length, std::vector<unsigned> const & values): m_permutation(length), m_rev(length) {
|
||||
for (unsigned i = 0; i < length; i++) {
|
||||
set_val(i, values[i]);
|
||||
}
|
||||
}
|
||||
// create a unit permutation of the given length
|
||||
template <typename T, typename X> void permutation_matrix<T, X>::init(unsigned length) {
|
||||
m_length = length;
|
||||
m_permutation.resize(length);
|
||||
m_rev.resize(length);
|
||||
unsigned i = length;
|
||||
while (i--)
|
||||
for (unsigned i = 0; i < length; i++) {
|
||||
m_permutation[i] = m_rev[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LEAN_DEBUG
|
||||
template <typename T, typename X> void permutation_matrix<T, X>::print(std::ostream & out) const {
|
||||
out << "[";
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
for (unsigned i = 0; i < size(); i++) {
|
||||
out << m_permutation[i];
|
||||
if (i < m_length - 1) {
|
||||
if (i < size() - 1) {
|
||||
out << ",";
|
||||
} else {
|
||||
out << "]";
|
||||
|
@ -50,15 +50,15 @@ void permutation_matrix<T, X>::apply_from_left_perm(std::vector<L> & w) {
|
|||
// L * deb_w = clone_vector<L>(w, row_count());
|
||||
// deb.apply_from_left(deb_w);
|
||||
#endif
|
||||
L * t = new L[m_length];
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
std::vector<L> t(size());
|
||||
unsigned i = size();
|
||||
while (i-- > 0) {
|
||||
t[i] = w[m_permutation[i]];
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
i = size();
|
||||
while (i-- > 0) {
|
||||
w[i] = t[i];
|
||||
}
|
||||
delete [] t;
|
||||
#ifdef LEAN_DEBUG
|
||||
// lean_assert(vectors_are_equal<L>(deb_w, w, row_count()));
|
||||
// delete [] deb_w;
|
||||
|
@ -96,15 +96,14 @@ template <typename T, typename X> void permutation_matrix<T, X>::apply_from_righ
|
|||
// T * deb_w = clone_vector<T>(w, row_count());
|
||||
// deb.apply_from_right(deb_w);
|
||||
#endif
|
||||
T * t = new T[m_length];
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
std::vector<T> t(size());
|
||||
for (unsigned i = 0; i < size(); i++) {
|
||||
t[i] = w[m_rev[i]];
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
for (unsigned i = 0; i < size(); i++) {
|
||||
w[i] = t[i];
|
||||
}
|
||||
delete [] t;
|
||||
#ifdef LEAN_DEBUG
|
||||
// lean_assert(vectors_are_equal<T>(deb_w, w, row_count()));
|
||||
// delete [] deb_w;
|
||||
|
@ -166,12 +165,13 @@ void permutation_matrix<T, X>::apply_reverse_from_left(std::vector<L> & w) {
|
|||
// T * deb_w = clone_vector<T>(w, row_count());
|
||||
// deb.apply_from_left(deb_w);
|
||||
#endif
|
||||
std::vector<L> t(m_length);
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
std::vector<L> t(size());
|
||||
unsigned i = size();
|
||||
while (i-- > 0) {
|
||||
t[m_permutation[i]] = w[i];
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
i = size();
|
||||
while (i-- > 0) {
|
||||
w[i] = t[i];
|
||||
}
|
||||
#ifdef LEAN_DEBUG
|
||||
|
@ -179,7 +179,6 @@ void permutation_matrix<T, X>::apply_reverse_from_left(std::vector<L> & w) {
|
|||
// delete [] deb_w;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T, typename X>template <typename L>
|
||||
void permutation_matrix<T, X>::apply_reverse_from_right(std::vector<L> & w) {
|
||||
// the result will be w = w * p(-1)
|
||||
|
@ -188,15 +187,15 @@ void permutation_matrix<T, X>::apply_reverse_from_right(std::vector<L> & w) {
|
|||
// T * deb_w = clone_vector<T>(w, row_count());
|
||||
// deb.apply_from_right(deb_w);
|
||||
#endif
|
||||
L * t = new T[m_length];
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
std::vector<L> t(size());
|
||||
unsigned i = size();
|
||||
while (i-- > 0) {
|
||||
t[i] = w[m_permutation[i]];
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
i = size();
|
||||
while (i-- > 0) {
|
||||
w[i] = t[i];
|
||||
}
|
||||
delete [] t;
|
||||
#ifdef LEAN_DEBUG
|
||||
// lean_assert(vectors_are_equal<T>(deb_w, w, row_count()));
|
||||
// delete deb_w;
|
||||
|
@ -205,7 +204,7 @@ void permutation_matrix<T, X>::apply_reverse_from_right(std::vector<L> & w) {
|
|||
|
||||
template <typename T, typename X> void permutation_matrix<T, X>::transpose_from_left(unsigned i, unsigned j) {
|
||||
// the result will be this = (i,j)*this
|
||||
lean_assert(i < m_length && j < m_length && i != j);
|
||||
lean_assert(i < size() && j < size() && i != j);
|
||||
auto pi = m_rev[i];
|
||||
auto pj = m_rev[j];
|
||||
set_val(pi, j);
|
||||
|
@ -214,7 +213,7 @@ template <typename T, typename X> void permutation_matrix<T, X>::transpose_from_
|
|||
|
||||
template <typename T, typename X> void permutation_matrix<T, X>::transpose_from_right(unsigned i, unsigned j) {
|
||||
// the result will be this = this * (i,j)
|
||||
lean_assert(i < m_length && j < m_length && i != j);
|
||||
lean_assert(i < size() && j < size() && i != j);
|
||||
auto pi = m_permutation[i];
|
||||
auto pj = m_permutation[j];
|
||||
set_val(i, pj);
|
||||
|
@ -222,8 +221,8 @@ template <typename T, typename X> void permutation_matrix<T, X>::transpose_from_
|
|||
}
|
||||
|
||||
template <typename T, typename X> unsigned * permutation_matrix<T, X>::clone_m_permutation() {
|
||||
auto r = new unsigned[m_length];
|
||||
for (int i = m_length - 1; i >= 0; i--) {
|
||||
auto r = new unsigned[size()];
|
||||
for (int i = size() - 1; i >= 0; i--) {
|
||||
r[i] = m_permutation[i];
|
||||
}
|
||||
return r;
|
||||
|
@ -231,56 +230,50 @@ template <typename T, typename X> unsigned * permutation_matrix<T, X>::clone_m_
|
|||
|
||||
template <typename T, typename X> void permutation_matrix<T, X>::multiply_by_permutation_from_left(permutation_matrix<T, X> & p) {
|
||||
auto clone = clone_m_permutation();
|
||||
lean_assert(p.m_length == m_length);
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
lean_assert(p.size() == size());
|
||||
unsigned i = size();
|
||||
while (i-- > 0) {
|
||||
set_val(i, clone[p[i]]); // we have m(P)*m(Q) = m(QP), where m is the matrix of the permutation
|
||||
}
|
||||
delete clone;
|
||||
delete [] clone;
|
||||
}
|
||||
|
||||
// this is multiplication in the matrix sense
|
||||
template <typename T, typename X> void permutation_matrix<T, X>::multiply_by_permutation_from_right(permutation_matrix<T, X> & p) {
|
||||
auto clone = clone_m_permutation();
|
||||
lean_assert(p.m_length == m_length);
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
lean_assert(p.size() == size());
|
||||
unsigned i = size();
|
||||
while (i-- > 0) {
|
||||
set_val(i, p[clone[i]]); // we have m(P)*m(Q) = m(QP), where m is the matrix of the permutation
|
||||
}
|
||||
delete clone;
|
||||
delete [] clone;
|
||||
}
|
||||
|
||||
template <typename T, typename X> void permutation_matrix<T, X>::multiply_by_reverse_from_right(permutation_matrix<T, X> & q){ // todo : condensed permutations ?
|
||||
auto clone = clone_m_permutation();
|
||||
// the result is this = this*q(-1)
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
unsigned i = size();
|
||||
while (i-- > 0) {
|
||||
set_val(i, q.m_rev[clone[i]]); // we have m(P)*m(Q) = m(QP), where m is the matrix of the permutation
|
||||
}
|
||||
delete clone;
|
||||
delete [] clone;
|
||||
}
|
||||
|
||||
template <typename T, typename X> void permutation_matrix<T, X>::multiply_by_permutation_reverse_from_left(permutation_matrix<T, X> & r){ // todo : condensed permutations?
|
||||
// the result is this = r(-1)*this
|
||||
auto clone = clone_m_permutation();
|
||||
// the result is this = this*q(-1)
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
unsigned i = size();
|
||||
while (i-- > 0) {
|
||||
set_val(i, clone[r.m_rev[i]]);
|
||||
}
|
||||
delete clone;
|
||||
delete [] clone;
|
||||
}
|
||||
|
||||
template <typename T, typename X> void permutation_matrix<T, X>::shrink_by_one_identity() {
|
||||
lean_assert(is_identity());
|
||||
m_length--;
|
||||
delete [] m_permutation;
|
||||
delete [] m_rev;
|
||||
m_permutation = new unsigned[m_length];
|
||||
m_rev = new unsigned[m_length];
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
m_permutation[i] = m_rev[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename X> bool permutation_matrix<T, X>::is_identity() const {
|
||||
for (unsigned i = 0; i < m_length; i++) {
|
||||
unsigned i = size();
|
||||
while (i-- > 0) {
|
||||
if (m_permutation[i] != i) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ namespace lean {
|
|||
template <typename T, typename X>
|
||||
class permutation_matrix
|
||||
: public tail_matrix<T, X> {
|
||||
unsigned m_length;
|
||||
std::vector<unsigned> m_permutation;
|
||||
std::vector<unsigned> m_rev;
|
||||
|
||||
|
@ -50,7 +49,7 @@ namespace lean {
|
|||
};
|
||||
|
||||
public:
|
||||
permutation_matrix() : m_length(0) {}
|
||||
permutation_matrix() {}
|
||||
permutation_matrix(unsigned length);
|
||||
|
||||
permutation_matrix(unsigned length, std::vector<unsigned> const & values);
|
||||
|
@ -61,7 +60,7 @@ namespace lean {
|
|||
|
||||
#ifdef LEAN_DEBUG
|
||||
permutation_matrix get_inverse() const {
|
||||
return permutation_matrix(m_length, m_rev);
|
||||
return permutation_matrix(size(), m_rev);
|
||||
}
|
||||
void print(std::ostream & out) const;
|
||||
#endif
|
||||
|
@ -99,7 +98,7 @@ namespace lean {
|
|||
void apply_reverse_from_right(std::vector<L> & w);
|
||||
|
||||
void set_val(unsigned i, unsigned pi) {
|
||||
lean_assert(i < m_length && pi < m_length); m_permutation[i] = pi; m_rev[pi] = i; }
|
||||
lean_assert(i < size() && pi < size()); m_permutation[i] = pi; m_rev[pi] = i; }
|
||||
|
||||
void transpose_from_left(unsigned i, unsigned j);
|
||||
|
||||
|
@ -110,8 +109,8 @@ namespace lean {
|
|||
T get_elem(unsigned i, unsigned j) const{
|
||||
return m_permutation[i] == j? numeric_traits<T>::one() : numeric_traits<T>::zero();
|
||||
}
|
||||
unsigned row_count() const{ return m_length; }
|
||||
unsigned column_count() const { return m_length; }
|
||||
unsigned row_count() const{ return size(); }
|
||||
unsigned column_count() const { return size(); }
|
||||
virtual void set_number_of_rows(unsigned /*m*/) { }
|
||||
virtual void set_number_of_columns(unsigned /*n*/) { }
|
||||
#endif
|
||||
|
@ -130,7 +129,7 @@ namespace lean {
|
|||
|
||||
bool is_identity() const;
|
||||
|
||||
unsigned size() const { return m_length; }
|
||||
unsigned size() const { return m_rev.size(); }
|
||||
|
||||
unsigned * values() const { return m_permutation; }
|
||||
}; // end of the permutation class
|
||||
|
|
|
@ -207,8 +207,9 @@ template <typename T, typename X>
|
|||
bool sparse_matrix<T, X>::pivot_with_eta(unsigned i, eta_matrix<T, X> *eta_matrix, lp_settings & settings) {
|
||||
T pivot = eta_matrix->get_diagonal_element();
|
||||
for (auto & it : eta_matrix->m_column_vector.m_data) {
|
||||
if (!pivot_row_to_row(i, it.second, it.first, settings))
|
||||
if (!pivot_row_to_row(i, it.second, it.first, settings)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
divide_row_by_constant(i, pivot, settings);
|
||||
if (!shorten_active_matrix(i, eta_matrix)) {
|
||||
|
@ -901,7 +902,6 @@ bool sparse_matrix<T, X>::pivot_queue_is_correct_after_pivoting(int k) {
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
template <typename T, typename X>
|
||||
bool sparse_matrix<T, X>::get_pivot_for_column(unsigned &i, unsigned &j, T const & c_partial_pivoting, unsigned k) {
|
||||
std::vector<upair> pivots_candidates_that_are_too_small;
|
||||
|
@ -919,14 +919,14 @@ bool sparse_matrix<T, X>::get_pivot_for_column(unsigned &i, unsigned &j, T const
|
|||
// lean_assert(false);
|
||||
// }
|
||||
#endif
|
||||
|
||||
recover_pivot_queue(pivots_candidates_that_are_too_small);
|
||||
i = i_inv;
|
||||
j = j_inv;
|
||||
return true;
|
||||
}
|
||||
if (small != 2) // 2 means that the pair is not in the matrix
|
||||
if (small != 2) { // 2 means that the pair is not in the matrix
|
||||
pivots_candidates_that_are_too_small.emplace_back(i, j);
|
||||
}
|
||||
}
|
||||
recover_pivot_queue(pivots_candidates_that_are_too_small);
|
||||
return false;
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <utility>
|
||||
#include <set>
|
||||
#include "util/lp/static_matrix.h"
|
||||
|
||||
namespace lean {
|
||||
// each assignment for this matrix should be issued only once!!!
|
||||
template <typename T, typename X>
|
||||
|
|
Loading…
Reference in a new issue