Macaulay2 Engine
Loading...
Searching...
No Matches
dmat.cpp
Go to the documentation of this file.
1// Copyright 2005,2013 Michael E. Stillman
2
3#include "exceptions.hpp"
4#include "error.h"
5
6#include "mat-linalg.hpp"
7
9// dmat code that might have alternate implementations, depending of type //
11
12namespace MatrixOps {
14 const DMatZZpFFPACK::ElementType& a,
15 const DMatZZpFFPACK& A,
16 const DMatZZpFFPACK& B)
17{
18 // Compute C := C + a*A*B
19 // Both DMat, and FFPACK store dense matrices in row major order.
20 // Note that the leading dimension in gemm arguments is #columns,
21 // as the matrix is in row-major order
22
23 FFLAS::FFLAS_TRANSPOSE tA = FFLAS::FflasNoTrans;
24 FFLAS::FFLAS_TRANSPOSE tB = FFLAS::FflasNoTrans;
25
26 size_t m = A.numRows();
27 size_t k = A.numColumns();
28 assert(A.numColumns() == B.numRows());
29 size_t n = B.numColumns();
30
31 assert(C.numRows() == m);
32 assert(C.numColumns() == n);
33
34 DMatZZpFFPACK::ElementType b;
35 C.ring().init(b);
36 C.ring().set_from_long(b, 1);
37 FFLAS::fgemm(C.ring().field(),
38 tB,
39 tA,
40 m,
41 n,
42 k,
43 a,
44 A.rowMajorArray(),
45 A.numColumns(),
46 B.rowMajorArray(),
47 B.numColumns(),
48 b,
49 C.rowMajorArray(),
50 C.numColumns());
51}
52
54 const DMatZZpFFPACK& A,
55 const DMatZZpFFPACK& B)
56{
57 DMatZZpFFPACK::ElementType one;
58 A.ring().set_from_long(one, 1);
59
60 addMultipleTo(C, one, A, B);
61}
62
64 const DMatZZpFFPACK& A,
65 const DMatZZpFFPACK& B)
66{
67 DMatZZpFFPACK::ElementType minus_one;
68 A.ring().set_from_long(minus_one, -1);
69 addMultipleTo(C, minus_one, A, B);
70}
71
72void mult(const DMatZZpFFPACK& A, const DMatZZpFFPACK& B, DMatZZpFFPACK& C)
73{
74 // We assume that C is set to the correct size, and is the zero matrix here.
75 addMultipleTo(C, A, B);
76}
77}; // namespace MatrixOps
78
79namespace ffpackInterface {
80size_t rank(const DMatZZpFFPACK& mat)
81{
83 DMatZZpFFPACK N(mat); // copy of matrix mat.
84 size_t result = FFPACK::Rank(mat.ring().field(),
85 mat.numRows(),
86 mat.numColumns(),
87 N.rowMajorArray(),
88 mat.numColumns());
89 return result;
90}
91
93{
95 if (mat.numRows() == 0)
96 {
97 // 26 April 2014: this branch is needed as FFPACK gives answer of 0 in
98 // this case.
99 mat.ring().set_from_long(result_det, 1);
100 }
101 else
102 {
103 DMatZZpFFPACK N(mat);
105 result_det = FFPACK::Det(mat.ring().field(),
106 det,
107 mat.numRows(),
108 N.rowMajorArray(),
109 mat.numColumns());
110 }
111}
112
113bool inverse(const DMatZZpFFPACK& mat, DMatZZpFFPACK& result_inv)
114{
115 assert(mat.numRows() == mat.numColumns());
116 result_inv.resize(mat.numRows(), mat.numRows());
117
118 assert(result_inv.numRows() == mat.numRows());
119 assert(result_inv.numColumns() == mat.numRows());
120
121 if (mat.numRows() == 0)
122 {
123 // 26 April 2014: this branch is needed as FFPACK gives answer of 0 in
124 // this case.
125 return true;
126 }
127
128 DMatZZpFFPACK N(mat);
129 size_t n = mat.numRows();
130 int nullspacedim;
131 FFPACK::Invert2(
132 mat.ring().field(), n, N.rowMajorArray(), n, result_inv.rowMajorArray(), n, nullspacedim);
133 return (nullspacedim == 0);
134}
135
136size_t nullSpace(const DMatZZpFFPACK& mat, DMatZZpFFPACK& nullspace)
137{
138 bool right_side = true; // This function is written so that one could set
139 // right_side to false.
140 // (It used to be a parameter).
141
142 DMatZZpFFPACK N(mat); // copy of mat
143 size_t nr = mat.numRows();
144 size_t nc = mat.numColumns();
145
146 DMatZZpFFPACK::ElementType* nullspaceFFPACK = nullptr;
147
148 size_t nullspace_dim;
149 size_t nullspace_leading_dim;
150
151 FFPACK::NullSpaceBasis(mat.ring().field(),
152 (right_side ? FFLAS::FflasRight : FFLAS::FflasLeft),
153 nr,
154 nc,
155 N.rowMajorArray(),
156 nc,
157 nullspaceFFPACK,
158 nullspace_leading_dim,
159 nullspace_dim);
160
161 // std::cerr << "leading dim = " << nullspace_leading_dim << " and dim = "
162 // << nullspace_dim << std::endl;
163 if (right_side && nullspace_dim != nullspace_leading_dim)
164 {
165 std::cerr << "error: this should not happen!" << std::endl;
166 }
167 else if (!right_side && nullspace_leading_dim != nc)
168 {
169 std::cerr << "error: this should not happen either!" << std::endl;
170 }
171
172 if (right_side)
173 nullspace.resize(nc, nullspace_dim);
174 else
175 nullspace.resize(nullspace_dim, nr);
176
177 std::swap(nullspace.rowMajorArray(), nullspaceFFPACK);
178
179 delete[] nullspaceFFPACK;
180 return nullspace_dim;
181}
182
184 const DMatZZpFFPACK& B,
185 bool right_side,
186 DMatZZpFFPACK& X,
187 bool declare_A_is_invertible) // this parameter is unused
188{
189 // std::cerr << "inside FFpackSolveLinear" << std::endl;
190 (void) declare_A_is_invertible;
191 size_t a_rows = A.numRows();
192 size_t a_cols = A.numColumns();
193
194 size_t b_rows = B.numRows();
195 size_t b_cols = B.numColumns();
196
197 DMatZZpFFPACK copyA(A);
198 DMatZZpFFPACK copyB(B);
199
200 // preallocate the space for the solutions:
201 size_t x_rows = (right_side ? a_cols : b_rows);
202 size_t x_cols = (right_side ? b_cols : a_rows);
203
204 X.resize(x_rows, x_cols); // sets it to 0 too.
205
206 int info = 0; // >0 if the system is inconsistent, ==0 means success
207
208 FFPACK::fgesv(A.ring().field(),
209 (right_side ? FFLAS::FflasLeft : FFLAS::FflasRight),
210 a_rows,
211 a_cols,
212 (right_side ? b_cols : b_rows),
213 copyA.rowMajorArray(),
214 a_cols, // leading dim of A
215 X.rowMajorArray(),
216 x_cols,
217 copyB.rowMajorArray(),
218 b_cols,
219 &info);
220
221 if (info > 0)
222 {
223 // the system is inconsistent
224 return false;
225 }
226
227 return true;
228}
229
231 const DMatZZpFFPACK& B,
232 DMatZZpFFPACK& X)
233{
234 return solveLinear(A, B, true, X, false);
235}
236
237M2_arrayintOrNull rankProfile(const DMatZZpFFPACK& mat, bool row_profile)
238
239{
240 DMatZZpFFPACK N(mat);
241
242 size_t* prof; // this is where the result will be placed
243 size_t rk;
244 if (row_profile)
245 rk = FFPACK::RowRankProfile(mat.ring().field(),
246 mat.numRows(),
247 mat.numColumns(),
248 N.rowMajorArray(),
249 mat.numColumns(),
250 prof);
251 else
252 rk = FFPACK::ColumnRankProfile(mat.ring().field(),
253 mat.numRows(),
254 mat.numColumns(),
255 N.rowMajorArray(),
256 mat.numColumns(),
257 prof);
258
259 M2_arrayint profile = M2_makearrayint(static_cast<int>(rk));
260 for (size_t i = 0; i < rk; i++) profile->array[i] = static_cast<int>(prof[i]);
261
262 delete[] prof;
263 return profile;
264}
265
267 bool row_profile,
268 std::vector<size_t>& result_profile)
269
270{
271 DMatZZpFFPACK N(mat);
272
273 size_t* prof; // this is where the result will be placed
274 size_t rk;
275 if (row_profile)
276 rk = FFPACK::RowRankProfile(mat.ring().field(),
277 mat.numRows(),
278 mat.numColumns(),
279 N.rowMajorArray(),
280 mat.numColumns(),
281 prof);
282 else
283 rk = FFPACK::ColumnRankProfile(mat.ring().field(),
284 mat.numRows(),
285 mat.numColumns(),
286 N.rowMajorArray(),
287 mat.numColumns(),
288 prof);
289
290 result_profile.resize(0);
291 for (size_t i = 0; i < rk; i++) result_profile.push_back(prof[i]);
292
293 delete[] prof;
294}
295
296}; // namespace ffpackInterface
297
298// Local Variables:
299// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
300// indent-tabs-mode: nil
301// End:
FieldType::Element ElementType
Engine error-reporting primitives: ERROR, INTERNAL_ERROR, error, error_message.
namespace exc — internal C++ exception types and the TRY / CATCH macro pair.
int minus_one
VALGRIND_MAKE_MEM_DEFINED & result(result)
M2_arrayint M2_makearrayint(int n)
Definition m2-types.cpp:6
M2_arrayint M2_arrayintOrNull
Definition m2-types.h:99
#define DMatZZpFFPACK
Templated DMat<R> linear algebra: LU, rank, determinant, solve, inverse, nullSpace.
void subtractMultipleTo(DMatZZpFFPACK &C, const DMatZZpFFPACK &A, const DMatZZpFFPACK &B)
Definition dmat.cpp:63
void addMultipleTo(DMatZZpFFPACK &C, const DMatZZpFFPACK::ElementType &a, const DMatZZpFFPACK &A, const DMatZZpFFPACK &B)
Definition dmat.cpp:13
void mult(const DMatZZpFFPACK &A, const DMatZZpFFPACK &B, DMatZZpFFPACK &C)
Definition dmat.cpp:72
void determinant(const DMatZZpFFPACK &A, ZZpFFPACK::ElementType &result_det)
Definition dmat.cpp:92
bool inverse(const DMatZZpFFPACK &A, DMatZZpFFPACK &result_inv)
Definition dmat.cpp:113
size_t rank(const DMatZZpFFPACK &A)
Definition dmat.cpp:80
size_t nullSpace(const DMatZZpFFPACK &A, DMatZZpFFPACK &result_nullspace)
Definition dmat.cpp:136
M2_arrayintOrNull rankProfile(const DMatZZpFFPACK &A, bool row_profile)
Definition dmat.cpp:237
bool solveLinear(const DMatZZpFFPACK &A, const DMatZZpFFPACK &B, DMatZZpFFPACK &X)
Definition dmat.cpp:230
void swap(mpfr::mpreal &x, mpfr::mpreal &y)
Definition mpreal.h:3244