Documentation of MARTY
A Modern ARtificial Theoretical phYsicist
adjacencyMatrix.h
Go to the documentation of this file.
1 // This file is part of MARTY.
2 //
3 // MARTY is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // MARTY 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
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with MARTY. If not, see <https://www.gnu.org/licenses/>.
15 
23 #pragma once
24 
25 #include <iostream>
26 #include <vector>
27 #include <cassert>
28 
29 namespace drawer {
30 
31 template<typename T1, typename T2 = T1>
32 class Base_iterable {
33 
34  public:
35 
36  using Type = T1;
37  using PType = T2;
38  using size_type = size_t;
39  using iterator = typename std::vector<Type>::iterator;
40  using const_iterator = typename std::vector<Type>::const_iterator;
41 
42  Base_iterable()
43  :elements(std::vector<Type>())
44  {}
45 
46  explicit
47  Base_iterable(size_t N)
48  :elements(std::vector<Type>(N, Type()))
49  {
50 
51  }
52 
53  explicit
54  Base_iterable(std::vector<Type> const& t_elements)
55  :elements(t_elements)
56  {}
57 
58  explicit
59  Base_iterable(std::vector<Type>&& t_elements)
60  :elements(std::move(t_elements))
61  {}
62 
63  virtual
64  ~Base_iterable()
65  {}
66 
67  Base_iterable(Base_iterable<T1, T2> const&) = default;
68  Base_iterable(Base_iterable<T1, T2>&&) = default;
69  Base_iterable& operator=(Base_iterable<T1, T2> const&) = default;
70  Base_iterable& operator=(Base_iterable<T1, T2>&&) = default;
71 
72  void clear() {
73  elements.clear();
74  }
75 
76  bool empty() const {
77  return elements.empty();
78  }
79 
80  size_t size() const {
81  return elements.size();
82  }
83 
84  iterator begin() {
85  return elements.begin();
86  }
87 
88  const_iterator begin() const {
89  return elements.begin();
90  }
91 
92  iterator end() {
93  return elements.end();
94  }
95 
96  const_iterator end() const {
97  return elements.end();
98  }
99 
100  Type& operator[](size_t pos) {
101  return elements[pos];
102  }
103 
104  Type operator[](size_t pos) const {
105  return elements[pos];
106  }
107 
108  protected:
109 
110  std::vector<Type> elements;
111 };
112 
113 template<typename T1, typename T2 = T1>
114 class Vector: public Base_iterable<T1, T2> {
115 
116  public:
117 
118  using Type = typename Base_iterable<T1, T2>::Type;
119  using size_type = typename Base_iterable<T1, T2>::size_type;
120  using iterator = typename Base_iterable<T1, T2>::iterator;
121  using const_iterator = typename Base_iterable<T1, T2>::const_iterator;
122 
123  Vector(size_t N)
124  :Base_iterable<T1, T2>(N)
125  {}
126 
127  Vector(std::vector<Type> const& t_containor)
128  :Base_iterable<T1, T2>(t_containor)
129  {}
130 
131  Vector(std::vector<Type>&& t_containor)
132  :Base_iterable<T1, T2>(std::move(t_containor))
133  {}
134 
135  ~Vector()
136  {}
137 
138  Vector(Vector<T1, T2> const&) = default;
139  Vector(Vector<T1, T2>&&) = default;
140  Vector& operator=(Vector<T1, T2> const&) = default;
141  Vector& operator=(Vector<T1, T2>&&) = default;
142 
143  int find(T1 const el) const {
144  for (auto iter = Base_iterable<T1, T2>::begin();
145  iter != Base_iterable<T1, T2>::end();
146  ++iter)
147  if (*iter == el)
148  return std::distance(iter, Base_iterable<T1, T2>::begin());
149  return -1;
150  }
151 
152  Type& operator()(size_t i) {
153  return this->elements[i];
154  }
155 
156  Type operator()(size_t i) const {
157  return this->elements[i];
158  }
159 
160  template<class U1, class U2>
161  friend
162  std::ostream& operator<<(std::ostream& out,
163  Vector<U1, U2> const& vec);
164 };
165 
166 template<class U1, class U2>
167 std::ostream& operator<<(std::ostream& out,
168  Vector<U1, U2> const& vec)
169 {
170  for (const auto& el : vec)
171  if constexpr (std::is_same<U1, U2>::value)
172  out << el << '\n';
173  else
174  out << U2(el) << '\n';
175  return out;
176 }
177 
178 template<typename T1, typename T2 = T1>
179 class Matrix: public Base_iterable<T1, T2> {
180 
181  public:
182 
183  using Type = typename Base_iterable<T1, T2>::Type;
184  using size_type = typename Base_iterable<T1, T2>::size_type;
185  using iterator = typename Base_iterable<T1, T2>::iterator;
186  using const_iterator = typename Base_iterable<T1, T2>::const_iterator;
187 
188  Matrix(size_t M)
189  :Base_iterable<T1, T2>(M * M),
190  N(M)
191  {}
192 
193  Matrix(std::vector<Type> const& t_containor)
194  :Base_iterable<T1, T2>(t_containor),
195  N(t_containor.size())
196  {}
197 
198  Matrix(std::vector<Type>&& t_containor)
199  :Base_iterable<T1, T2>(std::move(t_containor)),
200  N(t_containor.size())
201  {}
202 
203  ~Matrix()
204  {}
205 
206  Matrix(Matrix<T1, T2> const&) = default;
207  Matrix(Matrix<T1, T2>&&) = default;
208  Matrix& operator=(Matrix<T1, T2> const&) = default;
209  Matrix& operator=(Matrix<T1, T2>&&) = default;
210 
211  void clear() {
212  Base_iterable<T1, T2>::clear();
213  N = 0;
214  }
215 
216  size_type size() const {
217  return N;
218  }
219 
220  Type& operator()(size_t i, size_t j) {
221  return this->elements[this->size()*i + j];
222  }
223 
224  Type operator()(size_t i, size_t j) const {
225  return this->elements[this->size()*i + j];
226  }
227 
228  template<class U1, typename U2>
229  friend
230  std::ostream& operator<<(std::ostream& out,
231  Matrix<U1, U2> const& mat);
232 
233  private:
234 
235  size_type N;
236 };
237 
238 template<class U1, typename U2>
239 std::ostream& operator<<(std::ostream& out,
240  Matrix<U1, U2> const& mat)
241 {
242  for (size_t i = 0; i != mat.size(); ++i) {
243  for (size_t j = 0; j != mat.size(); ++j)
244  if constexpr (std::is_same<U1, U2>::value)
245  out << mat(i, j) << " ";
246  else
247  out << U2(mat(i, j)) << " ";
248  out << '\n';
249  }
250  return out;
251 }
252 
253 template<class T1, class T2, class T3>
254 Vector<T1, T2> operator+(Vector<T1, T2> const& vec,
255  T3 value)
256 {
257  Vector<T1, T2> copy(vec);
258  for (auto icopy = copy.begin(), ivec = vec.begin();
259  icopy != copy.end();
260  ++icopy, ++ivec)
261  icopy *= value;
262 
263  return copy;
264 }
265 
266 template<class T1, class T2, class T3>
267 Vector<T1, T2> operator+(T3 value,
268  Vector<T1, T2> const& vec)
269 {
270  Vector<T1, T2> copy(vec);
271  for (auto icopy = copy.begin(), ivec = vec.begin();
272  icopy != copy.end();
273  ++icopy, ++ivec)
274  icopy *= value;
275 
276  return copy;
277 }
278 
279 template<class T1, class T2, class T3>
280 Vector<T1, T2> operator*(Vector<T1, T2> const& vec,
281  T3 value)
282 {
283  Vector<T1, T2> copy(vec);
284  for (auto icopy = copy.begin(), ivec = vec.begin();
285  icopy != copy.end();
286  ++icopy, ++ivec)
287  icopy *= value;
288 
289  return copy;
290 }
291 
292 template<class T1, class T2, class T3>
293 Vector<T1, T2> operator*(T3 value,
294  Vector<T1, T2> const& vec)
295 {
296  Vector<T1, T2> copy(vec);
297  for (auto icopy = copy.begin(), ivec = vec.begin();
298  icopy != copy.end();
299  ++icopy, ++ivec)
300  icopy *= value;
301 
302  return copy;
303 }
304 
305 
306 template<class T1, class T2, class T3>
307 Matrix<T1, T2> operator+(Matrix<T1, T2> const& vec,
308  T3 value)
309 {
310  Matrix<T1, T2> copy(vec);
311  for (auto icopy = copy.begin(), ivec = vec.begin();
312  icopy != copy.end();
313  ++icopy, ++ivec)
314  icopy *= value;
315 
316  return copy;
317 }
318 
319 template<class T1, class T2, class T3>
320 Matrix<T1, T2> operator+(T3 value,
321  Matrix<T1, T2> const& vec)
322 {
323  Matrix<T1, T2> copy(vec);
324  for (auto icopy = copy.begin(), ivec = vec.begin();
325  icopy != copy.end();
326  ++icopy, ++ivec)
327  icopy *= value;
328 
329  return copy;
330 }
331 
332 template<class T1, class T2, class T3>
333 Matrix<T1, T2> operator*(Matrix<T1, T2> const& vec,
334  T3 value)
335 {
336  Matrix<T1, T2> copy(vec);
337  for (auto icopy = copy.begin(), ivec = vec.begin();
338  icopy != copy.end();
339  ++icopy, ++ivec)
340  icopy *= value;
341 
342  return copy;
343 }
344 
345 template<class T1, class T2, class T3>
346 Matrix<T1, T2> operator*(T3 value,
347  Matrix<T1, T2> const& vec)
348 {
349  Matrix<T1, T2> copy(vec);
350  for (auto icopy = copy.begin(), ivec = vec.begin();
351  icopy != copy.end();
352  ++icopy, ++ivec)
353  icopy *= value;
354 
355  return copy;
356 }
357 
358 template<class T1, class T2, class T3, class T4>
359 T1 operator*(Vector<T1, T2> const& left,
360  Vector<T3, T4> const& right)
361 {
362  assert(left.size() == right.size());
363  T1 init(0);
364  for (auto ileft = left.begin(), iright = right.begin();
365  ileft != left.end();
366  ++ileft, ++iright)
367  init += (*ileft) * (*iright);
368 
369  return init;
370 }
371 
372 template<class T1, class T2, class T3, class T4>
373 Vector<T1, T2> operator*(Vector<T1, T2> const& left,
374  Matrix<T3, T4> const& right)
375 {
376  assert(left.size() == right.size());
377  Vector<T1, T2> init(left.size());
378  auto imat = right.begin();
379 
380  for (auto ivec = left.begin(); ivec != left.end(); ++ivec)
381  for (auto ires = init.begin(); ires != init.end(); ++ires, ++imat)
382  *ires += (*imat) * (*ivec);
383 
384  return init;
385 }
386 
387 template<class T1, class T2, class T3, class T4>
388 Vector<T1, T2> operator*(Matrix<T1, T2> const& left,
389  Vector<T3, T4> const& right)
390 {
391  assert(left.size() == right.size());
392  Vector<T1, T2> init(right.size());
393  auto imat = left.begin();
394 
395  for (auto ires = init.begin(); ires != init.end(); ++ires)
396  for (auto ivec = right.begin(); ivec != right.end(); ++ivec, ++imat)
397  *ires += (*imat) * (*ivec);
398 
399  return init;
400 }
401 
402 template<class U1, class U2>
403 Matrix<U1, U2> operator*(Matrix<U1, U2> const& A,
404  Matrix<U1, U2> const& B)
405 {
406  assert(A.size() == B.size());
407  const size_t s = A.size();
408  Matrix<U1, U2> C(s);
409  for (size_t i = 0; i != s; ++i)
410  for (size_t j = 0; j != s; ++j)
411  for (size_t k = 0; k != s; ++k)
412  C(i, j) += A(i, k) * B(k, j);
413 
414  return C;
415 }
416 
417 template<class U1, class U2>
418 Matrix<U1, U2>& operator*=(Matrix<U1, U2>& A,
419  Matrix<U1, U2> const& B)
420 {
421  return A = std::move(A * B);
422 }
423 
424 template<class U1, class U2, class Int_type>
425 Matrix<U1, U2> pow(Matrix<U1, U2> const& mat, Int_type value)
426 {
427  assert(value > 0);
428  Matrix<U1, U2> res = mat;
429  for (size_t i = 1; i < value; ++i)
430  res = res * mat;
431  return res;
432 }
433 
434 
435 }
Type
Definition: drawer.h:29
std::ostream & operator<<(std::ostream &fout, csl::Type type)
Expr operator+(const Expr &a, const Expr &b)
Expr operator*(const Expr &a, const Expr &b)