3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-09-04 17:17:41 +00:00
z3/src/muz/spacer/spacer_matrix.cpp
Bruce Mitchener 177414c0ee Use const refs to reduce copying.
These are things that have been found by `clang-tidy`.
2018-01-30 21:43:56 +07:00

159 lines
3.9 KiB
C++

/*++
Copyright (c) 2017 Arie Gurfinkel
Module Name:
spacer_matrix.cpp
Abstract:
a matrix
Author:
Bernhard Gleiss
Revision History:
--*/
#include "muz/spacer/spacer_matrix.h"
namespace spacer
{
spacer_matrix::spacer_matrix(unsigned m, unsigned n) : m_num_rows(m), m_num_cols(n)
{
for (unsigned i=0; i < m; ++i)
{
vector<rational> v;
for (unsigned j=0; j < n; ++j)
{
v.push_back(rational(0));
}
m_matrix.push_back(v);
}
}
unsigned spacer_matrix::num_rows()
{
return m_num_rows;
}
unsigned spacer_matrix::num_cols()
{
return m_num_cols;
}
const rational& spacer_matrix::get(unsigned int i, unsigned int j)
{
SASSERT(i < m_num_rows);
SASSERT(j < m_num_cols);
return m_matrix[i][j];
}
void spacer_matrix::set(unsigned int i, unsigned int j, const rational& v)
{
SASSERT(i < m_num_rows);
SASSERT(j < m_num_cols);
m_matrix[i][j] = v;
}
unsigned spacer_matrix::perform_gaussian_elimination()
{
unsigned i=0;
unsigned j=0;
while(i < m_matrix.size() && j < m_matrix[0].size())
{
// find maximal element in column with row index bigger or equal i
rational max = m_matrix[i][j];
unsigned max_index = i;
for (unsigned k=i+1; k < m_matrix.size(); ++k)
{
if (max < m_matrix[k][j])
{
max = m_matrix[k][j];
max_index = k;
}
}
if (max.is_zero()) // skip this column
{
++j;
}
else
{
// reorder rows if necessary
vector<rational> tmp = m_matrix[i];
m_matrix[i] = m_matrix[max_index];
m_matrix[max_index] = m_matrix[i];
// normalize row
rational pivot = m_matrix[i][j];
if (!pivot.is_one())
{
for (unsigned k=0; k < m_matrix[i].size(); ++k)
{
m_matrix[i][k] = m_matrix[i][k] / pivot;
}
}
// subtract row from all other rows
for (unsigned k=1; k < m_matrix.size(); ++k)
{
if (k != i)
{
rational factor = m_matrix[k][j];
for (unsigned l=0; l < m_matrix[k].size(); ++l)
{
m_matrix[k][l] = m_matrix[k][l] - (factor * m_matrix[i][l]);
}
}
}
++i;
++j;
}
}
if (get_verbosity_level() >= 1)
{
SASSERT(m_matrix.size() > 0);
}
return i; //i points to the row after the last row which is non-zero
}
void spacer_matrix::print_matrix()
{
verbose_stream() << "\nMatrix\n";
for (const auto& row : m_matrix)
{
for (const auto& element : row)
{
verbose_stream() << element << ", ";
}
verbose_stream() << "\n";
}
verbose_stream() << "\n";
}
void spacer_matrix::normalize()
{
rational den = rational::one();
for (unsigned i=0; i < m_num_rows; ++i)
{
for (unsigned j=0; j < m_num_cols; ++j)
{
den = lcm(den, denominator(m_matrix[i][j]));
}
}
for (unsigned i=0; i < m_num_rows; ++i)
{
for (unsigned j=0; j < m_num_cols; ++j)
{
m_matrix[i][j] = den * m_matrix[i][j];
SASSERT(m_matrix[i][j].is_int());
}
}
}
}