3#ifndef _dmat_lu_inplace_hpp_
4#define _dmat_lu_inplace_hpp_
46#include <M2/gc-include.h>
48#pragma GCC diagnostic push
49#pragma GCC diagnostic ignored "-Wconversion"
50#include <flint/fq_nmod_mat.h>
51#include <flint/perm.h>
52#pragma GCC diagnostic pop
68 std::vector<size_t>& result_columns);
77 std::cout << o.
str() << std::endl;
112 size_t findPivot(
size_t row,
size_t col);
129 fq_nmod_mat_lu(perm,
mLU.fq_nmod_mat(),
false,
ring().flintContext());
132 for (
long i = 0; i <
mLU.numRows(); i++)
mPerm.push_back(perm[i]);
133 mSign = (_perm_parity(perm,
mLU.numRows()) == 0);
148 fq_zech_mat_lu(perm,
mLU.fq_zech_mat(),
false,
ring().flintContext());
151 for (
long i = 0; i <
mLU.numRows(); i++)
mPerm.push_back(perm[i]);
152 mSign = (_perm_parity(perm,
mLU.numRows()) == 0);
161template <
class RingType>
167 for (
size_t i = 0; i < A.
numRows(); i++)
mPerm.push_back(i);
170template <
class RingType>
176 for (
size_t i = row; i <
mLU.numRows(); i++)
178 if (!
ring().is_zero(
mLU.entry(i, col)))
return i;
180 return static_cast<size_t>(-1);
189 M2::ARingRRR::Element largest(
ring()),
abs(
ring());
190 size_t best_row_so_far =
static_cast<size_t>(-1);
192 ring().set_zero(largest);
193 for (
size_t i = row; i <
mLU.numRows(); i++)
196 if (
ring().compare_elems(
abs, largest) > 0)
202 return best_row_so_far;
212 M2::ARingRRR::Element largest(RR),
abs(RR);
213 size_t best_row_so_far =
static_cast<size_t>(-1);
217 for (
size_t i = row; i <
mLU.numRows(); i++)
226 return best_row_so_far;
229template <
class RingType>
235 typename RingType::Element tmp(
mLU.ring());
239 size_t nrows =
mLU.numRows();
240 size_t ncols =
mLU.numColumns();
242 while (col < ncols && row < nrows)
248 for (
size_t r = row; r < nrows; r++)
250 for (
size_t i = 0; i < row; i++)
252 mLU.ring().mult(tmp,
mLU.entry(r, i),
mLU.entry(i, col));
253 mLU.ring().subtract(
mLU.entry(r, col),
mLU.entry(r, col), tmp);
264 if (k ==
static_cast<size_t>(-1))
283 for (
size_t c = col + 1; c < ncols; c++)
285 for (
size_t i = 0; i < row; i++)
287 mLU.ring().mult(tmp,
mLU.entry(row, i),
mLU.entry(i, c));
288 mLU.ring().subtract(
mLU.entry(row, c),
mLU.entry(row, c), tmp);
302 for (
size_t r = row + 1; r < nrows; r++)
304 mLU.ring().divide(
mLU.entry(r, row),
mLU.entry(r, col), pivot);
305 if (row < col)
ring().set_zero(
mLU.entry(r, col));
324 int rows =
static_cast<int>(
mLU.numRows());
325 int cols =
static_cast<int>(
mLU.numColumns());
327 int min = (rows <= cols) ? rows : cols;
332 int* perm =
new int[min];
335 dgetrf_(&rows, &cols, copyA.data(), &rows, perm, &info);
348 for (
int i = 0; i < min; i++)
350 int thisloc = perm[i] - 1;
354 size_t tmp =
mPerm[thisloc];
372 int rows =
static_cast<int>(
mLU.numRows());
373 int cols =
static_cast<int>(
mLU.numColumns());
375 int min = (rows <= cols) ? rows : cols;
380 int* perm =
new int[min];
383 zgetrf_(&rows, &cols, copyA.data(), &rows, perm, &info);
395 for (
int i = 0; i < min; i++)
397 int thisloc = perm[i] - 1;
401 size_t tmp =
mPerm[thisloc];
413template <
class RingType>
416 size_t min = std::min(LU.numRows(), LU.numColumns());
417 lower.
resize(LU.numRows(), min);
418 upper.
resize(min, LU.numColumns());
424 for (
size_t c = 0; c < LU.numColumns(); c++)
426 if (c < min) LU.ring().set_from_long(lower.
entry(c, c), 1);
427 for (
size_t r = 0; r < LU.numRows(); r++)
430 LU.ring().set(upper.
entry(r, c), LU.entry(r, c));
433 LU.ring().set(lower.
entry(r, c), LU.entry(r, c));
439template <
class RingType>
441 std::vector<size_t>& result_columns)
443 result_columns.clear();
446 while (thisrow < LU.numRows() and thiscol < LU.numColumns())
448 if (not LU.ring().is_zero(LU.entry(thisrow, thiscol)))
450 result_columns.push_back(thiscol);
ElementType & entry(size_t row, size_t column)
void resize(size_t new_nrows, size_t new_ncols)
const RingType & ring() const
DMatLUinPlace(const Mat &A)
RingType::ElementType ElementType
std::vector< size_t > mPivotColumns
std::vector< size_t > mPerm
const std::vector< size_t > & permutation()
size_t findPivot(size_t row, size_t col)
const std::vector< size_t > & pivotColumns()
static void setUpperLower(const Mat &LU, Mat &lower, Mat &upper)
void debug_out(const Mat &M)
static void computePivotColumns(const Mat &LU, std::vector< size_t > &result_columns)
void set(ElementType &result, const ElementType &a) const
int compare_elems(const ElementType &f, const ElementType &g) const
void set_zero(ElementType &result) const
aring-style adapter for arbitrary-precision real numbers, backed by MPFR.
std::vector< double > make_lapack_array(const DMatRR &mat)
void fill_from_lapack_array(const std::vector< double > &doubles, DMatRR &mat)
DMat<ACoeffRing> — dense-matrix template plus the umbrella that wires in every per-ring specialisatio...
int zgetrf_(int *rows, int *cols, double *M, int *ld, int *ipiv, int *info)
DMat< M2::ARingCC > DMatCC
void dgetrf_(const int *rows, const int *cols, double *A, const int *ld, int *ipiv, int *info)
DMat< M2::ARingRR > DMatRR
MatElementaryOps<MT> — row / column primitives templated over dense or sparse matrix storage.
void displayMat(buffer &o, const Mat &A)
Generic helpers (displayMat, concatenateMatrices) for DMat / SMat matrices.
bool isZero(const DMat< RT > &A)
void swap(mpfr::mpreal &x, mpfr::mpreal &y)
#define newarray_atomic(T, len)