47template <
class RingType>
56template <
class RingType>
114 std::cout << o.
str() << std::endl;
121 for (
size_t i = 0; i < len; i++)
123 ring().elem_text_out(o,
x[i],
true,
false);
127 std::cout << o.
str();
131template <
class RingType>
137template <
class RingType>
143 auto A = mLU.rowMajorArray();
144 A += row * mLU.numColumns() + col;
145 for (
size_t i=row; i<mLU.numRows(); i++)
147 if (mLU.ring().is_zero(*A))
148 A += mLU.numColumns();
152 return static_cast<size_t>(-1);
156template <
class RingType>
164 mLU.
ring().init(tmp);
166 size_t nrows = mLU.numRows();
167 size_t ncols = mLU.numColumns();
169 auto array = mLU.rowMajorArray();
177 for (
size_t row = 0; row < nrows; row++)
182 size_t k = findPivot(row,col);
185 const ElementType& pivot = *A;
190 for (
size_t c = col+1; c < ncols; c++)
192 for (
size_t i = 0; i<row; i++)
194 mLU.ring().mult(tmp, *B1++, *C1);
195 mLU.ring().subtract(*A, *A, tmp);
203 for (
size_t r = row+1; r < nrows; r++)
205 for (
size_t i = 0; i<row; i++)
207 mLU.ring().mult(tmp, *B1++, *C1);
208 mLU.ring().subtract(*A, *A, tmp);
211 mLU.ring().divide(*A, *A, pivot);
222 mLU.ring().clear(tmp);
226template <
class RingType>
232 size_t min = std::min(
LU.numRows(),
LU.numColumns());
233 lower.resize(
LU.numRows(), min);
234 upper.resize(min,
LU.numColumns());
240 auto LUraw =
LU.rowMajorArray();
241 auto L = lower.rowMajorArray();
242 auto U = upper.rowMajorArray();
244 for (
size_t c=0; c<upper.numColumns(); c++)
247 for (
size_t r=0; r<=c; r++)
249 if (r >= upper.numRows())
break;
250 upper.ring().set(*U1, *LUraw++);
251 U1 += upper.numColumns();
255 if (c < lower.numColumns())
257 lower.ring().set_from_long(*L, 1);
258 L += lower.numColumns();
260 for (
size_t r=c+1; r<lower.numRows(); r++)
262 lower.ring().set(*L1, *LUraw++);
263 L1 += lower.numColumns();
270template <
class RingType>
273 size_t min = std::min(LU.numRows(), LU.numColumns());
274 lower.
resize(LU.numRows(), min);
275 upper.
resize(min, LU.numColumns());
281 for (
size_t c = 0; c < LU.numColumns(); c++)
283 if (c < min)
ring().set_from_long(lower.
entry(c, c), 1);
284 for (
size_t r = 0; r < LU.numRows(); r++)
287 ring().set(upper.
entry(r, c), LU.entry(r, c));
290 ring().set(lower.
entry(r, c), LU.entry(r, c));
296template <
class RingType>
307template <
class RingType>
313 assert(LU.numRows() == LU.numColumns());
319 for (
size_t i = 0; i < LU.numRows(); i++)
323template <
class RingType>
331template <
class RingType>
339template <
class RingType>
362 const std::vector<size_t>& pivotColumns =
mLUObject.pivotColumns();
363 const std::vector<size_t>& perm =
mLUObject.permutation();
364 size_t rk = pivotColumns.size();
366 typename RingType::Element tmp(
ring()), tmp2(
ring());
375 for (
size_t col = 0; col < B.
numColumns(); col++)
379 for (
size_t i = 0; i < LU.numColumns(); i++)
ring().set_zero(
x[i]);
382 for (
size_t r = 0; r < B.
numRows(); r++)
389 for (
size_t i = 0; i < rk; i++)
391 ring().set(y[i], b[i]);
392 for (
size_t j = 0; j < i; j++)
394 ring().mult(tmp, LU.entry(i, j), y[j]);
395 ring().subtract(y[i], y[i], tmp);
403 for (
size_t i = rk; i < LU.numRows(); i++)
405 ring().set(tmp, b[i]);
406 for (
size_t j = 0; j < rk; j++)
408 ring().mult(tmp2, LU.entry(i, j), y[j]);
409 ring().subtract(tmp, tmp, tmp2);
411 if (!
ring().is_zero(tmp))
422 for (
long i = rk - 1; i >= 0; --i)
424 ring().set(
x[i], y[i]);
425 for (
size_t j = i + 1; j <= rk - 1; j++)
427 ring().mult(tmp, LU.entry(i, pivotColumns[j]),
x[j]);
428 ring().subtract(
x[i],
x[i], tmp);
430 ring().divide(
x[i],
x[i], LU.entry(i, pivotColumns[i]));
431 ring().set(X.
entry(pivotColumns[i], col),
x[i]);
451template <
class RingType>
455 assert(mLUObject.numRows() == mLUObject.numColumns());
456 assert(mLUObject.numRows() == B.numRows());
458 if (rank() < mLUObject.numRows())
return false;
466 const std::vector<size_t> permutation,
470 result.resize(B.numRows(),
472 for (
long r = 0; r < B.numRows(); r++)
473 for (
long c = 0; c < B.numColumns(); c++)
474 B.ring().set(
result.entry(r, c), B.entry(permutation[r], c));
491 LU.ring().flintContext());
503 LU.ring().flintContext());
520 LU.ring().flintContext());
531 LU.ring().flintContext());
534template <
class RingType>
551 Mat B1(
ring(), LU.numRows(), LU.numRows());
552 printf(
"in dmat-lu solveInvertible step 3\n");
554 printf(
"in dmat-lu solveInvertible step 4\n");
556 printf(
"in dmat-lu solveInvertible step 5\n");
558 printf(
"in dmat-lu solveInvertible step 6\n");
563template <
class RingType>
571 Mat id(
ring(), LU.numRows(), LU.numRows());
572 for (
size_t i = 0; i < LU.numRows(); i++)
573 ring().set_from_long(
id.entry(i, i), 1);
579template <
class RingType>
583 const std::vector<size_t>& pivotColumns =
mLUObject.pivotColumns();
585 typename RingType::Element tmp(
ring()), tmp2(
ring());
588 X.
resize(LU.numColumns(), LU.numColumns() - pivotColumns.size());
591 size_t nextpivotidx = 0;
592 size_t nextpivotcol =
593 (pivotColumns.size() > 0 ? pivotColumns[0] : LU.numColumns());
597 if (col == nextpivotcol)
602 (nextpivotidx < pivotColumns.size() ? pivotColumns[nextpivotidx]
607 ring().set_from_long(X.
entry(col, colX), -1);
610 for (
long p = nextpivotidx - 1;
p >= 0;
p--)
613 ring().set(tmp, LU.entry(
p, col));
614 for (
size_t i = nextpivotidx - 1; i >=
p + 1; i--)
617 LU.entry(
p, pivotColumns[i]),
618 X.
entry(pivotColumns[i], colX));
619 ring().subtract(tmp, tmp, tmp2);
621 ring().divide(tmp, tmp, LU.entry(
p, pivotColumns[
p]));
622 ring().set(X.
entry(pivotColumns[
p], colX), tmp);
const fq_zech_mat_t & fq_zech_mat() const
const fq_nmod_mat_t & fq_nmod_mat() const
ElementType & entry(size_t row, size_t column)
void resize(size_t new_nrows, size_t new_ncols)
size_t numColumns() const
DMatLUinPlace< RingType > mLUObject
DMatLinAlg(const Mat &A)
Copies A into mLU and initializes all fields.
size_t rank()
Output: returns the approximate rank of A (-1 if fails).
const RingType & ring() const
RingType::ElementType ElementType
void determinant(ElementType &result)
Output: result, the determinant of A.
bool solveInvertible(const Mat &B, Mat &X)
bool matrixPLU(std::vector< size_t > &P, Mat &L, Mat &U)
void debug_out_list(ElementType *x, size_t len)
void setUpperLower(const Mat &LU, Mat &lower, Mat &upper)
bool solve(const Mat &B, Mat &X)
void columnRankProfile(std::vector< size_t > &profile)
Type-erased owning handle to a dense coefficient vector held by a ConcreteVectorArithmetic<Ring>.
DMatLUinPlace<RT> — the LU worker that DMatLinAlg<RT> delegates to, with RR / CC / GF specialisations...
DMatLinAlg<M2::ARingQQ> — rational dense LU routed through FLINT fmpq_mat / fmpz_mat.
DMatLinAlg<ARingZZpFFPACK> and the ffpackInterface namespace — FFLAS-FFPACK-backed Z/p linear algebra...
DMatLinAlg<M2::ARingZZpFlint> — dense Z/p linear algebra routed through FLINT nmod_mat_*.
void solveLowerTriangular(const Mat &LU, const Mat &B, Mat &X)
void solveUpperTriangular< DMatGFFlintBig >(const DMatGFFlintBig &LU, const DMatGFFlintBig &B, DMatGFFlintBig &X)
void solveUpperTriangular(const Mat &LU, const Mat &B, Mat &X)
void solveUpperTriangular< DMatGFFlint >(const DMatGFFlint &LU, const DMatGFFlint &B, DMatGFFlint &X)
void solveLowerTriangular< DMatGFFlintBig >(const DMatGFFlintBig &LU, const DMatGFFlintBig &B, DMatGFFlintBig &X)
DMat< M2::ARingGFFlintBig > DMatGFFlintBig
void solveLowerTriangular< DMatGFFlint >(const DMatGFFlint &LU, const DMatGFFlint &B, DMatGFFlint &X)
void permuteRows(const Mat &B, const std::vector< size_t > permutation, Mat &result)
DMat<ACoeffRing> — dense-matrix template plus the umbrella that wires in every per-ring specialisatio...
VALGRIND_MAKE_MEM_DEFINED & result(result)
MatElementaryOps<MT> — row / column primitives templated over dense or sparse matrix storage.
DMat< M2::ARingGFFlint > DMatGFFlint
void displayMat(buffer &o, const Mat &A)
Generic helpers (displayMat, concatenateMatrices) for DMat / SMat matrices.
bool isZero(const DMat< RT > &A)
M2_arrayintOrNull LU(const Mat &A, Mat &L, Mat &U)
const mpreal min(const mpreal &x, const mpreal &y)