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:
Lev Nachmanson 2016-02-24 13:52:31 -08:00 committed by Leonardo de Moura
parent 2fd5347901
commit 23079a75a7
11 changed files with 88 additions and 88 deletions

View file

@ -2449,7 +2449,6 @@ void test_square_dense_submatrix() {
#endif
}
int main(int argn, char * const * argv) {
initialize_util_module();
initialize_numerics_module();

View file

@ -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);

View file

@ -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

View file

@ -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();
}
}
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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)

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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>