barry: Your go-to motif accountant  0.0-1
Full enumeration of sample space and fast count of sufficient statistics for binary arrays
barraydense-meat.hpp
Go to the documentation of this file.
1 // #include <stdexcept>
2 // #include "barraydense-bones.hpp"
3 
4 #ifndef BARRY_BARRAYDENSE_MEAT_HPP
5 #define BARRY_BARRAYDENSE_MEAT_HPP
6 
7 template<typename Cell_Type, typename Data_Type>
8 class BArrayDenseRow;
9 
10 template<typename Cell_Type, typename Data_Type>
12 
13 template<typename Cell_Type, typename Data_Type>
14 class BArrayDenseCol;
15 
16 template<typename Cell_Type, typename Data_Type>
18 
19 template<typename Cell_Type, typename Data_Type>
20 class BArrayDenseCell;
21 
22 
23 #define ROW(a) this->el_ij[a]
24 #define COL(a) this->el_ji[a]
25 #define POS(a,b) (b)*N + (a)
26 #define POS_N(a,b,c) (b)*(c) + (a)
27 
28 template<typename Cell_Type, typename Data_Type>
29 Cell_Type BArrayDense<Cell_Type,Data_Type>::Cell_default = static_cast< Cell_Type >(1.0);
30 
31 #define ZERO_CELL static_cast<Cell_Type>(0.0)
32 
33 // Edgelist with data
34 template<typename Cell_Type, typename Data_Type>
36  size_t N_,
37  size_t M_,
38  const std::vector< size_t > & source,
39  const std::vector< size_t > & target,
40  const std::vector< Cell_Type > & value,
41  bool add
42 ) : N(N_), M(M_), el(N_ * M_, ZERO_CELL), el_rowsums(N_, ZERO_CELL), el_colsums(M_, ZERO_CELL) {
43 
44  if (source.size() != target.size())
45  throw std::length_error("-source- and -target- don't match on length.");
46  if (source.size() != value.size())
47  throw std::length_error("-sorce- and -value- don't match on length.");
48 
49  // Writing the data
50  for (size_t i = 0u; i < source.size(); ++i)
51  {
52 
53  // Checking range
54  bool empty = is_empty(source[i], target[i], true);
55  if (add && !empty)
56  {
57 
58  Cell_Type tmp = el[POS(source[i], target[i])];
59 
60  el_rowsums[source[i]] += (value[i] - tmp);
61  el_colsums[target[i]] += (value[i] - tmp);
62 
63  el[POS(source[i], target[i])] += value[i];
64 
65  continue;
66 
67  }
68 
69  if (!empty)
70  throw std::logic_error("The value already exists. Use 'add = true'.");
71 
72  el[POS(source[i], target[i])] = value[i];
73 
74  el_rowsums[source[i]] += value[i];
75  el_colsums[target[i]] += value[i];
76 
77 
78  }
79 
80  return;
81 
82 }
83 
84 // Edgelist without data
85 template<typename Cell_Type, typename Data_Type>
87  size_t N_, size_t M_,
88  const std::vector< size_t > & source,
89  const std::vector< size_t > & target,
90  bool add
91 ) : N(N_), M(M_), el(N_ * M_, ZERO_CELL), el_rowsums(N_, ZERO_CELL), el_colsums(M_, ZERO_CELL) {
92 
93  std::vector< Cell_Type > value(source.size(), static_cast<Cell_Type>(1.0));
94 
95  if (source.size() != target.size())
96  throw std::length_error("-source- and -target- don't match on length.");
97  if (source.size() != value.size())
98  throw std::length_error("-sorce- and -value- don't match on length.");
99 
100 
101  // Writing the data
102  for (size_t i = 0u; i < source.size(); ++i)
103  {
104 
105  // Checking range
106  bool empty = is_empty(source[i], target[i], true);
107  if (add && !empty)
108  {
109 
110  Cell_Type tmp = el[POS(source[i], target[i])];
111 
112  el_rowsums[source[i]] += (value[i] - tmp);
113  el_colsums[target[i]] += (value[i] - tmp);
114 
115  el[POS(source[i], target[i])] += value[i];
116 
117  continue;
118 
119  }
120 
121  if (!empty)
122  throw std::logic_error("The value already exists. Use 'add = true'.");
123 
124  el[POS(source[i], target[i])] = value[i];
125 
126  el_rowsums[source[i]] += value[i];
127  el_colsums[target[i]] += value[i];
128 
129 
130  }
131 
132 }
133 
134 template<typename Cell_Type, typename Data_Type>
137  bool copy_data
138 ) : N(Array_.N), M(Array_.M){
139 
140  // Dimensions
141  el = Array_.el;
142  el_rowsums = Array_.el_rowsums;
143  el_colsums = Array_.el_colsums;
144  // el.resize(0u);
145  // el_rowsums.resize(0u);
146  // el_colsums.resize(0u);
147 
148  // std::copy(Array_.el.begin(), Array_.el.end(), std::back_inserter(el));
149  // std::copy(Array_.el_rowsums.begin(), Array_.el_rowsums.end(), std::back_inserter(el_rowsums));
150  // std::copy(Array_.el_colsums.begin(), Array_.el_colsums.end(), std::back_inserter(el_colsums));
151 
152  // this->NCells = Array_.NCells;
153  this->visited = Array_.visited;
154 
155  // Data
156  if (Array_.data != nullptr)
157  {
158 
159  if (copy_data)
160  {
161 
162  data = new Data_Type(*Array_.data);
163  delete_data = true;
164 
165  } else {
166 
167  data = Array_.data;
168  delete_data = false;
169 
170  }
171 
172  }
173 
174  return;
175 
176 }
177 
178 template<typename Cell_Type, typename Data_Type>
180  const BArrayDense<Cell_Type, Data_Type> & Array_
181 ) {
182 
183  // Clearing
184  if (this != &Array_)
185  {
186 
187  el = Array_.el;
188  el_rowsums = Array_.el_rowsums;
189  el_colsums = Array_.el_colsums;
190  // el.resize(0u);
191  // el_rowsums.resize(0u);
192  // el_colsums.resize(0u);
193 
194  // // Entries
195  // std::copy(Array_.el.begin(), Array_.el.end(), std::back_inserter(el));
196  // std::copy(Array_.el_rowsums.begin(), Array_.el_rowsums.end(), std::back_inserter(el_rowsums));
197  // std::copy(Array_.el_colsums.begin(), Array_.el_colsums.end(), std::back_inserter(el_colsums));
198 
199 
200  // this->NCells = Array_.NCells;
201  this->N = Array_.N;
202  this->M = Array_.M;
203 
204  // Data
205  if (data != nullptr)
206  {
207 
208  if (delete_data)
209  delete data;
210  data = nullptr;
211 
212  }
213 
214  if (Array_.data != nullptr)
215  {
216 
217  data = new Data_Type(*Array_.data);
218  delete_data = true;
219 
220  }
221 
222  }
223 
224  return *this;
225 
226 }
227 
228 template<typename Cell_Type, typename Data_Type>
231  ) noexcept :
232  N(std::move(x.N)), M(std::move(x.M)),
233  // NCells(std::move(x.NCells)),
234  el(std::move(x.el)),
235  el_rowsums(std::move(x.el_rowsums)),
236  el_colsums(std::move(x.el_colsums)),
237  data(std::move(x.data)),
238  delete_data(std::move(x.delete_data))
239 {
240 
241  x.data = nullptr;
242  x.delete_data = false;
243 
244 }
245 
246 template<typename Cell_Type, typename Data_Type>
249 ) noexcept {
250 
251  // Clearing
252  if (this != &x)
253  {
254 
255  N = x.N;
256  M = x.M;
257  // NCells = x.NCells;
258 
259  std::swap(el, x.el);
260  std::swap(el_rowsums, x.el_rowsums);
261  std::swap(el_colsums, x.el_colsums);
262 
263  // Data
264  if (data != nullptr)
265  {
266 
267  if (delete_data)
268  delete data;
269  data = nullptr;
270 
271  }
272 
273  if (x.data != nullptr)
274  {
275 
276  data = std::move(x.data);
277  delete_data = x.delete_data;
278 
279  x.delete_data = false;
280  x.data = nullptr;
281 
282  }
283 
284  }
285 
286  return *this;
287 
288 }
289 
290 template<typename Cell_Type, typename Data_Type>
292  const BArrayDense<Cell_Type, Data_Type> & Array_
293 ) {
294 
295  // Dimension and number of cells used
296  if ( (N != Array_.nrow()) | (M != Array_.ncol()) )
297  return false;
298 
299  // One holds, and the other doesn't.
300  if ((!data & Array_.data) | (data & !Array_.data))
301  return false;
302 
303  if (this->el != Array_.el)
304  return false;
305 
306  return true;
307 }
308 
309 template<typename Cell_Type, typename Data_Type>
311 
312  if (delete_data && (data != nullptr))
313  delete data;
314 
315  return;
316 }
317 
318 template<typename Cell_Type, typename Data_Type>
320  Data_Type * data_,
321  bool delete_data_
322 ) {
323 
324  if ((data != nullptr) && delete_data)
325  delete data;
326 
327  data = data_;
328  delete_data = delete_data_;
329 
330  return;
331 
332 }
333 
334 template<typename Cell_Type, typename Data_Type>
336  return this->data;
337 }
338 
339 template<typename Cell_Type, typename Data_Type>
340 inline const Data_Type * BArrayDense<Cell_Type, Data_Type>::D_ptr () const {
341  return this->data;
342 }
343 
344 template<typename Cell_Type, typename Data_Type>
345  inline Data_Type & BArrayDense<Cell_Type, Data_Type>::D () {
346  return *this->data;
347 }
348 
349 template<typename Cell_Type, typename Data_Type>
350 inline const Data_Type & BArrayDense<Cell_Type, Data_Type>::D () const {
351  return *this->data;
352 }
353 
354 template<typename Cell_Type, typename Data_Type>
356  size_t i,
357  size_t j
358 ) const {
359 
360  if (i >= N)
361  {
362  std::string err_msg = "The row is out of range: " + std::to_string(i) + " >= " + std::to_string(N);
363  throw std::range_error(err_msg);
364 
365  } else if (j >= M)
366  {
367  std::string err_msg = "The column is out of range: " + std::to_string(j) + " >= " + std::to_string(M);
368  throw std::range_error(err_msg);
369  }
370 
371  return;
372 
373 }
374 
375 template<typename Cell_Type, typename Data_Type>
377  size_t i,
378  size_t j,
379  bool check_bounds
380 ) const {
381 
382  // Checking boundaries
383  if (check_bounds)
384  out_of_range(i,j);
385 
386  return el[POS(i, j)];
387 
388 }
389 
390 template<typename Cell_Type, typename Data_Type>
391 inline std::vector< Cell_Type > BArrayDense<Cell_Type, Data_Type>::get_row_vec (
392  size_t i,
393  bool check_bounds
394 ) const {
395 
396  // Checking boundaries
397  if (check_bounds)
398  out_of_range(i, 0u);
399 
400  std::vector< Cell_Type > ans;
401  ans.reserve(ncol());
402  for (size_t j = 0u; j < M; ++j)
403  ans.push_back(el[POS(i, j)]);
404 
405  return ans;
406 
407 }
408 
409 template<typename Cell_Type, typename Data_Type> inline void BArrayDense<Cell_Type, Data_Type>:: get_row_vec (
410  std::vector<Cell_Type> * x,
411  size_t i,
412  bool check_bounds
413 ) const {
414 
415  // Checking boundaries
416  if (check_bounds)
417  out_of_range(i, 0u);
418 
419  for (size_t j = 0u; j < M; ++j)
420  x->operator[](j) = el[POS(i, j)];
421 
422 }
423 
424 template<typename Cell_Type, typename Data_Type> inline std::vector< Cell_Type > BArrayDense<Cell_Type, Data_Type>:: get_col_vec(
425  size_t i,
426  bool check_bounds
427 ) const {
428 
429  // Checking boundaries
430  if (check_bounds)
431  out_of_range(0u, i);
432 
433  std::vector< Cell_Type > ans;
434  ans.reserve(nrow());
435  for (size_t j = 0u; j < N; ++j)
436  ans.push_back(el[POS(j, i)]);
437 
438  return ans;
439 
440 }
441 
442 template<typename Cell_Type, typename Data_Type> inline void BArrayDense<Cell_Type, Data_Type>:: get_col_vec (
443  std::vector<Cell_Type> * x,
444  size_t i,
445  bool check_bounds
446 ) const {
447 
448  // Checking boundaries
449  if (check_bounds)
450  out_of_range(0u, i);
451 
452  #ifdef __INTEL_LLVM_COMPILER
453  #pragma code_align 32
454  #endif
455  #if defined(__OPENMP) || defined(_OPENMP)
456  #pragma omp simd
457  #endif
458  for (size_t j = 0u; j < N; ++j)
459  x->operator[](j) = el[POS(j, i)];//this->get_cell(iter->first, i, false);
460 
461 }
462 template<typename Cell_Type, typename Data_Type>
464  size_t i,
465  bool check_bounds
466 ) const {
467 
468  if (check_bounds)
469  out_of_range(i, 0u);
470 
472 
473 }
474 
475 template<typename Cell_Type, typename Data_Type>
477  size_t i,
478  bool check_bounds
479 ) {
480 
481  if (check_bounds)
482  out_of_range(i, 0u);
483 
484  return BArrayDenseRow<Cell_Type,Data_Type>(*this, i);
485 
486 }
487 
488 template<typename Cell_Type, typename Data_Type>
491  size_t j,
492  bool check_bounds
493 ) const {
494 
495  if (check_bounds)
496  out_of_range(0u, j);
497 
499 
500 }
501 
502 template<typename Cell_Type, typename Data_Type>
505  size_t j,
506  bool check_bounds
507 ) {
508 
509  if (check_bounds)
510  out_of_range(0u, j);
511 
512  return BArrayDenseCol<Cell_Type,Data_Type>(*this, j);
513 
514 }
515 
516 template<typename Cell_Type, typename Data_Type> inline Entries< Cell_Type > BArrayDense<Cell_Type, Data_Type>:: get_entries() const {
517 
518  size_t nzero = this->nnozero();
519 
520  Entries<Cell_Type> res(nzero);
521 
522  for (size_t i = 0u; i < N; ++i)
523  {
524  for (size_t j = 0u; j < M; ++j)
525  {
526 
527  if (el[POS(i, j)] != BARRY_ZERO_DENSE)
528  {
529 
530  res.source.push_back(i),
531  res.target.push_back(j),
532  res.val.push_back(el[POS(i, j)]);
533 
534  }
535 
536 
537  }
538 
539  }
540 
541  return res;
542 
543 }
544 
545 template<typename Cell_Type, typename Data_Type> inline bool BArrayDense<Cell_Type, Data_Type>:: is_empty(
546  size_t i,
547  size_t j,
548  bool check_bounds
549 ) const {
550 
551  if (check_bounds)
552  out_of_range(i, j);
553 
554  return el[POS(i, j)] == ZERO_CELL;
555 
556 }
557 
558 template<typename Cell_Type, typename Data_Type> inline size_t BArrayDense<Cell_Type, Data_Type>:: nrow() const noexcept {
559  return N;
560 }
561 
562 template<typename Cell_Type, typename Data_Type> inline size_t BArrayDense<Cell_Type, Data_Type>:: ncol() const noexcept {
563  return M;
564 }
565 
566 template<typename Cell_Type, typename Data_Type> inline size_t BArrayDense<Cell_Type, Data_Type>:: nnozero() const noexcept {
567 
568  size_t nzero = 0u;
569  for (auto & v : el)
570  if (v != BARRY_ZERO_DENSE)
571  nzero++;
572 
573  return nzero;
574 }
575 
576 template<typename Cell_Type, typename Data_Type>
578  return this->Cell_default;
579 }
580 
581 template<typename Cell_Type, typename Data_Type>
583  const std::pair<size_t,size_t> & coords
584 ) {
585 
586 
587  size_t i = coords.first;
588  size_t j = coords.second;
589 
590  out_of_range(i, j);
591 
592  el[POS(i,j)] += 1;
593  el_rowsums[i] += 1;
594  el_colsums[j] += 1;
595 
596  return *this;
597 
598 }
599 
600 template<typename Cell_Type, typename Data_Type>
602  const std::pair<size_t,size_t> & coords
603 ) {
604 
605  size_t i = coords.first;
606  size_t j = coords.second;
607 
608  out_of_range(i, j);
609 
610  Cell_Type old = el[POS(i,j)];
611 
612  el[POS(i,j)] = ZERO_CELL;
613  el_rowsums[i] -= old;
614  el_colsums[j] -= old;
615 
616  return *this;
617 
618 }
619 
620 template<typename Cell_Type, typename Data_Type>
622  size_t i,
623  size_t j,
624  bool check_bounds
625 ) {
626 
627  return BArrayDenseCell<Cell_Type,Data_Type>(this, i, j, check_bounds);
628 
629 }
630 
631 template<typename Cell_Type, typename Data_Type>
633  size_t i,
634  size_t j,
635  bool check_bounds
636 ) const {
637 
638  if (check_bounds)
639  out_of_range(i, j);
640 
641  return el[POS(i,j)];
642 
643 }
644 
645 template<typename Cell_Type, typename Data_Type>
647  size_t i,
648  size_t j,
649  bool check_bounds,
650  bool check_exists
651 ) {
652 
653  // Checking the boundaries
654  if (check_bounds)
655  out_of_range(i,j);
656 
657  // BARRY_UNUSED(check_exists)
658 
659  // Remove the pointer first (so it wont point to empty)
660  el_rowsums[i] -= el[POS(i, j)];
661  el_colsums[j] -= el[POS(i, j)];
662  el[POS(i, j)] = BARRY_ZERO_DENSE;
663 
664  return;
665 
666 }
667 
668 template<typename Cell_Type, typename Data_Type>
670  size_t i,
671  size_t j,
672  const Cell< Cell_Type> & v,
673  bool check_bounds,
674  bool
675 ) {
676 
677  if (check_bounds)
678  out_of_range(i,j);
679 
680  if (el[POS(i,j)] == BARRY_ZERO_DENSE)
681  {
682 
683  el_rowsums[i] += v.value;
684  el_colsums[j] += v.value;
685 
686  }
687  else
688  {
689 
690  Cell_Type old = el[POS(i,j)];
691  el_rowsums[i] += (v.value - old);
692  el_colsums[j] += (v.value - old);
693 
694  }
695 
696  el[POS(i, j)] = v.value;
697 
698  return;
699 
700 
701 }
702 
703 template<typename Cell_Type, typename Data_Type> inline void BArrayDense<Cell_Type, Data_Type>:: insert_cell(
704  size_t i,
705  size_t j,
706  Cell_Type v,
707  bool check_bounds,
708  bool
709 ) {
710 
711  if (check_bounds)
712  out_of_range(i,j);
713 
714  if (el[POS(i,j)] == BARRY_ZERO_DENSE)
715  {
716 
717  el_rowsums[i] += v;
718  el_colsums[j] += v;
719 
720  }
721  else
722  {
723 
724  Cell_Type old = el[POS(i,j)];
725  el_rowsums[i] += (v - old);
726  el_colsums[j] += (v - old);
727 
728  }
729 
730  el[POS(i, j)] = v;
731 
732 }
733 
734 template<typename Cell_Type, typename Data_Type> inline void BArrayDense<Cell_Type, Data_Type>:: swap_cells (
735  size_t i0, size_t j0,
736  size_t i1, size_t j1,
737  bool check_bounds,
738  int check_exists,
739  int * report
740 ) {
741 
742  if (check_bounds) {
743  out_of_range(i0,j0);
744  out_of_range(i1,j1);
745  }
746 
747 
748  // Just in case, if this was passed
749  if (report != nullptr)
750  (*report) = EXISTS::BOTH;
751 
752  // If source and target coincide, we do nothing
753  if ((i0 == i1) && (j0 == j1))
754  return;
755 
756  // Updating rowand col sumns
757  Cell_Type val0 = el[POS(i0,j0)];
758  Cell_Type val1 = el[POS(i1,j1)];
759 
760  rm_cell(i0, j0, false, false);
761  rm_cell(i1, j1, false, false);
762 
763  // Inserting the cells by reference, these will be deleted afterwards
764  insert_cell(i0, j0, val1, false, false);
765  insert_cell(i1, j1, val0, false, false);
766 
767  return;
768 
769 }
770 
771 template<typename Cell_Type, typename Data_Type> inline void BArrayDense<Cell_Type, Data_Type>:: toggle_cell (
772  size_t i,
773  size_t j,
774  bool check_bounds,
775  int check_exists
776 ) {
777 
778  if (check_bounds)
779  out_of_range(i, j);
780 
781  if (el[POS(i,j)] == ZERO_CELL)
782  insert_cell(i,j,1,false,false);
783  else
784  rm_cell(i,j,false,false);
785 
786  return;
787 
788 }
789 
790 template<typename Cell_Type, typename Data_Type> inline void BArrayDense<Cell_Type, Data_Type>:: swap_rows (
791  size_t i0,
792  size_t i1,
793  bool check_bounds
794 ) {
795 
796  if (check_bounds)
797  {
798 
799  out_of_range(i0,0u);
800  out_of_range(i1,0u);
801 
802  }
803 
804  // if (NCells == 0u)
805  // return;
806 
807  // Swapping happens naturally, need to take care of the pointers
808  // though
809  for (size_t j = 0u; j < M; ++j)
810  std::swap(el[POS(i0, j)], el[POS(i1, j)]);
811 
812  std::swap(el_rowsums[i0], el_rowsums[i1]);
813 
814  return;
815 }
816 
817 // This swapping is more expensive overall
818 template<typename Cell_Type, typename Data_Type> inline void BArrayDense<Cell_Type, Data_Type>:: swap_cols (
819  size_t j0,
820  size_t j1,
821  bool check_bounds
822 ) {
823 
824  if (check_bounds)
825  {
826 
827  out_of_range(0u, j0);
828  out_of_range(0u, j1);
829 
830  }
831 
832  if ((el_colsums[j0] == ZERO_CELL) && el_colsums[j1] == ZERO_CELL)
833  return;
834 
835  // Swapping happens naturally, need to take care of the pointers
836  // though
837  for (size_t i = 0u; i < N; ++i)
838  std::swap(el[POS(i, j0)], el[POS(i, j1)]);
839 
840  std::swap(el_colsums[j0], el_colsums[j1]);
841 
842  return;
843 }
844 
845 template<typename Cell_Type, typename Data_Type> inline void BArrayDense<Cell_Type, Data_Type>:: zero_row (
846  size_t i,
847  bool check_bounds
848  ) {
849 
850  if (check_bounds)
851  out_of_range(i, 0u);
852 
853  if (el_rowsums[i] == ZERO_CELL)
854  return;
855 
856  // Else, remove all elements
857  for (size_t col = 0u; col < M; col++)
858  rm_cell(i, col, false, false);
859 
860  return;
861 
862 }
863 
864 template<typename Cell_Type, typename Data_Type> inline void BArrayDense<Cell_Type, Data_Type>:: zero_col (
865  size_t j,
866  bool check_bounds
867  ) {
868 
869  if (check_bounds)
870  out_of_range(0u, j);
871 
872  if (el_colsums[j] == ZERO_CELL)
873  return;
874 
875  // Else, remove all elements
876  for (size_t row = 0u; row < N; row++)
877  rm_cell(row, j, false, false);
878 
879  return;
880 
881 }
882 
883 template<typename Cell_Type, typename Data_Type> inline void BArrayDense<Cell_Type, Data_Type>:: transpose () {
884 
885  // if (NCells == 0u)
886  // {
887 
888  // std::swap(N, M);
889  // return;
890 
891  // }
892 
893  // Start by flipping the switch
894  visited = !visited;
895 
896  // size_t N0 = N, M0 = M;
897  std::vector< Cell< Cell_Type > > tmp_el(std::move(el));
898  el.resize(N * M, ZERO_CELL);
899  for (size_t i = 0u; i < N; ++i)
900  for (size_t j = 0u; j < M; ++j)
901  std::swap(tmp_el[POS(i, j)], el[POS_N(j, i, M)]);
902 
903  // Swapping the values
904  std::swap(N, M);
905  std::swap(el_rowsums, el_colsums);
906 
907  return;
908 
909 }
910 
911 template<typename Cell_Type, typename Data_Type> inline void BArrayDense<Cell_Type, Data_Type>:: clear (
912  bool hard
913 ) {
914 
915  BARRY_UNUSED(hard)
916 
917  std::fill(el.begin(), el.end(), ZERO_CELL);
918  std::fill(el_rowsums.begin(), el_rowsums.end(), ZERO_CELL);
919  std::fill(el_colsums.begin(), el_colsums.end(), ZERO_CELL);
920 
921  return;
922 
923 }
924 
925 template<typename Cell_Type, typename Data_Type> inline void BArrayDense<Cell_Type, Data_Type>:: resize (
926  size_t N_,
927  size_t M_
928 ) {
929 
930  // Moving stuff around
931  std::vector< Cell_Type > el_tmp(el);
932  el.resize(N_ * M_, ZERO_CELL);
933  el_rowsums.resize(N_, ZERO_CELL);
934  el_colsums.resize(M_, ZERO_CELL);
935 
936  for (size_t i = 0u; i < N; ++i)
937  {
938  // If reached the end
939  if (i >= N_)
940  break;
941 
942  for (size_t j = 0u; j < M; ++j)
943  {
944 
945  if (j >= M_)
946  break;
947 
948  insert_cell(i, j, el_tmp[POS_N(i, j, N_)], false, false);
949 
950  }
951 
952  }
953 
954  N = N_;
955  M = M_;
956 
957  return;
958 
959 }
960 
961 template<typename Cell_Type, typename Data_Type> inline void BArrayDense<Cell_Type, Data_Type>:: reserve () {
962 
963  el.reserve(N * M);
964  el_rowsums.reserve(N);
965  el_colsums.reserve(M);
966  return;
967 
968 }
969 
970 template<typename Cell_Type, typename Data_Type> inline void BArrayDense<Cell_Type, Data_Type>:: print (
971  const char * fmt,
972  ...
973 ) const
974 {
975 
976  std::va_list args;
977  va_start(args, fmt);
978  printf_barry(fmt, args);
979  va_end(args);
980 
981  for (size_t i = 0u; i < N; ++i)
982  {
983 
984  printf_barry("[%3li,] ", i);
985 
986  for (size_t j = 0u; j < M; ++j)
987  {
988 
989  if (this->is_empty(i, j, false))
990  printf_barry(" . ");
991  else
992  printf_barry(" %.2f ", static_cast<double>(this->get_cell(i, j, false)));
993 
994  }
995 
996  printf_barry("\n");
997 
998  }
999 
1000  return;
1001 
1002 }
1003 
1004 template<typename Cell_Type, typename Data_Type> inline const std::vector< Cell_Type > & BArrayDense<Cell_Type, Data_Type>:: get_data() const
1005 {
1006  return el;
1007 }
1008 
1009 template<typename Cell_Type, typename Data_Type> inline const Cell_Type BArrayDense<Cell_Type, Data_Type>:: rowsum(size_t i) const
1010 {
1011  return el_rowsums[i];
1012 }
1013 
1014 template<typename Cell_Type, typename Data_Type> inline const Cell_Type BArrayDense<Cell_Type, Data_Type>:: colsum(size_t j) const
1015 {
1016  return el_colsums[j];
1017 }
1018 
1019 #undef ROW
1020 #undef COL
1021 #undef POS
1022 #undef POS_N
1023 
1024 #undef ZERO_CELL
1025 
1026 #endif
1027 
#define POS_N(a, b, c)
#define ZERO_CELL
#define POS(a, b)
#define printf_barry
#define BARRY_ZERO_DENSE
Definition: barry-macros.hpp:5
#define BARRY_UNUSED(expr)
friend class BArrayDenseCol_const< Cell_Type, Data_Type >
friend class BArrayDenseCol< Cell_Type, Data_Type >
Baseline class for binary arrays.
Cell< Cell_Type > default_val() const
std::vector< Cell_Type > get_col_vec(size_t i, bool check_bounds=true) const
void zero_row(size_t i, bool check_bounds=true)
bool is_empty(size_t i, size_t j, bool check_bounds=true) const
BArrayDense< Cell_Type, Data_Type > & operator=(const BArrayDense< Cell_Type, Data_Type > &Array_)
Assignment constructor.
bool operator==(const BArrayDense< Cell_Type, Data_Type > &Array_)
void swap_cols(size_t j0, size_t j1, bool check_bounds=true)
const Cell_Type rowsum(size_t i) const
size_t ncol() const noexcept
const std::vector< Cell_Type > & get_data() const
void print(const char *fmt=nullptr,...) const
size_t nrow() const noexcept
size_t nnozero() const noexcept
void swap_cells(size_t i0, size_t j0, size_t i1, size_t j1, bool check_bounds=true, int check_exists=CHECK::BOTH, int *report=nullptr)
void insert_cell(size_t i, size_t j, const Cell< Cell_Type > &v, bool check_bounds, bool)
BArrayDenseCol< Cell_Type, Data_Type > & col(size_t j, bool check_bounds=true)
void rm_cell(size_t i, size_t j, bool check_bounds=true, bool check_exists=true)
void clear(bool hard=true)
void set_data(Data_Type *data_, bool delete_data_=false)
Set the data object.
Data_Type & D()
std::vector< Cell_Type > get_row_vec(size_t i, bool check_bounds=true) const
Entries< Cell_Type > get_entries() const
Get the edgelist.
void out_of_range(size_t i, size_t j) const
void toggle_cell(size_t i, size_t j, bool check_bounds=true, int check_exists=EXISTS::UKNOWN)
void zero_col(size_t j, bool check_bounds=true)
Data_Type * D_ptr()
void swap_rows(size_t i0, size_t i1, bool check_bounds=true)
BArrayDense< Cell_Type, Data_Type > & operator+=(const std::pair< size_t, size_t > &coords)
BArrayDenseCell< Cell_Type, Data_Type > operator()(size_t i, size_t j, bool check_bounds=true)
BArrayDenseRow< Cell_Type, Data_Type > & row(size_t i, bool check_bounds=true)
const Cell_Type colsum(size_t i) const
BArrayDense()
Zero-size array.
void resize(size_t N_, size_t M_)
Cell_Type get_cell(size_t i, size_t j, bool check_bounds=true) const
BArrayDense< Cell_Type, Data_Type > & operator-=(const std::pair< size_t, size_t > &coords)
Entries in BArray. For now, it only has two members:
Definition: cell-bones.hpp:10
Cell_Type value
Definition: cell-bones.hpp:12
A wrapper class to store source, target, val from a BArray object.
Definition: typedefs.hpp:78
return res
Data_Type &&counter_ data(std::move(counter_.data))
size_t size_t j
size_t i
Data_Type &&counter_ noexcept
Data_Type Counter_fun_type< Array_Type, Data_Type > Hasher_fun_type< Array_Type, Data_Type > Data_Type data_
const int BOTH
Definition: typedefs.hpp:38