30#ifdef TESTARRAYDEBINFO
32# define DEBINFO(args) info(args)
42template <
int num_dimensions,
typename elemT>
53 mem += (*this)[i].size_all();
54 if (mem != &(*(*
this)[i + 1].
begin_all()))
60template <
int num_dimensions,
typename elemT>
65 typename base_type::iterator iter = this->
begin();
66 typename IndexRange<num_dimensions>::const_iterator range_iter = range.
begin();
67 for (; iter != this->
end(); ++iter, ++range_iter)
68 (*iter).
resize(*range_iter);
71template <
int num_dimensions,
typename elemT>
76 auto iter = this->begin();
77 auto range_iter = range.
begin();
79 for (; iter != this->end(); ++iter, ++range_iter)
81 (*iter).init(*range_iter, ptr, copy_data);
82 ptr += range_iter->size_all();
86template <
int num_dimensions,
typename elemT>
88Array<num_dimensions, elemT>::init_with_copy(
const IndexRange<num_dimensions>& range, elemT
const*
const data_ptr)
90 base_type::resize(range.get_min_index(), range.get_max_index());
91 auto iter = this->begin();
92 auto range_iter = range.begin();
94 for (; iter != this->end(); ++iter, ++range_iter)
96 (*iter).init_with_copy(*range_iter, ptr);
97 ptr += range_iter->size_all();
101template <
int num_dimensions,
typename elemT>
108template <
int num_dimensions,
typename elemT>
109Array<num_dimensions, elemT>::Array()
111 _allocated_full_data_ptr(nullptr)
114template <
int num_dimensions,
typename elemT>
117 _allocated_full_data_ptr(new elemT[range.
size_all()])
122 std::for_each(this->_allocated_full_data_ptr.get(), this->_allocated_full_data_ptr.get() + range.
size_all(), [](elemT& e) {
125 this->init(range, this->_allocated_full_data_ptr.get(),
false);
128template <
int num_dimensions,
typename elemT>
131 this->_allocated_full_data_ptr = data_sptr;
132 this->init(range, this->_allocated_full_data_ptr.get(),
false);
135template <
int num_dimensions,
typename elemT>
136Array<num_dimensions, elemT>::Array(
const self& t)
138 _allocated_full_data_ptr(new elemT[t.
size_all()])
140 this->init(t.get_index_range(), this->_allocated_full_data_ptr.get(),
false);
141 std::copy(t.begin_all(), t.end_all(), this->_allocated_full_data_ptr.get());
142 DEBINFO(
"constructor " + std::to_string(num_dimensions) +
"copy of size " + std::to_string(this->
size_all()));
147template <
int num_dimensions,
typename elemT>
148Array<num_dimensions, elemT>::Array(
const base_type& t)
150 _allocated_full_data_ptr(nullptr)
152 DEBINFO(
"constructor basetype " + std::to_string(num_dimensions) +
" of size " + std::to_string(this->
size_all()));
156template <
int num_dimensions,
typename elemT>
159 if (this->_allocated_full_data_ptr)
166template <
int num_dimensions,
typename elemT>
167Array<num_dimensions, elemT>::Array(Array<num_dimensions, elemT>&& other) noexcept
171 DEBINFO(
"move constructor " + std::to_string(num_dimensions) +
"copy of size " + std::to_string(this->
size_all()));
174template <
int num_dimensions,
typename elemT>
179 DEBINFO(
"Array= " + std::to_string(num_dimensions) +
"copy of size " + std::to_string(this->
size_all()));
183template <
int num_dimensions,
typename elemT>
194template <
int num_dimensions,
typename elemT>
204template <
int num_dimensions,
typename elemT>
211template <
int num_dimensions,
typename elemT>
224template <
int num_dimensions,
typename elemT>
237template <
int num_dimensions,
typename elemT>
244template <
int num_dimensions,
class elemT>
246Array<num_dimensions, elemT>::get_index_range()
const
251 const_iterator array_iter = this->
begin();
253 for (; range_iter != range.end(); range_iter++, array_iter++)
255 *range_iter = (*array_iter).get_index_range();
260template <
int num_dimensions,
typename elemT>
267# if _OPENMP >= 201107
268# pragma omp parallel for reduction(+ : acc)
290template <
int num_dimensions,
typename elemT>
294 this->_full_pointer_access =
true;
296 error(
"Array::get_full_data_ptr() called for non-contiguous array.");
309template <
int num_dimensions,
typename elemT>
313 this->_full_pointer_access =
true;
315 error(
"Array::get_const_full_data_ptr() called for non-contiguous array.");
327template <
int num_dimensions,
typename elemT>
331 assert(this->_full_pointer_access);
333 this->_full_pointer_access =
false;
343template <
int num_dimensions,
typename elemT>
347 assert(this->_full_pointer_access);
348 this->_full_pointer_access =
false;
351template <
int num_dimensions,
typename elemT>
356 typename HigherPrecision<elemT>::type acc;
359# if _OPENMP >= 201107
360# pragma omp parallel for reduction(+ : acc)
364 acc += this->
num[i].
sum();
365 return static_cast<elemT
>(acc);
368template <
int num_dimensions,
typename elemT>
373 typename HigherPrecision<elemT>::type acc;
376# if _OPENMP >= 201107
377# pragma omp parallel for reduction(+ : acc)
382 return static_cast<elemT
>(acc);
385template <
int num_dimensions,
typename elemT>
390 if (this->
size() > 0)
394# if _OPENMP >= 201107
395# pragma omp parallel for reduction(max : maxval)
400 maxval = std::max(this->
num[i].
find_max(), maxval);
411template <
int num_dimensions,
typename elemT>
416 if (this->
size() > 0)
420# if _OPENMP >= 201107
421# pragma omp parallel for reduction(min : minval)
426 minval = std::min(this->
num[i].
find_min(), minval);
437template <
int num_dimensions,
typename elemT>
447template <
int num_dimensions,
typename elemT>
457template <
int num_dimensions,
typename elemT>
467template <
int num_dimensions,
typename elemT>
471 return get_index_range().is_regular();
475template <
int num_dimensions,
typename elemT>
484template <
int num_dimension,
typename elemT>
485Array<num_dimension - 1, elemT>&
491template <
int num_dimension,
typename elemT>
492const Array<num_dimension - 1, elemT>&
497template <
int num_dimensions,
typename elemT>
503template <
int num_dimensions,
typename elemT>
510template <
int num_dimension,
typename elemT>
511Array<num_dimension - 1, elemT>&
512Array<num_dimension, elemT>::at(
int i)
514 return base_type::at(i);
517template <
int num_dimension,
typename elemT>
518const Array<num_dimension - 1, elemT>&
519Array<num_dimension, elemT>::at(
int i)
const
521 return base_type::at(i);
523template <
int num_dimensions,
typename elemT>
529template <
int num_dimensions,
typename elemT>
536template <
int num_dimensions,
typename elemT>
537template <
typename elemT2>
544template <
int num_dimensions,
typename elemT>
549 if ((this->get_index_range() != x.get_index_range()) || (this->get_index_range() != y.get_index_range()))
550 error(
"Array::xapyb: index ranges don't match");
555 while (this_iter != this->
end_all())
557 *this_iter++ = (*x_iter++) * a + (*y_iter++) * b;
561template <
int num_dimensions,
typename elemT>
566 if ((this->get_index_range() != x.get_index_range()) || (this->get_index_range() != y.get_index_range())
567 || (this->get_index_range() != a.get_index_range()) || (this->get_index_range() != b.get_index_range()))
568 error(
"Array::xapyb: index ranges don't match");
576 while (this_iter != this->
end_all())
578 *this_iter++ = (*x_iter++) * (*a_iter++) + (*y_iter++) * (*b_iter++);
582template <
int num_dimensions,
typename elemT>
587 this->
xapyb(*
this, a, y, b);
593template <
class elemT>
595Array<1, elemT>::init_with_copy(
const IndexRange<1>& range, elemT
const*
const data_ptr)
600template <
class elemT>
602Array<1, elemT>::init(
const IndexRange<1>& range, elemT*
const data_ptr,
bool copy_data)
604 base_type::init(range.get_min_index(), range.get_max_index(), data_ptr, copy_data);
607template <
class elemT>
612 const int oldstart = this->get_min_index();
613 const size_type oldlength = this->size();
615 base_type::resize(min_index, max_index);
617 if (!initialise_with_0)
625 for (
int i = this->get_min_index(); i <= this->get_max_index(); i++)
626 assign(this->num[i], 0);
630 for (
int i = this->get_min_index(); i < oldstart && i <= this->get_max_index(); ++i)
631 assign(this->num[i], 0);
632 for (
int i = std::max(
static_cast<int>(oldstart + oldlength), this->get_min_index()); i <= this->get_max_index(); ++i)
633 assign(this->num[i], 0);
638template <
class elemT>
642 resize(min_index, max_index,
true);
645template <
class elemT>
649 resize(range.get_min_index(), range.get_max_index());
652template <
class elemT>
656 resize(min_index, max_index);
659template <
class elemT>
663 grow(range.get_min_index(), range.get_max_index());
666template <
class elemT>
667Array<1, elemT>::Array()
671template <
class elemT>
678template <
class elemT>
679Array<1, elemT>::Array(
const int min_index,
const int max_index)
682 grow(min_index, max_index);
685template <
class elemT>
686Array<1, elemT>::Array(
const IndexRange<1>& range, shared_ptr<elemT[]> data_sptr)
687 : base_type(range.get_min_index(), range.get_max_index(), data_sptr)
690template <
class elemT>
691Array<1, elemT>::Array(
const IndexRange<1>& range,
const elemT*
const data_ptr)
692 : base_type(range.get_min_index(), range.get_max_index(), data_ptr)
695template <
class elemT>
696Array<1, elemT>::Array(
const base_type& il)
700template <
typename elemT>
705template <
typename elemT>
709template <
typename elemT>
716template <
typename elemT>
721 base_type::operator=(other);
725template <
typename elemT>
729 return this->begin();
732template <
typename elemT>
736 return this->begin();
739template <
typename elemT>
746template <
typename elemT>
753template <
typename elemT>
757 return this->begin();
760template <
typename elemT>
767template <
typename elemT>
769Array<1, elemT>::get_index_range()
const
771 return IndexRange<1>(this->get_min_index(), this->get_max_index());
774template <
typename elemT>
781template <
class elemT>
786 typename HigherPrecision<elemT>::type acc;
789# if _OPENMP >= 201107
790# pragma omp parallel for reduction(+ : acc)
793 for (
int i = this->get_min_index(); i <= this->get_max_index(); ++i)
795 return static_cast<elemT
>(acc);
798template <
class elemT>
803 typename HigherPrecision<elemT>::type acc;
806# if _OPENMP >= 201107
807# pragma omp parallel for reduction(+ : acc)
810 for (
int i = this->get_min_index(); i <= this->get_max_index(); i++)
812 if (this->num[i] > 0)
815 return static_cast<elemT
>(acc);
818template <
class elemT>
823 if (this->size() > 0)
825 return *std::max_element(this->begin(), this->end());
835template <
class elemT>
840 if (this->size() > 0)
842 return *std::min_element(this->begin(), this->end());
852template <
typename elemT>
859template <
typename elemT>
864 return range.get_regular_range(min, max);
876template <
class elemT>
878Array<1, elemT>::operator+(
const base_type& iv)
const
885template <
class elemT>
887Array<1, elemT>::operator-(
const base_type& iv)
const
893template <
class elemT>
895Array<1, elemT>::operator*(
const base_type& iv)
const
902template <
class elemT>
904Array<1, elemT>::operator/(
const base_type& iv)
const
911template <
class elemT>
913Array<1, elemT>::operator+(
const elemT a)
const
917 return (retval += a);
920template <
class elemT>
922Array<1, elemT>::operator-(
const elemT a)
const
926 return (retval -= a);
929template <
class elemT>
931Array<1, elemT>::operator*(
const elemT a)
const
935 return (retval *= a);
938template <
class elemT>
940Array<1, elemT>::operator/(
const elemT a)
const
944 return (retval /= a);
947template <
typename elemT>
951 return base_type::operator[](i);
954template <
typename elemT>
958 return base_type::operator[](i);
961template <
typename elemT>
965 return (*
this)[c[1]];
968template <
typename elemT>
972 return (*
this)[c[1]];
975template <
typename elemT>
977Array<1, elemT>::at(
int i)
const
979 return base_type::at(i);
982template <
typename elemT>
984Array<1, elemT>::at(
int i)
986 return base_type::at(i);
989template <
typename elemT>
993 return (*this).at(c[1]);
996template <
typename elemT>
1000 return (*this).at(c[1]);
class stir::HigherPrecision
defines the stir::assign function to assign values to different data types
This class defines multi-dimensional (numeric) arrays.
Definition Array.h:78
virtual void resize(const IndexRange< num_dimensions > &range)
change the array to a new range of indices, new elements are set to 0
Definition Array.inl:62
full_iterator begin_all()
start value for iterating through all elements in the array, see full_iterator
Definition Array.inl:213
FullArrayIterator< typename base_type::iterator, typename Array< num_dimensions - 1, elemT >::full_iterator, elemT, full_reference, full_pointer > full_iterator
This defines an iterator type that iterates through all elements.
Definition Array.h:117
Array< num_dimensions - 1, elemT > & operator[](int i)
allow array-style access, read/write
Definition Array.inl:486
virtual void grow(const IndexRange< num_dimensions > &range)
alias for resize()
Definition Array.inl:103
bool is_contiguous() const
return if the array is contiguous in memory
Definition Array.inl:44
void apply_lower_threshold(const elemT &l)
Sets elements below value to the value.
Definition Array.inl:449
size_t size_all() const
return the total number of elements in this array
Definition Array.inl:262
const elemT * get_const_full_data_ptr() const
member function for access to the data via a const elemT*
Definition Array.inl:311
bool get_regular_range(BasicCoordinate< num_dimensions, int > &min, BasicCoordinate< num_dimensions, int > &max) const
find regular range, returns false if the range is not regular
Definition Array.inl:477
elemT sum_positive() const
return sum of all positive elements
Definition Array.inl:370
Array & operator=(Array other)
assignment operator
Definition Array.inl:176
void release_full_data_ptr()
signal end of access to elemT*
Definition Array.inl:329
elemT find_max() const
return maximum of all the elements
Definition Array.inl:387
STIR_DEPRECATED void axpby(const elemT2 a, const Array &x, const elemT2 b, const Array &y)
void xapyb(const Array &x, const elemT a, const Array &y, const elemT b)
set values of the array to x*a+y*b, where a and b are scalar
Definition Array.inl:546
elemT * get_full_data_ptr()
member function for access to the data via a elemT*
Definition Array.inl:292
bool is_regular() const
checks if the index range is 'regular'
Definition Array.inl:469
const_full_iterator end_all_const() const
end value for iterating through all elements in the array, see full_iterator
Definition Array.inl:196
elemT find_min() const
return minimum of all the elements
Definition Array.inl:413
void sapyb(const T &a, const Array &y, const T &b)
set values of the array to self*a+y*b where a and b are scalar or arrays
Definition Array.inl:585
void release_const_full_data_ptr() const
signal end of access to const elemT*
Definition Array.inl:345
full_iterator end_all()
end value for iterating through all elements in the array, see full_iterator
Definition Array.inl:185
void fill(const elemT &n)
Fill elements with value n.
Definition Array.inl:439
const_full_iterator begin_all_const() const
start value for iterating through all elements in the array, see full_iterator
Definition Array.inl:226
elemT sum() const
return sum of all elements
Definition Array.inl:353
FullArrayIterator< typename base_type::const_iterator, typename Array< num_dimensions - 1, elemT >::const_full_iterator, elemT, const_full_reference, const_full_pointer > const_full_iterator
As full_iterator, but for const objects.
Definition Array.h:125
friend void swap(Array &first, Array &second)
Definition Array.h:171
~Array() override
virtual destructor, frees up any allocated memory
Definition Array.inl:157
void apply_upper_threshold(const elemT &u)
Sets elements above value to the value.
Definition Array.inl:459
class BasicCoordinate<int num_dimensions, typename coordT> defines num_dimensions -dimensional coordi...
Definition BasicCoordinate.h:57
This class defines ranges which can be 'irregular'.
Definition IndexRange.h:69
size_t size_all() const
return the total number of elements in this range
Definition IndexRange.inl:71
bool get_regular_range(BasicCoordinate< num_dimensions, int > &min, BasicCoordinate< num_dimensions, int > &max) const
find regular range, returns false if the range is not regular
Definition IndexRange.cxx:29
A templated class for vectors, but with indices starting not from 0.
Definition VectorWithOffset.h:65
iterator begin()
use to initialise an iterator to the first element of the vector
Definition VectorWithOffset.inl:190
void check_state() const
Definition VectorWithOffset.inl:87
int get_max_index() const
get value of last valid index
Definition VectorWithOffset.inl:131
int get_min_index() const
get value of first valid index
Definition VectorWithOffset.inl:124
virtual void resize(const int min_index, const int max_index)
change the range of the vector, new elements are set to T()
Definition VectorWithOffset.inl:426
iterator end()
iterator 'past' the last element of the vector
Definition VectorWithOffset.inl:206
T & operator[](int i)
allow array-style access, read/write
Definition VectorWithOffset.inl:139
Array< num_dimensions - 1, std::complex< float > > * num
Definition VectorWithOffset.h:370
size_t size() const
Definition VectorWithOffset.inl:546
Declaration of stir::error()
BasicCoordinate< num_dimensions - 1, coordT > cut_first_dimension(const BasicCoordinate< num_dimensions, coordT > &c)
make a shorter BasicCoordinate, by cutting the first element from c
Definition BasicCoordinate.inl:477
void error(const char *const s,...)
Print error with format string a la printf and throw exception.
Definition error.cxx:42
elemT sum(IterT start, IterT end, elemT init)
Compute the sum of a sequence using operator+=(), using an initial value.
Definition more_algorithms.inl:52
Declaration of stir::info()