36 #ifndef VIGRA_COORDINATE_ITERATOR_HXX
37 #define VIGRA_COORDINATE_ITERATOR_HXX
42 #include "accessor.hxx"
43 #include "tinyvector.hxx"
44 #include "numerictraits.hxx"
45 #include "multi_iterator.hxx"
46 #include "multi_array.hxx"
53 typedef typename MultiArrayShape<N>::type index_type;
54 typedef TinyVector<double, N> coord_type;
55 typedef coord_type deref_type;
56 typedef StridePair type;
57 typedef StridePair stride_type;
58 typedef TinyVector<type, N> stride_array_type;
59 typedef TinyVector<index_type, N> shape_array_type;
60 typedef shape_array_type shape_type;
65 StridePair(
const index_type & i) : index(i), coord(i) {}
66 StridePair(
const coord_type & c) : index(), coord(c) {}
67 StridePair(
const index_type & i,
const coord_type & c)
68 : index (i), coord(c) {}
70 : index(index_type(i)), coord(c) {}
74 const coord_type & operator*()
const
89 StridePair
operator+(
const StridePair & x)
91 StridePair ret = *
this;
95 StridePair
operator-(
const StridePair & x)
97 StridePair ret = *
this;
101 StridePair operator*(
const StridePair & x)
103 StridePair ret = *
this;
104 ret.index *= x.index;
105 ret.coord *= x.coord;
108 StridePair operator/(
const StridePair & x)
110 StridePair ret = *
this;
111 ret.index /= x.index;
112 ret.coord /= x.coord;
120 const index_type & idx()
const
136 struct NumericTraits<StridePair<M> >
137 :
public NumericTraits<typename StridePair<M>::index_type>
141 struct StridePairCoord :
public TinyVector<double, N>
143 typedef TinyVector<double, N> entry_type;
145 StridePairCoord(
const entry_type & c) : entry_type(c) {}
158 struct NumericTraits<StridePairCoord<M> >
159 :
public NumericTraits<typename StridePairCoord<M>::entry_type>
163 struct StridePairDiff :
public StridePairCoord<N>
167 typedef StridePairCoord<N> base_type;
169 : base_type(x), c(c_) {}
170 StridePairDiff(
const base_type & x)
171 : base_type(x), c(0) {}
172 StridePairDiff(
const TinyVector<double, N> & x)
173 : base_type(x), c(0) {}
174 StridePairDiff(
const TinyVector<MultiArrayIndex, N> & x)
175 : base_type(x), c(0) {}
176 StridePairDiff() : c(0) {}
178 const base_type & base()
const
182 StridePairDiff operator*(
const StridePairDiff & x)
184 StridePairDiff ret = base() * x.base();
191 struct NumericTraits<StridePairDiff<M> >
192 :
public NumericTraits<StridePairCoord<M> >
195 template<
unsigned N,
class T>
196 struct StridePairPointer :
public StridePairCoord<N>
198 typedef const T* index_type;
199 typedef StridePairCoord<N> coord_type;
200 typedef typename coord_type::entry_type coord_num_type;
201 typedef StridePairPointer type;
202 typedef type deref_type;
203 typedef StridePairDiff<N> stride_type;
204 typedef TinyVector<stride_type, N> stride_array_type;
205 typedef typename MultiArrayShape<N>::type shape_array_type;
206 typedef shape_array_type shape_type;
210 StridePairPointer(
const index_type & i,
const coord_type & c)
211 : coord_type(c), index(i) {}
213 const type & operator*()
const
217 const T & value()
const
221 const coord_type & coord()
const
230 const index_type & idx()
const
247 template<
unsigned M,
class T>
248 struct NumericTraits<StridePairPointer<M, T> >
249 :
public NumericTraits<typename StridePairPointer<M, T>::coord_type>
254 template<class T, bool is_complex = NumericTraits<T>::isComplex::value,
255 bool is_vector = !NumericTraits<T>::isScalar::value>
258 static double get(
const T & x)
265 struct weighted_abs<T, true, false>
267 static double get(
const T & x)
274 template<
class T,
bool is_complex>
275 struct weighted_abs<T, is_complex, true>
277 static double get(
const T & x)
279 return x.magnitude();
284 struct accumulable_coord_access;
286 struct accumulable_value_access;
288 struct accumulable_weighted_access;
290 template<
unsigned N,
class T>
291 struct accumulable_coord_access<StridePairPointer<N, T> >
293 typedef StridePairPointer<N, T> accumulable_type;
294 typedef typename accumulable_type::coord_num_type type;
295 static const type &
get(
const accumulable_type & v) {
return v.coord(); }
298 template<
unsigned N,
class T>
299 struct accumulable_value_access<StridePairPointer<N, T> >
301 typedef StridePairPointer<N, T> accumulable_type;
303 static const type &
get(
const accumulable_type & v) {
return v.value(); }
306 template<
unsigned N,
class T>
307 struct accumulable_weighted_access<StridePairPointer<N, T> >
309 typedef StridePairPointer<N, T> accumulable_type;
310 typedef typename accumulable_type::coord_num_type type;
311 static type
get(
const accumulable_type & v)
318 void dismember(X & r,
const X & x,
unsigned i)
323 void dismember(StridePair<N> & r,
const StridePair<N> & x,
unsigned i)
325 r.index[i] = x.index[i];
326 r.coord[i] = x.coord[i];
329 void dismember(StridePairDiff<N> & r,
const StridePairDiff<N> & x,
unsigned i)
334 template<
unsigned N,
class X>
336 dismember(
const X & x)
338 TinyVector<X, N> ret;
339 for (
unsigned i = 0; i != N; ++i)
340 dismember(ret[i], x, i);
344 TinyVector<StridePairDiff<N>, N>
345 dismember(
const TinyVector<MultiArrayIndex, N> & x,
346 const StridePairCoord<N> & y)
348 typedef StridePairDiff<N> type;
349 TinyVector<type, N> ret;
350 for (
unsigned i = 0; i != N; ++i)
366 template<
unsigned N,
class S = Str
idePair<N> >
367 class CoordinateStride :
protected S
371 typedef typename S::stride_type stride_type;
372 typedef typename S::deref_type deref_type;
373 typedef CoordinateStride<N> type;
374 typedef typename S::coord_type coord_type;
375 typedef typename S::index_type index_type;
376 typedef typename S::shape_array_type shape_array_type;
381 CoordinateStride(
void*) {}
384 CoordinateStride(
const S & x,
double s0)
385 : S(x), stride_0(s0) {}
409 dim0() += n * stride_0;
414 dim0() -= n * stride_0;
417 stride_type operator[](difference_type n)
const
424 stride_type operator[](stride_type x)
const
430 bool operator!=(
const CoordinateStride & y)
const
432 return idx() != y.idx();
434 bool operator==(
const CoordinateStride & y)
const
436 if (stride_0 != y.stride_0)
438 return idx() == y.idx();
440 bool operator<(
const CoordinateStride & y)
const
442 return idx() < y.idx();
445 bool operator<=(
const CoordinateStride & y)
const
447 if (stride_0 == y.stride_0)
451 bool operator>(
const CoordinateStride & y)
const
455 bool operator>=(
const CoordinateStride & y)
const
457 if (stride_0 == y.stride_0)
462 friend std::ostream &
463 operator<<(std::ostream & os,
const CoordinateStride & x)
465 os <<
"{" << x.stride_0 <<
": " <<
static_cast<const S &
>(x) <<
"}";
469 typedef MultiIterator<N, deref_type, const deref_type &, CoordinateStride>
473 template <
unsigned N,
class S>
474 struct MultiIteratorStrideTraits<CoordinateStride<N, S> >
476 typedef typename S::stride_type stride_type;
477 typedef typename S::stride_array_type stride_array_type;
478 typedef typename S::shape_array_type shape_array_type;
479 static stride_array_type shift(
const stride_array_type & s,
unsigned d)
481 stride_array_type ret;
482 for (
unsigned i = d; i != N; ++i)
488 template <
unsigned N>
489 struct CoordinateMultiIterator :
public CoordinateStride<N>::iterator_type
491 typedef CoordinateStride<N> ptr_type;
492 typedef typename ptr_type::iterator_type base_type;
493 typedef typename ptr_type::stride_type stride_type;
494 typedef typename ptr_type::shape_array_type shape_array_type;
495 typedef typename ptr_type::coord_type coord_type;
496 typedef typename ptr_type::index_type index_type;
498 CoordinateMultiIterator(
const stride_type & origin,
499 const stride_type & stride,
500 const index_type & shape)
502 : base_type(ptr_type(origin, stride.dim0()),
503 detail::dismember<N>(stride),
504 detail::dismember<N>(shape)) {}
506 CoordinateMultiIterator(
const base_type & x) : base_type(x) {}
512 struct CoordinateMultiRangeReturns
514 typedef CoordinateMultiIterator<N> iterator_type;
515 typedef typename iterator_type::coord_type coord_type;
516 typedef StridePair<N> pair_type;
517 typedef typename pair_type::type stride_type;
518 typedef typename pair_type::stride_array_type stride_array_type;
520 typedef typename AccessorTraits<coord_type>::default_const_accessor
522 typedef triple<iterator_type, stride_array_type, access_type> type;
527 template <
unsigned N>
528 typename detail::CoordinateMultiRangeReturns<N>::type
529 coordinateMultiRange(
const typename MultiArrayShape<N>::type & shape,
530 const TinyVector<double, N> & stride
531 = TinyVector<double, N>(1.0),
532 const TinyVector<double, N> & origin
533 = TinyVector<double, N>(0.0))
536 detail::CoordinateMultiRangeReturns<N>::stride_type stride_type;
538 detail::CoordinateMultiRangeReturns<N>::access_type access_type;
540 return typename detail::CoordinateMultiRangeReturns<N>::type
541 (CoordinateMultiIterator<N>(stride_type(0, origin),
542 stride_type(1, stride),
544 detail::dismember<N>(stride_type(shape)),
548 template <
unsigned N,
class T>
549 struct CombinedMultiIterator
550 :
public CoordinateStride<N, StridePairPointer<N, T> >::iterator_type
552 typedef StridePairPointer<N, T> pair_type;
553 typedef CoordinateStride<N, pair_type> ptr_type;
554 typedef typename ptr_type::iterator_type base_type;
555 typedef typename ptr_type::stride_type stride_type;
556 typedef typename ptr_type::coord_type coord_type;
557 typedef typename pair_type::shape_array_type shape_array_type;
559 CombinedMultiIterator(
const T* raw_pointer,
560 const stride_type & origin,
561 const TinyVector<MultiArrayIndex, N> & pointer_stride,
562 const stride_type & stride,
563 const shape_array_type & shape)
565 : base_type(ptr_type(pair_type(raw_pointer, origin), stride.dim0()),
566 detail::dismember<N>(pointer_stride, stride),
569 CombinedMultiIterator(
const base_type & x) : base_type(x) {}
572 template<
unsigned N,
class T>
573 struct SrcCoordinateMultiArrayRangeReturns
575 typedef CombinedMultiIterator<N, T> iterator_type;
576 typedef typename iterator_type::coord_type coord_type;
577 typedef typename iterator_type::pair_type pair_type;
578 typedef typename iterator_type::ptr_type ptr_type;
579 typedef typename ptr_type::deref_type deref_type;
580 typedef typename iterator_type::stride_type stride_type;
581 typedef typename pair_type::stride_array_type stride_array_type;
582 typedef typename pair_type::shape_array_type shape_array_type;
584 typedef typename AccessorTraits<deref_type>::default_const_accessor
586 typedef triple<iterator_type, stride_array_type, access_type> type;
591 struct CoordinateSteps
593 typedef const TinyVector<double, N> & type;
596 template <
unsigned int N,
class T,
class Str
ideTag>
597 inline typename SrcCoordinateMultiArrayRangeReturns<N, T>::type
598 srcCoordinateMultiArrayRange(
const MultiArrayView<N, T, StrideTag> & array,
599 typename CoordinateSteps<N>::type stride
600 = TinyVector<double, N>(1.0),
601 typename CoordinateSteps<N>::type origin
602 = TinyVector<double, N>(0.0))
604 typedef SrcCoordinateMultiArrayRangeReturns<N, T> returns;
605 typedef typename returns::type type;
606 typedef typename returns::stride_type stride_type;
607 typedef typename returns::access_type access_type;
608 typedef typename returns::iterator_type iterator_type;
609 typedef typename returns::shape_array_type shape_array_type;
611 shape_array_type shape = array.shape();
612 return type(iterator_type(array.traverser_begin().get(),
617 detail::dismember<N>(stride_type(shape)),
621 template <
class VALUETYPE,
class COORD>
622 struct AccessorCoordinatePair
624 typedef VALUETYPE value_type;
625 typedef COORD coord_type;
626 typedef AccessorCoordinatePair type;
629 const coord_type & c;
631 AccessorCoordinatePair(
const value_type & v_,
const coord_type & c_)
634 const value_type & value()
const
638 const coord_type & coord()
const
654 template <
class Accessor,
class COORD>
658 typedef typename Accessor::value_type forward_type;
659 typedef AccessorCoordinatePair<forward_type, COORD> value_type;
664 template <
class ITERATOR>
667 const typename ITERATOR::value_type & x = *i;
668 return value_type(a(&x.value()), x.coord());
672 template <
class ITERATOR,
class DIFFERENCE>
673 value_type
operator()(ITERATOR
const & i, DIFFERENCE
const & diff)
const
675 const typename ITERATOR::value_type & x = i[diff];
676 return value_type(a(&x.value()), x.coord());
680 template<
unsigned N,
class T,
class Accessor>
681 struct SrcCoordinateMultiArrayRangeAccessorReturns
683 typedef CombinedMultiIterator<N, T> iterator_type;
684 typedef typename iterator_type::coord_type coord_type;
685 typedef typename iterator_type::pair_type pair_type;
686 typedef typename iterator_type::ptr_type ptr_type;
687 typedef typename ptr_type::deref_type deref_type;
688 typedef typename iterator_type::stride_type stride_type;
689 typedef typename pair_type::stride_array_type stride_array_type;
690 typedef typename pair_type::shape_array_type shape_array_type;
692 typedef CoordinateConstValueAccessor<Accessor, coord_type> access_type;
693 typedef triple<iterator_type, stride_array_type, access_type> type;
696 template <
unsigned int N,
class T,
class Str
ideTag,
class Access>
697 inline typename SrcCoordinateMultiArrayRangeAccessorReturns<N, T, Access>::type
698 srcCoordinateMultiArrayRangeAccessor(
const MultiArrayView<N, T, StrideTag> &
701 typename CoordinateSteps<N>::type stride
702 = TinyVector<double, N>(1.0),
703 typename CoordinateSteps<N>::type origin
704 = TinyVector<double, N>(0.0))
706 typedef SrcCoordinateMultiArrayRangeAccessorReturns<N, T, Access> returns;
707 typedef typename returns::type type;
708 typedef typename returns::stride_type stride_type;
709 typedef typename returns::access_type access_type;
710 typedef typename returns::iterator_type iterator_type;
711 typedef typename returns::shape_array_type shape_array_type;
713 shape_array_type shape = array.shape();
714 return type(iterator_type(array.traverser_begin().get(),
719 detail::dismember<N>(stride_type(shape)),
727 template <
unsigned N>
729 operator<<(ostream & os, const vigra::StridePair<N> & x)
731 os <<
"[" << x.index <<
", " << x.coord <<
"]";
735 template <
unsigned N>
737 operator<<(ostream & os, const vigra::StridePairDiff<N> & x)
739 os <<
"<" << x.c <<
"; "
740 <<
static_cast<vigra::StridePairCoord<N>
>(x) <<
">";
744 template <
unsigned N,
class T>
746 operator<<(ostream & os, const vigra::StridePairPointer<N, T> & x)
748 os <<
"[" << x.value() <<
", " << x.coord() <<
"]";
752 template <
class VALUETYPE,
class COORD>
754 operator<<(ostream & os,
755 const vigra::AccessorCoordinatePair<VALUETYPE, COORD> & x)
757 os <<
"[" << x.value() <<
", " << x.coord() <<
"]";
763 #endif // VIGRA_COORDINATE_ITERATOR_HXX
CoupledHandleCast< TARGET_INDEX, Handle >::reference get(Handle &handle)
Definition: multi_handle.hxx:927
value_type operator()(ITERATOR const &i, DIFFERENCE const &diff) const
Definition: coordinate_iterator.hxx:673
Diff2D operator-(Diff2D const &a, Diff2D const &b)
Definition: diff2d.hxx:711
Diff2D operator+(Diff2D const &a, Diff2D const &b)
Definition: diff2d.hxx:739
std::ptrdiff_t MultiArrayIndex
Definition: multi_fwd.hxx:60
FFTWComplex< R > & operator-=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
subtract-assignment
Definition: fftw3.hxx:867
bool operator<=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less or equal
Definition: fixedpoint.hxx:521
FFTWComplex< R > & operator+=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
add-assignment
Definition: fftw3.hxx:859
value_type operator()(ITERATOR const &i) const
Definition: coordinate_iterator.hxx:665
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition: fftw3.hxx:841
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal
Definition: fftw3.hxx:825
bool operator<(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less than
Definition: fixedpoint.hxx:512
bool operator>=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater or equal
Definition: fixedpoint.hxx:539
FFTWComplex< R >::NormType abs(const FFTWComplex< R > &a)
absolute value (= magnitude)
Definition: fftw3.hxx:1002
Forward accessor to the value() part of the values an iterator points to.
Definition: coordinate_iterator.hxx:655
bool operator>(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater
Definition: fixedpoint.hxx:530