3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-29 03:45:51 +00:00

add var_register

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

fill the matrix A in hnf_cutter

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

fill the matrix A in hnf_cutter

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

first steps of hnf cutter

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

handle generated cases in hnf

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

call hnf only for a full rank matrix

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

get (H reversed) * b

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

finding the cut row randomly, exiting if is not there

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

produce first cuts with hnf

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

produce first cuts with hnf

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

define by lp_settings if to avoid calling hnf_cutter when the solution is not on the boundary

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

hnf

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

revert to the previous version

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2018-05-17 15:59:38 -07:00
parent 3b5337823a
commit 82eb80de6d
17 changed files with 482 additions and 129 deletions

View file

@ -104,7 +104,7 @@ void extended_gcd_minimal_uv(const mpq & a, const mpq & b, mpq & d, mpq & u, mpq
template <typename M> bool prepare_pivot_for_lower_triangle(M &m, unsigned r) {
template <typename M> bool prepare_pivot_for_lower_triangle(M &m, unsigned r, svector<unsigned> & basis_rows) {
lp_assert(m.row_count() <= m.column_count());
for (unsigned i = r; i < m.row_count(); i++) {
for (unsigned j = r; j < m.column_count(); j++) {
@ -112,6 +112,7 @@ template <typename M> bool prepare_pivot_for_lower_triangle(M &m, unsigned r) {
if (i != r) {
m.transpose_rows(i, r);
}
basis_rows.push_back(i);
if (j != r) {
m.transpose_columns(j, r);
}
@ -137,12 +138,12 @@ template <typename M> void pivot_column_non_fractional(M &m, unsigned & r) {
}
// returns the rank of the matrix
template <typename M> unsigned to_lower_triangle_non_fractional(M &m) {
template <typename M> void to_lower_triangle_non_fractional(M &m, svector<unsigned> & basis_rows ) {
lp_assert(m.row_count() <= m.column_count());
unsigned i = 0;
for (; i < m.row_count() - 1; i++) {
if (!prepare_pivot_for_lower_triangle(m, i)) {
return i;
if (!prepare_pivot_for_lower_triangle(m, i, basis_rows)) {
return;
}
pivot_column_non_fractional(m, i);
}
@ -150,10 +151,10 @@ template <typename M> unsigned to_lower_triangle_non_fractional(M &m) {
// go over the last row and try to find a non-zero in the row to the right of diagonal
for (unsigned j = i; j < m.column_count(); j++) {
if (!is_zero(m[i][j])) {
return m.row_count();
basis_rows.push_back(i);
break;
}
}
return i;
}
template <typename M>
mpq gcd_of_row_starting_from_diagonal(const M& m, unsigned i) {
@ -173,8 +174,8 @@ mpq gcd_of_row_starting_from_diagonal(const M& m, unsigned i) {
}
// it returns "r" - the rank of the matrix and the gcd of r-minors
template <typename M> mpq determinant_of_rectangular_matrix(const M& m, unsigned & r) {
// it fills "r" - the basic rows of m
template <typename M> mpq determinant_of_rectangular_matrix(const M& m, svector<unsigned> & basis_rows) {
if (m.column_count() < m.row_count())
throw "not implemented"; // consider working with the transposed m, or create a "transposed" version if needed
// The plan is to transform m to the lower triangular form by using non-fractional Gaussian Elimination by columns.
@ -182,19 +183,18 @@ template <typename M> mpq determinant_of_rectangular_matrix(const M& m, unsigned
// m[r-1][r-1], m[r-1][r], ..., m[r-1]m[m.column_count() - 1] give the determinants of all minors of rank r.
// The gcd of these minors is the return value
auto mc = m;
r = to_lower_triangle_non_fractional(mc);
if (r == 0)
to_lower_triangle_non_fractional(mc, basis_rows);
if (basis_rows.size() == 0)
return one_of_type<mpq>();
lp_assert(!is_zero(gcd_of_row_starting_from_diagonal(mc, r - 1)));
return gcd_of_row_starting_from_diagonal(mc, r - 1);
return gcd_of_row_starting_from_diagonal(mc, basis_rows.size() - 1);
}
template <typename M> mpq determinant(const M& m) {
lp_assert(m.row_count() == m.column_count());
auto mc = m;
unsigned r;
mpq d = determinant_of_rectangular_matrix(mc, r);
return r < m.row_count() ? zero_of_type<mpq>() : d;
svector<unsigned> basis_rows;
mpq d = determinant_of_rectangular_matrix(mc, basis_rows);
return basis_rows.size() < m.row_count() ? zero_of_type<mpq>() : d;
}
} // end of namespace hnf_calc
@ -204,7 +204,7 @@ class hnf {
// fields
#ifdef Z3DEBUG
M & m_H;
M m_H;
M m_U;
M m_U_reverse;
#endif
@ -215,7 +215,7 @@ class hnf {
unsigned m_m;
unsigned m_n;
mpq m_d; // it is a positive number and a multiple of gcd of r-minors of m_A_orig, where r is the rank of m_A_orig
mpq m_r; // the rank of m_A
// we suppose that the rank of m_A is equal to row_count(), and that row_count() <= column_count(), that is m_A has the full rank
unsigned m_i;
unsigned m_j;
mpq m_R;
@ -391,7 +391,7 @@ class hnf {
void work_on_columns_less_than_i_in_the_triangle(unsigned i) {
const mpq & mii = m_H[i][i];
lp_assert(is_pos(mii));
if (is_zero(mii)) return;
for (unsigned j = 0; j < i; j++) {
const mpq & mij = m_H[i][j];
if (!is_pos(mij) && - mij < mii)
@ -444,7 +444,7 @@ class hnf {
const mpq & hij = m_H[i][j];
if (is_pos(hij))
return false;
if (- hij >= hii)
if (!is_zero(hii) && - hij >= hii)
return false;
}
@ -594,7 +594,7 @@ private:
}
public:
hnf(M & A, const mpq & d, unsigned r) :
hnf(M & A, const mpq & d) :
#ifdef Z3DEBUG
m_H(A),
#endif
@ -604,12 +604,10 @@ public:
m_m(A.row_count()),
m_n(A.column_count()),
m_d(d),
m_r(r),
m_R(m_d),
m_half_R(floor(m_R / 2))
{
lp_assert(m_m > 0 && m_n > 0);
if (is_zero(m_d))
if (m_m == 0 || m_n == 0 || is_zero(m_d))
return;
#ifdef Z3DEBUG
prepare_U_and_U_reverse();
@ -627,7 +625,7 @@ public:
#endif
}
const M & W() const { return m_W; }
};