Macaulay2 Engine
Loading...
Searching...
No Matches
dmat-lu-zzp-flint.hpp
Go to the documentation of this file.
1
32
33// The following needs to be included before any flint files are included.
34#include <M2/gc-include.h>
35
36#pragma GCC diagnostic push
37#pragma GCC diagnostic ignored "-Wconversion"
38#include <flint/nmod_mat.h> // for nmod_mat_lu, nmod_mat_rank, nmod_mat_det
39#pragma GCC diagnostic pop
40
42// ZZpFlint //////////
44
59template <>
60class DMatLinAlg<M2::ARingZZpFlint>
61{
62 public:
66
67 public:
68 DMatLinAlg(const Mat& A) : mMatrix(A) {}
69 size_t rank() { return nmod_mat_rank(mMatrix.nmod_mat()); }
70 void determinant(ElementType& result_det)
71 {
72 result_det = nmod_mat_det(mMatrix.nmod_mat());
73 }
74
75 void columnRankProfile(std::vector<size_t>& profile)
76 {
77 Mat LU(mMatrix); // copy
78 mp_limb_signed_t* perm = newarray_atomic(mp_limb_signed_t, LU.numRows());
79 nmod_mat_lu(perm, LU.nmod_mat(), false);
80 freemem(perm);
82 }
83
84 void matrixPLU(std::vector<size_t>& P, Mat& L, Mat& U)
85 {
86 // std::cout << "calling matrixPLU zzp-flint\n";
87 Mat LU(mMatrix); // copy
88 mp_limb_signed_t* perm = newarray_atomic(mp_limb_signed_t, LU.numRows());
89 nmod_mat_lu(perm, LU.nmod_mat(), false);
90 P.resize(0);
91 for (long i = 0; i < LU.numRows(); i++) P.push_back(perm[i]);
92 freemem(perm);
94 }
95
96 bool solveInvertible(const Mat& B, Mat& X)
97 {
98 // printf("called mat-linalg zzp flint solveInvertible\n");
99 assert(mMatrix.numRows() == mMatrix.numColumns());
100 assert(mMatrix.numRows() == B.numRows());
101 X.resize(mMatrix.numColumns(), B.numColumns());
102 int isinvertible =
103 nmod_mat_solve(X.nmod_mat(), mMatrix.nmod_mat(), B.nmod_mat());
104 return (isinvertible != 0);
105 }
106
107 bool solve(const Mat& B, Mat& X)
108 {
109 // printf("in dmat lu zzp flint solve\n");
110 long nrows = mMatrix.numRows();
111 long ncols = mMatrix.numColumns();
112 std::vector<size_t> profile;
113 Mat AB(mMatrix.ring(), nrows, ncols + B.numColumns());
115 nmod_mat_rref(AB.nmod_mat());
117 if (profile.size() >= 1 and profile[profile.size() - 1] >= ncols)
118 return false; // system is inconsistent
119 // At this point, we know the solutions. Should we go through FlintQQMat,
120 // or go directly to Mat?
121 X.resize(ncols, B.numColumns());
122 for (long c = 0; c < B.numColumns(); c++)
123 {
124 // Fill in this column
125 for (long r = 0; r < profile.size(); r++)
126 {
127 mMatrix.ring().set(X.entry(profile[r], c), AB.entry(r, ncols + c));
128 }
129 }
130 return true;
131 }
132
133 bool inverse(Mat& result_inv)
134 {
135 assert(mMatrix.numRows() == mMatrix.numColumns());
136 Mat& A = const_cast<Mat&>(mMatrix);
137 result_inv.resize(mMatrix.numRows(), mMatrix.numColumns());
138 return nmod_mat_inv(result_inv.nmod_mat(), A.nmod_mat());
139 }
140
141 size_t kernel(Mat& result_nullspace)
142 {
143 long rank = nmod_mat_rank(mMatrix.nmod_mat());
144 result_nullspace.resize(
145 mMatrix.numColumns(),
146 mMatrix.numColumns() - rank); // the largest the answer could be
147 long nullity =
148 nmod_mat_nullspace(result_nullspace.nmod_mat(), mMatrix.nmod_mat());
149 assert(rank == mMatrix.numColumns() - nullity);
150 return nullity;
151 }
152
153 private:
154 const Mat& mMatrix; // reference to the original matrix
155};
156
157// Local Variables:
158// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
159// indent-tabs-mode: nil
160// End:
size_t numRows() const
Definition dmat.hpp:144
ElementType & entry(size_t row, size_t column)
Definition dmat.hpp:148
void resize(size_t new_nrows, size_t new_ncols)
Definition dmat.hpp:157
size_t numColumns() const
Definition dmat.hpp:145
Definition dmat.hpp:62
void matrixPLU(std::vector< size_t > &P, Mat &L, Mat &U)
void columnRankProfile(std::vector< size_t > &profile)
size_t kernel(Mat &result_nullspace)
bool solve(const Mat &B, Mat &X)
void determinant(ElementType &result_det)
bool solveInvertible(const Mat &B, Mat &X)
static void setUpperLower(const Mat &LU, Mat &lower, Mat &upper)
static void computePivotColumns(const Mat &LU, std::vector< size_t > &result_columns)
aring-style adapter for Z/p with p a word-size prime, backed by FLINT's nmod_* routines.
void freemem(void *s)
Definition m2-mem.cpp:103
static void concatenateMatrices(const Mat &A, const Mat &B, Mat &C)
Definition mat-util.hpp:90
Definition aring-CC.cpp:3
#define newarray_atomic(T, len)
Definition newdelete.hpp:91