3#ifndef _mat_elementary_ops_hpp_
4#define _mat_elementary_ops_hpp_
72 if (!mat.
ring().is_zero(mat.
entry(row, col)))
return row;
74 return static_cast<size_t>(-1);
87 if (!mat.
ring().is_zero(mat.
entry(row, col)))
93 return static_cast<size_t>(-1);
120 for (
size_t r = 0; r < mat.
numRows(); ++r)
138 for (
size_t r = 0; r < mat.
numRows(); ++r)
156 for (
size_t r = 0; r < mat.
numRows(); ++r)
168 mat.
ring().set_zero(f);
185 mat.
ring().set_zero(f);
187 for (
size_t r = 0; r < mat.
numRows(); ++r)
210 const RT& ring { mat.
ring() };
211 Element f1(ring), f2(ring), g1(ring), g2(ring);
219 ring.mult(f1, a1, mat.
entry(r1,c));
220 ring.mult(f2, a2, mat.
entry(r2,c));
221 ring.add(f1, f1, f2);
223 ring.mult(g1, b1, mat.
entry(r1,c));
224 ring.mult(g2, b2, mat.
entry(r2,c));
225 ring.add(g1, g1, g2);
227 ring.set(mat.
entry(r1,c), f1);
228 ring.set(mat.
entry(r2,c), g1);
247 const RT& ring { mat.
ring() };
248 Element f1(ring), f2(ring), g1(ring), g2(ring);
254 for (
size_t r = 0; r < mat.
numRows(); ++r)
256 ring.mult(f1, a1, mat.
entry(r, c1));
257 ring.mult(f2, a2, mat.
entry(r, c2));
258 ring.add(f1, f1, f2);
260 ring.mult(g1, b1, mat.
entry(r, c1));
261 ring.mult(g2, b2, mat.
entry(r, c2));
262 ring.add(g1, g1, g2);
264 ring.set(mat.
entry(r, c1), f1);
265 ring.set(mat.
entry(r, c2), g1);
279 mat.
ring().set_zero(f);
282 for (
size_t r = 0; r < mat.
numRows(); ++r)
292 size_t nrows_to_permute = perm->len;
293 std::unique_ptr<bool[]> done(
new bool[nrows_to_permute]);
294 for (
size_t i = 0; i < nrows_to_permute; i++) done[i] =
true;
296 for (
size_t i = 0; i < nrows_to_permute; i++)
298 size_t j = perm->array[i];
301 ERROR(
"expected permutation");
309 while (next < nrows_to_permute)
311 if (done[next] || perm->array[next] == next)
321 while (perm->array[r] != next)
326 mat.
entry(start_row + r, i));
341 size_t ncols_to_permute = perm->len;
342 std::unique_ptr<bool[]> done(
new bool[ncols_to_permute]);
343 for (
size_t i = 0; i < ncols_to_permute; i++) done[i] =
true;
345 for (
size_t i = 0; i < ncols_to_permute; i++)
347 size_t j = perm->array[i];
350 ERROR(
"expected permutation");
355 typename RT::ElementArray tmp(mat.
ring(), mat.
numRows());
358 while (next < ncols_to_permute)
360 if (done[next] || perm->array[next] == next)
370 while (perm->array[c] != next)
373 for (
int i = 0; i < mat.
numRows(); ++i)
375 mat.
entry(i, start_col + c));
390 size_t new_ncols = mat.
numColumns() + n_to_add;
393 for (
size_t r = 0; r < mat.
numRows(); r++)
395 for (
size_t c = 0; c < i; c++)
398 mat.
ring().swap(mat.
entry(r, c), newMatrix.
entry(r, c + n_to_add));
406 size_t new_nrows = mat.
numRows() + n_to_add;
411 for (
size_t r = 0; r < i; r++)
413 for (
size_t r = i; r < mat.
numRows(); r++)
414 mat.
ring().swap(mat.
entry(r, c), newMatrix.
entry(r + n_to_add, c));
425 size_t n_to_delete = j - i + 1;
426 size_t new_ncols = mat.
numColumns() - n_to_delete;
429 for (
size_t r = 0; r < mat.
numRows(); r++)
431 for (
size_t c = 0; c < i; c++)
433 for (
size_t c = j + 1; c < mat.
numColumns(); c++)
434 mat.
ring().swap(mat.
entry(r, c), newMatrix.
entry(r, c - n_to_delete));
445 size_t n_to_delete = j - i + 1;
446 size_t new_nrows = mat.
numRows() - n_to_delete;
451 for (
size_t r = 0; r < i; r++)
453 for (
size_t r = j + 1; r < mat.
numRows(); r++)
454 mat.
ring().swap(mat.
entry(r, c), newMatrix.
entry(r - n_to_delete, c));
482 M.
ring().set_from_long(one, 1);
486 long pivotrow =
lead_row(M, nc, pivot);
487 if (pivot_type == -1)
489 else if (pivot_type == 0)
491 for (
int i = 0; i < nc; i++)
494 if (pivotrow < 0)
continue;
498 M.
ring().negate(f, coef);
515 M.
ring().set_from_long(one, 1);
521 for (
size_t i = 0; i <= nc; i++)
523 for (
size_t j = 0; j < M.
numRows(); ++j)
526 if (M.
ring().is_zero(
p))
continue;
528 if (M.
ring().is_equal(one,
p))
539 if (nr ==
static_cast<size_t>(-1) or
540 nc ==
static_cast<size_t>(-1))
550 for (
size_t i = 0; i <= nc; i++)
552 for (
size_t j = 0; j < M.
numRows(); ++j)
555 if (M.
ring().is_zero(
p))
continue;
556 if (!M.
ring().is_unit(
p))
continue;
558 if (M.
ring().is_equal(one,
p))
568 if (nr ==
static_cast<size_t>(-1) or nc ==
static_cast<size_t>(-1))
589 for (
size_t r = r0; r <= r1; r++)
590 for (
size_t c = c0; c <= c1; c++)
601 result.resize(rows->len, cols->len);
602 for (
size_t r = 0; r < rows->len; r++)
603 for (
size_t c = 0; c < cols->len; c++)
605 mat.
entry(rows->array[r], cols->array[c]));
613 for (
size_t r = 0; r < mat.
numRows(); r++)
614 for (
size_t c = 0; c < cols->len; c++)
632 static void perform_reduction(Mat& M,
634 size_t nr,
size_t nc,
644 const Ring *R = M->get_ring();
645 M->interchange_columns(c,nc);
646 M->interchange_rows(r,nr);
648 long pivotrow = M->lead_row(nc, pivot);
649 if (pivot_type == -1)
650 M->scale_column(nc,pivot);
651 else if (pivot_type == 0)
652 M->divide_column(nc, pivot);
653 for (
int i=0; i<nc; i++)
656 pivotrow = M->lead_row(i,coef);
657 if (pivotrow < 0)
continue;
663 M->column_op(i, f, nc);
666 M->scale_column(nc, R->
zero());
667 M->set_entry(nr,nc,R->
one());
670 static void reduceByPivots(Mat& M)
672 if (M.numRows() == 0 or M.numColumns() == 0)
return;
673 size_t nr = M.numRows()-1;
674 size_t nc = M.numColumns()-1;
676 const Ring *K = M->get_ring();
677 ring_elem one = K->
one();
683 MutableMatrix::iterator *
p = M->begin();
684 for (
int i=0; i<=nc; i++)
687 for (;
p->valid();
p->next())
691 p->copy_ring_elem(coef);
698 perform_reduction(M,
static_cast<int>(
p->row()), i, nr, nc, pivot_type);
699 if (nr == 0 or nc == 0)
return;
710 for (
int i=0; i<=nc; i++)
713 for (;
p->valid();
p->next())
716 p->copy_ring_elem(coef);
717 if (!K->
is_unit(coef))
continue;
724 perform_reduction(M,
static_cast<int>(
p->row()), i, nr, nc, pivot_type);
725 if (nr == 0 or nc == 0)
return;
737template <
typename RT>
809 mat.
row2by2(r1, r2, a1, a2, b1, b2);
850 "reduce_py_pivots not yet implemented for sparse mutable matrices");
860 result.setFromSubmatrix(mat, rows, cols);
866 result.setFromSubmatrix(mat, cols);
ElementType & entry(size_t row, size_t column)
const ACoeffRing & ring() const
void swap(DMat< ACoeffRing > &M)
RT::ElementType ElementType
size_t numColumns() const
static void setEntry(Mat &mat, size_t r, size_t c, const ElementType &a)
static void scale_row(Mat &mat, size_t i, const ElementType &a)
static void insert_columns(Mat &mat, size_t i, size_t n_to_add)
static void setFromSubmatrix(const Mat &mat, M2_arrayint rows, M2_arrayint cols, Mat &result)
static void divide_row(Mat &mat, size_t i, const ElementType &a)
static void scale_column(Mat &mat, size_t i, const ElementType &a)
static void setFromSubmatrix(const Mat &mat, M2_arrayint cols, Mat &result)
static void column_op(Mat &mat, size_t i, const ElementType &a, size_t j)
static void interchange_columns(Mat &mat, size_t i, size_t j)
static void dot_product(const Mat &mat, size_t i, size_t j, ElementType &result)
static void insert_rows(Mat &mat, size_t i, size_t n_to_add)
Mat::ElementType ElementType
static size_t lead_row(const Mat &mat, size_t col)
static void delete_columns(Mat &mat, size_t i, size_t j)
static void perform_reduction(Mat &M, size_t r, size_t c, size_t nr, size_t nc, int pivot_type)
static void delete_rows(Mat &mat, size_t i, size_t j)
static size_t lead_row(const Mat &mat, size_t col, ElementType &result)
static void interchange_rows(Mat &mat, size_t i, size_t j)
static bool column_permute(Mat &mat, size_t start_col, M2_arrayint perm)
static void column2by2(Mat &mat, size_t c1, size_t c2, const ElementType &a1, const ElementType &a2, const ElementType &b1, const ElementType &b2)
static void setFromSubmatrix(const Mat &mat, size_t r0, size_t r1, size_t c0, size_t c1, Mat &result)
static void row2by2(Mat &mat, size_t r1, size_t r2, const ElementType &a1, const ElementType &a2, const ElementType &b1, const ElementType &b2)
static void reduce_by_pivots(Mat &M)
static void getEntry(const Mat &mat, size_t r, size_t c, ElementType &result)
static void row_op(Mat &mat, size_t i, const ElementType &a, size_t j)
static void divide_column(Mat &mat, size_t i, const ElementType &a)
static bool row_permute(Mat &mat, size_t start_row, M2_arrayint perm)
static void column_op(Mat &mat, size_t i, const ElementType &r, size_t j)
static void insert_columns(Mat &mat, size_t i, size_t n_to_add)
static void scale_row(Mat &mat, size_t i, const ElementType &r)
static void interchange_columns(Mat &mat, size_t i, size_t j)
static void divide_row(Mat &mat, size_t i, const ElementType &r)
Mat::ElementType ElementType
static void column2by2(Mat &mat, size_t c1, size_t c2, const ElementType &a1, const ElementType &a2, const ElementType &b1, const ElementType &b2)
static void setEntry(Mat &mat, size_t r, size_t c, const ElementType &a)
static void getEntry(const Mat &mat, size_t r, size_t c, ElementType &result)
static bool row_permute(Mat &mat, size_t start_row, M2_arrayint perm)
static size_t lead_row(const Mat &mat, size_t col, ElementType &result)
static void setFromSubmatrix(const Mat &mat, M2_arrayint rows, M2_arrayint cols, Mat &result)
static void dot_product(const Mat &mat, size_t i, size_t j, ElementType &result)
static void delete_rows(Mat &mat, size_t i, size_t j)
static void delete_columns(Mat &mat, size_t i, size_t j)
static void setFromSubmatrix(const Mat &mat, M2_arrayint cols, Mat &result)
static bool column_permute(Mat &mat, size_t start_col, M2_arrayint perm)
static void row2by2(Mat &mat, size_t r1, size_t r2, const ElementType &a1, const ElementType &a2, const ElementType &b1, const ElementType &b2)
static size_t lead_row(const Mat &mat, size_t col)
static void insert_rows(Mat &mat, size_t i, size_t n_to_add)
static void row_op(Mat &mat, size_t i, const ElementType &r, size_t j)
static void scale_column(Mat &mat, size_t i, const ElementType &r)
static void divide_column(Mat &mat, size_t i, const ElementType &r)
static void interchange_rows(Mat &mat, size_t i, size_t j)
static void reduce_by_pivots(Mat &M)
virtual bool is_unit(const ring_elem f) const =0
virtual bool is_equal(const ring_elem f, const ring_elem g) const =0
ring_elem minus_one() const
virtual ring_elem negate(const ring_elem f) const =0
void set_entry(size_t r, size_t c, const elem a)
void interchange_rows(size_t i, size_t j)
void insert_columns(size_t i, size_t n_to_add)
void delete_columns(size_t i, size_t j)
bool row_permute(size_t start_row, M2_arrayint perm)
void divide_row(size_t i, elem r)
void interchange_columns(size_t i, size_t j)
size_t lead_row(size_t col) const
void column2by2(size_t c1, size_t c2, elem a1, elem a2, elem b1, elem b2)
void delete_rows(size_t i, size_t j)
void scale_column(size_t i, elem r)
void row_op(size_t i, elem r, size_t j)
void row2by2(size_t r1, size_t r2, elem a1, elem a2, elem b1, elem b2)
void scale_row(size_t i, elem r)
bool get_entry(size_t r, size_t c, elem &result) const
void column_op(size_t i, elem r, size_t j)
void divide_column(size_t i, elem r)
bool column_permute(size_t start_col, M2_arrayint perm)
CoeffRing::elem ElementType
void insert_rows(size_t i, size_t n_to_add)
void dot_product(size_t i, size_t j, elem &result) const
VALGRIND_MAKE_MEM_DEFINED & result(result)
void swap(mpfr::mpreal &x, mpfr::mpreal &y)