Macaulay2 Engine
Loading...
Searching...
No Matches
mat-arith.hpp
Go to the documentation of this file.
1// Copyright 2013 Michael E. Stillman
2
3#ifndef _mat_arith_hpp_
4#define _mat_arith_hpp_
5
39
40template <typename MT>
42// template <typename MT> class MatArithmetic;
43#include "dmat.hpp"
44#include "smat.hpp"
45
59// Use below via
60// MatrixWindow(first_row, first_col, #rows, #columns)
62{
65 long end_row;
67 MatrixWindow(long x, long y, long nrows, long ncols)
68 : begin_row(x), begin_column(y), end_row(x + nrows), end_column(y + ncols)
69 {
70 // empty body OK
71 }
72
73 bool sameSize(const MatrixWindow& b) const
74 {
75 return (end_row - begin_row == b.end_row - b.begin_row) and
77 }
78};
79
80template <typename MatType>
82{
83 MatType& matrix;
84 const long begin_row;
85 const long end_row;
86 const long begin_column;
87 const long end_column;
88
89 SubMatrix(MatType& m)
90 : matrix(m),
91 begin_row(0),
92 end_row(m.numRows()),
93 begin_column(0),
94 end_column(m.numColumns())
95 {
96 }
97
98 SubMatrix(MatType& m, long x, long y, long nrows, long ncols)
99 : matrix(m),
100 begin_row(x),
101 end_row(x + nrows),
102 begin_column(y),
103 end_column(y + ncols)
104 {
105 }
106
107 bool sameSize(const SubMatrix& b) const
108 {
109 return (end_row - begin_row == b.end_row - b.begin_row) and
111 }
112
113 void operator=(int x)
114 {
115 if (x == 0)
116 {
117 for (long rA = begin_row; rA < end_row; ++rA)
118 for (size_t cA = begin_column; cA < end_column; ++cA)
119 matrix.ring().set_zero(matrix.entry(rA, cA));
120 }
121 }
122
124 {
125 assert(sameSize(src));
126 long rA = begin_row;
127 long rB = src.begin_row;
128 for (; rA < end_row; ++rA, ++rB)
129 {
130 long cA = begin_column;
131 long cB = src.begin_column;
132 for (; cA < end_column; ++cA, ++cB)
133 matrix.ring().set(matrix.entry(rA, cA), src.matrix.entry(rB, cB));
134 }
135 }
136
138 {
139 assert(sameSize(src));
140 long rA = begin_row;
141 long rB = src.begin_row;
142 for (; rA < end_row; ++rA, ++rB)
143 {
144 long cA = begin_column;
145 long cB = src.begin_column;
146 for (; cA < end_column; ++cA, ++cB)
147 {
148 auto& a = matrix.entry(rA, cA);
149 matrix.ring().add(a, a, src.matrix.entry(rB, cB));
150 }
151 }
152 }
153
154 template <typename ElementType>
155 void addMultipleTo(ElementType& c, SubMatrix<MatType> src)
156 {
157 assert(sameSize(src));
158 long rA = begin_row;
159 long rB = src.begin_row;
160 for (; rA < end_row; ++rA, ++rB)
161 {
162 long cA = begin_column;
163 long cB = src.begin_column;
164 for (; cA < end_column; ++cA, ++cB)
165 matrix.ring().addMultipleTo(
166 matrix.entry(rA, cA), c, src.matrix.entry(rB, cB));
167 }
168 }
169
170 template <typename ElementType>
171 void operator*=(ElementType& c)
172 {
173 for (long rA = begin_row; rA < end_row; ++rA)
174 {
175 for (long cA = begin_column; cA < end_column; ++cA)
176 {
177 auto& a = matrix.entry(rA, cA);
178 matrix.ring().mult(a, a, c);
179 }
180 }
181 }
182};
183
184template <typename MatType>
186 typename MatType::CoeffRing::RealElementType& result)
187{
188 const auto& C = M.matrix.ring();
189 const auto& R = C.real_ring();
190 typename MatType::CoeffRing::RealRingType::Element c(R);
191 R.set_zero(result);
192 for (long rA = M.begin_row; rA < M.end_row; ++rA)
193 for (long cA = M.begin_column; cA < M.end_column; ++cA)
194 {
195 C.abs_squared(c, M.matrix.entry(rA, cA));
196 R.add(result, result, c);
197 }
198}
199
200template <typename MatType>
202{
203 return SubMatrix<MatType>(m);
204}
205template <typename MatType>
206SubMatrix<MatType> submatrix(MatType& m, long x, long y, long nrows, long ncols)
207{
208 return SubMatrix<MatType>(m, x, y, nrows, ncols);
209}
210
211namespace MatrixOps {
212template <typename RT>
213bool isZero(const DMat<RT>& A)
214{
215 for (int r = 0; r < A.numRows(); ++r)
216 for (int c = 0; c < A.numColumns(); ++c)
217 if (!A.ring().is_zero(A.entry(r,c))) return false;
218 return true;
219}
220
221template <typename RT>
222bool isEqual(const DMat<RT>& A, const DMat<RT>& B)
223{
224 assert(&A.ring() == &B.ring());
225 if (B.numRows() != A.numRows()) return false;
226 if (B.numColumns() != A.numColumns()) return false;
227
228 for (int r = 0; r < A.numRows(); ++r)
229 for (int c = 0; c < A.numColumns(); ++c)
230 if (!A.ring().is_equal(A.entry(r,c), B.entry(r,c))) return false;
231 return true;
232}
233
234template <typename RT>
235void scalarMultInPlace(DMat<RT>& A, const typename RT::ElementType& f)
236{
237 for (int r = 0; r < A.numRows(); ++r)
238 for (int c = 0; c < A.numColumns(); ++c)
239 A.ring().mult(A.entry(r,c), f, A.entry(r,c));
240}
241
242template <typename RT>
244// A = -A
245{
246 for (int r = 0; r < A.numRows(); ++r)
247 for (int c = 0; c < A.numColumns(); ++c)
248 A.ring().negate(A.entry(r,c), A.entry(r,c));
249}
250
251template <typename RT>
252void addInPlace(DMat<RT>& A, const DMat<RT>& B)
253// A += B.
254{
255 assert(&B.ring() == &A.ring());
256 assert(B.numRows() == A.numRows());
257 assert(B.numColumns() == A.numColumns());
258
259 for (int r = 0; r < A.numRows(); ++r)
260 for (int c = 0; c < A.numColumns(); ++c)
261 A.ring().add(A.entry(r,c), A.entry(r,c), B.entry(r,c));
262}
263
264template <typename RT>
266// A -= B
267{
268 assert(&B.ring() == &A.ring());
269 assert(B.numRows() == A.numRows());
270 assert(B.numColumns() == A.numColumns());
271
272 for (int r = 0; r < A.numRows(); ++r)
273 for (int c = 0; c < A.numColumns(); ++c)
274 A.ring().subtract(A.entry(r,c), A.entry(r,c), B.entry(r,c));
275}
276
277template <typename RT>
279{
280 assert(&A != &result); // these cannot be aliased!
281 assert(result.numRows() == A.numColumns());
282 assert(result.numColumns() == A.numRows());
283
284 for (int r = 0; r < A.numRows(); ++r)
285 for (int c = 0; c < A.numColumns(); ++c)
286 A.ring().set(result.entry(c,r), A.entry(r,c));
287}
288
289// wA = 0
290template <typename RT>
292{
293 for (long rA = wA.begin_row; rA < wA.end_row; ++rA)
294 for (size_t cA = wA.begin_column; cA < wA.end_column; ++cA)
295 A.ring().set_zero(A.entry(rA, cA));
296}
297
298template <typename MatType>
300{
301 auto& M = A.matrix;
302 for (long rA = A.begin_row; rA < A.end_row; ++rA)
303 for (size_t cA = A.begin_column; cA < A.end_column; ++cA)
304 M.ring().set_zero(M.entry(rA, cA));
305}
306
307// wA = wB
308template <typename RT>
310{
311 assert(wA.sameSize(wB));
312 long rA = wA.begin_row;
313 long rB = wB.begin_row;
314 for (; rA < wA.end_row; ++rA, ++rB)
315 {
316 long cA = wA.begin_column;
317 long cB = wB.begin_column;
318 for (; cA < wA.end_column; ++cA, ++cB)
319 A.ring().set(A.entry(rA, cA), B.entry(rB, cB));
320 }
321}
322
323// wA += wB
324template <typename RT>
326{
327 assert(wA.sameSize(wB));
328 long rA = wA.begin_row;
329 long rB = wB.begin_row;
330 for (; rA < wA.end_row; ++rA, ++rB)
331 {
332 long cA = wA.begin_column;
333 long cB = wB.begin_column;
334 for (; cA < wA.end_column; ++cA, ++cB)
335 {
336 auto& a = A.entry(rA, cA);
337 A.ring().add(a, a, B.entry(rB, cB));
338 }
339 }
340}
341
342// wA += c * wB
343template <typename RT>
345 MatrixWindow wA,
346 const typename RT::ElementType& c,
347 const DMat<RT>& B,
348 MatrixWindow wB)
349{
350 assert(wA.sameSize(wB));
351 typename RT::Element tmp(A.ring());
352 long rA = wA.begin_row;
353 long rB = wB.begin_row;
354 for (; rA < wA.end_row; ++rA, ++rB)
355 {
356 long cA = wA.begin_column;
357 long cB = wB.begin_column;
358 for (; cA < wA.end_column; ++cA, ++cB)
359 {
360 A.ring().mult(tmp, c, B.entry(rB, cB));
361 auto& a = A.entry(rA, cA);
362 A.ring().add(a, a, tmp);
363 }
364 }
365}
366
367// wA = c * wB
368template <typename RT>
370 MatrixWindow wA,
371 const typename RT::ElementType& c,
372 const DMat<RT>& B,
373 MatrixWindow wB)
374{
375 assert(wA.sameSize(wB));
376 long rA = wA.begin_row;
377 long rB = wB.begin_row;
378 for (; rA < wA.end_row; ++rA, ++rB)
379 {
380 long cA = wA.begin_column;
381 long cB = wB.begin_column;
382 for (; cA < wA.end_column; ++cA, ++cB)
383 {
384 A.ring().mult(A.entry(rA, cA), c, B.entry(rB, cB));
385 }
386 }
387}
388
389// wA *= c
390template <typename RT>
392 MatrixWindow wA,
393 const typename RT::ElementType& c)
394{
395 long rA = wA.begin_row;
396 for (; rA < wA.end_row; ++rA)
397 {
398 long cA = wA.begin_column;
399 for (; cA < wA.end_column; ++cA)
400 {
401 auto& a = A.entry(rA, cA);
402 A.ring().mult(a, a, c);
403 }
404 }
405}
406
408// Sparse matrix template routines for matrix operations //
410
411template <typename RT>
412bool isZero(const SMat<RT>& A)
413{
414 return A.is_zero();
415}
416
417template <typename RT>
418bool isEqual(const SMat<RT>& A, const SMat<RT>& B)
419{
420 return A.is_equal(B);
421}
422
423template <typename RT>
424void scalarMultInPlace(SMat<RT>& A, const typename RT::ElementType& f)
425// A = f*A
426{
428}
429
430template <typename RT>
432// A = -A
433{
434 A.negateInPlace();
435}
436
437template <typename RT>
438void addInPlace(SMat<RT>& A, const SMat<RT>& B)
439{
440 assert(&B.ring() == &A.ring());
441 assert(B.numRows() == A.numRows());
442 assert(B.numColumns() == A.numColumns());
443
444 A.addInPlace(B);
445}
446
447template <typename RT>
449// A -= B
450{
451 assert(&B.ring() == &A.ring());
452 assert(B.numRows() == A.numRows());
453 assert(B.numColumns() == A.numColumns());
454
455 A.subtractInPlace(B);
456}
457
458template <typename RT>
460{
461 // result should be the 0 matrix of the correct size.
462 (void) A;
463 (void) result;
464 assert(&A != &result); // these cannot be aliased!
465 assert(result.numRows() == A.numColumns());
466 assert(result.numColumns() == A.numRows());
467 throw exc::engine_error(
468 "'transpose' not written for sparse mutable matrices");
469 // TODO: MES: write this!!
470}
471};
472
473#endif
474
475// Local Variables:
476// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
477// indent-tabs-mode: nil
478// End:
size_t numRows() const
Definition dmat.hpp:144
ElementType & entry(size_t row, size_t column)
Definition dmat.hpp:148
const ACoeffRing & ring() const
Definition dmat.hpp:143
size_t numColumns() const
Definition dmat.hpp:145
Definition dmat.hpp:62
const CoeffRing & ring() const
Definition smat.hpp:104
bool is_zero() const
Definition smat.hpp:1107
void addInPlace(const SMat &B)
Definition smat.hpp:1162
void scalarMultInPlace(const elem &f)
Definition smat.hpp:1203
void negateInPlace()
Definition smat.hpp:1194
bool is_equal(const SMat &B) const
Definition smat.hpp:1115
size_t numRows() const
Definition smat.hpp:99
void subtractInPlace(const SMat &B)
Definition smat.hpp:1177
size_t numColumns() const
Definition smat.hpp:100
Definition smat.hpp:43
DMat<ACoeffRing> — dense-matrix template plus the umbrella that wires in every per-ring specialisatio...
VALGRIND_MAKE_MEM_DEFINED & result(result)
void normSquared(SubMatrix< MatType > M, typename MatType::CoeffRing::RealElementType &result)
SubMatrix< MatType > submatrix(MatType &m)
void scalarMult(DMat< RT > &A, MatrixWindow wA, const typename RT::ElementType &c, const DMat< RT > &B, MatrixWindow wB)
void scalarMultInPlace(DMat< RT > &A, const typename RT::ElementType &f)
void negateInPlace(DMat< RT > &A)
void set(DMat< RT > &A, MatrixWindow wA, const DMat< RT > &B, MatrixWindow wB)
bool isEqual(const DMat< RT > &A, const DMat< RT > &B)
bool isZero(const DMat< RT > &A)
void setZero(DMat< RT > &A, MatrixWindow wA)
void subtractInPlace(DMat< RT > &A, const DMat< RT > &B)
void addTo(DMat< RT > &A, MatrixWindow wA, const DMat< RT > &B, MatrixWindow wB)
void addMultipleTo(DMatZZpFFPACK &C, const DMatZZpFFPACK::ElementType &a, const DMatZZpFFPACK &A, const DMatZZpFFPACK &B)
Definition dmat.cpp:13
void addInPlace(DMat< RT > &A, const DMat< RT > &B)
void transpose(const DMat< RT > &A, DMat< RT > &result)
volatile int x
SMat<ACoeffRing> — column-oriented sparse matrix template, dual of DMat<R>.
bool sameSize(const MatrixWindow &b) const
Definition mat-arith.hpp:73
MatrixWindow(long x, long y, long nrows, long ncols)
Definition mat-arith.hpp:67
long begin_column
Definition mat-arith.hpp:64
Half-open rectangular submatrix descriptor: [begin_row, end_row) x [begin_column, end_column).
Definition mat-arith.hpp:62
void addMultipleTo(ElementType &c, SubMatrix< MatType > src)
const long begin_row
Definition mat-arith.hpp:84
const long begin_column
Definition mat-arith.hpp:86
const long end_column
Definition mat-arith.hpp:87
void operator*=(ElementType &c)
void operator+=(SubMatrix< MatType > src)
bool sameSize(const SubMatrix &b) const
void operator=(SubMatrix< MatType > src)
SubMatrix(MatType &m, long x, long y, long nrows, long ncols)
Definition mat-arith.hpp:98
void operator=(int x)
const long end_row
Definition mat-arith.hpp:85
MatType & matrix
Definition mat-arith.hpp:83
SubMatrix(MatType &m)
Definition mat-arith.hpp:89