STIR 6.4.0
VectorWithOffset.inl
Go to the documentation of this file.
1//
2//
3/*
4 Copyright (C) 2000 PARAPET partners
5 Copyright (C) 2000 - 2010-07-01, Hammersmith Imanet Ltd
6 Copyright (C) 2012-06-01 - 2012, Kris Thielemans
7 Copyright (C) 2023 - 2024, University College London
8 This file is part of STIR.
9
10 SPDX-License-Identifier: Apache-2.0 AND License-ref-PARAPET-license
11
12 See STIR/LICENSE.txt for details
13*/
24
25#include "stir/IndexRange.h"
26#include <algorithm>
27#include <stdexcept>
28#include "thresholding.h"
29#include "stir/error.h"
30
31START_NAMESPACE_STIR
32
33template <class T>
34void
35VectorWithOffset<T>::init()
36{
37 length = 0; // i.e. an empty row of zero length,
38 start = 0; // no offsets
39 num = nullptr; // and no data.
40 begin_allocated_memory = nullptr;
41 end_allocated_memory = nullptr;
42 allocated_memory_sptr = nullptr;
43}
44
45template <class T>
46void
47VectorWithOffset<T>::init_with_copy(const int min_index, const int max_index, T const* const data_ptr)
48{
49 this->pointer_access = false;
50 this->resize(min_index, max_index);
51 std::copy(data_ptr, data_ptr + this->length, this->begin());
52}
53
54template <class T>
55void
56VectorWithOffset<T>::init(const int min_index, const int max_index, T* const data_ptr, bool copy_data)
57{
58 if (copy_data)
59 {
60 this->init_with_copy(min_index, max_index, data_ptr);
61 }
62 else
63 {
64 this->pointer_access = false;
65 this->length = max_index >= min_index ? static_cast<unsigned>(max_index - min_index) + 1 : 0U;
66 this->start = min_index;
67 this->begin_allocated_memory = data_ptr;
68 this->end_allocated_memory = data_ptr + this->length;
69 this->num = this->begin_allocated_memory - this->start;
70 this->check_state();
71 }
72}
73
74template <class T>
75bool
77{
78 return this->allocated_memory_sptr ? true : false;
79}
80
83is used before and after any modification of the object
84*/
85template <class T>
86void
88{
89 // disable for normal debugging
90#if _DEBUG > 1
91 assert(((length > 0) || (length == 0 && start == 0 && num == begin_allocated_memory)));
92
93#endif
94 assert(begin_allocated_memory <= num + start);
95 assert(end_allocated_memory >= begin_allocated_memory);
96 assert(static_cast<unsigned>(end_allocated_memory - begin_allocated_memory) >= length);
97 assert(!allocated_memory_sptr || (allocated_memory_sptr.get() == begin_allocated_memory));
98}
100template <class T>
101void
102VectorWithOffset<T>::_destruct_and_deallocate()
103{
104 // check if data is being accessed via a pointer (see get_data_ptr())
105 assert(pointer_access == false);
106 // TODO when reserve() no longer initialises new elements,
107 // we'll have to be careful to delete only initialised elements
108 // and just de-allocate the rest
109
110 this->allocated_memory_sptr = nullptr;
111}
113template <class T>
114void
116{
117 this->check_state();
118 this->_destruct_and_deallocate();
119 this->init();
120}
121
122template <class T>
123int
125{
126 return start;
127}
128
129template <class T>
130int
132{
133 return start + length - 1;
135
137template <class T>
138T&
140{
141 this->check_state();
142 assert(i >= this->get_min_index());
143 assert(i <= this->get_max_index());
144
145 return num[i];
146}
147
149template <class T>
150const T&
152{
153 this->check_state();
154 assert(i >= this->get_min_index());
155 assert(i <= this->get_max_index());
157 return num[i];
158}
159
160template <class T>
161T&
163{
164 if (length == 0 || i < this->get_min_index() || i > this->get_max_index())
165 throw std::out_of_range("index out of range");
166 this->check_state();
167 return num[i];
168}
169
170template <class T>
171const T&
173{
174 if (length == 0 || i < this->get_min_index() || i > this->get_max_index())
175 throw std::out_of_range("index out of range");
176 this->check_state();
177
178 return num[i];
179}
180
181template <class T>
182bool
185 return length == 0;
186}
188template <class T>
189typename VectorWithOffset<T>::iterator
191{
192 this->check_state();
193 return typename VectorWithOffset<T>::iterator(num + this->get_min_index());
194}
195
196template <class T>
197typename VectorWithOffset<T>::const_iterator
199{
200 this->check_state();
201 return typename VectorWithOffset<T>::const_iterator(num + this->get_min_index());
202}
203
204template <class T>
205typename VectorWithOffset<T>::iterator
207{
208 this->check_state();
209 return typename VectorWithOffset<T>::iterator(num + (this->get_max_index() + 1));
211
212template <class T>
213typename VectorWithOffset<T>::const_iterator
215{
216 this->check_state();
217 return typename VectorWithOffset<T>::const_iterator(num + (this->get_max_index() + 1));
218}
220template <class T>
221typename VectorWithOffset<T>::reverse_iterator
222VectorWithOffset<T>::rbegin()
223{
224 this->check_state();
225 return std::make_reverse_iterator(end());
226}
228template <class T>
229typename VectorWithOffset<T>::const_reverse_iterator
230VectorWithOffset<T>::rbegin() const
231{
232 this->check_state();
233 return std::make_reverse_iterator(end());
234}
236template <class T>
237typename VectorWithOffset<T>::reverse_iterator
238VectorWithOffset<T>::rend()
239{
240 this->check_state();
241 return std::make_reverse_iterator(begin());
242}
244template <class T>
245typename VectorWithOffset<T>::const_reverse_iterator
246VectorWithOffset<T>::rend() const
248 this->check_state();
249 return std::make_reverse_iterator(begin());
251
252template <class T>
254 : pointer_access(false)
255{
256 this->init();
257}
258
259template <class T>
261 : VectorWithOffset(0, hsz - 1)
262{}
263
264template <class T>
265VectorWithOffset<T>::VectorWithOffset(const int min_index, const int max_index)
266 : length(static_cast<unsigned>(max_index - min_index) + 1),
267 start(min_index),
268 pointer_access(false)
269{
270 if (max_index >= min_index)
272 allocated_memory_sptr = shared_ptr<T[]>(new T[length]);
273 begin_allocated_memory = allocated_memory_sptr.get();
274 end_allocated_memory = begin_allocated_memory + length;
275 num = begin_allocated_memory - min_index;
276 }
277 else
278 this->init();
279 this->check_state();
280}
281
282#if STIR_VERSION < 070000
283template <class T>
284VectorWithOffset<T>::VectorWithOffset(const int min_index, const int max_index, T* const data_ptr, T* const end_of_data_ptr)
285 : length(static_cast<unsigned>(max_index - min_index) + 1),
286 start(min_index),
287 allocated_memory_sptr(nullptr), // we don't own the data
288 pointer_access(false)
289{
290 this->begin_allocated_memory = data_ptr;
291 this->end_allocated_memory = end_of_data_ptr;
292 this->num = this->begin_allocated_memory - this->start;
293 this->check_state();
295
296template <class T>
297VectorWithOffset<T>::VectorWithOffset(const int sz, T* const data_ptr, T* const end_of_data_ptr)
298 : VectorWithOffset(0, sz - 1, data_ptr, end_of_data_ptr)
299{}
300#endif // STIR_VERSION < 070000
301
302template <class T>
303VectorWithOffset<T>::VectorWithOffset(const int min_index, const int max_index, const T* const data_ptr)
304{
305 // first set empty, such that resize() will work ok
306 this->init();
307 this->init_with_copy(min_index, max_index, data_ptr);
308}
309
310template <class T>
311VectorWithOffset<T>::VectorWithOffset(const int sz, const T* const data_ptr)
312 : VectorWithOffset(0, sz - 1, data_ptr)
314
315template <class T>
316VectorWithOffset<T>::VectorWithOffset(const int min_index, const int max_index, shared_ptr<T[]> data_sptr)
317{
318 this->allocated_memory_sptr = data_sptr;
319 this->init(min_index, max_index, data_sptr.get(), /* copy_data = */ false);
320}
321
322template <class T>
325{
326 swap(*this, other);
327}
328
329template <class T>
331{
332 // check if data is being accessed via a pointer (see get_data_ptr())
333 assert(pointer_access == false);
334 _destruct_and_deallocate();
335}
336
337template <class T>
338void
340{
341 this->check_state();
342 // only do something when non-zero length
343 if (length == 0)
344 return;
345 num += start - min_index;
346 start = min_index;
347}
348
349template <class T>
350void
352{
353 this->set_offset(min_index);
354}
355
356template <class T>
357size_t
360 return size_t(end_allocated_memory - begin_allocated_memory);
361}
363template <class T>
364int
366{
367 // the behaviour for length==0 depends on num==begin_allocated_memory
368 assert(length > 0 || num == begin_allocated_memory);
369 return static_cast<int>(begin_allocated_memory - num);
370}
371
372template <class T>
373int
375{
376 // the behaviour for length==0 depends on num==begin_allocated_memory
377 assert(length > 0 || num == begin_allocated_memory);
378 return static_cast<int>(end_allocated_memory - num - 1);
379}
381// the new members will be initialised with the default constructor for T
382// but this should change in the future
383template <class T>
384void
385VectorWithOffset<T>::reserve(const int new_capacity_min_index, const int new_capacity_max_index)
386{
387 this->check_state();
388 const int actual_capacity_min_index
389 = length == 0 ? new_capacity_min_index : std::min(this->get_capacity_min_index(), new_capacity_min_index);
390 const int actual_capacity_max_index
391 = length == 0 ? new_capacity_max_index : std::max(this->get_capacity_max_index(), new_capacity_max_index);
392 if (actual_capacity_min_index > actual_capacity_max_index)
393 return;
394
395 const unsigned int new_capacity = static_cast<unsigned>(actual_capacity_max_index - actual_capacity_min_index) + 1;
396 if (new_capacity <= this->capacity())
397 return;
398
399 // check if data is being accessed via a pointer (see get_data_ptr())
400 assert(pointer_access == false);
401 // TODO use allocator here instead of new
402 shared_ptr<T[]> new_allocated_memory_sptr(new T[new_capacity]);
403 const unsigned extra_at_the_left = length == 0 ? 0U : std::max(0, this->get_min_index() - actual_capacity_min_index);
404 std::copy(this->begin(), this->end(), new_allocated_memory_sptr.get() + extra_at_the_left);
405 this->_destruct_and_deallocate();
406 allocated_memory_sptr = std::move(new_allocated_memory_sptr);
407 begin_allocated_memory = allocated_memory_sptr.get();
408 end_allocated_memory = begin_allocated_memory + new_capacity;
409 num = begin_allocated_memory + extra_at_the_left - (length > 0 ? start : 0);
410 this->check_state();
411}
412
413template <class T>
414void
415VectorWithOffset<T>::reserve(const unsigned int new_size)
416{
417 // note: for 0 new_size, we avoid a wrap-around
418 // otherwise we would be reserving quite a lot of memory!
419 if (new_size != 0)
420 reserve(0, static_cast<int>(new_size - 1));
421}
422
423// the new members will be initialised with the default constructor for T
424template <class T>
425void
426VectorWithOffset<T>::resize(const int min_index, const int max_index)
427{
428 this->check_state();
429 if (min_index > max_index)
430 {
431 length = 0;
432 start = 0;
433 num = begin_allocated_memory;
434 return;
435 }
436 const unsigned old_length = length;
437 if (old_length > 0)
438 {
439 if (min_index == this->get_min_index() && max_index == this->get_max_index())
440 return;
441 // determine overlapping range to avoid copying too much data when calling reserve()
442 const int overlap_min_index = std::max(this->get_min_index(), min_index);
443 const int overlap_max_index = std::min(this->get_max_index(), max_index);
444 // TODO when using non-initialised memory, call delete here on elements that go out of range
445 length = overlap_max_index - overlap_min_index < 0 ? 0 : static_cast<unsigned>(overlap_max_index - overlap_min_index) + 1;
446 if (length == 0)
447 {
448 start = 0;
449 num = begin_allocated_memory;
450 }
451 else
452 {
453 // do not change num as num[0] should remain the same
454 start = overlap_min_index;
455 }
456 } // end if (length>0)
457 const unsigned overlapping_length = length;
458 this->reserve(min_index, max_index);
459 // TODO when using allocator, call default constructor for new elements here
460 // (and delete the ones that go out of range!)
461 length = static_cast<unsigned>(max_index - min_index) + 1;
462 start = min_index;
463 if (overlapping_length > 0)
464 {
465 // do not change num as num[0] should remain the same
466 }
467 else
468 {
469 // we have reallocated the whole array, so set num correctly
470 num = begin_allocated_memory - min_index;
471 }
472 this->check_state();
473}
474
475template <class T>
476void
477VectorWithOffset<T>::resize(const unsigned new_size)
478{
479 if (new_size == 0)
480 {
481 length = 0;
482 start = 0;
483 num = begin_allocated_memory;
484 }
485 else
486 this->resize(0, static_cast<int>(new_size - 1));
487}
488
489template <class T>
490void
491VectorWithOffset<T>::grow(const int min_index, const int max_index)
492{
493 this->resize(min_index, max_index);
494}
495
496template <class T>
497void
498VectorWithOffset<T>::grow(const unsigned new_size)
499{
500 this->grow(0, static_cast<int>(new_size - 1));
501}
502
503template <class T>
504VectorWithOffset<T>&
506{
507 this->check_state();
508 if (this == &il)
509 return *this; // in case of x=x
510 {
511 if (this->capacity() < il.size())
512 {
513 // first truncate current and then reserve space
514 length = 0;
515 start = 0;
516 num = begin_allocated_memory;
517 this->reserve(il.get_min_index(), il.get_max_index());
518 }
519 length = il.length;
520 this->set_offset(il.get_min_index());
521 std::copy(il.begin(), il.end(), this->begin());
522 }
523
524 this->check_state();
525 return *this;
526}
527
528template <class T>
530 : pointer_access(false)
531{
532 this->init();
533 *this = il; // Uses assignment operator (above)
534}
535
536template <class T>
537int
539{
540 this->check_state();
541 return static_cast<int>(length);
542}
543
544template <class T>
545size_t
547{
548 this->check_state();
549 return size_t(length);
550}
551
552template <class T>
553bool
554VectorWithOffset<T>::operator==(const VectorWithOffset& iv) const
555{
556 this->check_state();
557 if (length != iv.length || start != iv.start)
558 return false;
559 return std::equal(this->begin(), this->end(), iv.begin());
560}
561
562template <class T>
563bool
564VectorWithOffset<T>::operator!=(const VectorWithOffset& iv) const
565{
566 return !(*this == iv);
567}
568
569template <class T>
570void
572{
573 this->check_state();
574 std::fill(this->begin(), this->end(), n);
575 this->check_state();
576}
577
578template <class T>
579inline void
581{
582 this->check_state();
583 threshold_lower(this->begin(), this->end(), lower);
584 this->check_state();
585}
586
587template <class T>
588inline void
590{
591 this->check_state();
592 threshold_upper(this->begin(), this->end(), upper);
593 this->check_state();
594}
595
610template <class T>
611T*
613{
614 assert(!pointer_access);
615
616 pointer_access = true;
617 return (num + start);
618
619 // if implementation changes, this would need to keep track
620 // if which pointer it returns.
621};
622
632template <class T>
633const T*
635{
636 assert(!pointer_access);
637
638 pointer_access = true;
639 return (num + start);
640
641 // if implementation changes, this would need to keep track
642 // if which pointer it returns.
643};
644
653template <class T>
654void
656{
657 assert(pointer_access);
658
659 pointer_access = false;
660}
661
669
670template <class T>
671void
673{
674 assert(pointer_access);
675
676 pointer_access = false;
677}
678
679/********************** arithmetic operators ****************/
680template <class T>
683{
684 this->check_state();
685#if 1
686 if (this->get_min_index() != v.get_min_index() && this->get_max_index() != v.get_max_index())
687 error("VectorWithOffset::+= with non-matching range");
688#else
689 // first check if *this is empty
690 if (this->get_length() == 0)
691 {
692 return *this = v;
693 }
694 this->grow(std::min(get_min_index(), v.get_min_index()), std::max(get_max_index(), v.get_max_index()));
695#endif
696 for (int i = v.get_min_index(); i <= v.get_max_index(); i++)
697 num[i] += v.num[i];
698 this->check_state();
699 return *this;
700}
701
702template <class T>
705{
706 this->check_state();
707#if 1
708 if (this->get_min_index() != v.get_min_index() && this->get_max_index() != v.get_max_index())
709 error("VectorWithOffset::-= with non-matching range");
710#else
711 // first check if *this is empty
712 if (get_length() == 0)
713 {
714 *this = v;
715 return *this *= -1;
716 }
717 grow(std::min(get_min_index(), v.get_min_index()), std::max(get_max_index(), v.get_max_index()));
718#endif
719 for (int i = v.get_min_index(); i <= v.get_max_index(); i++)
720 num[i] -= v.num[i];
721 this->check_state();
722 return *this;
723}
724
725template <class T>
728{
729 this->check_state();
730#if 1
731 if (this->get_min_index() != v.get_min_index() && this->get_max_index() != v.get_max_index())
732 error("VectorWithOffset::*= with non-matching range");
733#else
734 // first check if *this is empty
735 if (get_length() == 0)
736 {
737 // we have to return an object of the same dimensions as v, but filled with 0.
738 *this = v;
739 return *this *= 0;
740 }
741 grow(std::min(get_min_index(), v.get_min_index()), std::max(get_max_index(), v.get_max_index()));
742#endif
743 for (int i = v.get_min_index(); i <= v.get_max_index(); i++)
744 num[i] *= v.num[i];
745 this->check_state();
746 return *this;
747}
748
749template <class T>
752{
753 this->check_state();
754#if 1
755 if (this->get_min_index() != v.get_min_index() && this->get_max_index() != v.get_max_index())
756 error("VectorWithOffset::/= with non-matching range");
757#else
758 // first check if *this is empty
759 if (get_length() == 0)
760 {
761 // we have to return an object of the same dimensions as v, but filled with 0.
762 *this = v;
763 return *this *= 0;
764 }
765 grow(std::min(get_min_index(), v.get_min_index()), std::max(get_max_index(), v.get_max_index()));
766#endif
767 for (int i = v.get_min_index(); i <= v.get_max_index(); i++)
768 num[i] /= v.num[i];
769 this->check_state();
770 return *this;
771}
772
773/**** operator+=(T) etc *****/
774#if 0
775// disabled for now
776// warning: not tested
777template <class T>
778inline VectorWithOffset<T>&
780{
781 typename iterator iter = this->begin();
782 const typename iterator end_iter = this->end();
783 while (iter != end_iter)
784 *iter++ += t;
785}
786
787template <class T>
788inline VectorWithOffset<T>&
790{
791 typename iterator iter = this->begin();
792 const typename iterator end_iter = this->end();
793 while (iter != end_iter)
794 *iter++ -= t;
795}
796template <class T>
797inline VectorWithOffset<T>&
799{
800 typename iterator iter = this->begin();
801 const typename iterator end_iter = this->end();
802 while (iter != end_iter)
803 *iter++ *= t;
804}
805template <class T>
806inline VectorWithOffset<T>&
808{
809 typename iterator iter = this->begin();
810 const typename iterator end_iter = this->end();
811 while (iter != end_iter)
812 *iter++ /= t;
813}
814
815#endif
816
817/**** operator* etc ********/
818
819// addition
820template <class T>
823{
824 this->check_state();
825 VectorWithOffset retval(*this);
826 return retval += v;
827}
828
829// subtraction
830template <class T>
833{
834 this->check_state();
835 VectorWithOffset retval(*this);
836 return retval -= v;
837}
838
839// elem by elem multiplication
840template <class T>
843{
844 this->check_state();
845 VectorWithOffset retval(*this);
846 return retval *= v;
847}
848
849// elem by elem division
850template <class T>
853{
854 this->check_state();
855 VectorWithOffset retval(*this);
856 return retval /= v;
857}
858
859END_NAMESPACE_STIR
This file defines the stir::IndexRange class.
A templated class for vectors, but with indices starting not from 0.
Definition VectorWithOffset.h:65
void release_const_data_ptr() const
signal end of access to const T*
Definition VectorWithOffset.inl:672
T & at(int i)
allow array-style access, read/write, but with range checking (throws std::out_of_range)
Definition VectorWithOffset.inl:162
const T * get_const_data_ptr() const
member function for access to the data via a const T*
Definition VectorWithOffset.inl:634
iterator begin()
use to initialise an iterator to the first element of the vector
Definition VectorWithOffset.inl:190
VectorWithOffset & operator=(const VectorWithOffset &il)
assignment operator with another vector
Definition VectorWithOffset.inl:505
void check_state() const
Called internally to see if all variables are consistent.
Definition VectorWithOffset.inl:87
virtual ~VectorWithOffset()
Destructor.
Definition VectorWithOffset.inl:330
int get_max_index() const
get value of last valid index
Definition VectorWithOffset.inl:131
void init(const int min_index, const int max_index, T *const data_ptr, bool copy_data)
initialise vector to the given index range and either copy from or point to data_ptr
Definition VectorWithOffset.inl:56
VectorWithOffset & operator*=(const VectorWithOffset &v)
multiplying elements of the current vector with elements of v
Definition VectorWithOffset.inl:727
size_t capacity() const
get allocated size
Definition VectorWithOffset.inl:358
VectorWithOffset & operator+=(const VectorWithOffset &v)
adding elements of v to the current vector
Definition VectorWithOffset.inl:682
VectorWithOffset operator-(const VectorWithOffset &v) const
subtracting vectors, element by element
Definition VectorWithOffset.inl:832
int get_min_index() const
get value of first valid index
Definition VectorWithOffset.inl:124
virtual void grow(const int min_index, const int max_index)
grow the range of the vector, new elements are set to T()
Definition VectorWithOffset.inl:491
bool owns_memory_for_data() const
check if this object owns the memory for the data
Definition VectorWithOffset.inl:76
void release_data_ptr()
signal end of access to T*
Definition VectorWithOffset.inl:655
void reserve(const int min_index, const int max_index)
make the allocated range at least from min_index to max_index
Definition VectorWithOffset.inl:385
VectorWithOffset & operator-=(const VectorWithOffset &v)
subtracting elements of v from the current vector
Definition VectorWithOffset.inl:704
VectorWithOffset operator*(const VectorWithOffset &v) const
multiplying vectors, element by element
Definition VectorWithOffset.inl:842
VectorWithOffset operator+(const VectorWithOffset &v) const
adding vectors, element by element
Definition VectorWithOffset.inl:822
int get_length() const
return number of elements in this vector
Definition VectorWithOffset.inl:538
void set_min_index(const int min_index)
identical to set_offset()
Definition VectorWithOffset.inl:351
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
void set_offset(const int min_index)
change value of starting index
Definition VectorWithOffset.inl:339
VectorWithOffset & operator/=(const VectorWithOffset &v)
dividing all elements of the current vector by elements of v
Definition VectorWithOffset.inl:751
iterator end()
iterator 'past' the last element of the vector
Definition VectorWithOffset.inl:206
VectorWithOffset operator/(const VectorWithOffset &v) const
dividing vectors, element by element
Definition VectorWithOffset.inl:852
void apply_lower_threshold(const T &lower)
Sets elements below value to the value.
Definition VectorWithOffset.inl:580
int get_capacity_max_index() const
get max_index within allocated range
Definition VectorWithOffset.inl:374
VectorWithOffset()
Default constructor: creates a vector of length 0.
Definition VectorWithOffset.inl:253
void recycle()
Free all memory and make object as if default-constructed.
Definition VectorWithOffset.inl:115
void fill(const T &n)
fill elements with value n
Definition VectorWithOffset.inl:571
T * get_data_ptr()
member function for access to the data via a T*
Definition VectorWithOffset.inl:612
T & operator[](int i)
allow array-style access, read/write
Definition VectorWithOffset.inl:139
int get_capacity_min_index() const
get min_index within allocated range
Definition VectorWithOffset.inl:365
bool empty() const
checks if the vector is empty
Definition VectorWithOffset.inl:183
void init_with_copy(const int min_index, const int max_index, T const *const data_ptr)
change vector to the new index range and copy data from data_ptr
Definition VectorWithOffset.inl:47
void apply_upper_threshold(const T &upper)
Sets elements above value to the value.
Definition VectorWithOffset.inl:589
friend void swap(VectorWithOffset &first, VectorWithOffset &second)
Swap content/members of 2 objects.
Definition VectorWithOffset.h:141
T * num
pointer to (*this)[0] (taking get_min_index() into account that is).
Definition VectorWithOffset.h:370
size_t size() const
return number of elements in this vector
Definition VectorWithOffset.inl:546
Declaration of stir::error()
void error(const char *const s,...)
Print error with format string a la printf and throw exception.
Definition error.cxx:42
void threshold_upper(forw_iterT begin, forw_iterT end, const elemT new_max)
Threshold a sequence from above.
Definition thresholding.h:61
void threshold_lower(forw_iterT begin, forw_iterT end, const elemT new_min)
Threshold a sequence from below.
Definition thresholding.h:75
Declaration of functions that threshold sequences (specified by iterators).