mirror of
https://github.com/Z3Prover/z3
synced 2025-06-17 03:16:17 +00:00
kernel
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
54648f6b50
commit
5ca3bc3212
3 changed files with 54 additions and 76 deletions
|
@ -136,6 +136,7 @@ namespace simplex {
|
||||||
svector<int> m_var_pos; // temporary map from variables to positions in row
|
svector<int> m_var_pos; // temporary map from variables to positions in row
|
||||||
unsigned_vector m_var_pos_idx; // indices in m_var_pos
|
unsigned_vector m_var_pos_idx; // indices in m_var_pos
|
||||||
stats m_stats;
|
stats m_stats;
|
||||||
|
scoped_numeral m_zero;
|
||||||
|
|
||||||
bool well_formed_row(unsigned row_id) const;
|
bool well_formed_row(unsigned row_id) const;
|
||||||
bool well_formed_column(unsigned column_id) const;
|
bool well_formed_column(unsigned column_id) const;
|
||||||
|
@ -144,7 +145,7 @@ namespace simplex {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
sparse_matrix(manager& _m): m(_m) {}
|
sparse_matrix(manager& _m): m(_m), m_zero(m) {}
|
||||||
~sparse_matrix();
|
~sparse_matrix();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
@ -216,6 +217,7 @@ namespace simplex {
|
||||||
unsigned column_size(var_t v) const { return m_columns[v].size(); }
|
unsigned column_size(var_t v) const { return m_columns[v].size(); }
|
||||||
|
|
||||||
unsigned num_vars() const { return m_columns.size(); }
|
unsigned num_vars() const { return m_columns.size(); }
|
||||||
|
unsigned num_rows() const { return m_rows.size(); }
|
||||||
|
|
||||||
class col_iterator {
|
class col_iterator {
|
||||||
friend class sparse_matrix;
|
friend class sparse_matrix;
|
||||||
|
@ -306,11 +308,11 @@ namespace simplex {
|
||||||
|
|
||||||
all_rows get_rows() { return all_rows(*this); }
|
all_rows get_rows() { return all_rows(*this); }
|
||||||
|
|
||||||
numeral& get_coeff(row r, unsigned v) {
|
numeral const& get_coeff(row r, unsigned v) {
|
||||||
for (auto & [coeff, u] : get_row(r))
|
for (auto & [coeff, u] : get_row(r))
|
||||||
if (u == v)
|
if (u == v)
|
||||||
return coeff;
|
return coeff;
|
||||||
throw default_exception("variable not in row");
|
return m_zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,73 +26,44 @@ namespace simplex {
|
||||||
class sparse_matrix_ops {
|
class sparse_matrix_ops {
|
||||||
public:
|
public:
|
||||||
static void kernel(sparse_matrix<mpq_ext>& M, vector<vector<rational>>& K) {
|
static void kernel(sparse_matrix<mpq_ext>& M, vector<vector<rational>>& K) {
|
||||||
mpq_ext::numeral coeff;
|
|
||||||
rational D;
|
rational D;
|
||||||
vector<unsigned> d, c;
|
vector<unsigned> d, c;
|
||||||
unsigned m = M.num_vars();
|
unsigned n = M.num_vars(), m = M.num_rows();
|
||||||
auto& mgr = M.get_manager();
|
auto& mgr = M.get_manager();
|
||||||
for (unsigned v = 0; v < m; ++v)
|
c.resize(m, 0u);
|
||||||
c.push_back(0);
|
d.resize(n, 0u);
|
||||||
|
|
||||||
unsigned nullity = 0, rank = 0;
|
for (unsigned k = 0; k < n; ++k) {
|
||||||
for (auto const& row : M.get_rows()) {
|
d[k] = 0;
|
||||||
// scan for non-zero variable in row
|
for (auto [row, row_entry] : M.get_rows(k)) {
|
||||||
bool found = false;
|
if (c[row.id()] != 0)
|
||||||
d.push_back(0);
|
continue;
|
||||||
++nullity;
|
auto& m_jk = row_entry->m_coeff;
|
||||||
for (auto& [coeff1, v] : M.get_row(row)) {
|
if (mpq_manager<false>::is_zero(m_jk))
|
||||||
if (mpq_manager<false>::is_zero(coeff1))
|
|
||||||
continue;
|
continue;
|
||||||
if (c[v] != 0)
|
D = rational(-1) / m_jk;
|
||||||
continue;
|
M.mul(row, D.to_mpq());
|
||||||
--nullity;
|
for (auto [row_i, row_i_entry] : M.get_rows(k)) {
|
||||||
++rank;
|
if (row_i.id() == row.id())
|
||||||
d.back() = v + 1;
|
continue;
|
||||||
c[v] = row.id() + 1;
|
auto& m_ik = row_i_entry->m_coeff;
|
||||||
D = rational(-1) / coeff1;
|
// row_i += m_ik * row
|
||||||
mgr.set(coeff1, mpq(-1));
|
M.add(row_i, m_ik, row);
|
||||||
// eliminate v from other rows.
|
}
|
||||||
for (auto [row2, row_entry2] : M.get_rows(v)) {
|
c[row.id()] = k + 1;
|
||||||
if (row.id() >= row2.id())
|
d[k] = row.id() + 1;
|
||||||
continue;
|
|
||||||
mpq & m_js = row_entry2->m_coeff;
|
|
||||||
mgr.set(m_js, (D * m_js).to_mpq());
|
|
||||||
}
|
|
||||||
for (auto& [m_ik, w] : M.get_row(row)) {
|
|
||||||
if (v == w)
|
|
||||||
continue;
|
|
||||||
D = m_ik;
|
|
||||||
mgr.set(m_ik, mpq(0));
|
|
||||||
for (auto [row2, row_entry2] : M.get_rows(w)) {
|
|
||||||
if (row.id() >= row2.id())
|
|
||||||
continue;
|
|
||||||
auto& m_js = M.get_coeff(row2, v);
|
|
||||||
auto & m_is = row_entry2->m_coeff;
|
|
||||||
mgr.set(m_is, (m_is + D * m_js).to_mpq());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mgr.del(coeff);
|
for (unsigned k = 0; k < n; ++k) {
|
||||||
|
|
||||||
std::cout << "nullity " << nullity << "\n";
|
|
||||||
std::cout << "rank " << rank << "\n";
|
|
||||||
unsigned_vector pivots(rank, 0u);
|
|
||||||
unsigned_vector nonpivots(nullity, 0u);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: extract kernel using d
|
|
||||||
for (unsigned k = 0; k < d.size(); ++k) {
|
|
||||||
if (d[k] != 0)
|
if (d[k] != 0)
|
||||||
continue;
|
continue;
|
||||||
K.push_back(vector<rational>());
|
K.push_back(vector<rational>());
|
||||||
for (unsigned i = 0; i < d.size(); ++i) {
|
for (unsigned i = 0; i < n; ++i) {
|
||||||
if (d[i] > 0) {
|
if (d[i] > 0) {
|
||||||
// row r = row(i);
|
auto r = sparse_matrix<mpq_ext>::row(d[i]-1);
|
||||||
// K.back().push_back(M[d[i]-1][k]);
|
K.back().push_back(rational(M.get_coeff(r, k)));
|
||||||
}
|
}
|
||||||
else if (i == k)
|
else if (i == k)
|
||||||
K.back().push_back(rational(1));
|
K.back().push_back(rational(1));
|
||||||
|
@ -102,6 +73,7 @@ namespace simplex {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,23 +31,23 @@ static vector<R> vec(int i, int j, int k) {
|
||||||
return nv;
|
return nv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static vector<R> vec(int i, int j, int k, int l) {
|
static vector<R> vec(int i, int j, int k, int l) {
|
||||||
// vector<R> nv = vec(i, j, k);
|
vector<R> nv = vec(i, j, k);
|
||||||
// nv.push_back(R(l));
|
nv.push_back(R(l));
|
||||||
// return nv;
|
return nv;
|
||||||
// }
|
}
|
||||||
|
|
||||||
/// static vector<R> vec(int i, int j, int k, int l, int x) {
|
static vector<R> vec(int i, int j, int k, int l, int x) {
|
||||||
/// vector<R> nv = vec(i, j, k, l);
|
vector<R> nv = vec(i, j, k, l);
|
||||||
/// nv.push_back(R(x));
|
nv.push_back(R(x));
|
||||||
/// return nv;
|
return nv;
|
||||||
/// }
|
}
|
||||||
|
|
||||||
// static vector<R> vec(int i, int j, int k, int l, int x, int y) {
|
static vector<R> vec(int i, int j, int k, int l, int x, int y) {
|
||||||
// vector<R> nv = vec(i, j, k, l, x);
|
vector<R> nv = vec(i, j, k, l, x);
|
||||||
// nv.push_back(R(y));
|
nv.push_back(R(y));
|
||||||
// return nv;
|
return nv;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// static vector<R> vec(int i, int j, int k, int l, int x, int y, int z) {
|
// static vector<R> vec(int i, int j, int k, int l, int x, int y, int z) {
|
||||||
// vector<R> nv = vec(i, j, k, l, x, y);
|
// vector<R> nv = vec(i, j, k, l, x, y);
|
||||||
|
@ -133,7 +133,7 @@ static void test4() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add(qmatrix& m, vector<R> const& v) {
|
static void add(qmatrix& m, vector<R> const& v) {
|
||||||
m.ensure_var(v.size());
|
m.ensure_var(v.size()-1);
|
||||||
auto r = m.mk_row();
|
auto r = m.mk_row();
|
||||||
for (unsigned u = 0; u < v.size(); ++u)
|
for (unsigned u = 0; u < v.size(); ++u)
|
||||||
m.add_var(r, v[u].to_mpq(), u);
|
m.add_var(r, v[u].to_mpq(), u);
|
||||||
|
@ -142,12 +142,16 @@ static void add(qmatrix& m, vector<R> const& v) {
|
||||||
static void test5() {
|
static void test5() {
|
||||||
unsynch_mpq_manager m;
|
unsynch_mpq_manager m;
|
||||||
qmatrix M(m);
|
qmatrix M(m);
|
||||||
add(M, vec(1, 2, 3));
|
add(M, vec(1, 0, -3, 0, 2, -8));
|
||||||
add(M, vec(2, 2, 4));
|
add(M, vec(0, 1, 5, 0, -1, 4));
|
||||||
|
add(M, vec(0, 0, 0, 1, 7, -9));
|
||||||
|
add(M, vec(0, 0, 0, 0, 0, 0));
|
||||||
M.display(std::cout);
|
M.display(std::cout);
|
||||||
vector<vector<rational>> K;
|
vector<vector<rational>> K;
|
||||||
kernel(M, K);
|
kernel(M, K);
|
||||||
std::cout << "after\n";
|
std::cout << "after\n";
|
||||||
|
for (auto const& v : K)
|
||||||
|
std::cout << v << "\n";
|
||||||
M.display(std::cout);
|
M.display(std::cout);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue