22#ifndef symmetric_matrix_h
23#define symmetric_matrix_h
57 const AT* elePtr(
int i,
int j)
const {
58 return j > i ? ele+i*lda+j : ele+i+j*lda;
61 AT* elePtr(
int i,
int j) {
62 return j > i ? ele+i*lda+j : ele+i+j*lda;
69 static constexpr bool isVector {
false};
70 using value_type = AT;
77 explicit Matrix() : memory(), ele(nullptr) {
80 explicit Matrix(
int n_,
Noinit) : memory(n_*n_), ele((AT*)memory.get()), n(n_), lda(n_) { }
81 explicit Matrix(
int n_, Init ini=INIT,
const AT &a=AT()) : memory(n_*n_), ele((AT*)memory.get()), n(n_), lda(n_) { init(a); }
82 explicit Matrix(
int n_, Eye ini,
const AT &a=1) : memory(n_*n_), ele((AT*)memory.get()), n(n_), lda(n_) { init(ini,a); }
83 explicit Matrix(
int m_,
int n_, Noinit) : memory(n_*n_), ele((AT*)memory.get()), n(n_), lda(n_) { }
84 explicit Matrix(
int m_,
int n_, Init ini=INIT,
const AT &a=AT()) : memory(n_*n_), ele((AT*)memory.get()), n(n_), lda(n_) { init(a); }
85 explicit Matrix(
int m_,
int n_, Eye ini,
const AT &a=1) : memory(n_*n_), ele((AT*)memory.get()), n(n_), lda(n_) { init(ini,a); }
111 template<
class Type,
class Row,
class Col>
113 FMATVEC_ASSERT(A.
rows() == A.
cols(), AT);
124 explicit Matrix(
int n_, AT* ele_) : memory(), ele(ele_), n(n_), lda(n_) { }
133 ele = (AT*)memory.get();
139 Matrix<Symmetric,Ref,Ref,AT>& resize(
int n, Eye ini,
const AT &a=1) {
return resize(n,Noinit()).
init(ini,a); }
145 throw std::runtime_error(
"A symmetric matrix cannot have different dimensions for rows and columns.");
156 FMATVEC_ASSERT(n == A.
rows(), AT);
166 template<
class Type,
class Row,
class Col>
168 FMATVEC_ASSERT(A.
rows() == A.
cols(), AT);
169 FMATVEC_ASSERT(n == A.
rows(), AT);
193 template<
class Type,
class Row,
class Col>
195 FMATVEC_ASSERT(A.
rows() == A.
cols(), AT);
196 if(n!=A.
rows()) resize(A.
rows(),NONINIT);
210 FMATVEC_ASSERT(i>=0, AT);
211 FMATVEC_ASSERT(j>=0, AT);
212 FMATVEC_ASSERT(i<n, AT);
213 FMATVEC_ASSERT(j<n, AT);
222 FMATVEC_ASSERT(i>=0, AT);
223 FMATVEC_ASSERT(j>=0, AT);
224 FMATVEC_ASSERT(i<n, AT);
225 FMATVEC_ASSERT(j<n, AT);
230 AT& ei(
int i,
int j) {
234 const AT& ei(
int i,
int j)
const {
238 AT& ej(
int i,
int j) {
242 const AT& ej(
int i,
int j)
const {
246 AT& e(
int i,
int j) {
247 return j > i ? ej(i,j) : ei(i,j);
250 const AT& e(
int i,
int j)
const {
251 return j > i ? ej(i,j) : ei(i,j);
299 return CblasColMajor;
322 inline Matrix<Symmetric,Ref,Ref,AT>& init(Eye,
const AT &val=1);
323 inline Matrix<Symmetric,Ref,Ref,AT>& init(Noinit,
const AT &a=AT()) {
return *
this; }
327 inline const Matrix<General,Ref,Ref,AT>
operator()(
const Range<Var,Var> &I,
const Range<Var,Var> &J)
const;
331 inline const Matrix<Symmetric,Ref,Ref,AT>
operator()(
const Range<Var,Var> &I)
const;
333 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);
334 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);
336 template<
class Row>
inline void set(
const Range<Var,Var> &I,
const Matrix<Symmetric,Row,Row,AT> &A);
337 template<
class Row>
inline void add(
const Range<Var,Var> &I,
const Matrix<Symmetric,Row,Row,AT> &A);
339 inline const Matrix<General,Ref,Ref,AT>
operator()(
const Indices &I,
const Indices &J)
const;
341 inline const Matrix<Symmetric,Ref,Ref,AT>
operator()(
const Indices &I)
const;
343 inline void ref(Matrix<Symmetric,Ref,Ref,AT> &A,
const Range<Var,Var> &I);
349 explicit inline operator std::vector<std::vector<AT>>()
const;
356 explicit Matrix(
const std::vector<std::vector<AT>> &m);
373 inline int nonZeroElements()
const;
379 for(
int i=0; i<
rows(); i++)
380 for(
int j=i; j<
cols(); j++)
389 for(
int i=0; i<size(); i++) {
391 for(
int j=i+1; j<size(); j++) {
400 FMATVEC_ASSERT(I.
end()<n, AT);
401 FMATVEC_ASSERT(J.
end()<n, AT);
404 for(
int i=0; i<A.
rows(); i++)
405 for(
int j=0; j<A.
cols(); j++)
413 FMATVEC_ASSERT(I.
end()<n, AT);
417 for(
int i=0; i<A.
rows(); i++)
418 for(
int j=i; j<A.
cols(); j++)
424 template <
class AT>
template<
class Type,
class Row,
class Col>
425 inline void Matrix<Symmetric,Ref,Ref,AT>::set(
const Range<Var,Var> &I,
const Range<Var,Var> &J,
const Matrix<Type,Row,Col,AT> &A) {
428 else FMATVEC_ASSERT(J.
start()>=I.
end(), AT);
429 FMATVEC_ASSERT(I.
end()<
rows(), AT);
430 FMATVEC_ASSERT(J.
end()<
cols(), AT);
431 FMATVEC_ASSERT(I.
size()==A.
rows(), AT);
432 FMATVEC_ASSERT(J.
size()==A.
cols(), AT);
434 for(
int i=I.
start(), ii=0; i<=I.
end(); i++, ii++)
435 for(
int j=J.
start(), jj=0; j<=J.
end(); j++, jj++)
439 template <
class AT>
template<
class Type,
class Row,
class Col>
440 inline void Matrix<Symmetric,Ref,Ref,AT>::add(
const Range<Var,Var> &I,
const Range<Var,Var> &J,
const Matrix<Type,Row,Col,AT> &A) {
442 if(I.start()>=J.start()) FMATVEC_ASSERT(I.start()>=J.end(), AT)
443 else FMATVEC_ASSERT(J.start()>=I.end(), AT);
444 FMATVEC_ASSERT(I.end()<
rows(), AT);
445 FMATVEC_ASSERT(J.end()<
cols(), AT);
446 FMATVEC_ASSERT(I.size()==A.rows(), AT);
447 FMATVEC_ASSERT(J.size()==A.cols(), AT);
449 for(
int i=I.start(), ii=0; i<=I.end(); i++, ii++)
450 for(
int j=J.start(), jj=0; j<=J.end(); j++, jj++)
451 e(i,j) += A.e(ii,jj);
454 template <
class AT>
template<
class Row>
455 inline void Matrix<Symmetric,Ref,Ref,AT>::set(
const Range<Var,Var> &I,
const Matrix<Symmetric,Row,Row,AT> &A) {
457 FMATVEC_ASSERT(I.end()<size(), AT);
458 FMATVEC_ASSERT(I.size()==A.size(), AT);
460 for(
int i=I.start(), ii=0; i<=I.end(); i++, ii++)
461 for(
int j=i, jj=ii; j<=I.end(); j++, jj++)
465 template <
class AT>
template<
class Row>
466 inline void Matrix<Symmetric,Ref,Ref,AT>::add(
const Range<Var,Var> &I,
const Matrix<Symmetric,Row,Row,AT> &A) {
468 FMATVEC_ASSERT(I.end()<size(), AT);
469 FMATVEC_ASSERT(I.size()==A.size(), AT);
471 for(
int i=I.start(), ii=0; i<=I.end(); i++, ii++)
472 for(
int j=i, jj=ii; j<=I.end(); j++, jj++)
473 e(i,j) += A.e(ii,jj);
478 FMATVEC_ASSERT(I.max()<size(), AT);
479 FMATVEC_ASSERT(J.max()<size(), AT);
481 Matrix<General,Ref,Ref,AT> A(I.size(),J.size(),NONINIT);
483 for(
int i=0; i<A.rows(); i++)
484 for(
int j=0; j<A.cols(); j++)
485 A.e(i,j) = e(I[i],J[j]);
492 FMATVEC_ASSERT(I.max()<size(), AT);
494 Matrix<Symmetric,Ref,Ref,AT> A(I.size(),NONINIT);
496 for(
int i=0; i<A.rows(); i++)
497 for(
int j=0; j<A.cols(); j++)
498 A.e(i,j) = e(I[i],I[j]);
504 inline void Matrix<Symmetric,Ref,Ref,AT>::ref(Matrix<Symmetric,Ref,Ref,AT> &A,
const Range<Var,Var> &I) {
505 FMATVEC_ASSERT(I.end()<A.size(), AT);
508 ele = A.elePtr(I.start(),I.start());
514 std::vector<std::vector<AT>> ret(rows(),std::vector<AT>(cols()));
515 for(
int r=0; r<rows(); r++) {
516 for(
int c=r; c<cols(); c++) {
526 Matrix<Symmetric,Ref,Ref,AT>::Matrix(
const std::vector<std::vector<AT>> &m) : memory(m.size()*m.size()), ele((AT*)memory.get()), n(static_cast<int>(m.size())), lda(static_cast<int>(m.size())) {
527 for(
int r=0; r<
rows(); r++) {
528 if(
static_cast<int>(m[r].size())!=
cols())
529 throw std::runtime_error(
"The rows of the input have different length.");
530 for(
int c=r; c<
cols(); c++) {
532 if(c>r && abs(m[r][c]-m[c][r])>abs(m[r][c]*1e-13+1e-13))
533 throw std::runtime_error(
"The input is not symmetric.");
541 for (
int j = 0; j < n; j++) {
542 for (
int i = j+1; i < n; i++) {
543 if (fabs(e(i, j)) > 1e-16) {
554 inline Matrix<Symmetric,Ref,Ref,AT>& Matrix<Symmetric,Ref,Ref,AT>::copy(
const Matrix<Symmetric,Ref,Ref,AT> &A) {
555 for(
int i=0; i<n; i++)
556 for(
int j=i; j<n; j++)
561 template <
class AT>
template <
class Type,
class Row,
class Col>
562 inline Matrix<Symmetric,Ref,Ref,AT>& Matrix<Symmetric,Ref,Ref,AT>::copy(
const Matrix<Type,Row,Col,AT> &A) {
563 for(
int i=0; i<n; i++)
564 for(
int j=i; j<n; j++)
570 inline Matrix<Symmetric,Ref,Ref,AT>& Matrix<Symmetric,Ref,Ref,AT>::copy(
const Matrix<SymmetricSparse,Ref,Ref,AT> &A) {
571 for(
int i=0; i<n; i++) {
572 for(
int j=i; j<n; j++)
574 for(
int j=A.Ip()[i]; j<A.Ip()[i+1]; j++)
575 ej(i,A.Jp()[j]) = A()[j];
Shape class for general matrices.
Definition: types.h:116
This is a matrix class for general matrices.
Definition: general_matrix.h:42
int cols() const
Number of columns.
Definition: general_matrix.h:313
int rows() const
Number of rows.
Definition: general_matrix.h:307
This is a matrix class for sparse quadratic matrices.
Definition: symmetric_sparse_matrix.h:44
This is a matrix class for symmetric matrices.
Definition: symmetric_matrix.h:40
Matrix(const Matrix< Symmetric, Ref, Ref, AT > &A)
Copy Constructor.
Definition: symmetric_matrix.h:92
Matrix(const Matrix< Symmetric, Row, Row, AT > &A)
Copy Constructor.
Definition: symmetric_matrix.h:102
const AT & operator()(int i, int j) const
Element operator.
Definition: symmetric_matrix.h:221
const AT * operator()() const
Pointer operator.
Definition: symmetric_matrix.h:265
Matrix(const Matrix< Type, Row, Col, AT > &A)
Copy Constructor.
Definition: symmetric_matrix.h:112
int ldim() const
Leading dimension.
Definition: symmetric_matrix.h:289
Matrix< Symmetric, Ref, Ref, AT > & operator=(const Matrix< Symmetric, Ref, Ref, AT > &A)
Assignment operator.
Definition: symmetric_matrix.h:155
Matrix< Symmetric, Ref, Ref, AT > & operator=(const Matrix< Type, Row, Col, AT > &A)
Assignment operator.
Definition: symmetric_matrix.h:167
AT * operator()()
Pointer operator.
Definition: symmetric_matrix.h:259
int size() const
Size.
Definition: symmetric_matrix.h:271
Matrix< Symmetric, Ref, Ref, AT > & operator&=(Matrix< Symmetric, Ref, Ref, AT > &A)
Reference operator.
Definition: symmetric_matrix.h:179
~Matrix()=default
Destructor.
Matrix(int n_, AT *ele_)
Regular Constructor.
Definition: symmetric_matrix.h:124
CBLAS_UPLO blasUplo() const
Symmetry convention.
Definition: symmetric_matrix.h:309
CBLAS_ORDER blasOrder() const
Storage convention.
Definition: symmetric_matrix.h:298
int cols() const
Number of columns.
Definition: symmetric_matrix.h:283
int rows() const
Number of rows.
Definition: symmetric_matrix.h:277
AT & operator()(int i, int j)
Element operator.
Definition: symmetric_matrix.h:209
Matrix< Symmetric, Ref, Ref, AT > & init(const AT &val)
Initialization.
Definition: symmetric_matrix.h:377
Matrix()
Standard constructor.
Definition: symmetric_matrix.h:77
void resize(int n, int m)
Definition: symmetric_matrix.h:143
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
This is an index class for creating submatrices.
Definition: range.h:44
int end() const
Last element.
Definition: range.h:91
int size() const
Size.
Definition: range.h:97
int start() const
First element.
Definition: range.h:85
Shape class for symmetric matrices.
Definition: types.h:132
Namespace fmatvec.
Definition: _memory.cc:28