Macaulay2 Engine
Loading...
Searching...
No Matches
mat.hpp
Go to the documentation of this file.
1// Copyright 2005 Michael E. Stillman
2
3#ifndef _mat_hpp_
4#define _mat_hpp_
5
46
47#include "exceptions.hpp"
48#include "hash.hpp"
49#include "relem.hpp"
50
51#include <iostream>
52
53class buffer;
54class RingElement;
55class Ring;
56class Matrix;
57template <class T>
58class MutableMat;
59
79{
80 protected:
82 public:
84 {
85 }
86
87#if 0
88 // MESXXX
89 class iterator : public our_new_delete
90 {
91 public:
92 virtual ~iterator() {}
93 virtual void set(size_t col) = 0;
94 virtual void next() = 0;
95 virtual bool valid() = 0;
96 virtual size_t row() = 0;
97 virtual void copy_ring_elem(ring_elem &a) = 0;
98 };
99#endif
100#if 0
101 // MESXX
102 virtual iterator * begin() const = 0;
103#endif
104 virtual const Ring *get_ring() const = 0;
105
106 virtual size_t n_rows() const = 0;
107
108 virtual size_t n_cols() const = 0;
109
110 virtual bool is_dense() const = 0;
111
112 static MutableMatrix *zero_matrix(const Ring *R,
113 size_t nrows,
114 size_t ncols,
115 bool dense);
116 // If the ring is RR or CC, and dense is true, then MutableMatrixRR or
117 // MutableMatrixCC will be used.
118
119 static MutableMatrix *identity(const Ring *R, size_t nrows, bool dense);
120
121 static MutableMatrix *from_matrix(const Matrix *N, bool is_dense);
122 // If the ring is RR or CC, and dense is true, then MutableMatrixRR or
123 // MutableMatrixCC will be used.
124
125 virtual Matrix *to_matrix() const = 0;
126
127 void text_out(buffer &o) const;
128
129 virtual MutableMatrix *copy(bool prefer_dense) const = 0;
130
131 bool set_values(M2_arrayint rows,
132 M2_arrayint cols,
133 engine_RawRingElementArray values);
134
136 // Casts down the hierarchy //
138 template <typename MatType>
140 {
141 return dynamic_cast<MutableMat<MatType> *>(this);
142 }
143
144 template <typename MatType>
146 {
147 return dynamic_cast<const MutableMat<MatType> *>(this);
148 }
149
150 template <typename MatT>
151 MatT *coerce()
152 {
154 if (P == 0) return 0;
155 return P->get_Mat();
156 }
157
158 template <typename MatT>
159 const MatT *coerce_const() const
160 {
162 if (P == 0) return 0;
163 return P->get_Mat();
164 }
165
167 // Row and column operations //
169 // The following routines return false if one of the row or columns given
170 // is out of range.
171
172 virtual size_t lead_row(size_t col) const = 0;
173 /* returns the largest index row which has a non-zero value in column 'col'.
174 returns -1 if the column is 0 */
175
176 virtual size_t lead_row(size_t col, ring_elem &result) const = 0;
177 /* returns the largest index row which has a non-zero value in column 'col'.
178 Also sets result to be the entry at this index.
179 returns -1 if the column is 0 */
180
181 virtual bool get_entry(size_t r, size_t c, ring_elem &result) const = 0;
182 // Returns false if (r,c) is out of range or if result is 0. No error
183 // is returned. result <-- this(r,c), and is set to zero if false is returned.
184
185 virtual bool set_entry(size_t r, size_t c, const ring_elem a) = 0;
186 // Returns false if (r,c) is out of range, or the ring of a is wrong.
187
188 virtual bool interchange_rows(size_t i, size_t j) = 0;
189 /* swap rows: row(i) <--> row(j) */
190
191 virtual bool interchange_columns(size_t i, size_t j) = 0;
192 /* swap columns: column(i) <--> column(j) */
193
194 virtual bool scale_row(size_t i, ring_elem r) = 0;
195 /* row(i) <- r * row(i) */
196
197 virtual bool scale_column(size_t i, ring_elem r) = 0;
198 /* column(i) <- r * column(i) */
199
200 virtual bool divide_row(size_t i, ring_elem r) = 0;
201 /* row(i) <- row(i) / r */
202
203 virtual bool divide_column(size_t i, ring_elem r) = 0;
204 /* column(i) <- column(i) / r */
205
206 virtual bool row_op(size_t i, ring_elem r, size_t j) = 0;
207 /* row(i) <- row(i) + r * row(j) */
208
209 virtual bool column_op(size_t i, ring_elem r, size_t j) = 0;
210 /* column(i) <- column(i) + r * column(j) */
211
212 virtual bool column2by2(size_t c1,
213 size_t c2,
214 ring_elem a1,
215 ring_elem a2,
216 ring_elem b1,
217 ring_elem b2) = 0;
218 /* column(c1) <- a1 * column(c1) + a2 * column(c2),
219 column(c2) <- b1 * column(c1) + b2 * column(c2)
220 */
221
222 virtual bool row2by2(size_t r1,
223 size_t r2,
224 ring_elem a1,
225 ring_elem a2,
226 ring_elem b1,
227 ring_elem b2) = 0;
228 /* row(r1) <- a1 * row(r1) + a2 * row(r2),
229 row(r2) <- b1 * row(r1) + b2 * row(r2)
230 */
231
232 virtual bool dot_product(size_t i, size_t j, ring_elem &result) const = 0;
233
234 virtual bool row_permute(size_t start_row, M2_arrayint perm) = 0;
235
236 virtual bool column_permute(size_t start_col, M2_arrayint perm) = 0;
237
238 virtual bool insert_columns(size_t i, size_t n_to_add) = 0;
239 /* Insert n_to_add columns directly BEFORE column i. */
240
241 virtual bool insert_rows(size_t i, size_t n_to_add) = 0;
242 /* Insert n_to_add rows directly BEFORE row i. */
243
244 virtual bool delete_columns(size_t i, size_t j) = 0;
245 /* Delete columns i .. j from M */
246
247 virtual bool delete_rows(size_t i, size_t j) = 0;
248 /* Delete rows i .. j from M */
249
250 virtual void reduce_by_pivots() = 0;
251 /* Finds units (starting with 1 and -1, then moving to other units)
252 in the matrix 'this', and performs row and column operations to
253 create a matrix with isomorphic cokernel
254 */
255
257 // Matrix operations //////////
259
261 M2_arrayint cols) const = 0;
262
263 virtual MutableMatrix *submatrix(M2_arrayint cols) const = 0;
264
265 virtual bool is_zero() const = 0;
266
267 virtual bool is_equal(const MutableMatrix *B) const = 0;
268
269 virtual MutableMatrix /* or null */ *add(const MutableMatrix *B) const = 0;
270 // return this + B. return NULL of sizes or types do not match.
271
272 virtual MutableMatrix /* or null */ *subtract(
273 const MutableMatrix *B) const = 0;
274 // return this - B. return NULL of sizes or types do not match.
275 // note: can subtract a sparse + dense
276 // can subtract a matrix over RR and one over CC and/or one over ZZ.
277
278 virtual MutableMatrix /* or null */ *mult(const RingElement *f) const = 0;
279 // return f*this. return NULL of sizes or types do not match.
280
281 virtual MutableMatrix *negate() const = 0;
282
283 virtual MutableMatrix /* or null */ *transpose() const = 0;
284
286 // Linear algebra /////////////
288
290
291 virtual M2_arrayintOrNull LUincremental(std::vector<size_t>& P, const MutableMatrix* v, int m) = 0;
292
293 virtual void triangularSolve(MutableMatrix* x, int m, int strategy) = 0;
294
295 // replace 'this=A' with a matrix which encodes both 'L' and 'U', returning a
296 // permutation P
297 // of 0..numRows A-1 s.t. LU = PA
298 // virtual M2_arrayintOrNull LUInPlace() const = 0;
299
300 virtual bool eigenvalues(MutableMatrix *eigenvals,
301 bool is_symm_or_hermitian) const = 0;
302
303 virtual bool eigenvectors(MutableMatrix *eigenvals,
304 MutableMatrix *eigenvecs,
305 bool is_symm_or_hermitian) const = 0;
306
307 virtual bool SVD(MutableMatrix *Sigma,
308 MutableMatrix *U,
309 MutableMatrix *Vt,
310 bool use_divide_and_conquer) const = 0;
311
312 virtual bool least_squares(const MutableMatrix *b,
314 bool assume_full_rank) const = 0;
315
316 virtual bool QR(MutableMatrix *Q, MutableMatrix *R, bool return_QR) const = 0;
317
321
322 // A = m x n 'this' is factored as A = LQUP, where
323 // L is m x m lower unit triangular
324 // U is m x n upper triangular
325 // Q is a m x m permutation matrix
326 // P is an n x n permutation matrix
327 // However, the result is constructed in an abbreviated, encoded format:
328 // First, the entries of A are modified:
329 // L and U are placed into A
330 // Two integer arrays are returned:
331 // The first represents Q, giving the rows of U ??
332 // The second represents P, which tells which columns of A have non-zero
333 // pivots
334 // (and, the elements below the main diagonal in these columns form the
335 // lower part of L).
336 // If the ring or matrix type does not support this computation, an
337 // engine_error is thrown.
339 {
340 (void) transpose;
341 throw exc::engine_error("not implemented for this ring or matrix type");
342 }
343
345
346 virtual size_t rank() const = 0;
347
348 virtual const RingElement *determinant() const = 0;
349
350 // Find the inverse matrix. If the matrix is not square, or
351 // the ring is one in which th matrix cannot be inverted,
352 // then NULL is returned, and an error message is set.
353 virtual MutableMatrix *invert() const = 0;
354
355 // Find the row reduced echelon form of 'this'. If
356 // the ring is one in which the rref cannot be computed,
357 // then NULL is returned, and an error message is set.
359
360 // Returns an array of increasing integers {n_1, n_2, ...}
361 // such that if M is the matrix with rows (resp columns, if row_profile is
362 // false)
363 // then rank(M_{0..n_i-1}) + 1 = rank(M_{0..n_i}).
364 // NULL is returned, and an error is set, if this function is not available
365 // for the given choice of ring and dense/sparseness.
366 virtual M2_arrayintOrNull rankProfile(bool row_profile) const = 0;
367
368 // Find a spanning set for the null space. If M = this,
369 // return a matrix whose columns span {x | Mx = 0}
370 virtual MutableMatrix *nullSpace() const = 0;
371
372 // Returns X, if (this=A) AX=B has a solution.
373 // Returns NULL, if not.
374 // Throws an exception if any other usage issues arise (bad rings, sizes, not
375 // implemented...)
376 virtual MutableMatrix *solveLinear(const MutableMatrix *B) const = 0;
377
378 // Returns X, if this=A is invertible, and AX=B. (so X is uniquely determined)
379 // Returns NULL, if A is not invertible.
380 // Throws an exception if any other usage issues arise.
381 virtual MutableMatrix *solveInvertible(const MutableMatrix *B) const = 0;
382
383 virtual void addMultipleTo(const MutableMatrix *A,
384 const MutableMatrix *B) = 0;
385
386 virtual void subtractMultipleTo(const MutableMatrix *A,
387 const MutableMatrix *B) = 0;
388
389 virtual MutableMatrix /* or null */ *mult(const MutableMatrix *B) const = 0;
390
391 // return this * B.
392 // both matrices must be of the same type.
393 // If not, or sizes don't match, NULL is returned.
394
395 virtual void clean(gmp_RR epsilon) = 0; // modifies 'this'
396 virtual gmp_RRorNull norm() const = 0;
397
399 M2SLProgram *P,
400 M2_arrayint constsPos,
401 M2_arrayint varsPos) const = 0; // this = const matrix
402
404 M2_string libName,
405 int nInputs,
406 int nOutputs) const = 0; // this = const matrix
407};
408
409#endif
410
411// Local Variables:
412// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
413// indent-tabs-mode: nil
414// End:
MutableEngineObject wrapper holding a raw SLEvaluator*.
Definition SLP-defs.hpp:248
MutableEngineObject wrapper that owns an SLProgram via unique_ptr.
Definition SLP-defs.hpp:64
virtual size_t n_rows() const =0
virtual engine_RawArrayIntPairOrNull LQUPFactorizationInPlace(bool transpose)
LU decomposition routines /////.
Definition mat.hpp:338
virtual bool dot_product(size_t i, size_t j, ring_elem &result) const =0
virtual const RingElement * determinant() const =0
virtual MutableMatrix * copy(bool prefer_dense) const =0
virtual MutableMatrix * nullSpace() const =0
virtual void triangularSolve(MutableMatrix *x, int m, int strategy)=0
virtual bool column2by2(size_t c1, size_t c2, ring_elem a1, ring_elem a2, ring_elem b1, ring_elem b2)=0
MutableMat< MatType > * cast_to_MutableMat()
Definition mat.hpp:139
const MutableMat< MatType > * cast_to_MutableMat() const
Definition mat.hpp:145
virtual MutableMatrix * mult(const RingElement *f) const =0
virtual Matrix * to_matrix() const =0
virtual bool row_op(size_t i, ring_elem r, size_t j)=0
virtual bool scale_column(size_t i, ring_elem r)=0
virtual size_t n_cols() const =0
virtual bool interchange_rows(size_t i, size_t j)=0
virtual bool interchange_columns(size_t i, size_t j)=0
virtual bool QR(MutableMatrix *Q, MutableMatrix *R, bool return_QR) const =0
virtual size_t lead_row(size_t col) const =0
virtual bool is_equal(const MutableMatrix *B) const =0
virtual bool divide_row(size_t i, ring_elem r)=0
virtual bool get_entry(size_t r, size_t c, ring_elem &result) const =0
virtual void addMultipleTo(const MutableMatrix *A, const MutableMatrix *B)=0
virtual size_t rank() const =0
Fast linear algebra routines (well, fast for some rings).
virtual M2_arrayintOrNull rankProfile(bool row_profile) const =0
virtual bool SVD(MutableMatrix *Sigma, MutableMatrix *U, MutableMatrix *Vt, bool use_divide_and_conquer) const =0
virtual MutableMatrix * invert() const =0
virtual gmp_RRorNull norm() const =0
virtual bool eigenvectors(MutableMatrix *eigenvals, MutableMatrix *eigenvecs, bool is_symm_or_hermitian) const =0
static MutableMatrix * zero_matrix(const Ring *R, size_t nrows, size_t ncols, bool dense)
Definition mat.cpp:54
virtual bool is_zero() const =0
static MutableMatrix * from_matrix(const Matrix *N, bool is_dense)
Definition mat.cpp:76
virtual size_t lead_row(size_t col, ring_elem &result) const =0
virtual bool row2by2(size_t r1, size_t r2, ring_elem a1, ring_elem a2, ring_elem b1, ring_elem b2)=0
virtual bool column_permute(size_t start_col, M2_arrayint perm)=0
virtual MutableMatrix * solveInvertible(const MutableMatrix *B) const =0
virtual bool is_dense() const =0
virtual bool delete_rows(size_t i, size_t j)=0
virtual void reduce_by_pivots()=0
void text_out(buffer &o) const
Definition mat.cpp:89
virtual MutableMatrix * transpose() const =0
virtual bool scale_row(size_t i, ring_elem r)=0
virtual MutableMatrix * submatrix(M2_arrayint rows, M2_arrayint cols) const =0
bool set_values(M2_arrayint rows, M2_arrayint cols, engine_RawRingElementArray values)
Definition mat.cpp:121
virtual MutableMatrix * negate() const =0
virtual bool insert_columns(size_t i, size_t n_to_add)=0
virtual bool eigenvalues(MutableMatrix *eigenvals, bool is_symm_or_hermitian) const =0
virtual MutableMatrix * submatrix(M2_arrayint cols) const =0
virtual bool column_op(size_t i, ring_elem r, size_t j)=0
virtual bool row_permute(size_t start_row, M2_arrayint perm)=0
virtual const Ring * get_ring() const =0
virtual void clean(gmp_RR epsilon)=0
virtual MutableMatrix * subtract(const MutableMatrix *B) const =0
virtual bool insert_rows(size_t i, size_t n_to_add)=0
virtual void subtractMultipleTo(const MutableMatrix *A, const MutableMatrix *B)=0
virtual M2_arrayintOrNull LU(MutableMatrix *L, MutableMatrix *U) const =0
virtual bool delete_columns(size_t i, size_t j)=0
virtual MutableMatrix * mult(const MutableMatrix *B) const =0
virtual M2SLEvaluator * createSLEvaluator(M2SLProgram *P, M2_arrayint constsPos, M2_arrayint varsPos) const =0
virtual M2_arrayintOrNull LUincremental(std::vector< size_t > &P, const MutableMatrix *v, int m)=0
MatT * coerce()
Definition mat.hpp:151
virtual ~MutableMatrix()
Definition mat.hpp:83
virtual bool set_entry(size_t r, size_t c, const ring_elem a)=0
virtual bool least_squares(const MutableMatrix *b, MutableMatrix *x, bool assume_full_rank) const =0
virtual MutableMatrix * solveLinear(const MutableMatrix *B) const =0
MutableMatrix()
Definition mat.hpp:81
virtual M2SLEvaluator * createCompiledSLEvaluator(M2_string libName, int nInputs, int nOutputs) const =0
const MatT * coerce_const() const
Definition mat.hpp:159
virtual bool divide_column(size_t i, ring_elem r)=0
virtual MutableMatrix * add(const MutableMatrix *B) const =0
virtual MutableMatrix * rowReducedEchelonForm() const =0
static MutableMatrix * identity(const Ring *R, size_t nrows, bool dense)
Definition mat.cpp:69
Front-end-visible "ring element" value: an engine ring_elem paired with the Ring* that gives it meani...
Definition relem.hpp:67
xxx xxx xxx
Definition ring.hpp:102
namespace exc — internal C++ exception types and the TRY / CATCH macro pair.
#define Matrix
Definition factory.cpp:14
EngineObject / MutableEngineObject — shared bases that supply the hash an M2 interpreter object expec...
VALGRIND_MAKE_MEM_DEFINED & result(result)
mpfr_srcptr gmp_RR
Definition m2-types.h:148
M2_arrayint M2_arrayintOrNull
Definition m2-types.h:99
engine_RawArrayIntPair engine_RawArrayIntPairOrNull
Definition m2-types.h:188
mpfr_srcptr gmp_RRorNull
Definition m2-types.h:149
void set(DMat< RT > &A, MatrixWindow wA, const DMat< RT > &B, MatrixWindow wB)
volatile int x
RingElement — tagged (Ring*, ring_elem) pair, the engine's universal element type.
TermIterator< Nterm > begin(Nterm *ptr)
Definition ringelem.cpp:4