/* Copyright (c) 2017 Microsoft Corporation Author: Lev Nachmanson */ #pragma once #include "util/vector.h" #include "util/debug.h" #include #include #include "util/lp/lp_utils.h" #include "util/lp/lp_settings.h" #include namespace lp { template void print_vector(const vector & t, std::ostream & out); template void print_vector(const buffer & t, std::ostream & out); template void print_sparse_vector(const vector & t, std::ostream & out); void print_vector(const vector & t, std::ostream & out); template class indexed_vector { public: // m_index points to non-zero elements of m_data vector m_data; vector m_index; indexed_vector(unsigned data_size) { m_data.resize(data_size, numeric_traits::zero()); } indexed_vector& operator=(const indexed_vector& y) { for (unsigned i: m_index) m_data[i] = zero_of_type(); m_index = y.m_index; m_data.resize(y.data_size()); for (unsigned i : m_index) m_data[i] = y[i]; return *this; } bool operator==(const indexed_vector& y) const { std::unordered_set y_index; for (unsigned i : y.m_index) y_index.insert(i); std::unordered_set this_index; for (unsigned i : m_index) this_index.insert(i); for (unsigned i : y.m_index) { if (this_index.find(i) == this_index.end()) return false; } for (unsigned i : m_index) { if (y_index.find(i) == y_index.end()) return false; } return vectors_are_equal(m_data, m_data); } indexed_vector() {} void resize(unsigned data_size); unsigned data_size() const { return m_data.size(); } unsigned size() { return m_index.size(); } void set_value(const T& value, unsigned index); void clear(); void clear_all(); const T& operator[] (unsigned i) const { return m_data[i]; } T& operator[] (unsigned i) { return m_data[i]; } void clean_up() { #if 0==1 for (unsigned k = 0; k < m_index.size(); k++) { unsigned i = m_index[k]; T & v = m_data[i]; if (lp_settings::is_eps_small_general(v, 1e-14)) { v = zero_of_type(); m_index.erase(m_index.begin() + k--); } } #endif vector index_copy; for (unsigned i : m_index) { T & v = m_data[i]; if (!lp_settings::is_eps_small_general(v, 1e-14)) { index_copy.push_back(i); } else if (!numeric_traits::is_zero(v)) { v = zero_of_type(); } } m_index = index_copy; } void erase_from_index(unsigned j); void add_value_at_index_with_drop_tolerance(unsigned j, const T& val_to_add) { T & v = m_data[j]; bool was_zero = is_zero(v); v += val_to_add; if (lp_settings::is_eps_small_general(v, 1e-14)) { v = zero_of_type(); if (!was_zero) { erase_from_index(j); } } else { if (was_zero) m_index.push_back(j); } } void add_value_at_index(unsigned j, const T& val_to_add) { T & v = m_data[j]; bool was_zero = is_zero(v); v += val_to_add; if (is_zero(v)) { if (!was_zero) erase_from_index(j); } else { if (was_zero) m_index.push_back(j); } } void restore_index_and_clean_from_data() { m_index.resize(0); for (unsigned i = 0; i < m_data.size(); i++) { T & v = m_data[i]; if (lp_settings::is_eps_small_general(v, 1e-14)) { v = zero_of_type(); } else { m_index.push_back(i); } } } #ifdef LEAN_DEBUG bool is_OK() const; void print(std::ostream & out); #endif }; }