fmatvec  0.0.0
var_fixed_general_matrix.h
1/* Copyright (C) 2003-2005 Martin Förg
2
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 *
17 * Contact:
18 * martin.o.foerg@googlemail.com
19 *
20 */
21
22#ifndef var_fixed_general_matrix_h
23#define var_fixed_general_matrix_h
24
25#include "types.h"
26#include "range.h"
27#include <vector>
28#include <cstdlib>
29#include <stdexcept>
30
31namespace fmatvec {
32
41 template <int N, class AT> class Matrix<General,Var,Fixed<N>,AT> {
42
43 public:
44 static constexpr bool isVector {false};
45 using value_type = AT;
46 using shape_type = General;
47
49
50 protected:
51
52 int M{0};
53
54 AT *ele;
55
56 template <class Type, class Row, class Col> inline Matrix<General,Var,Fixed<N>,AT>& copy(const Matrix<Type,Row,Col,AT> &A);
57
59
60 public:
61
62 explicit Matrix() : ele(nullptr) { }
63
64 explicit Matrix(int m, Noinit) : M(m), ele(new AT[M*N]) { }
65 explicit Matrix(int m, Init ini=INIT, const AT &a=AT()) : M(m), ele(new AT[M*N]) { init(a); }
66#ifndef SWIG
67 explicit Matrix(int m, Eye ini, const AT &a=1) : M(m), ele(new AT[M*N]) { init(ini,a); }
68#endif
69 explicit Matrix(int m, int n, Noinit) : M(m), ele(new AT[M*N]) { FMATVEC_ASSERT(n==N, AT); }
70 explicit Matrix(int m, int n, Init ini=INIT, const AT &a=AT()) : M(m), ele(new AT[M*N]) { FMATVEC_ASSERT(n==N, AT); init(a); }
71#ifndef SWIG
72 explicit Matrix(int m, int n, Eye ini, const AT &a=1) : M(m), ele(new AT[M*N]) { FMATVEC_ASSERT(n==N, AT); init(ini,a); }
73#endif
74
75 // move
76 Matrix(Matrix<General,Var,Fixed<N>,AT> &&src) noexcept {
77 M=src.M;
78 src.M=0;
79 ele=src.ele;
80 src.ele=nullptr;
81 }
82 Matrix<General,Var,Fixed<N>,AT>& operator=(Matrix<General,Var,Fixed<N>,AT> &&src) noexcept {
83 FMATVEC_ASSERT(M == src.rows(), AT);
84 src.M=0;
85 delete[]ele;
86 ele=src.ele;
87 src.ele=nullptr;
88 return *this;
89 }
90
96 Matrix(const Matrix<General,Var,Fixed<N>,AT> &A) : M(A.M), ele(new AT[M*N]) {
97 copy(A);
98 }
99
105 template<class Row, class Col>
106 Matrix(const Matrix<General,Row,Col,AT> &A) : M(A.rows()), ele(new AT[M*N]) {
107 FMATVEC_ASSERT(A.cols() == N, AT);
108 copy(A);
109 }
110
116 template<class Type, class Row, class Col>
117 explicit Matrix(const Matrix<Type,Row,Col,AT> &A) : M(A.rows()), ele(new AT[M*N]) {
118 FMATVEC_ASSERT(A.cols() == N, AT);
119 copy(A);
120 }
121
134 Matrix(const std::string &strs);
135 Matrix(const char *strs);
136
137 using iterator = AT *;
138 using const_iterator = const AT *;
139 iterator begin() { return &ele[0]; }
140 iterator end() { return &ele[M*N]; }
141 const_iterator begin() const { return &ele[0]; }
142 const_iterator end() const { return &ele[M*N]; }
143
147 delete[] ele;
148 }
149
150 Matrix<General,Var,Fixed<N>,AT>& resize(int m, Noinit) {
151 delete[] ele;
152 M = m;
153 ele = new AT[M*N];
154 return *this;
155 }
156
157 Matrix<General,Var,Fixed<N>,AT>& resize(int m, Init ini=INIT, const AT &a=AT()) { return resize(m,Noinit()).init(a); }
158
159#ifndef SWIG
160 Matrix<General,Var,Fixed<N>,AT>& resize(int m, Eye ini, const AT &a=1) { return resize(m,Noinit()).init(ini,a); }
161#endif
162
165 void resize(int m, int n) {
166 if(n!=N)
167 throw std::runtime_error("A var-fixed matrix can only be resized in the first dimension.");
168 resize(m);
169 }
170
178 FMATVEC_ASSERT(M == A.rows(), AT);
179 return copy(A);
180 }
181
188 template <class Type, class Row, class Col>
189 inline Matrix<General,Var,Fixed<N>,AT>& operator=(const Matrix<Type,Row,Col,AT> &A) {
190 FMATVEC_ASSERT(N == A.cols(), AT);
191 FMATVEC_ASSERT(M == A.rows(), AT);
192 return copy(A);
193 }
194
201 template <class Type, class Row, class Col>
202 inline Matrix<General,Var,Fixed<N>,AT>& operator<<=(const Matrix<Type,Row,Col,AT> &A) {
203 FMATVEC_ASSERT(N == A.cols(), AT);
204 if(M!=A.rows()) resize(A.rows(),NONINIT);
205 return copy(A);
206 }
207 // move
208 inline Matrix<General,Var,Fixed<N>,AT>& operator<<=(Matrix<General,Var,Fixed<N>,AT> &&src) {
209 FMATVEC_ASSERT(N == src.cols(), AT);
210 M=src.M;
211 src.M=0;
212 delete[]ele;
213 ele=src.ele;
214 src.ele=nullptr;
215 return *this;
216 }
217
227 AT& operator()(int i, int j) {
228 FMATVEC_ASSERT(i>=0, AT);
229 FMATVEC_ASSERT(j>=0, AT);
230 FMATVEC_ASSERT(i<M, AT);
231 FMATVEC_ASSERT(j<N, AT);
232
233 return e(i,j);
234 }
235
240 const AT& operator()(int i, int j) const {
241 FMATVEC_ASSERT(i>=0, AT);
242 FMATVEC_ASSERT(j>=0, AT);
243 FMATVEC_ASSERT(i<M, AT);
244 FMATVEC_ASSERT(j<N, AT);
245
246 return e(i,j);
247 }
248
249 AT& e(int i, int j) {
250 return ele[i*N+j];
251 }
252
257 const AT& e(int i, int j) const {
258 return ele[i*N+j];
259 }
260
261 AT& e(int i) {
262 return ele[i];
263 }
264
269 const AT& e(int i) const {
270 return ele[i];
271 }
272
278 AT* operator()() {return ele;}
279
284 const AT* operator()() const {return ele;}
285
290 constexpr int rows() const {return M;}
291
296 constexpr int cols() const {return N;}
297
302 int ldim() const {return N;}
303
310 CBLAS_TRANSPOSE blasTrans() const {
311 return CblasNoTrans;
312 }
313
321 CBLAS_ORDER blasOrder() const {
322 return CblasRowMajor;
323 }
324
325#ifndef SWIG
326 inline const Matrix<General,Var,Var,AT> operator()(const Range<Var,Var> &I, const Range<Var,Var> &J) const;
327#endif
328
329 inline const RowVector<Fixed<N>,AT> row(int i) const;
330 inline const Vector<Var,AT> col(int j) const;
331
339 inline Matrix<General,Var,Fixed<N>,AT>& init(const AT &val=AT());
340 inline Matrix<General,Var,Fixed<N>,AT>& init(Init, const AT &a=AT()) { return init(a); }
341#ifndef SWIG
342 inline Matrix<General,Var,Fixed<N>,AT>& init(Eye, const AT &val=1);
343#endif
344 inline Matrix<General,Var,Fixed<N>,AT>& init(Noinit, const AT &a=AT()) { return *this; }
345
350 explicit inline operator std::vector<std::vector<AT>>() const;
351
357 explicit inline Matrix(const std::vector<std::vector<AT>> &m);
358
359// /*! \brief Cast to AT.
360// *
361// * \return The AT representation of the matrix
362// * */
363// explicit operator AT() const {
364// FMATVEC_ASSERT(M==1, AT);
365// FMATVEC_ASSERT(N==1, AT);
366// return ele[0];
367// }
368//
369// /*! \brief AT Constructor.
370// * Constructs and initializes a matrix with a AT object.
371// * \param x The AT the matrix will be initialized with.
372// * */
373// explicit Matrix(const AT &x) : M(1), ele(new AT[1]) {
374// FMATVEC_ASSERT(N==1, AT);
375// ele[0] = x;
376// }
377
378 inline const Matrix<General,Fixed<N>,Var,AT> T() const;
379
380 template<class Row> inline void set(int j, const Vector<Row,AT> &x);
381
382 template<class Col> inline void set(int i, const RowVector<Col,AT> &x);
383
384 template<class Type, class Row, class Col> inline void set(const Range<Var,Var> &I, const Range<Var,Var> &J, const Matrix<Type,Row,Col,AT> &A);
385
386 template<class Row> inline void add(int j, const Vector<Row,AT> &x);
387
388 template<class Col> inline void add(int i, const RowVector<Col,AT> &x);
389
390 template<class Type, class Row, class Col> inline void add(const Range<Var,Var> &I, const Range<Var,Var> &J, const Matrix<Type,Row,Col,AT> &A);
391 };
392
393 template <int N, class AT>
394 Matrix<General,Var,Fixed<N>,AT>::Matrix(const std::string &strs) : ele(0) {
395 std::istringstream iss(strs);
396 iss>>*this;
397
398 // check end of stream
399 iss>>std::ws;
400 if(!iss.eof())
401 throw std::runtime_error("Input not fully read.");
402 }
403 template <int N, class AT> Matrix<General,Var,Fixed<N>,AT>::Matrix(const char * strs) :
404 Matrix<General,Var,Fixed<N>,AT>::Matrix(std::string(strs)) {}
405
406 template <int N, class AT>
407 inline Matrix<General,Var,Fixed<N>,AT>& Matrix<General,Var,Fixed<N>,AT>::init(const AT &val) {
408 #if __GNUC__ >= 10
409 // gcc >= 11 triggers a false positive on this code due to init(val) calls from ctor setting M=0
410 #pragma GCC diagnostic push
411 #pragma GCC diagnostic ignored "-Warray-bounds"
412 #pragma GCC diagnostic ignored "-Wstringop-overflow"
413 #endif
414 for(int i=0; i<M*N; i++)
415 e(i) = val;
416 #if __GNUC__ >= 10
417 #pragma GCC diagnostic pop
418 #endif
419 return *this;
420 }
421
422 template <int N, class AT>
423 inline Matrix<General,Var,Fixed<N>,AT>& Matrix<General,Var,Fixed<N>,AT>::init(Eye eye, const AT &val) {
424 for(int i=0; i<M; i++)
425 for(int j=0; j<N; j++)
426 e(i,j) = (i==j) ? val : 0;
427 return *this;
428 }
429
430 template <int N, class AT>
431 inline const Matrix<General,Var,Var,AT> Matrix<General,Var,Fixed<N>,AT>::operator()(const Range<Var,Var> &I, const Range<Var,Var> &J) const {
432 FMATVEC_ASSERT(I.end()<M, AT);
433 FMATVEC_ASSERT(J.end()<N, AT);
434 Matrix<General,Var,Var,AT> A(I.size(),J.size(),NONINIT);
435
436 for(int i=0; i<A.rows(); i++)
437 for(int j=0; j<A.cols(); j++)
438 A.e(i,j) = e(I.start()+i,J.start()+j);
439
440 return A;
441 }
442
443 template <int N, class AT>
444 inline const RowVector<Fixed<N>,AT> Matrix<General,Var,Fixed<N>,AT>::row(int i) const {
445
446 FMATVEC_ASSERT(i>=0, AT);
447 FMATVEC_ASSERT(i<M, AT);
448
449 RowVector<Fixed<N>,AT> x(NONINIT);
450
451 for(int j=0; j<N; j++)
452 x.e(j) = e(i,j);
453
454 return x;
455
456 }
457
458 template <int N, class AT>
459 inline const Vector<Var,AT> Matrix<General,Var,Fixed<N>,AT>::col(int j) const {
460
461 FMATVEC_ASSERT(j>=0, AT);
462 FMATVEC_ASSERT(j<N, AT);
463
464 Vector<Var,AT> x(M,NONINIT);
465
466 for(int i=0; i<M; i++)
467 x.e(i) = e(i,j);
468
469 return x;
470
471 }
472
473 template <int N, class AT>
474 inline const Matrix<General,Fixed<N>,Var,AT> Matrix<General,Var,Fixed<N>,AT>::T() const {
475 Matrix<General,Fixed<N>,Var,AT> A(rows(),NONINIT);
476 for(int i=0; i<N; i++)
477 for(int j=0; j<M; j++)
478 A.e(i,j) = e(j,i);
479 return A;
480 }
481
482 template <int N, class AT> template <class Row>
483 inline void Matrix<General,Var,Fixed<N>,AT>::set(int j, const Vector<Row,AT> &x) {
484 FMATVEC_ASSERT(j<cols(), AT);
485 FMATVEC_ASSERT(rows()==x.size(), AT);
486 for(int i=0; i<rows(); i++)
487 e(i,j) = x.e(i);
488 }
489
490 template <int N, class AT> template <class Col>
491 inline void Matrix<General,Var,Fixed<N>,AT>::set(int i, const RowVector<Col,AT> &x) {
492 FMATVEC_ASSERT(i<rows(), AT);
493 FMATVEC_ASSERT(cols()==x.size(), AT);
494 for(int j=0; j<cols(); j++)
495 e(i,j) = x.e(j);
496 }
497
498 template <int N, class AT> template<class Type, class Row, class Col>
499 inline void Matrix<General,Var,Fixed<N>,AT>::set(const Range<Var,Var> &I, const Range<Var,Var> &J, const Matrix<Type,Row,Col,AT> &A) {
500
501 FMATVEC_ASSERT(I.end()<rows(), AT);
502 FMATVEC_ASSERT(J.end()<cols(), AT);
503 FMATVEC_ASSERT(I.size()==A.rows(), AT);
504 FMATVEC_ASSERT(J.size()==A.cols(), AT);
505
506 for(int i=I.start(), ii=0; i<=I.end(); i++, ii++)
507 for(int j=J.start(), jj=0; j<=J.end(); j++, jj++)
508 e(i,j) = A.e(ii,jj);
509 }
510
511 template <int N, class AT> template <class Row>
512 inline void Matrix<General,Var,Fixed<N>,AT>::add(int j, const Vector<Row,AT> &x) {
513 FMATVEC_ASSERT(j<cols(), AT);
514 FMATVEC_ASSERT(rows()==x.size(), AT);
515 for(int i=0; i<rows(); i++)
516 e(i,j) += x.e(i);
517 }
518
519 template <int N, class AT> template <class Col>
520 inline void Matrix<General,Var,Fixed<N>,AT>::add(int i, const RowVector<Col,AT> &x) {
521 FMATVEC_ASSERT(i<rows(), AT);
522 FMATVEC_ASSERT(cols()==x.size(), AT);
523 for(int j=0; j<cols(); j++)
524 e(i,j) += x.e(j);
525 }
526
527 template <int N, class AT> template<class Type, class Row, class Col>
528 inline void Matrix<General,Var,Fixed<N>,AT>::add(const Range<Var,Var> &I, const Range<Var,Var> &J, const Matrix<Type,Row,Col,AT> &A) {
529
530 FMATVEC_ASSERT(I.end()<rows(), AT);
531 FMATVEC_ASSERT(J.end()<cols(), AT);
532 FMATVEC_ASSERT(I.size()==A.rows(), AT);
533 FMATVEC_ASSERT(J.size()==A.cols(), AT);
534
535 for(int i=I.start(), ii=0; i<=I.end(); i++, ii++)
536 for(int j=J.start(), jj=0; j<=J.end(); j++, jj++)
537 e(i,j) += A.e(ii,jj);
538 }
539
540 template <int N, class AT>
541 inline Matrix<General,Var,Fixed<N>,AT>::operator std::vector<std::vector<AT>>() const {
542 std::vector<std::vector<AT>> ret(rows(),std::vector<AT>(cols()));
543 for(int r=0; r<rows(); r++) {
544 for(int c=0; c<cols(); c++)
545 ret[r][c]=e(r,c);
546 }
547 return ret;
548 }
549
550 template <int N, class AT>
551 inline Matrix<General,Var,Fixed<N>,AT>::Matrix(const std::vector<std::vector<AT>> &m) : M(static_cast<int>(m.size())), ele(new AT[M*N]) {
552 if((m.empty()?0:m[0].size()) != N)
553 throw std::runtime_error("The input has "+std::to_string(m.empty()?0:m[0].size())+" columns but "+std::to_string(N)+" columns are required.");
554 for(int r=0; r<rows(); r++) {
555 if(static_cast<int>(m[r].size())!=cols())
556 throw std::runtime_error("The rows of the input have different length.");
557 for(int c=0; c<cols(); c++)
558 e(r,c)=m[r][c];
559 }
560 }
561
563
564 template <int N, class AT> template <class Type, class Row, class Col>
566 for(int i=0; i<M; i++)
567 for(int j=0; j<N; j++)
568 e(i,j) = A.e(i,j);
569 return *this;
570 }
571
573
574}
575
576#endif
Definition: types.h:94
Definition: types.h:108
Shape class for general matrices.
Definition: types.h:116
Definition: types.h:93
constexpr int cols() const
Number of columns.
Definition: var_fixed_general_matrix.h:296
void resize(int m, int n)
Definition: var_fixed_general_matrix.h:165
constexpr int rows() const
Number of rows.
Definition: var_fixed_general_matrix.h:290
Matrix(const Matrix< General, Var, Fixed< N >, AT > &A)
Copy Constructor.
Definition: var_fixed_general_matrix.h:96
Matrix(const Matrix< General, Row, Col, AT > &A)
Copy Constructor.
Definition: var_fixed_general_matrix.h:106
const AT & operator()(int i, int j) const
Element operator.
Definition: var_fixed_general_matrix.h:240
const AT & e(int i) const
Element operator.
Definition: var_fixed_general_matrix.h:269
CBLAS_TRANSPOSE blasTrans() const
Transposed status.
Definition: var_fixed_general_matrix.h:310
AT * operator()()
Pointer operator.
Definition: var_fixed_general_matrix.h:278
AT & operator()(int i, int j)
Element operator.
Definition: var_fixed_general_matrix.h:227
CBLAS_ORDER blasOrder() const
Storage convention.
Definition: var_fixed_general_matrix.h:321
Matrix< General, Var, Fixed< N >, AT > & operator=(const Matrix< General, Var, Fixed< N >, AT > &A)
Assignment operator.
Definition: var_fixed_general_matrix.h:177
~Matrix()
Destructor.
Definition: var_fixed_general_matrix.h:146
int ldim() const
Leading dimension.
Definition: var_fixed_general_matrix.h:302
Matrix(const Matrix< Type, Row, Col, AT > &A)
Copy Constructor.
Definition: var_fixed_general_matrix.h:117
const AT & e(int i, int j) const
Element operator.
Definition: var_fixed_general_matrix.h:257
const AT * operator()() const
Pointer operator.
Definition: var_fixed_general_matrix.h:284
This is a matrix class for general matrices.
Definition: var_general_matrix.h:41
This is the basic matrix class for arbitrary matrices.
Definition: matrix.h:52
int rows() const
Number of rows.
int cols() const
Number of columns.
AT & operator()(int i, int j)
Standard constructor.
Definition: matrix.h:84
Definition: types.h:92
This is an index class for creating submatrices.
Definition: range.h:44
Definition: matrix.h:170
Definition: types.h:105
This is a vector class of general shape in dense storage format.
Definition: var_vector.h:39
Namespace fmatvec.
Definition: _memory.cc:28