immutable_dense_matrix.cpp
1 #include <symengine/matrices/immutable_dense_matrix.h>
2 #include <symengine/matrices/zero_matrix.h>
3 #include <symengine/matrices/identity_matrix.h>
4 #include <symengine/matrices/diagonal_matrix.h>
5 
6 namespace SymEngine
7 {
8 
10 {
11  hash_t seed = SYMENGINE_IMMUTABLEDENSEMATRIX;
12  hash_combine(seed, m_);
13  hash_combine(seed, n_);
14  for (const auto &a : values_) {
15  hash_combine<Basic>(seed, *a);
16  }
17  return seed;
18 }
19 
20 bool ImmutableDenseMatrix::__eq__(const Basic &o) const
21 {
22  if (is_a<ImmutableDenseMatrix>(o)) {
23  const ImmutableDenseMatrix &other
24  = down_cast<const ImmutableDenseMatrix &>(o);
25  if (m_ != other.m_ || n_ != other.n_) {
26  return false;
27  }
28  return unified_eq(values_, other.values_);
29  }
30  return false;
31 }
32 
34 {
35  SYMENGINE_ASSERT(is_a<ImmutableDenseMatrix>(o));
36  const ImmutableDenseMatrix &other
37  = down_cast<const ImmutableDenseMatrix &>(o);
38  if (m_ < other.m_) {
39  return -1;
40  } else if (m_ > other.m_) {
41  return 1;
42  }
43  if (n_ < other.n_) {
44  return -1;
45  } else if (n_ > other.n_) {
46  return 1;
47  }
48  return unified_compare(values_, other.values_);
49 }
50 
51 bool is_identity_dense(size_t n, const vec_basic &container)
52 {
53  size_t i = 0;
54  for (size_t row = 0; row < n; row++) {
55  for (size_t col = 0; col < n; col++) {
56  auto &e = container[i];
57  if (col == row) {
58  if (!(is_a<Integer>(*e)
59  && down_cast<const Integer &>(*e).is_one())) {
60  return false;
61  }
62  } else {
63  if (!(is_a<Integer>(*e)
64  && down_cast<const Integer &>(*e).is_zero())) {
65  return false;
66  }
67  }
68  i++;
69  }
70  }
71  return true;
72 }
73 
74 bool is_diagonal_dense(size_t n, const vec_basic &container)
75 {
76  size_t i = 0;
77  for (size_t row = 0; row < n; row++) {
78  for (size_t col = 0; col < n; col++) {
79  if (col != row) {
80  auto &e = container[i];
81  if (!(is_a<Integer>(*e)
82  && down_cast<const Integer &>(*e).is_zero())) {
83  return false;
84  }
85  }
86  i++;
87  }
88  }
89  return true;
90 }
91 
92 vec_basic extract_diagonal(size_t n, const vec_basic &container)
93 {
94  vec_basic keep;
95  size_t i = 0;
96  for (size_t row = 0; row < n; row++) {
97  for (size_t col = 0; col < n; col++) {
98  if (col == row) {
99  auto &e = container[i];
100  keep.push_back(e);
101  }
102  i++;
103  }
104  }
105  return keep;
106 }
107 
108 bool ImmutableDenseMatrix::is_canonical(size_t m, size_t n,
109  const vec_basic &values) const
110 {
111  if (m < 1 || n < 1 || values.size() == 0) {
112  return false;
113  }
114  if (m * n != values.size()) {
115  return false;
116  }
117  if (is_zero_vec(values)) {
118  return false;
119  }
120  if (m == n && is_identity_dense(m, values)) {
121  return false;
122  }
123  if (m == n && is_diagonal_dense(m, values)) {
124  return false;
125  }
126  return true;
127 }
128 
129 RCP<const MatrixExpr> immutable_dense_matrix(size_t m, size_t n,
130  const vec_basic &container)
131 {
132  if (is_zero_vec(container)) {
133  return make_rcp<const ZeroMatrix>(integer(m), integer(n));
134  } else if (m == n && is_identity_dense(m, container)) {
135  return make_rcp<const IdentityMatrix>(integer(m));
136  } else if (m == n && is_diagonal_dense(m, container)) {
137  return make_rcp<const DiagonalMatrix>(extract_diagonal(m, container));
138  } else {
139  return make_rcp<const ImmutableDenseMatrix>(m, n, container);
140  }
141 }
142 
143 } // namespace SymEngine
The lowest unit of symbolic representation.
Definition: basic.h:97
int compare(const Basic &o) const override
bool __eq__(const Basic &o) const override
Test equality.
Main namespace for SymEngine package.
Definition: add.cpp:19
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
Definition: integer.h:197
void hash_combine(hash_t &seed, const T &v)
Definition: basic-inl.h:95
int unified_compare(const T &a, const T &b)
Definition: dict.h:205
T push_back(T... args)