36#ifndef VIGRA_ACCUMULATOR_HXX
37#define VIGRA_ACCUMULATOR_HXX
40#pragma warning (disable: 4503)
43#include "accumulator-grammar.hxx"
45#include "metaprogramming.hxx"
46#include "bit_array.hxx"
47#include "static_assert.hxx"
48#include "mathutil.hxx"
50#include "multi_iterator_coupled.hxx"
52#include "multi_math.hxx"
53#include "eigensystem.hxx"
54#include "histogram.hxx"
57 #include "polytope.hxx"
59#include "functorexpression.hxx"
60#include "labelimage.hxx"
61#include "multi_labeling.hxx"
394template <
class T01=void,
class T02=void,
class T03=void,
class T04=void,
class T05=void,
395 class T06=void,
class T07=void,
class T08=void,
class T09=void,
class T10=void,
396 class T11=void,
class T12=void,
class T13=void,
class T14=void,
class T15=void,
397 class T16=void,
class T17=void,
class T18=void,
class T19=void,
class T20=
void>
399:
public MakeTypeList<
400 typename StandardizeTag<T01>::type, typename StandardizeTag<T02>::type, typename StandardizeTag<T03>::type,
401 typename StandardizeTag<T04>::type, typename StandardizeTag<T05>::type, typename StandardizeTag<T06>::type,
402 typename StandardizeTag<T07>::type, typename StandardizeTag<T08>::type, typename StandardizeTag<T09>::type,
403 typename StandardizeTag<T10>::type, typename StandardizeTag<T11>::type, typename StandardizeTag<T12>::type,
404 typename StandardizeTag<T13>::type, typename StandardizeTag<T14>::type, typename StandardizeTag<T15>::type,
405 typename StandardizeTag<T16>::type, typename StandardizeTag<T17>::type, typename StandardizeTag<T18>::type,
406 typename StandardizeTag<T19>::type, typename StandardizeTag<T20>::type
411template <
class T01,
class T02,
class T03,
class T04,
class T05,
412 class T06,
class T07,
class T08,
class T09,
class T10,
413 class T11,
class T12,
class T13,
class T14,
class T15,
414 class T16,
class T17,
class T18,
class T19,
class T20>
415struct StandardizeTag<
Select<T01, T02, T03, T04, T05,
416 T06, T07, T08, T09, T10,
417 T11, T12, T13, T14, T15,
418 T16, T17, T18, T19, T20>,
419 Select<T01, T02, T03, T04, T05,
420 T06, T07, T08, T09, T10,
421 T11, T12, T13, T14, T15,
422 T16, T17, T18, T19, T20> >
424 typedef typename Select<T01, T02, T03, T04, T05,
425 T06, T07, T08, T09, T10,
426 T11, T12, T13, T14, T15,
427 T16, T17, T18, T19, T20>::type type;
430struct AccumulatorBegin
432 typedef Select<> Dependencies;
434 static std::string name()
436 return "AccumulatorBegin (internal)";
441 template <
class T,
class BASE>
448struct AccumulatorEnd;
453struct LabelDispatchTag;
455template <
class T,
class TAG,
class CHAIN>
456struct HandleArgSelector;
458struct Error__Global_statistics_are_only_defined_for_AccumulatorChainArray;
470 static std::string name()
472 return std::string(
"LabelArg<") +
asString(INDEX) +
"> (internal)";
477 template <
class T,
class BASE>
481 typedef LabelArgTag Tag;
482 typedef void value_type;
483 typedef void result_type;
485 static const int value = INDEX;
486 static const unsigned int workInPass = 0;
496 static std::string name()
498 return std::string(
"CoordArg<") +
asString(INDEX) +
"> (internal)";
503 template <
class T,
class BASE>
507 typedef CoordArgTag Tag;
508 typedef void value_type;
509 typedef void result_type;
511 static const int value = INDEX;
512 static const unsigned int workInPass = 0;
516template <
class T,
class TAG,
class NEXT=AccumulatorEnd>
517struct AccumulatorBase;
519template <
class Tag,
class A>
522template <
class Tag,
class A,
class TargetTag=
typename A::Tag>
523struct LookupDependency;
527template <
class TAG,
class A>
528typename LookupTag<TAG, A>::reference
531template <
class TAG,
class A>
532typename LookupDependency<TAG, A>::result_type
533getDependency(A
const & a);
537namespace acc_detail {
548struct PushArgTagToTail
553#define VIGRA_PUSHARGTAG(TAG) \
554template <int INDEX, class TAIL> \
555struct PushArgTagToTail<TypeList<TAG<INDEX>, TAIL> > \
557 typedef typename Push<TAIL, TypeList<TAG<INDEX> > >::type type; \
560VIGRA_PUSHARGTAG(DataArg)
561VIGRA_PUSHARGTAG(WeightArg)
562VIGRA_PUSHARGTAG(CoordArg)
563VIGRA_PUSHARGTAG(LabelArg)
565#undef VIGRA_PUSHARGTAG
571struct AddDependencies;
573template <
class HEAD,
class TAIL>
574struct AddDependencies<TypeList<HEAD, TAIL> >
576 typedef typename AddDependencies<TAIL>::type TailWithDependencies;
577 typedef typename StandardizeDependencies<HEAD>::type HeadDependencies;
578 typedef typename AddDependencies<HeadDependencies>::type TransitiveHeadDependencies;
579 typedef TypeList<HEAD, TransitiveHeadDependencies> HeadWithDependencies;
580 typedef typename PushUnique<HeadWithDependencies, TailWithDependencies>::type UnsortedDependencies;
581 typedef typename PushArgTagToTail<UnsortedDependencies>::type type;
585struct AddDependencies<void>
592template <
class Dependencies>
593struct ActivateDependencies;
595template <
class HEAD,
class TAIL>
596struct ActivateDependencies<TypeList<HEAD, TAIL> >
598 template <
class Chain,
class ActiveFlags>
599 static void exec(ActiveFlags & flags)
601 LookupTag<HEAD, Chain>::type::activateImpl(flags);
602 ActivateDependencies<TAIL>::template exec<Chain>(flags);
605 template <
class Chain,
class ActiveFlags,
class GlobalFlags>
606 static void exec(ActiveFlags & flags, GlobalFlags & gflags)
608 LookupTag<HEAD, Chain>::type::template activateImpl<Chain>(flags, gflags);
609 ActivateDependencies<TAIL>::template exec<Chain>(flags, gflags);
613template <
class HEAD,
class TAIL>
614struct ActivateDependencies<TypeList<Global<HEAD>, TAIL> >
616 template <
class Chain,
class ActiveFlags,
class GlobalFlags>
617 static void exec(ActiveFlags & flags, GlobalFlags & gflags)
619 LookupTag<Global<HEAD>, Chain>::type::activateImpl(gflags);
620 ActivateDependencies<TAIL>::template exec<Chain>(flags, gflags);
625struct ActivateDependencies<void>
627 template <
class Chain,
class ActiveFlags>
628 static void exec(ActiveFlags &)
631 template <
class Chain,
class ActiveFlags,
class GlobalFlags>
632 static void exec(ActiveFlags &, GlobalFlags &)
637struct SeparateGlobalAndRegionTags;
639template <
class HEAD,
class TAIL>
640struct SeparateGlobalAndRegionTags<TypeList<HEAD, TAIL> >
642 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
643 typedef TypeList<HEAD, typename Inner::RegionTags> RegionTags;
644 typedef typename Inner::GlobalTags GlobalTags;
647template <
class HEAD,
class TAIL>
648struct SeparateGlobalAndRegionTags<TypeList<Global<HEAD>, TAIL> >
650 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
651 typedef typename Inner::RegionTags RegionTags;
652 typedef TypeList<HEAD, typename Inner::GlobalTags> GlobalTags;
655template <
int INDEX,
class TAIL>
656struct SeparateGlobalAndRegionTags<TypeList<DataArg<INDEX>, TAIL> >
658 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
659 typedef TypeList<DataArg<INDEX>,
typename Inner::RegionTags> RegionTags;
660 typedef TypeList<DataArg<INDEX>,
typename Inner::GlobalTags> GlobalTags;
663template <
int INDEX,
class TAIL>
664struct SeparateGlobalAndRegionTags<TypeList<LabelArg<INDEX>, TAIL> >
666 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
667 typedef TypeList<LabelArg<INDEX>,
typename Inner::RegionTags> RegionTags;
668 typedef TypeList<LabelArg<INDEX>,
typename Inner::GlobalTags> GlobalTags;
671template <
int INDEX,
class TAIL>
672struct SeparateGlobalAndRegionTags<TypeList<WeightArg<INDEX>, TAIL> >
674 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
675 typedef TypeList<WeightArg<INDEX>,
typename Inner::RegionTags> RegionTags;
676 typedef TypeList<WeightArg<INDEX>,
typename Inner::GlobalTags> GlobalTags;
679template <
int INDEX,
class TAIL>
680struct SeparateGlobalAndRegionTags<TypeList<CoordArg<INDEX>, TAIL> >
682 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
683 typedef TypeList<CoordArg<INDEX>,
typename Inner::RegionTags> RegionTags;
684 typedef TypeList<CoordArg<INDEX>,
typename Inner::GlobalTags> GlobalTags;
688struct SeparateGlobalAndRegionTags<void>
690 typedef void RegionTags;
691 typedef void GlobalTags;
700template <
class Accumulators>
701struct CollectAccumulatorNames;
703template <
class HEAD,
class TAIL>
704struct CollectAccumulatorNames<TypeList<HEAD, TAIL> >
706 template <
class BackInsertable>
707 static void exec(BackInsertable & a,
bool skipInternals=
true)
709 if(!skipInternals || HEAD::name().find(
"internal") == std::string::npos)
710 a.push_back(HEAD::name());
711 CollectAccumulatorNames<TAIL>::exec(a, skipInternals);
716struct CollectAccumulatorNames<void>
718 template <
class BackInsertable>
719 static void exec(BackInsertable &,
bool =
true)
724struct ApplyVisitorToTag;
726template <
class HEAD,
class TAIL>
727struct ApplyVisitorToTag<TypeList<HEAD, TAIL> >
729 template <
class Accu,
class Visitor>
730 static bool exec(Accu & a, std::string
const & tag, Visitor
const & v)
732 static std::string * name = VIGRA_SAFE_STATIC(name,
new std::string(
normalizeString(HEAD::name())));
735 v.template exec<HEAD>(a);
740 return ApplyVisitorToTag<TAIL>::exec(a, tag, v);
746struct ApplyVisitorToTag<void>
748 template <
class Accu,
class Visitor>
749 static bool exec(Accu &, std::string
const &, Visitor
const &)
755struct ActivateTag_Visitor
757 template <
class TAG,
class Accu>
758 void exec(Accu & a)
const
760 a.template activate<TAG>();
764struct TagIsActive_Visitor
768 template <
class TAG,
class Accu>
769 void exec(Accu & a)
const
771 result = a.template isActive<TAG>();
782struct SetHistogramBincount
784 template <
class Accu>
785 static void exec(Accu &, HistogramOptions
const &)
789template <
template <
int>
class Histogram>
790struct SetHistogramBincount<Histogram<0> >
792 template <
class Accu>
793 static void exec(Accu & a, HistogramOptions
const & options)
795 a.setBinCount(options.binCount);
800struct ApplyHistogramOptions
802 template <
class Accu>
803 static void exec(Accu &, HistogramOptions
const &)
808struct ApplyHistogramOptions<StandardQuantiles<TAG> >
810 template <
class Accu>
811 static void exec(Accu &, HistogramOptions
const &)
815template <
class TAG,
template <
class>
class MODIFIER>
816struct ApplyHistogramOptions<MODIFIER<TAG> >
817:
public ApplyHistogramOptions<TAG>
821struct ApplyHistogramOptions<IntegerHistogram<0> >
823 template <
class Accu>
824 static void exec(Accu & a, HistogramOptions
const & options)
826 SetHistogramBincount<IntegerHistogram<0> >::exec(a, options);
830template <
int BinCount>
831struct ApplyHistogramOptions<UserRangeHistogram<BinCount> >
833 template <
class Accu>
834 static void exec(Accu & a, HistogramOptions
const & options)
836 SetHistogramBincount<UserRangeHistogram<BinCount> >::exec(a, options);
837 if(a.scale_ == 0.0 && options.validMinMax())
838 a.setMinMax(options.minimum, options.maximum);
842template <
int BinCount>
843struct ApplyHistogramOptions<AutoRangeHistogram<BinCount> >
845 template <
class Accu>
846 static void exec(Accu & a, HistogramOptions
const & options)
848 SetHistogramBincount<AutoRangeHistogram<BinCount> >::exec(a, options);
849 if(a.scale_ == 0.0 && options.validMinMax())
850 a.setMinMax(options.minimum, options.maximum);
854template <
int BinCount>
855struct ApplyHistogramOptions<GlobalRangeHistogram<BinCount> >
857 template <
class Accu>
858 static void exec(Accu & a, HistogramOptions
const & options)
860 SetHistogramBincount<GlobalRangeHistogram<BinCount> >::exec(a, options);
863 if(options.validMinMax())
864 a.setMinMax(options.minimum, options.maximum);
866 a.setRegionAutoInit(options.local_auto_init);
883template <
unsigned LEVEL,
class GlobalAccumulatorHandle>
884struct AccumulatorEndImpl
886 typedef typename GlobalAccumulatorHandle::type GlobalAccumulatorType;
888 typedef AccumulatorEnd Tag;
889 typedef void value_type;
890 typedef bool result_type;
891 typedef BitArray<LEVEL> AccumulatorFlags;
893 static const unsigned int workInPass = 0;
894 static const int index = -1;
895 static const unsigned level = LEVEL;
897 AccumulatorFlags active_accumulators_;
898 mutable AccumulatorFlags is_dirty_;
899 GlobalAccumulatorHandle globalAccumulator_;
901 template <
class GlobalAccumulator>
902 void setGlobalAccumulator(GlobalAccumulator
const * a)
904 globalAccumulator_.pointer_ = a;
907 static std::string name()
909 return "AccumulatorEnd (internal)";
912 bool operator()()
const {
return false; }
913 bool get()
const {
return false; }
915 template <
unsigned,
class U>
919 template <
unsigned,
class U>
920 void pass(U
const &,
double)
924 void mergeImpl(U
const &)
928 void resize(U
const &)
932 void setCoordinateOffsetImpl(U
const &)
943 template <
class Flags>
944 static void activateImpl(Flags &)
947 template <
class Accu,
class Flags1,
class Flags2>
948 static void activateImpl(Flags1 &, Flags2 &)
951 template <
class Flags>
952 static bool isActiveImpl(Flags
const &)
957 void applyHistogramOptions(HistogramOptions
const &)
960 static unsigned int passesRequired()
965 static unsigned int passesRequired(AccumulatorFlags
const &)
972 active_accumulators_.clear();
977 void setDirtyImpl()
const
979 is_dirty_.template set<which>();
983 void setCleanImpl()
const
985 is_dirty_.template reset<which>();
989 bool isDirtyImpl()
const
991 return is_dirty_.template test<which>();
996template <
class A,
unsigned CurrentPass,
bool allowRuntimeActivation,
unsigned WorkPass=A::workInPass>
1000 static void exec(A &, T
const &)
1004 static void exec(A &, T
const &,
double)
1008template <
class A,
unsigned CurrentPass>
1009struct DecoratorImpl<A, CurrentPass, false, CurrentPass>
1012 static void exec(A & a, T
const & t)
1018 static void exec(A & a, T
const & t,
double weight)
1020 a.update(t, weight);
1023 static typename A::result_type
get(A
const & a)
1028 static void mergeImpl(A & a, A
const & o)
1034 static void resize(A & a, T
const & t)
1039 static void applyHistogramOptions(A & a, HistogramOptions
const & options)
1041 ApplyHistogramOptions<typename A::Tag>::exec(a, options);
1044 static unsigned int passesRequired()
1046 static const unsigned int A_workInPass = A::workInPass;
1047 return std::max(A_workInPass, A::InternalBaseType::passesRequired());
1051template <
class A,
unsigned CurrentPass>
1052struct DecoratorImpl<A, CurrentPass, true, CurrentPass>
1056 return A::isActiveImpl(getAccumulator<AccumulatorEnd>(a).active_accumulators_);
1060 static void exec(A & a, T
const & t)
1067 static void exec(A & a, T
const & t,
double weight)
1070 a.update(t, weight);
1073 static typename A::result_type
get(A
const & a)
1077 std::string message = std::string(
"get(accumulator): attempt to access inactive statistic '") +
1078 A::Tag::name() +
"'.";
1079 vigra_precondition(
false, message);
1084 static void mergeImpl(A & a, A
const & o)
1091 static void resize(A & a, T
const & t)
1097 static void applyHistogramOptions(A & a, HistogramOptions
const & options)
1100 ApplyHistogramOptions<typename A::Tag>::exec(a, options);
1103 template <
class ActiveFlags>
1104 static unsigned int passesRequired(ActiveFlags
const & flags)
1106 static const unsigned int A_workInPass = A::workInPass;
1107 return A::isActiveImpl(flags)
1108 ? std::max(A_workInPass, A::InternalBaseType::passesRequired(flags))
1109 : A::InternalBaseType::passesRequired(flags);
1115template <
class T,
class Shape>
1116void reshapeImpl(T &, Shape
const &)
1119template <
class T,
class Shape,
class Initial>
1120void reshapeImpl(T &, Shape
const &, Initial
const & = T())
1123template <
unsigned int N,
class T,
class Alloc,
class Shape>
1124void reshapeImpl(MultiArray<N, T, Alloc> & a, Shape
const & s, T
const & initial = T())
1126 MultiArray<N, T, Alloc>(s, initial).swap(a);
1129template <
class T,
class Alloc,
class Shape>
1130void reshapeImpl(Matrix<T, Alloc> & a, Shape
const & s, T
const & initial = T())
1132 Matrix<T, Alloc>(s, initial).swap(a);
1135template <
class T,
class U>
1136void copyShapeImpl(T
const &, U
const &)
1139template <
unsigned int N,
class T,
class Alloc,
class U>
1140void copyShapeImpl(MultiArray<N, T, Alloc>
const & from, U & to)
1142 to.reshape(from.shape());
1145template <
class T,
class Alloc,
class U>
1146void copyShapeImpl(Matrix<T, Alloc>
const & from, U & to)
1148 to.reshape(from.shape());
1151template <
class T,
class U>
1152bool hasDataImpl(T
const &)
1157template <
unsigned int N,
class T,
class Str
ide>
1158bool hasDataImpl(MultiArrayView<N, T, Stride>
const & a)
1164template <
unsigned int N,
class T,
class Str
ide>
1166shapeOf(MultiArrayView<N, T, Stride>
const & a)
1171template <
class T,
int N>
1173shapeOf(TinyVector<T, N>
const &)
1178template <
class T,
class NEXT>
1179inline CoupledHandle<T, NEXT>
const &
1180shapeOf(CoupledHandle<T, NEXT>
const & t)
1185#define VIGRA_SHAPE_OF(type) \
1192VIGRA_SHAPE_OF(
unsigned char)
1193VIGRA_SHAPE_OF(
signed char)
1194VIGRA_SHAPE_OF(
unsigned short)
1195VIGRA_SHAPE_OF(
short)
1196VIGRA_SHAPE_OF(
unsigned int)
1198VIGRA_SHAPE_OF(
unsigned long)
1200VIGRA_SHAPE_OF(
unsigned long long)
1201VIGRA_SHAPE_OF(
long long)
1202VIGRA_SHAPE_OF(
float)
1203VIGRA_SHAPE_OF(
double)
1204VIGRA_SHAPE_OF(
long double)
1206#undef VIGRA_SHAPE_OF
1215template <
class T,
class GlobalAccumulators,
class RegionAccumulators>
1218 typedef LabelDispatchTag Tag;
1219 typedef GlobalAccumulators GlobalAccumulatorChain;
1220 typedef RegionAccumulators RegionAccumulatorChain;
1221 typedef typename LookupTag<AccumulatorEnd, RegionAccumulatorChain>::type::AccumulatorFlags ActiveFlagsType;
1222 typedef ArrayVector<RegionAccumulatorChain> RegionAccumulatorArray;
1224 typedef LabelDispatch type;
1225 typedef LabelDispatch & reference;
1226 typedef LabelDispatch
const & const_reference;
1227 typedef GlobalAccumulatorChain InternalBaseType;
1229 typedef T
const & argument_type;
1230 typedef argument_type first_argument_type;
1231 typedef double second_argument_type;
1232 typedef RegionAccumulatorChain & result_type;
1234 static const int index = GlobalAccumulatorChain::index + 1;
1236 template <
class IndexDefinition,
class TagFound=
typename IndexDefinition::Tag>
1237 struct CoordIndexSelector
1239 static const int value = 0;
1242 template <
class IndexDefinition>
1243 struct CoordIndexSelector<IndexDefinition, CoordArgTag>
1245 static const int value = IndexDefinition::value;
1248 static const int coordIndex = CoordIndexSelector<typename LookupTag<CoordArgTag, GlobalAccumulatorChain>::type>::value;
1249 static const int coordSize = CoupledHandleCast<coordIndex, T>::type::value_type::static_size;
1250 typedef TinyVector<double, coordSize> CoordinateType;
1252 GlobalAccumulatorChain next_;
1253 RegionAccumulatorArray regions_;
1254 HistogramOptions region_histogram_options_;
1256 ActiveFlagsType active_region_accumulators_;
1257 CoordinateType coordinateOffset_;
1259 template <
class TAG>
1262 typedef typename LookupTag<TAG, type>::type TargetAccumulator;
1264 static void activate(GlobalAccumulatorChain & globals, RegionAccumulatorArray & regions,
1265 ActiveFlagsType & flags)
1267 TargetAccumulator::template activateImpl<LabelDispatch>(
1268 flags, getAccumulator<AccumulatorEnd>(globals).active_accumulators_);
1269 for(
unsigned int k=0; k<regions.size(); ++k)
1270 getAccumulator<AccumulatorEnd>(regions[k]).active_accumulators_ = flags;
1273 static bool isActive(GlobalAccumulatorChain
const &, ActiveFlagsType
const & flags)
1275 return TargetAccumulator::isActiveImpl(flags);
1279 template <
class TAG>
1280 struct ActivateImpl<Global<TAG> >
1282 static void activate(GlobalAccumulatorChain & globals, RegionAccumulatorArray &, ActiveFlagsType &)
1284 LookupTag<TAG, GlobalAccumulatorChain>::type::activateImpl(getAccumulator<AccumulatorEnd>(globals).active_accumulators_);
1287 static bool isActive(GlobalAccumulatorChain
const & globals, ActiveFlagsType
const &)
1289 return LookupTag<TAG, GlobalAccumulatorChain>::type::isActiveImpl(getAccumulator<AccumulatorEnd>(globals).active_accumulators_);
1293 template <
int INDEX>
1294 struct ActivateImpl<LabelArg<INDEX> >
1296 static void activate(GlobalAccumulatorChain &, RegionAccumulatorArray &, ActiveFlagsType &)
1299 static bool isActive(GlobalAccumulatorChain
const & globals, ActiveFlagsType
const &)
1301 return getAccumulator<LabelArg<INDEX> >(globals).
isActive();
1308 region_histogram_options_(),
1310 active_region_accumulators_()
1313 LabelDispatch(LabelDispatch
const & o)
1315 regions_(o.regions_),
1316 region_histogram_options_(o.region_histogram_options_),
1317 ignore_label_(o.ignore_label_),
1318 active_region_accumulators_(o.active_region_accumulators_)
1320 for(
unsigned int k=0; k<regions_.size(); ++k)
1322 getAccumulator<AccumulatorEnd>(regions_[k]).setGlobalAccumulator(&next_);
1331 void setMaxRegionLabel(
unsigned maxlabel)
1335 unsigned int oldSize = regions_.size();
1336 regions_.resize(maxlabel + 1);
1337 for(
unsigned int k=oldSize; k<regions_.size(); ++k)
1339 getAccumulator<AccumulatorEnd>(regions_[k]).setGlobalAccumulator(&next_);
1340 getAccumulator<AccumulatorEnd>(regions_[k]).active_accumulators_ = active_region_accumulators_;
1341 regions_[k].applyHistogramOptions(region_histogram_options_);
1342 regions_[k].setCoordinateOffsetImpl(coordinateOffset_);
1353 return ignore_label_;
1356 void applyHistogramOptions(HistogramOptions
const & options)
1358 applyHistogramOptions(options, options);
1361 void applyHistogramOptions(HistogramOptions
const & regionoptions,
1362 HistogramOptions
const & globaloptions)
1364 region_histogram_options_ = regionoptions;
1365 for(
unsigned int k=0; k<regions_.size(); ++k)
1367 regions_[k].applyHistogramOptions(region_histogram_options_);
1369 next_.applyHistogramOptions(globaloptions);
1372 void setCoordinateOffsetImpl(CoordinateType
const & offset)
1374 coordinateOffset_ = offset;
1375 for(
unsigned int k=0; k<regions_.size(); ++k)
1377 regions_[k].setCoordinateOffsetImpl(coordinateOffset_);
1379 next_.setCoordinateOffsetImpl(coordinateOffset_);
1382 void setCoordinateOffsetImpl(
MultiArrayIndex k, CoordinateType
const & offset)
1385 "Accumulator::setCoordinateOffset(k, offset): region k does not exist.");
1386 regions_[k].setCoordinateOffsetImpl(offset);
1390 void resize(U
const & t)
1392 if(regions_.size() == 0)
1394 typedef HandleArgSelector<U, LabelArgTag, GlobalAccumulatorChain> LabelHandle;
1395 typedef typename LabelHandle::value_type LabelType;
1396 typedef MultiArrayView<LabelHandle::size, LabelType, StridedArrayTag> LabelArray;
1397 LabelArray labelArray(t.shape(), LabelHandle::getHandle(t).strides(),
1398 const_cast<LabelType *
>(LabelHandle::getHandle(t).ptr()));
1400 LabelType minimum, maximum;
1401 labelArray.minmax(&minimum, &maximum);
1402 setMaxRegionLabel(maximum);
1406 for(
unsigned int k=0; k<regions_.size(); ++k)
1407 regions_[k].resize(t);
1410 template <
unsigned N>
1411 void pass(T
const & t)
1413 typedef HandleArgSelector<T, LabelArgTag, GlobalAccumulatorChain> LabelHandle;
1414 if(LabelHandle::getValue(t) != ignore_label_)
1416 next_.template pass<N>(t);
1417 regions_[LabelHandle::getValue(t)].template pass<N>(t);
1421 template <
unsigned N>
1422 void pass(T
const & t,
double weight)
1424 typedef HandleArgSelector<T, LabelArgTag, GlobalAccumulatorChain> LabelHandle;
1425 if(LabelHandle::getValue(t) != ignore_label_)
1427 next_.template pass<N>(t, weight);
1428 regions_[LabelHandle::getValue(t)].template pass<N>(t, weight);
1432 static unsigned int passesRequired()
1434 return std::max(GlobalAccumulatorChain::passesRequired(), RegionAccumulatorChain::passesRequired());
1437 unsigned int passesRequiredDynamic()
const
1439 return std::max(GlobalAccumulatorChain::passesRequired(getAccumulator<AccumulatorEnd>(next_).active_accumulators_),
1440 RegionAccumulatorChain::passesRequired(active_region_accumulators_));
1447 active_region_accumulators_.clear();
1448 RegionAccumulatorArray().swap(regions_);
1454 template <
class TAG>
1457 ActivateImpl<TAG>::activate(next_, regions_, active_region_accumulators_);
1462 getAccumulator<AccumulatorEnd>(next_).active_accumulators_.set();
1463 active_region_accumulators_.set();
1464 for(
unsigned int k=0; k<regions_.size(); ++k)
1465 getAccumulator<AccumulatorEnd>(regions_[k]).active_accumulators_.set();
1468 template <
class TAG>
1471 return ActivateImpl<TAG>::isActive(next_, active_region_accumulators_);
1474 void mergeImpl(LabelDispatch
const & o)
1476 for(
unsigned int k=0; k<regions_.size(); ++k)
1477 regions_[k].mergeImpl(o.regions_[k]);
1478 next_.mergeImpl(o.next_);
1481 void mergeImpl(
unsigned i,
unsigned j)
1483 regions_[i].mergeImpl(regions_[j]);
1484 regions_[j].reset();
1485 getAccumulator<AccumulatorEnd>(regions_[j]).active_accumulators_ = active_region_accumulators_;
1488 template <
class ArrayLike>
1489 void mergeImpl(LabelDispatch
const & o, ArrayLike
const & labelMapping)
1491 MultiArrayIndex newMaxLabel = std::max<MultiArrayIndex>(maxRegionLabel(), *
argMax(labelMapping.begin(), labelMapping.end()));
1492 setMaxRegionLabel(newMaxLabel);
1493 for(
unsigned int k=0; k<labelMapping.size(); ++k)
1494 regions_[labelMapping[k]].mergeImpl(o.regions_[k]);
1495 next_.mergeImpl(o.next_);
1499template <
class TargetTag,
class TagList>
1502template <
class TargetTag,
class HEAD,
class TAIL>
1503struct FindNextTag<TargetTag, TypeList<HEAD, TAIL> >
1505 typedef typename FindNextTag<TargetTag, TAIL>::type type;
1508template <
class TargetTag,
class TAIL>
1509struct FindNextTag<TargetTag, TypeList<TargetTag, TAIL> >
1511 typedef typename TAIL::Head type;
1514template <
class TargetTag>
1515struct FindNextTag<TargetTag, TypeList<TargetTag, void> >
1520template <
class TargetTag>
1521struct FindNextTag<TargetTag, void>
1527template <
class TAG,
class CONFIG,
unsigned LEVEL=0>
1528struct AccumulatorFactory
1530 typedef typename FindNextTag<TAG, typename CONFIG::TagList>::type NextTag;
1531 typedef typename AccumulatorFactory<NextTag, CONFIG, LEVEL+1>::type NextType;
1532 typedef typename CONFIG::InputType InputType;
1543 template <
class T,
class NEXT>
1544 struct ConfigureTag<CoupledHandle<T, NEXT> >
1546 typedef typename StandardizeTag<DataFromHandle<TAG> >::type WrappedTag;
1547 typedef typename IfBool<(!HasModifierPriority<WrappedTag, WeightingPriority>::value && ShouldBeWeighted<WrappedTag>::value),
1548 Weighted<WrappedTag>, WrappedTag>::type type;
1551 typedef typename ConfigureTag<InputType>::type UseTag;
1555 struct AccumulatorBase
1557 typedef AccumulatorBase ThisType;
1559 typedef NextType InternalBaseType;
1560 typedef InputType input_type;
1561 typedef input_type
const & argument_type;
1562 typedef argument_type first_argument_type;
1563 typedef double second_argument_type;
1564 typedef void result_type;
1566 static const unsigned int workInPass = 1;
1567 static const int index = InternalBaseType::index + 1;
1569 InternalBaseType next_;
1571 static std::string name()
1576 template <
class ActiveFlags>
1577 static void activateImpl(ActiveFlags & flags)
1579 flags.template set<index>();
1580 typedef typename StandardizeDependencies<Tag>::type StdDeps;
1581 acc_detail::ActivateDependencies<StdDeps>::template exec<ThisType>(flags);
1584 template <
class Accu,
class ActiveFlags,
class GlobalFlags>
1585 static void activateImpl(ActiveFlags & flags, GlobalFlags & gflags)
1587 flags.template set<index>();
1588 typedef typename StandardizeDependencies<Tag>::type StdDeps;
1589 acc_detail::ActivateDependencies<StdDeps>::template exec<Accu>(flags, gflags);
1592 template <
class ActiveFlags>
1593 static bool isActiveImpl(ActiveFlags & flags)
1595 return flags.template test<index>();
1598 void setDirty()
const
1600 next_.template setDirtyImpl<index>();
1603 template <
int INDEX>
1604 void setDirtyImpl()
const
1606 next_.template setDirtyImpl<INDEX>();
1609 void setClean()
const
1611 next_.template setCleanImpl<index>();
1614 template <
int INDEX>
1615 void setCleanImpl()
const
1617 next_.template setCleanImpl<INDEX>();
1620 bool isDirty()
const
1622 return next_.template isDirtyImpl<index>();
1625 template <
int INDEX>
1626 bool isDirtyImpl()
const
1628 return next_.template isDirtyImpl<INDEX>();
1634 template <
class Shape>
1635 void setCoordinateOffset(Shape
const &)
1638 template <
class Shape>
1639 void reshape(Shape
const &)
1646 void update(U
const &)
1650 void update(U
const &,
double)
1653 template <
class TargetTag>
1654 typename LookupDependency<TargetTag, ThisType>::result_type
1655 call_getDependency()
const
1657 return getDependency<TargetTag>(*
this);
1662 typedef typename UseTag::template Impl<InputType, AccumulatorBase> AccumulatorImpl;
1669 :
public AccumulatorImpl
1671 typedef Accumulator type;
1672 typedef Accumulator & reference;
1673 typedef Accumulator
const & const_reference;
1674 typedef AccumulatorImpl A;
1676 static const unsigned int workInPass = A::workInPass;
1677 static const bool allowRuntimeActivation = CONFIG::allowRuntimeActivation;
1680 void resize(T
const & t)
1682 this->next_.resize(t);
1683 DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::resize(*
this, t);
1688 this->next_.reset();
1692 typename A::result_type
get()
const
1694 return DecoratorImpl<A, workInPass, allowRuntimeActivation>::get(*
this);
1697 template <
unsigned N,
class T>
1698 void pass(T
const & t)
1700 this->next_.template pass<N>(t);
1701 DecoratorImpl<Accumulator, N, allowRuntimeActivation>::exec(*
this, t);
1704 template <
unsigned N,
class T>
1705 void pass(T
const & t,
double weight)
1707 this->next_.template pass<N>(t, weight);
1708 DecoratorImpl<Accumulator, N, allowRuntimeActivation>::exec(*
this, t, weight);
1711 void mergeImpl(Accumulator
const & o)
1713 DecoratorImpl<Accumulator, Accumulator::workInPass, allowRuntimeActivation>::mergeImpl(*
this, o);
1714 this->next_.mergeImpl(o.next_);
1717 void applyHistogramOptions(HistogramOptions
const & options)
1719 DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::applyHistogramOptions(*
this, options);
1720 this->next_.applyHistogramOptions(options);
1723 template <
class SHAPE>
1724 void setCoordinateOffsetImpl(SHAPE
const & offset)
1726 this->setCoordinateOffset(offset);
1727 this->next_.setCoordinateOffsetImpl(offset);
1730 static unsigned int passesRequired()
1732 return DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::passesRequired();
1735 template <
class ActiveFlags>
1736 static unsigned int passesRequired(ActiveFlags
const & flags)
1738 return DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::passesRequired(flags);
1742 typedef Accumulator type;
1745template <
class CONFIG,
unsigned LEVEL>
1746struct AccumulatorFactory<void, CONFIG, LEVEL>
1748 typedef AccumulatorEndImpl<LEVEL, typename CONFIG::GlobalAccumulatorHandle> type;
1751struct InvalidGlobalAccumulatorHandle
1753 typedef Error__Global_statistics_are_only_defined_for_AccumulatorChainArray type;
1755 InvalidGlobalAccumulatorHandle()
1759 type
const * pointer_;
1765template <
class T,
class Selected,
bool dynamic=false,
class GlobalHandle=Inval
idGlobalAccumulatorHandle>
1766struct ConfigureAccumulatorChain
1768:
public ConfigureAccumulatorChain<T, typename AddDependencies<typename Selected::type>::type, dynamic>
1772template <
class T,
class HEAD,
class TAIL,
bool dynamic,
class GlobalHandle>
1773struct ConfigureAccumulatorChain<T, TypeList<HEAD, TAIL>, dynamic, GlobalHandle>
1775 typedef TypeList<HEAD, TAIL> TagList;
1776 typedef T InputType;
1777 static const bool allowRuntimeActivation = dynamic;
1778 typedef GlobalHandle GlobalAccumulatorHandle;
1780 typedef typename AccumulatorFactory<HEAD, ConfigureAccumulatorChain>::type type;
1783template <
class T,
class Selected,
bool dynamic=false>
1784struct ConfigureAccumulatorChainArray
1786:
public ConfigureAccumulatorChainArray<T, typename AddDependencies<typename Selected::type>::type, dynamic>
1790template <
class T,
class HEAD,
class TAIL,
bool dynamic>
1791struct ConfigureAccumulatorChainArray<T, TypeList<HEAD, TAIL>, dynamic>
1793 typedef TypeList<HEAD, TAIL> TagList;
1794 typedef SeparateGlobalAndRegionTags<TagList> TagSeparator;
1795 typedef typename TagSeparator::GlobalTags GlobalTags;
1796 typedef typename TagSeparator::RegionTags RegionTags;
1797 typedef typename ConfigureAccumulatorChain<T, GlobalTags, dynamic>::type GlobalAccumulatorChain;
1799 struct GlobalAccumulatorHandle
1801 typedef GlobalAccumulatorChain type;
1803 GlobalAccumulatorHandle()
1807 type
const * pointer_;
1810 typedef typename ConfigureAccumulatorChain<T, RegionTags, dynamic, GlobalAccumulatorHandle>::type RegionAccumulatorChain;
1812 typedef LabelDispatch<T, GlobalAccumulatorChain, RegionAccumulatorChain> type;
1824template <
class T,
class NEXT>
1825class AccumulatorChainImpl
1828 typedef NEXT InternalBaseType;
1829 typedef AccumulatorBegin Tag;
1830 typedef typename InternalBaseType::argument_type argument_type;
1831 typedef typename InternalBaseType::first_argument_type first_argument_type;
1832 typedef typename InternalBaseType::second_argument_type second_argument_type;
1833 typedef void value_type;
1834 typedef typename InternalBaseType::result_type result_type;
1836 static const int staticSize = InternalBaseType::index;
1838 InternalBaseType next_;
1842 unsigned int current_pass_;
1844 AccumulatorChainImpl()
1850 void setHistogramOptions(HistogramOptions
const & options)
1852 next_.applyHistogramOptions(options);
1858 void setHistogramOptions(HistogramOptions
const & regionoptions, HistogramOptions
const & globaloptions)
1860 next_.applyHistogramOptions(regionoptions, globaloptions);
1869 template <
class SHAPE>
1870 void setCoordinateOffset(SHAPE
const & offset)
1872 next_.setCoordinateOffsetImpl(offset);
1877 void reset(
unsigned int reset_to_pass = 0)
1879 current_pass_ = reset_to_pass;
1880 if(reset_to_pass == 0)
1884 template <
unsigned N>
1885 void update(T
const & t)
1887 if(current_pass_ == N)
1889 next_.template pass<N>(t);
1891 else if(current_pass_ < N)
1895 next_.resize(acc_detail::shapeOf(t));
1896 next_.template pass<N>(t);
1900 std::string message(
"AccumulatorChain::update(): cannot return to pass ");
1901 message << N <<
" after working on pass " << current_pass_ <<
".";
1902 vigra_precondition(
false, message);
1906 template <
unsigned N>
1907 void update(T
const & t,
double weight)
1909 if(current_pass_ == N)
1911 next_.template pass<N>(t, weight);
1913 else if(current_pass_ < N)
1917 next_.resize(acc_detail::shapeOf(t));
1918 next_.template pass<N>(t, weight);
1922 std::string message(
"AccumulatorChain::update(): cannot return to pass ");
1923 message << N <<
" after working on pass " << current_pass_ <<
".";
1924 vigra_precondition(
false, message);
1930 void operator+=(AccumulatorChainImpl
const & o)
1937 void merge(AccumulatorChainImpl
const & o)
1939 next_.mergeImpl(o.next_);
1942 result_type operator()()
const
1947 void operator()(T
const & t)
1952 void operator()(T
const & t,
double weight)
1954 update<1>(t, weight);
1957 void updatePass2(T
const & t)
1962 void updatePass2(T
const & t,
double weight)
1964 update<2>(t, weight);
1969 void updatePassN(T
const & t,
unsigned int N)
1973 case 1: update<1>(t);
break;
1974 case 2: update<2>(t);
break;
1975 case 3: update<3>(t);
break;
1976 case 4: update<4>(t);
break;
1977 case 5: update<5>(t);
break;
1979 vigra_precondition(
false,
1980 "AccumulatorChain::updatePassN(): 0 < N < 6 required.");
1986 void updatePassN(T
const & t,
double weight,
unsigned int N)
1990 case 1: update<1>(t, weight);
break;
1991 case 2: update<2>(t, weight);
break;
1992 case 3: update<3>(t, weight);
break;
1993 case 4: update<4>(t, weight);
break;
1994 case 5: update<5>(t, weight);
break;
1996 vigra_precondition(
false,
1997 "AccumulatorChain::updatePassN(): 0 < N < 6 required.");
2003 unsigned int passesRequired()
const
2005 return InternalBaseType::passesRequired();
2041template <
class T,
class Selected,
bool dynamic=false>
2044:
public AccumulatorChainImpl<T, typename acc_detail::ConfigureAccumulatorChain<T, Selected, dynamic>::type>
2049 typedef typename acc_detail::ConfigureAccumulatorChain<T, Selected, dynamic>::TagList AccumulatorTags;
2053 template <
class U,
int N>
2056 vigra_precondition(this->current_pass_ == 0,
2057 "AccumulatorChain::reshape(): cannot reshape after seeing data. Call AccumulatorChain::reset() first.");
2058 this->next_.resize(s);
2059 this->current_pass_ = 1;
2083 template <
class SHAPE>
2087 void reset(
unsigned int reset_to_pass = 0);
2094 void merge(AccumulatorChainImpl
const & o);
2114 acc_detail::CollectAccumulatorNames<AccumulatorTags>::exec(n);
2120template <
unsigned int N,
class T1,
class T2,
class T3,
class T4,
class T5,
class Selected,
bool dynamic>
2121class AccumulatorChain<
CoupledArrays<N, T1, T2, T3, T4, T5>, Selected, dynamic>
2122:
public AccumulatorChain<typename CoupledArrays<N, T1, T2, T3, T4, T5>::HandleType, Selected, dynamic>
2156template <
class T,
class Selected>
2162 typedef typename DynamicAccumulatorChain::AccumulatorTags AccumulatorTags;
2168 vigra_precondition(activateImpl(tag),
2169 std::string(
"DynamicAccumulatorChain::activate(): Tag '") + tag +
"' not found.");
2174 template <
class TAG>
2177 LookupTag<TAG, DynamicAccumulatorChain>::type::activateImpl(getAccumulator<AccumulatorEnd>(*this).active_accumulators_);
2184 getAccumulator<AccumulatorEnd>(*this).active_accumulators_.set();
2190 acc_detail::TagIsActive_Visitor v;
2191 vigra_precondition(isActiveImpl(tag, v),
2192 std::string(
"DynamicAccumulatorChain::isActive(): Tag '") + tag +
"' not found.");
2198 template <
class TAG>
2201 return LookupTag<TAG, DynamicAccumulatorChain>::type::isActiveImpl(getAccumulator<AccumulatorEnd>(*this).active_accumulators_);
2219 return InternalBaseType::passesRequired(getAccumulator<AccumulatorEnd>(*this).active_accumulators_);
2224 bool activateImpl(std::string tag)
2226 return acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec(*
this,
2230 bool isActiveImpl(std::string tag, acc_detail::TagIsActive_Visitor & v)
const
2232 return acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec(*
this,
normalizeString(tag), v);
2236template <
unsigned int N,
class T1,
class T2,
class T3,
class T4,
class T5,
class Selected>
2237class DynamicAccumulatorChain<CoupledArrays<N, T1, T2, T3, T4, T5>, Selected>
2238:
public DynamicAccumulatorChain<typename CoupledArrays<N, T1, T2, T3, T4, T5>::HandleType, Selected>
2267template<
unsigned int N,
class T,
class SELECT>
2273 typedef typename CoupledHandleType<N, T>::type HandleType;
2274 typedef typename HandleType::base_type CoordHandle;
2275 typedef typename CoordHandle::value_type CoordType;
2276 typedef SELECT SelectType;
2281 handle_((T
const *)0, CoordType(), CoordHandle(CoordType()))
2284 void updatePassN(
const T & val,
const CoordType & coord,
unsigned int p)
2286 cast<0>(handle_).internal_reset(coord);
2287 cast<1>(handle_).internal_reset(&val);
2317template<
unsigned int N,
class SELECT>
2323 typedef typename CoupledHandleType<N>::type HandleType;
2324 typedef typename HandleType::value_type CoordType;
2326 typedef SELECT SelectType;
2331 handle_(CoordType())
2334 template<
class IGNORED_DATA>
2336 updatePassN(
const IGNORED_DATA &,
2337 const CoordType & coord,
2340 this->updatePassN(coord, p);
2344 void updatePassN(
const CoordType & coord,
unsigned int p)
2346 handle_.internal_reset(coord);
2378template <
class T,
class Selected,
bool dynamic=false>
2381:
public AccumulatorChainImpl<T, typename acc_detail::ConfigureAccumulatorChainArray<T, Selected, dynamic>::type>
2385 typedef AccumulatorChainImpl<T, typename acc_detail::ConfigureAccumulatorChainArray<T, Selected, dynamic>::type> base_type;
2386 typedef typename acc_detail::ConfigureAccumulatorChainArray<T, Selected, dynamic> Creator;
2387 typedef typename Creator::TagList AccumulatorTags;
2388 typedef typename Creator::GlobalTags GlobalTags;
2389 typedef typename Creator::RegionTags RegionTags;
2395 this->next_.ignoreLabel(l);
2402 return this->next_.ignoredLabel();
2409 this->next_.setMaxRegionLabel(label);
2416 return this->next_.maxRegionLabel();
2423 return this->next_.regions_.size();
2438 "AccumulatorChainArray::merge(): region labels out of range.");
2439 this->next_.mergeImpl(i, j);
2449 "AccumulatorChainArray::merge(): maxRegionLabel must be equal.");
2450 this->next_.mergeImpl(o.next_);
2455 template <
class ArrayLike>
2458 vigra_precondition(labelMapping.size() == o.
regionCount(),
2459 "AccumulatorChainArray::merge(): labelMapping.size() must match regionCount() of RHS.");
2460 this->next_.mergeImpl(o.next_, labelMapping);
2471 using base_type::setCoordinateOffset;
2479 template <
class SHAPE>
2482 this->next_.setCoordinateOffsetImpl(k, offset);
2496 template <
class SHAPE>
2500 void reset(
unsigned int reset_to_pass = 0);
2517 acc_detail::CollectAccumulatorNames<AccumulatorTags>::exec(n);
2523template <
unsigned int N,
class T1,
class T2,
class T3,
class T4,
class T5,
class Selected,
bool dynamic>
2524class AccumulatorChainArray<
CoupledArrays<N, T1, T2, T3, T4, T5>, Selected, dynamic>
2525:
public AccumulatorChainArray<typename CoupledArrays<N, T1, T2, T3, T4, T5>::HandleType, Selected, dynamic>
2549template <
class T,
class Selected>
2554 typedef typename DynamicAccumulatorChainArray::AccumulatorTags AccumulatorTags;
2559 vigra_precondition(activateImpl(tag),
2560 std::string(
"DynamicAccumulatorChainArray::activate(): Tag '") + tag +
"' not found.");
2564 template <
class TAG>
2567 this->next_.template activate<TAG>();
2573 this->next_.activateAll();
2580 acc_detail::TagIsActive_Visitor v;
2581 vigra_precondition(isActiveImpl(tag, v),
2582 std::string(
"DynamicAccumulatorChainArray::isActive(): Tag '") + tag +
"' not found.");
2588 template <
class TAG>
2591 return this->next_.template isActive<TAG>();
2607 return this->next_.passesRequiredDynamic();
2612 bool activateImpl(std::string tag)
2614 return acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec(this->next_,
2618 bool isActiveImpl(std::string tag, acc_detail::TagIsActive_Visitor & v)
const
2620 return acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec(this->next_,
normalizeString(tag), v);
2624template <
unsigned int N,
class T1,
class T2,
class T3,
class T4,
class T5,
class Selected>
2625class DynamicAccumulatorChainArray<CoupledArrays<N, T1, T2, T3, T4, T5>, Selected>
2626:
public DynamicAccumulatorChainArray<typename CoupledArrays<N, T1, T2, T3, T4, T5>::HandleType, Selected>
2636struct Error__Attempt_to_access_inactive_statistic;
2638namespace acc_detail {
2643template <
class TAG,
class A,
class FromTag=
typename A::Tag>
2646:
public LookupTagImpl<TAG, typename A::InternalBaseType>
2651template <
class TAG,
class A,
class FromTag>
2652struct LookupTagImpl<TAG, A const, FromTag>
2653:
public LookupTagImpl<TAG, A>
2655 typedef typename LookupTagImpl<TAG, A>::type
const & reference;
2656 typedef typename LookupTagImpl<TAG, A>::type
const * pointer;
2660template <
class TAG,
class A>
2661struct LookupTagImpl<TAG, A, TAG>
2665 typedef A & reference;
2666 typedef A * pointer;
2667 typedef typename A::value_type value_type;
2668 typedef typename A::result_type result_type;
2672template <
class TAG,
class A>
2673struct LookupTagImpl<TAG, A const, TAG>
2674:
public LookupTagImpl<TAG, A, TAG>
2676 typedef typename LookupTagImpl<TAG, A, TAG>::type
const & reference;
2677 typedef typename LookupTagImpl<TAG, A, TAG>::type
const * pointer;
2682template <
class TAG,
class A>
2683struct LookupTagImpl<TAG, A, AccumulatorEnd>
2687 typedef A & reference;
2688 typedef A * pointer;
2689 typedef Error__Attempt_to_access_inactive_statistic<TAG> value_type;
2690 typedef Error__Attempt_to_access_inactive_statistic<TAG> result_type;
2695struct LookupTagImpl<AccumulatorEnd, A, AccumulatorEnd>
2697 typedef AccumulatorEnd Tag;
2699 typedef A & reference;
2700 typedef A * pointer;
2701 typedef void value_type;
2702 typedef void result_type;
2708template <
class TAG,
class A>
2709struct LookupTagImpl<Global<TAG>, A, AccumulatorEnd>
2710:
public LookupTagImpl<TAG, typename A::GlobalAccumulatorType>
2712 typedef Global<TAG> Tag;
2717template <
class TAG,
class A>
2718struct LookupTagImpl<TAG, A, LabelDispatchTag>
2719:
public LookupTagImpl<TAG, typename A::RegionAccumulatorChain>
2725template <
class TAG,
class A>
2726struct LookupTagImpl<Global<TAG>, A, LabelDispatchTag>
2727:
public LookupTagImpl<TAG, typename A::GlobalAccumulatorChain>
2729 typedef Global<TAG> Tag;
2734struct LookupTagImpl<LabelDispatchTag, A, LabelDispatchTag>
2736 typedef LabelDispatchTag Tag;
2738 typedef A & reference;
2739 typedef A * pointer;
2740 typedef void value_type;
2741 typedef void result_type;
2747template <
class Tag,
class A>
2749:
public acc_detail::LookupTagImpl<typename StandardizeTag<Tag>::type, A>
2756template <
class Tag,
class A,
class TargetTag>
2757struct LookupDependency
2758:
public acc_detail::LookupTagImpl<
2759 typename TransferModifiers<TargetTag, typename StandardizeTag<Tag>::type>::type, A>
2763namespace acc_detail {
2767template <
class Tag,
class FromTag,
class reference>
2771 static reference exec(A & a)
2773 return CastImpl<Tag, typename A::InternalBaseType::Tag, reference>::exec(a.next_);
2779 return CastImpl<Tag, typename A::InternalBaseType::Tag, reference>::exec(a.next_, label);
2783template <
class Tag,
class reference>
2784struct CastImpl<Tag, Tag, reference>
2787 static reference exec(A & a)
2789 return const_cast<reference
>(a);
2795 vigra_precondition(
false,
2796 "getAccumulator(): region accumulators can only be queried for AccumulatorChainArray.");
2801template <
class Tag,
class reference>
2802struct CastImpl<Tag, AccumulatorEnd, reference>
2805 static reference exec(A & a)
2817template <
class Tag,
class reference>
2818struct CastImpl<Global<Tag>, AccumulatorEnd, reference>
2821 static reference exec(A & a)
2823 return CastImpl<Tag, typename A::GlobalAccumulatorType::Tag, reference>::exec(*a.globalAccumulator_.pointer_);
2827template <
class reference>
2828struct CastImpl<AccumulatorEnd, AccumulatorEnd, reference>
2831 static reference exec(A & a)
2843template <
class Tag,
class reference>
2844struct CastImpl<Tag, LabelDispatchTag, reference>
2847 static reference exec(A & a)
2849 vigra_precondition(
false,
2850 "getAccumulator(): a region label is required when a region accumulator is queried.");
2851 return CastImpl<Tag, typename A::RegionAccumulatorChain::Tag, reference>::exec(a.regions_[0]);
2857 return CastImpl<Tag, typename A::RegionAccumulatorChain::Tag, reference>::exec(a.regions_[label]);
2861template <
class Tag,
class reference>
2862struct CastImpl<Global<Tag>, LabelDispatchTag, reference>
2865 static reference exec(A & a)
2867 return CastImpl<Tag, typename A::GlobalAccumulatorChain::Tag, reference>::exec(a.next_);
2871template <
class reference>
2872struct CastImpl<LabelDispatchTag, LabelDispatchTag, reference>
2875 static reference exec(A & a)
2908template <
class TAG,
class A>
2909inline typename LookupTag<TAG, A>::reference
2912 typedef typename LookupTag<TAG, A>::Tag StandardizedTag;
2913 typedef typename LookupTag<TAG, A>::reference reference;
2914 return acc_detail::CastImpl<StandardizedTag, typename A::Tag, reference>::exec(a);
2920template <
class TAG,
class A>
2921inline typename LookupTag<TAG, A>::reference
2924 typedef typename LookupTag<TAG, A>::Tag StandardizedTag;
2925 typedef typename LookupTag<TAG, A>::reference reference;
2926 return acc_detail::CastImpl<StandardizedTag, typename A::Tag, reference>::exec(a, label);
2940template <
class TAG,
class A>
2941inline typename LookupTag<TAG, A>::result_type
2944 return getAccumulator<TAG>(a).get();
2968template <
class TAG,
class A>
2969inline typename LookupTag<TAG, A>::result_type
2972 return getAccumulator<TAG>(a, label).get();
2979template <
class TAG,
class A>
2980inline typename LookupDependency<TAG, A>::result_type
2981getDependency(A
const & a)
2983 typedef typename LookupDependency<TAG, A>::Tag StandardizedTag;
2984 typedef typename LookupDependency<TAG, A>::reference reference;
2985 return acc_detail::CastImpl<StandardizedTag, typename A::Tag, reference>::exec(a)();
2992template <
class Tag,
class A>
2996 a.template activate<Tag>();
3003template <
class Tag,
class A>
3007 return a.template isActive<Tag>();
3085template <
class ITERATOR,
class ACCUMULATOR>
3088 for(
unsigned int k=1; k <= a.passesRequired(); ++k)
3089 for(ITERATOR i=start; i < end; ++i)
3090 a.updatePassN(*i, k);
3093template <
unsigned int N,
class T1,
class S1,
3099 Iterator start = createCoupledIterator(a1),
3100 end = start.getEndIterator();
3104template <
unsigned int N,
class T1,
class S1,
3108 MultiArrayView<N, T2, S2>
const & a2,
3111 typedef typename CoupledIteratorType<N, T1, T2>::type Iterator;
3112 Iterator start = createCoupledIterator(a1, a2),
3113 end = start.getEndIterator();
3117template <
unsigned int N,
class T1,
class S1,
3122 MultiArrayView<N, T2, S2>
const & a2,
3123 MultiArrayView<N, T3, S3>
const & a3,
3126 typedef typename CoupledIteratorType<N, T1, T2, T3>::type Iterator;
3127 Iterator start = createCoupledIterator(a1, a2, a3),
3128 end = start.getEndIterator();
3132template <
unsigned int N,
class T1,
class S1,
3138 MultiArrayView<N, T2, S2>
const & a2,
3139 MultiArrayView<N, T3, S3>
const & a3,
3140 MultiArrayView<N, T4, S4>
const & a4,
3143 typedef typename CoupledIteratorType<N, T1, T2, T3, T4>::type Iterator;
3144 Iterator start = createCoupledIterator(a1, a2, a3, a4),
3145 end = start.getEndIterator();
3149template <
unsigned int N,
class T1,
class S1,
3156 MultiArrayView<N, T2, S2>
const & a2,
3157 MultiArrayView<N, T3, S3>
const & a3,
3158 MultiArrayView<N, T4, S4>
const & a4,
3159 MultiArrayView<N, T5, S5>
const & a5,
3162 typedef typename CoupledIteratorType<N, T1, T2, T3, T4, T5>::type Iterator;
3163 Iterator start = createCoupledIterator(a1, a2, a3, a4, a5),
3164 end = start.getEndIterator();
3175struct AccumulatorResultTraits
3178 typedef T element_type;
3179 typedef double element_promote_type;
3180 typedef T MinmaxType;
3181 typedef element_promote_type SumType;
3182 typedef element_promote_type FlatCovarianceType;
3183 typedef element_promote_type CovarianceType;
3186template <
class T,
int N>
3187struct AccumulatorResultTraits<TinyVector<T, N> >
3189 typedef TinyVector<T, N> type;
3190 typedef T element_type;
3191 typedef double element_promote_type;
3192 typedef TinyVector<T, N> MinmaxType;
3193 typedef TinyVector<element_promote_type, N> SumType;
3194 typedef TinyVector<element_promote_type, N*(N+1)/2> FlatCovarianceType;
3195 typedef Matrix<element_promote_type> CovarianceType;
3199template <
class T,
unsigned int RED_IDX,
unsigned int GREEN_IDX,
unsigned int BLUE_IDX>
3200struct AccumulatorResultTraits<RGBValue<T, RED_IDX, GREEN_IDX, BLUE_IDX> >
3202 typedef RGBValue<T> type;
3203 typedef T element_type;
3204 typedef double element_promote_type;
3205 typedef RGBValue<T> MinmaxType;
3206 typedef RGBValue<element_promote_type> SumType;
3207 typedef TinyVector<element_promote_type, 3*(3+1)/2> FlatCovarianceType;
3208 typedef Matrix<element_promote_type> CovarianceType;
3213template <
unsigned int N,
class T,
class Str
ide>
3214struct AccumulatorResultTraits<MultiArrayView<N, T, Stride> >
3216 typedef MultiArrayView<N, T, Stride> type;
3217 typedef T element_type;
3218 typedef double element_promote_type;
3219 typedef MultiArray<N, T> MinmaxType;
3220 typedef MultiArray<N, element_promote_type> SumType;
3221 typedef MultiArray<1, element_promote_type> FlatCovarianceType;
3222 typedef Matrix<element_promote_type> CovarianceType;
3225template <
unsigned int N,
class T,
class Alloc>
3226struct AccumulatorResultTraits<MultiArray<N, T, Alloc> >
3228 typedef MultiArrayView<N, T, Alloc> type;
3229 typedef T element_type;
3230 typedef double element_promote_type;
3231 typedef MultiArray<N, T> MinmaxType;
3232 typedef MultiArray<N, element_promote_type> SumType;
3233 typedef MultiArray<1, element_promote_type> FlatCovarianceType;
3234 typedef Matrix<element_promote_type> CovarianceType;
3251 typedef typename StandardizeTag<TAG>::type TargetTag;
3252 typedef typename TargetTag::Dependencies Dependencies;
3254 static std::string name()
3256 return std::string(
"Global<") + TargetTag::name() +
" >";
3272 static std::string name()
3274 return std::string(
"DataArg<") +
asString(INDEX) +
"> (internal)";
3279 template <
class T,
class BASE>
3283 typedef DataArgTag Tag;
3284 typedef void value_type;
3285 typedef void result_type;
3287 static const int value = INDEX;
3288 static const unsigned int workInPass = 0;
3292namespace acc_detail {
3294template <
class T,
int DEFAULT,
class TAG,
class IndexDefinition,
3295 class TagFound=
typename IndexDefinition::Tag>
3296struct HandleArgSelectorImpl
3298 static const int value = DEFAULT;
3299 typedef typename CoupledHandleCast<value, T>::type type;
3300 typedef typename CoupledHandleCast<value, T>::value_type value_type;
3301 static const int size = type::dimensions;
3303 template <
class U,
class NEXT>
3304 static typename CoupledHandleCast<value, CoupledHandle<U, NEXT> >::type
const &
3307 return vigra::cast<value>(t);
3310 template <
class U,
class NEXT>
3311 static typename CoupledHandleCast<value, CoupledHandle<U, NEXT> >::type::const_reference
3314 return vigra::get<value>(t);
3318template <
class T,
int DEFAULT,
class TAG,
class IndexDefinition>
3319struct HandleArgSelectorImpl<T, DEFAULT, TAG, IndexDefinition, TAG>
3321 static const int value = IndexDefinition::value;
3322 typedef typename CoupledHandleCast<value, T>::type type;
3323 typedef typename CoupledHandleCast<value, T>::value_type value_type;
3324 static const int size = type::dimensions;
3326 template <
class U,
class NEXT>
3327 static typename CoupledHandleCast<value, CoupledHandle<U, NEXT> >::type
const &
3328 getHandle(CoupledHandle<U, NEXT>
const & t)
3330 return vigra::cast<value>(t);
3333 template <
class U,
class NEXT>
3334 static typename CoupledHandleCast<value, CoupledHandle<U, NEXT> >::type::const_reference
3335 getValue(CoupledHandle<U, NEXT>
const & t)
3337 return vigra::get<value>(t);
3343template <
class T,
class CHAIN>
3344struct HandleArgSelector<T, LabelArgTag, CHAIN>
3345:
public acc_detail::HandleArgSelectorImpl<T, 2, LabelArgTag,
3346 typename LookupTag<LabelArgTag, CHAIN>::type>
3349template <
class T,
class CHAIN>
3350struct HandleArgSelector<T, DataArgTag, CHAIN>
3351:
public acc_detail::HandleArgSelectorImpl<T, 1, DataArgTag,
3352 typename LookupTag<DataArgTag, CHAIN>::type>
3355template <
class T,
class CHAIN>
3356struct HandleArgSelector<T, CoordArgTag, CHAIN>
3357:
public acc_detail::HandleArgSelectorImpl<T, 0, CoordArgTag,
3358 typename LookupTag<CoordArgTag, CHAIN>::type>
3360 typedef acc_detail::HandleArgSelectorImpl<T, 0, CoordArgTag,
3361 typename LookupTag<CoordArgTag, CHAIN>::type> base_type;
3362 typedef TinyVector<double, base_type::size> value_type;
3370 typedef typename StandardizeTag<TAG>::type TargetTag;
3371 typedef typename TargetTag::Dependencies Dependencies;
3373 static std::string name()
3375 return std::string(
"DataFromHandle<") + TargetTag::name() +
" > (internal)";
3380 template <
class T,
class BASE>
3382 :
public TargetTag::template Impl<typename HandleArgSelector<T, DataArgTag, BASE>::value_type, BASE>
3384 typedef HandleArgSelector<T, DataArgTag, BASE> DataHandle;
3385 typedef typename DataHandle::value_type input_type;
3386 typedef input_type
const & argument_type;
3387 typedef argument_type first_argument_type;
3389 typedef typename TargetTag::template Impl<input_type, BASE> ImplType;
3391 using ImplType::reshape;
3393 template <
class U,
class NEXT>
3394 void reshape(CoupledHandle<U, NEXT>
const & t)
3396 ImplType::reshape(acc_detail::shapeOf(DataHandle::getValue(t)));
3399 template <
class U,
class NEXT>
3400 void update(CoupledHandle<U, NEXT>
const & t)
3402 ImplType::update(DataHandle::getValue(t));
3405 template <
class U,
class NEXT>
3406 void update(CoupledHandle<U, NEXT>
const & t,
double weight)
3408 ImplType::update(DataHandle::getValue(t), weight);
3421 typedef typename StandardizeTag<TAG>::type TargetTag;
3422 typedef typename TargetTag::Dependencies Dependencies;
3424 static std::string name()
3426 return std::string(
"Coord<") + TargetTag::name() +
" >";
3431 template <
class T,
class BASE>
3433 :
public TargetTag::template Impl<typename HandleArgSelector<T, CoordArgTag, BASE>::value_type, BASE>
3435 typedef HandleArgSelector<T, CoordArgTag, BASE> CoordHandle;
3436 typedef typename CoordHandle::value_type input_type;
3437 typedef input_type
const & argument_type;
3438 typedef argument_type first_argument_type;
3440 typedef typename TargetTag::template Impl<input_type, BASE> ImplType;
3448 void setCoordinateOffset(input_type
const & offset)
3453 using ImplType::reshape;
3455 template <
class U,
class NEXT>
3458 ImplType::reshape(acc_detail::shapeOf(CoordHandle::getValue(t)));
3461 template <
class U,
class NEXT>
3464 ImplType::update(CoordHandle::getValue(t)+offset_);
3467 template <
class U,
class NEXT>
3470 ImplType::update(CoordHandle::getValue(t)+offset_, weight);
3485 static std::string name()
3487 return std::string(
"WeightArg<") +
asString(INDEX) +
"> (internal)";
3492 template <
class T,
class BASE>
3496 typedef WeightArgTag Tag;
3497 typedef void value_type;
3498 typedef void result_type;
3500 static const int value = INDEX;
3501 static const unsigned int workInPass = 0;
3511 typedef typename StandardizeTag<TAG>::type TargetTag;
3512 typedef typename TargetTag::Dependencies Dependencies;
3514 static std::string name()
3516 return std::string(
"Weighted<") + TargetTag::name() +
" >";
3521 template <
class IndexDefinition,
class TagFound=
typename IndexDefinition::Tag>
3522 struct WeightIndexSelector
3524 template <
class U,
class NEXT>
3531 template <
class IndexDefinition>
3532 struct WeightIndexSelector<IndexDefinition, WeightArgTag>
3534 template <
class U,
class NEXT>
3537 return (
double)get<IndexDefinition::value>(t);
3541 template <
class T,
class BASE>
3543 :
public TargetTag::template Impl<T, BASE>
3545 typedef typename TargetTag::template Impl<T, BASE> ImplType;
3547 typedef typename LookupTag<WeightArgTag, BASE>::type FindWeightIndex;
3549 template <
class U,
class NEXT>
3552 ImplType::update(t, WeightIndexSelector<FindWeightIndex>::exec(t));
3563 static std::string name()
3565 return "Centralize (internal)";
3570 template <
class U,
class BASE>
3574 static const unsigned int workInPass = 2;
3576 typedef typename AccumulatorResultTraits<U>::element_promote_type element_type;
3577 typedef typename AccumulatorResultTraits<U>::SumType value_type;
3578 typedef value_type
const & result_type;
3580 mutable value_type value_;
3588 value_ = element_type();
3591 template <
class Shape>
3592 void reshape(Shape
const & s)
3594 acc_detail::reshapeImpl(value_, s);
3597 void update(U
const & t)
const
3600 value_ = t - getDependency<Mean>(*
this);
3603 void update(U
const & t,
double)
const
3608 result_type operator()(U
const & t)
const
3614 result_type operator()()
const
3629 typedef typename StandardizeTag<TAG>::type TargetTag;
3632 static std::string name()
3634 return std::string(
"Central<") + TargetTag::name() +
" >";
3639 template <
class U,
class BASE>
3641 :
public TargetTag::template Impl<typename AccumulatorResultTraits<U>::SumType, BASE>
3643 typedef typename TargetTag::template Impl<typename AccumulatorResultTraits<U>::SumType, BASE> ImplType;
3645 static const unsigned int workInPass = 2;
3649 vigra_precondition(
false,
3650 "Central<...>::operator+=(): not supported.");
3654 void update(T
const &)
3656 ImplType::update(getDependency<Centralize>(*
this));
3660 void update(T
const &,
double weight)
3662 ImplType::update(getDependency<Centralize>(*
this), weight);
3705class PrincipalProjection
3710 static std::string name()
3712 return "PrincipalProjection (internal)";
3717 template <
class U,
class BASE>
3721 static const unsigned int workInPass = 2;
3723 typedef typename AccumulatorResultTraits<U>::element_promote_type element_type;
3724 typedef typename AccumulatorResultTraits<U>::SumType value_type;
3725 typedef value_type
const & result_type;
3727 mutable value_type value_;
3735 value_ = element_type();
3738 template <
class Shape>
3739 void reshape(Shape
const & s)
3741 acc_detail::reshapeImpl(value_, s);
3744 void update(U
const & t)
const
3746 for(
unsigned int k=0; k<t.size(); ++k)
3748 value_[k] = getDependency<Principal<CoordinateSystem> >(*this)(0, k)*getDependency<Centralize>(*
this)[0];
3749 for(
unsigned int d=1; d<t.size(); ++d)
3750 value_[k] += getDependency<Principal<CoordinateSystem> >(*
this)(d, k)*getDependency<Centralize>(*
this)[d];
3754 void update(U
const & t,
double)
const
3759 result_type operator()(U
const & t)
const
3761 getAccumulator<Centralize>(*this).update(t);
3766 result_type operator()()
const
3781 typedef typename StandardizeTag<TAG>::type TargetTag;
3784 static std::string name()
3786 return std::string(
"Principal<") + TargetTag::name() +
" >";
3791 template <
class U,
class BASE>
3793 :
public TargetTag::template Impl<typename AccumulatorResultTraits<U>::SumType, BASE>
3795 typedef typename TargetTag::template Impl<typename AccumulatorResultTraits<U>::SumType, BASE> ImplType;
3797 static const unsigned int workInPass = 2;
3801 vigra_precondition(
false,
3802 "Principal<...>::operator+=(): not supported.");
3806 void update(T
const &)
3808 ImplType::update(getDependency<PrincipalProjection>(*
this));
3812 void update(T
const &,
double weight)
3814 ImplType::update(getDependency<PrincipalProjection>(*
this), weight);
3851 static std::string name()
3853 return "CoordinateSystem";
3858 template <
class U,
class BASE>
3862 typedef double element_type;
3864 typedef value_type
const & result_type;
3874 value_ = element_type();
3877 template <
class Shape>
3878 void reshape(Shape
const & s)
3880 acc_detail::reshapeImpl(value_, s);
3883 result_type operator()()
const
3890template <
class BASE,
class T,
3891 class ElementType=
typename AccumulatorResultTraits<T>::element_promote_type,
3892 class SumType=
typename AccumulatorResultTraits<T>::SumType>
3896 typedef ElementType element_type;
3897 typedef SumType value_type;
3898 typedef value_type
const & result_type;
3908 value_ = element_type();
3911 template <
class Shape>
3912 void reshape(Shape
const & s)
3914 acc_detail::reshapeImpl(value_, s);
3922 result_type operator()()
const
3933 typedef Select<> Dependencies;
3935 static std::string name()
3937 return "PowerSum<0>";
3942 template <
class T,
class BASE>
3944 :
public SumBaseImpl<BASE, T, double, double>
3946 void update(T
const &)
3951 void update(T
const &,
double weight)
3953 this->value_ += weight;
3963 typedef Select<> Dependencies;
3965 static std::string name()
3967 return "PowerSum<1>";
3972 template <
class U,
class BASE>
3974 :
public SumBaseImpl<BASE, U>
3976 void update(U
const & t)
3981 void update(U
const & t,
double weight)
3983 using namespace multi_math;
3985 this->value_ += weight*t;
3994template <
unsigned N>
4000 static std::string name()
4002 return std::string(
"PowerSum<") +
asString(N) +
">";
4007 template <
class U,
class BASE>
4009 :
public SumBaseImpl<BASE, U>
4011 void update(U
const & t)
4014 this->value_ += pow(t, (
int)N);
4017 void update(U
const & t,
double weight)
4020 this->value_ += weight*pow(t, (
int)N);
4031 static std::string name()
4033 return "AbsPowerSum<1>";
4038 template <
class U,
class BASE>
4040 :
public SumBaseImpl<BASE, U>
4042 void update(U
const & t)
4045 this->value_ +=
abs(t);
4048 void update(U
const & t,
double weight)
4051 this->value_ += weight*
abs(t);
4060template <
unsigned N>
4066 static std::string name()
4068 return std::string(
"AbsPowerSum<") +
asString(N) +
">";
4073 template <
class U,
class BASE>
4075 :
public SumBaseImpl<BASE, U>
4077 void update(U
const & t)
4080 this->value_ += pow(
abs(t), (
int)N);
4083 void update(U
const & t,
double weight)
4086 this->value_ += weight*pow(
abs(t), (
int)N);
4091template <
class BASE,
class VALUE_TYPE,
class U>
4092struct CachedResultBase
4095 typedef typename AccumulatorResultTraits<U>::element_type element_type;
4096 typedef VALUE_TYPE value_type;
4097 typedef value_type
const & result_type;
4099 mutable value_type value_;
4107 value_ = element_type();
4111 template <
class Shape>
4112 void reshape(Shape
const & s)
4114 acc_detail::reshapeImpl(value_, s);
4122 void update(U
const &)
4127 void update(U
const &,
double)
4140 typedef typename StandardizeTag<TAG>::type TargetTag;
4143 static std::string name()
4145 return std::string(
"DivideByCount<") + TargetTag::name() +
" >";
4150 template <
class U,
class BASE>
4152 :
public CachedResultBase<BASE, typename LookupDependency<TargetTag, BASE>::value_type, U>
4154 typedef typename CachedResultBase<BASE, typename LookupDependency<TargetTag, BASE>::value_type, U>::result_type result_type;
4156 result_type operator()()
const
4160 using namespace multi_math;
4161 this->value_ = getDependency<TargetTag>(*
this) / getDependency<Count>(*
this);
4164 return this->value_;
4176 typedef typename StandardizeTag<TAG>::type TargetTag;
4179 static std::string name()
4181 return std::string(
"DivideUnbiased<") + TargetTag::name() +
" >";
4186 template <
class U,
class BASE>
4190 typedef typename LookupDependency<TargetTag, BASE>::value_type value_type;
4191 typedef value_type result_type;
4193 result_type operator()()
const
4195 using namespace multi_math;
4196 return getDependency<TargetTag>(*
this) / (getDependency<Count>(*
this) - 1.0);
4208 typedef typename StandardizeTag<DivideByCount<TAG> >::type TargetTag;
4211 static std::string name()
4213 typedef typename StandardizeTag<TAG>::type InnerTag;
4214 return std::string(
"RootDivideByCount<") + InnerTag::name() +
" >";
4219 template <
class U,
class BASE>
4223 typedef typename LookupDependency<TargetTag, BASE>::value_type value_type;
4224 typedef value_type result_type;
4226 result_type operator()()
const
4228 using namespace multi_math;
4229 return sqrt(getDependency<TargetTag>(*
this));
4241 typedef typename StandardizeTag<DivideUnbiased<TAG> >::type TargetTag;
4244 static std::string name()
4246 typedef typename StandardizeTag<TAG>::type InnerTag;
4247 return std::string(
"RootDivideUnbiased<") + InnerTag::name() +
" >";
4252 template <
class U,
class BASE>
4256 typedef typename LookupDependency<TargetTag, BASE>::value_type value_type;
4257 typedef value_type result_type;
4259 result_type operator()()
const
4261 using namespace multi_math;
4262 return sqrt(getDependency<TargetTag>(*
this));
4275 static std::string name()
4277 return "Central<PowerSum<2> >";
4282 template <
class U,
class BASE>
4284 :
public SumBaseImpl<BASE, U>
4289 double n1 = getDependency<Count>(*
this), n2 = getDependency<Count>(o);
4292 this->value_ = o.value_;
4296 this->value_ += o.value_ + n1 * n2 / (n1 + n2) *
sq(getDependency<Mean>(*
this) - getDependency<Mean>(o));
4300 void update(U
const & t)
4302 double n = getDependency<Count>(*
this);
4306 this->value_ += n / (n - 1.0) *
sq(getDependency<Mean>(*
this) - t);
4310 void update(U
const & t,
double weight)
4312 double n = getDependency<Count>(*
this);
4316 this->value_ += n / (n - weight) *
sq(getDependency<Mean>(*
this) - t);
4330 static std::string name()
4332 return "Central<PowerSum<3> >";
4337 template <
class U,
class BASE>
4339 :
public SumBaseImpl<BASE, U>
4341 typedef typename SumBaseImpl<BASE, U>::value_type value_type;
4343 static const unsigned int workInPass = 2;
4350 double n1 = getDependency<Count>(*
this), n2 = getDependency<Count>(o);
4353 this->value_ = o.value_;
4358 double weight = n1 * n2 * (n1 - n2) /
sq(n);
4359 value_type delta = getDependency<Mean>(o) - getDependency<Mean>(*
this);
4360 this->value_ += o.value_ + weight * pow(delta, 3) +
4361 3.0 / n * delta * (n1 * getDependency<Sum2Tag>(o) - n2 * getDependency<Sum2Tag>(*
this));
4365 void update(U
const &)
4368 this->value_ += pow(getDependency<Centralize>(*
this), 3);
4371 void update(U
const &,
double weight)
4374 this->value_ += weight*pow(getDependency<Centralize>(*
this), 3);
4386 static std::string name()
4388 return "Central<PowerSum<4> >";
4393 template <
class U,
class BASE>
4395 :
public SumBaseImpl<BASE, U>
4397 typedef typename SumBaseImpl<BASE, U>::value_type value_type;
4399 static const unsigned int workInPass = 2;
4407 double n1 = getDependency<Count>(*
this), n2 = getDependency<Count>(o);
4410 this->value_ = o.value_;
4415 double n1_2 =
sq(n1);
4416 double n2_2 =
sq(n2);
4418 double weight = n1 * n2 * (n1_2 - n1*n2 + n2_2) / n_2 / n;
4419 value_type delta = getDependency<Mean>(o) - getDependency<Mean>(*
this);
4420 this->value_ += o.value_ + weight * pow(delta, 4) +
4421 6.0 / n_2 *
sq(delta) * (n1_2 * getDependency<Sum2Tag>(o) + n2_2 * getDependency<Sum2Tag>(*
this)) +
4422 4.0 / n * delta * (n1 * getDependency<Sum3Tag>(o) - n2 * getDependency<Sum3Tag>(*
this));
4426 void update(U
const &)
4429 this->value_ += pow(getDependency<Centralize>(*
this), 4);
4432 void update(U
const &,
double weight)
4435 this->value_ += weight*pow(getDependency<Centralize>(*
this), 4);
4450 static std::string name()
4457 template <
class U,
class BASE>
4461 static const unsigned int workInPass = 2;
4463 typedef typename LookupDependency<Central<PowerSum<3> >, BASE>::value_type value_type;
4464 typedef value_type result_type;
4466 result_type operator()()
const
4471 using namespace multi_math;
4472 return sqrt(getDependency<Count>(*
this)) * getDependency<Sum3>(*
this) / pow(getDependency<Sum2>(*
this), 1.5);
4486 static std::string name()
4488 return "UnbiasedSkewness";
4493 template <
class U,
class BASE>
4497 static const unsigned int workInPass = 2;
4499 typedef typename LookupDependency<Central<PowerSum<3> >, BASE>::value_type value_type;
4500 typedef value_type result_type;
4502 result_type operator()()
const
4504 using namespace multi_math;
4505 double n = getDependency<Count>(*
this);
4506 return sqrt(n*(n-1.0)) / (n - 2.0) * getDependency<Skewness>(*
this);
4522 static std::string name()
4529 template <
class U,
class BASE>
4533 static const unsigned int workInPass = 2;
4535 typedef typename LookupDependency<Central<PowerSum<4> >, BASE>::value_type value_type;
4536 typedef value_type result_type;
4538 result_type operator()()
const
4543 using namespace multi_math;
4544 return getDependency<Count>(*
this) * getDependency<Sum4>(*
this) /
sq(getDependency<Sum2>(*
this)) - 3.0;
4558 static std::string name()
4560 return "UnbiasedKurtosis";
4565 template <
class U,
class BASE>
4569 static const unsigned int workInPass = 2;
4571 typedef typename LookupDependency<Central<PowerSum<4> >, BASE>::value_type value_type;
4572 typedef value_type result_type;
4574 result_type operator()()
const
4576 using namespace multi_math;
4577 double n = getDependency<Count>(*
this);
4578 return (n-1.0)/((n-2.0)*(n-3.0))*((n+1.0)*getDependency<Kurtosis>(*
this) + value_type(6.0));
4583namespace acc_detail {
4585template <
class Scatter,
class Sum>
4586void updateFlatScatterMatrix(Scatter & sc,
Sum const & s,
double w)
4588 int size = s.size();
4591 sc[k] += w*s[i]*s[j];
4595void updateFlatScatterMatrix(
double & sc,
Sum const & s,
double w)
4600template <
class Cov,
class Scatter>
4601void flatScatterMatrixToScatterMatrix(Cov & cov, Scatter
const & sc)
4603 int size = cov.shape(0), k=0;
4610 cov(j,i) = cov(i,j);
4615template <
class Scatter>
4616void flatScatterMatrixToScatterMatrix(
double & cov, Scatter
const & sc)
4621template <
class Cov,
class Scatter>
4622void flatScatterMatrixToCovariance(Cov & cov, Scatter
const & sc,
double n)
4624 int size = cov.shape(0), k=0;
4627 cov(j,j) = sc[k++] / n;
4630 cov(i,j) = sc[k++] / n;
4631 cov(j,i) = cov(i,j);
4636template <
class Scatter>
4637void flatScatterMatrixToCovariance(
double & cov, Scatter
const & sc,
double n)
4654 static std::string name()
4656 return "FlatScatterMatrix";
4661 template <
class U,
class BASE>
4665 typedef typename AccumulatorResultTraits<U>::element_promote_type element_type;
4666 typedef typename AccumulatorResultTraits<U>::FlatCovarianceType value_type;
4667 typedef value_type
const & result_type;
4669 typedef typename AccumulatorResultTraits<U>::SumType SumType;
4681 value_ = element_type();
4684 template <
class Shape>
4685 void reshape(Shape
const & s)
4688 acc_detail::reshapeImpl(value_,
Shape1(size*(size+1)/2));
4689 acc_detail::reshapeImpl(diff_, s);
4694 double n1 = getDependency<Count>(*
this), n2 = getDependency<Count>(o);
4702 diff_ = getDependency<Mean>(*
this) - getDependency<Mean>(o);
4703 acc_detail::updateFlatScatterMatrix(value_, diff_, n1 * n2 / (n1 + n2));
4708 void update(U
const & t)
4713 void update(U
const & t,
double weight)
4718 result_type operator()()
const
4724 void compute(U
const & t,
double weight = 1.0)
4726 double n = getDependency<Count>(*
this);
4730 diff_ = getDependency<Mean>(*
this) - t;
4731 acc_detail::updateFlatScatterMatrix(value_, diff_, n * weight / (n - weight));
4744 static std::string name()
4746 return "DivideByCount<FlatScatterMatrix>";
4751 template <
class U,
class BASE>
4753 :
public CachedResultBase<BASE, typename AccumulatorResultTraits<U>::CovarianceType, U>
4755 typedef CachedResultBase<BASE, typename AccumulatorResultTraits<U>::CovarianceType, U> BaseType;
4756 typedef typename BaseType::result_type result_type;
4758 template <
class Shape>
4759 void reshape(Shape
const & s)
4762 acc_detail::reshapeImpl(this->value_, Shape2(size,size));
4765 result_type operator()()
const
4769 acc_detail::flatScatterMatrixToCovariance(this->value_, getDependency<FlatScatterMatrix>(*
this), getDependency<Count>(*
this));
4772 return this->value_;
4779class DivideUnbiased<FlatScatterMatrix>
4782 typedef Select<FlatScatterMatrix, Count> Dependencies;
4784 static std::string name()
4786 return "DivideUnbiased<FlatScatterMatrix>";
4791 template <
class U,
class BASE>
4793 :
public CachedResultBase<BASE, typename AccumulatorResultTraits<U>::CovarianceType, U>
4795 typedef CachedResultBase<BASE, typename AccumulatorResultTraits<U>::CovarianceType, U> BaseType;
4796 typedef typename BaseType::result_type result_type;
4798 template <
class Shape>
4799 void reshape(Shape
const & s)
4802 acc_detail::reshapeImpl(this->value_, Shape2(size,size));
4805 result_type operator()()
const
4809 acc_detail::flatScatterMatrixToCovariance(this->value_, getDependency<FlatScatterMatrix>(*
this), getDependency<Count>(*
this) - 1.0);
4812 return this->value_;
4824 static std::string name()
4826 return "ScatterMatrixEigensystem";
4831 template <
class U,
class BASE>
4835 typedef typename AccumulatorResultTraits<U>::element_promote_type element_type;
4836 typedef typename AccumulatorResultTraits<U>::SumType EigenvalueType;
4837 typedef typename AccumulatorResultTraits<U>::CovarianceType EigenvectorType;
4838 typedef std::pair<EigenvalueType, EigenvectorType> value_type;
4839 typedef value_type
const & result_type;
4841 mutable value_type value_;
4849 if(!acc_detail::hasDataImpl(value_.second))
4851 acc_detail::copyShapeImpl(o.value_.first, value_.first);
4852 acc_detail::copyShapeImpl(o.value_.second, value_.second);
4857 void update(U
const &)
4862 void update(U
const &,
double)
4869 value_.first = element_type();
4870 value_.second = element_type();
4874 template <
class Shape>
4875 void reshape(Shape
const & s)
4878 acc_detail::reshapeImpl(value_.first,
Shape1(size));
4879 acc_detail::reshapeImpl(value_.second, Shape2(size,size));
4882 result_type operator()()
const
4886 compute(getDependency<FlatScatterMatrix>(*
this), value_.first, value_.second);
4893 template <
class Flat,
class EW,
class EV>
4894 static void compute(Flat
const & flatScatter, EW & ew, EV & ev)
4896 EigenvectorType scatter(ev.shape());
4897 acc_detail::flatScatterMatrixToScatterMatrix(scatter, flatScatter);
4900 symmetricEigensystem(scatter, ewview, ev);
4903 static void compute(
double v,
double & ew,
double & ev)
4918 static std::string name()
4920 return "DivideByCount<ScatterMatrixEigensystem>";
4925 template <
class U,
class BASE>
4929 typedef typename LookupDependency<ScatterMatrixEigensystem, BASE>::type SMImpl;
4930 typedef typename SMImpl::element_type element_type;
4931 typedef typename SMImpl::EigenvalueType EigenvalueType;
4932 typedef typename SMImpl::EigenvectorType EigenvectorType;
4933 typedef std::pair<EigenvalueType, EigenvectorType const &> value_type;
4934 typedef value_type
const & result_type;
4936 mutable value_type value_;
4939 : value_(EigenvalueType(), BASE::template call_getDependency<ScatterMatrixEigensystem>().second)
4947 void update(U
const &)
4952 void update(U
const &,
double)
4959 value_.first = element_type();
4963 template <
class Shape>
4964 void reshape(Shape
const & s)
4967 acc_detail::reshapeImpl(value_.first, Shape2(size,1));
4970 result_type operator()()
const
4974 value_.first = getDependency<ScatterMatrixEigensystem>(*this).first / getDependency<Count>(*
this);
5072 static std::string name()
5074 return "Principal<PowerSum<2> >";
5079 template <
class U,
class BASE>
5083 typedef typename LookupDependency<ScatterMatrixEigensystem, BASE>::type::EigenvalueType value_type;
5084 typedef value_type
const & result_type;
5086 result_type operator()()
const
5088 return getDependency<ScatterMatrixEigensystem>(*this).first;
5103 static std::string name()
5105 return "Principal<CoordinateSystem>";
5110 template <
class U,
class BASE>
5114 typedef typename LookupDependency<ScatterMatrixEigensystem, BASE>::type::EigenvectorType value_type;
5115 typedef value_type
const & result_type;
5117 result_type operator()()
const
5119 return getDependency<ScatterMatrixEigensystem>(*this).second;
5133 static std::string name()
5140 template <
class U,
class BASE>
5144 typedef typename AccumulatorResultTraits<U>::element_type element_type;
5145 typedef typename AccumulatorResultTraits<U>::MinmaxType value_type;
5146 typedef value_type
const & result_type;
5152 value_ = NumericTraits<element_type>::max();
5157 value_ = NumericTraits<element_type>::max();
5160 template <
class Shape>
5161 void reshape(Shape
const & s)
5163 acc_detail::reshapeImpl(value_, s, NumericTraits<element_type>::max());
5168 updateImpl(o.value_);
5171 void update(U
const & t)
5176 void update(U
const & t,
double)
5181 result_type operator()()
const
5188 void updateImpl(T
const & o)
5190 using namespace multi_math;
5191 value_ = min(value_, o);
5194 template <
class T,
class Alloc>
5197 value_ = multi_math::min(value_, o);
5211 static std::string name()
5218 template <
class U,
class BASE>
5222 typedef typename AccumulatorResultTraits<U>::element_type element_type;
5223 typedef typename AccumulatorResultTraits<U>::MinmaxType value_type;
5224 typedef value_type
const & result_type;
5230 value_ = NumericTraits<element_type>::min();
5235 value_ = NumericTraits<element_type>::min();
5238 template <
class Shape>
5239 void reshape(Shape
const & s)
5241 acc_detail::reshapeImpl(value_, s, NumericTraits<element_type>::min());
5246 updateImpl(o.value_);
5249 void update(U
const & t)
5254 void update(U
const & t,
double)
5259 result_type operator()()
const
5266 void updateImpl(T
const & o)
5268 using namespace multi_math;
5269 value_ = max(value_, o);
5272 template <
class T,
class Alloc>
5275 value_ = multi_math::max(value_, o);
5290 static std::string name()
5297 template <
class U,
class BASE>
5301 typedef typename AccumulatorResultTraits<U>::element_type element_type;
5302 typedef typename AccumulatorResultTraits<U>::MinmaxType value_type;
5303 typedef value_type
const & result_type;
5313 value_ = element_type();
5316 template <
class Shape>
5317 void reshape(Shape
const & s)
5319 acc_detail::reshapeImpl(value_, s);
5325 if(reverse(o.value_) < reverse(value_))
5329 void update(U
const & t)
5331 if(getDependency<Count>(*
this) == 1)
5335 void update(U
const & t,
double)
5340 result_type operator()()
const
5358 static std::string name()
5365 template <
class U,
class BASE>
5369 typedef typename AccumulatorResultTraits<U>::MinmaxType minmax_type;
5370 typedef std::pair<minmax_type, minmax_type> value_type;
5371 typedef value_type result_type;
5373 result_type operator()()
const
5375 return value_type(getDependency<Minimum>(*
this), getDependency<Maximum>(*
this));
5389 static std::string name()
5391 return "ArgMinWeight";
5396 template <
class U,
class BASE>
5400 typedef typename AccumulatorResultTraits<U>::element_type element_type;
5401 typedef typename AccumulatorResultTraits<U>::MinmaxType value_type;
5402 typedef value_type
const & result_type;
5408 : min_weight_(NumericTraits<double>::max()),
5414 min_weight_ = NumericTraits<double>::max();
5415 value_ = element_type();
5418 template <
class Shape>
5419 void reshape(Shape
const & s)
5421 acc_detail::reshapeImpl(value_, s);
5426 using namespace multi_math;
5427 if(o.min_weight_ < min_weight_)
5429 min_weight_ = o.min_weight_;
5434 void update(U
const &)
5436 vigra_precondition(
false,
"ArgMinWeight::update() needs weights.");
5439 void update(U
const & t,
double weight)
5441 if(weight < min_weight_)
5443 min_weight_ = weight;
5448 result_type operator()()
const
5464 static std::string name()
5466 return "ArgMaxWeight";
5471 template <
class U,
class BASE>
5475 typedef typename AccumulatorResultTraits<U>::element_type element_type;
5476 typedef typename AccumulatorResultTraits<U>::MinmaxType value_type;
5477 typedef value_type
const & result_type;
5483 : max_weight_(NumericTraits<double>::min()),
5489 max_weight_ = NumericTraits<double>::min();
5490 value_ = element_type();
5493 template <
class Shape>
5494 void reshape(Shape
const & s)
5496 acc_detail::reshapeImpl(value_, s);
5501 using namespace multi_math;
5502 if(o.max_weight_ > max_weight_)
5504 max_weight_ = o.max_weight_;
5509 void update(U
const &)
5511 vigra_precondition(
false,
"ArgMaxWeight::update() needs weights.");
5514 void update(U
const & t,
double weight)
5516 if(weight > max_weight_)
5518 max_weight_ = weight;
5523 result_type operator()()
const
5531template <
class BASE,
int BinCount>
5537 typedef double element_type;
5539 typedef value_type
const & result_type;
5542 double left_outliers, right_outliers;
5552 value_ = element_type();
5553 left_outliers = 0.0;
5554 right_outliers = 0.0;
5560 left_outliers += o.left_outliers;
5561 right_outliers += o.right_outliers;
5564 result_type operator()()
const
5570template <
class BASE>
5571class HistogramBase<BASE, 0>
5576 typedef double element_type;
5578 typedef value_type
const & result_type;
5581 double left_outliers, right_outliers;
5591 value_ = element_type();
5592 left_outliers = 0.0;
5593 right_outliers = 0.0;
5598 if(value_.size() == 0)
5602 else if(o.value_.size() > 0)
5604 vigra_precondition(value_.size() == o.value_.size(),
5605 "HistogramBase::operator+=(): bin counts must be equal.");
5608 left_outliers += o.left_outliers;
5609 right_outliers += o.right_outliers;
5612 void setBinCount(
int binCount)
5614 vigra_precondition(binCount > 0,
5615 "HistogramBase:.setBinCount(): binCount > 0 required.");
5616 value_type(
Shape1(binCount)).swap(value_);
5619 result_type operator()()
const
5625template <
class BASE,
int BinCount,
class U=
typename BASE::input_type>
5626class RangeHistogramBase
5627:
public HistogramBase<BASE, BinCount>
5630 double scale_, offset_, inverse_scale_;
5632 RangeHistogramBase()
5642 inverse_scale_ = 0.0;
5643 HistogramBase<BASE, BinCount>::reset();
5646 void operator+=(RangeHistogramBase
const & o)
5648 vigra_precondition(scale_ == 0.0 || o.scale_ == 0.0 || (scale_ == o.scale_ && offset_ == o.offset_),
5649 "RangeHistogramBase::operator+=(): cannot merge histograms with different data mapping.");
5651 HistogramBase<BASE, BinCount>::operator+=(o);
5655 offset_ = o.offset_;
5656 inverse_scale_ = o.inverse_scale_;
5660 void update(U
const & t)
5665 void update(U
const & t,
double weight)
5667 double m = mapItem(t);
5668 int index = (m == (double)this->value_.size())
5672 this->left_outliers += weight;
5673 else if(index >= (
int)this->value_.size())
5674 this->right_outliers += weight;
5676 this->value_[index] += weight;
5679 void setMinMax(
double mi,
double ma)
5681 vigra_precondition(this->value_.size() > 0,
5682 "RangeHistogramBase::setMinMax(...): setBinCount(...) has not been called.");
5683 vigra_precondition(mi <= ma,
5684 "RangeHistogramBase::setMinMax(...): min <= max required.");
5686 ma += this->value_.size() * NumericTraits<double>::epsilon();
5688 scale_ = (double)this->value_.size() / (ma - mi);
5689 inverse_scale_ = 1.0 / scale_;
5692 double mapItem(
double t)
const
5694 return scale_ * (t - offset_);
5697 double mapItemInverse(
double t)
const
5699 return inverse_scale_ * t + offset_;
5702 template <
class ArrayLike>
5703 void computeStandardQuantiles(
double minimum,
double maximum,
double count,
5704 ArrayLike
const & desiredQuantiles, ArrayLike & res)
const
5711 double mappedMinimum = mapItem(minimum);
5712 double mappedMaximum = mapItem(maximum);
5714 keypoints.push_back(mappedMinimum);
5715 cumhist.push_back(0.0);
5717 if(this->left_outliers > 0.0)
5719 keypoints.push_back(0.0);
5720 cumhist.push_back(this->left_outliers);
5723 int size = (int)this->value_.size();
5724 double cumulative = this->left_outliers;
5725 for(
int k=0; k<size; ++k)
5727 if(this->value_[k] > 0.0)
5729 if(keypoints.
back() <= k)
5731 keypoints.push_back(k);
5732 cumhist.push_back(cumulative);
5734 cumulative += this->value_[k];
5735 keypoints.push_back(k+1);
5736 cumhist.push_back(cumulative);
5740 if(this->right_outliers > 0.0)
5742 if(keypoints.
back() != size)
5744 keypoints.push_back(size);
5745 cumhist.push_back(cumulative);
5747 keypoints.push_back(mappedMaximum);
5748 cumhist.push_back(count);
5752 keypoints.
back() = mappedMaximum;
5753 cumhist.
back() = count;
5756 int quantile = 0, end = (int)desiredQuantiles.size();
5758 if(desiredQuantiles[0] == 0.0)
5763 if(desiredQuantiles[end-1] == 1.0)
5765 res[end-1] = maximum;
5770 double qcount = count * desiredQuantiles[quantile];
5771 while(quantile < end)
5773 if(cumhist[point] < qcount && cumhist[point+1] >= qcount)
5775 double t = (qcount - cumhist[point]) / (cumhist[point+1] - cumhist[point]) * (keypoints[point+1] - keypoints[point]);
5776 res[quantile] = mapItemInverse(t + keypoints[point]);
5778 qcount = count * desiredQuantiles[quantile];
5796template <
int BinCount>
5803 static std::string name()
5805 return std::string(
"IntegerHistogram<") +
asString(BinCount) +
">";
5810 template <
class U,
class BASE>
5812 :
public HistogramBase<BASE, BinCount>
5814 void update(
int index)
5817 ++this->left_outliers;
5818 else if(index >= (
int)this->value_.size())
5819 ++this->right_outliers;
5821 ++this->value_[index];
5824 void update(
int,
double)
5828 vigra_precondition(
false,
"IntegerHistogram::update(): weighted histograms not supported, use another histogram type.");
5831 template <
class ArrayLike>
5832 void computeStandardQuantiles(
double minimum,
double maximum,
double count,
5833 ArrayLike
const & desiredQuantiles, ArrayLike & res)
const
5835 int quantile = 0, end = (int)desiredQuantiles.size();
5837 if(desiredQuantiles[0] == 0.0)
5842 if(desiredQuantiles[end-1] == 1.0)
5844 res[end-1] = maximum;
5849 int currentBin = 0, size = (int)this->value_.size();
5850 double cumulative1 = this->left_outliers,
5851 cumulative2 = this->value_[currentBin] + cumulative1;
5855 double qcount = desiredQuantiles[quantile]*count + 1.0;
5857 while(quantile < end)
5859 if(cumulative2 == qcount)
5861 res[quantile] = currentBin;
5863 qcount = desiredQuantiles[quantile]*count + 1.0;
5865 else if(cumulative2 > qcount)
5867 if(cumulative1 > qcount)
5869 res[quantile] = minimum;
5871 if(cumulative1 + 1.0 > qcount)
5873 res[quantile] = currentBin - 1 + qcount - std::floor(qcount);
5877 res[quantile] = currentBin;
5880 qcount = desiredQuantiles[quantile]*count + 1.0;
5882 else if(currentBin == size-1)
5884 res[quantile] = maximum;
5886 qcount = desiredQuantiles[quantile]*count + 1.0;
5891 cumulative1 = cumulative2;
5892 cumulative2 += this->value_[currentBin];
5909template <
int BinCount>
5916 static std::string name()
5918 return std::string(
"UserRangeHistogram<") +
asString(BinCount) +
">";
5923 template <
class U,
class BASE>
5925 :
public RangeHistogramBase<BASE, BinCount, U>
5927 void update(U
const & t)
5932 void update(U
const & t,
double weight)
5934 vigra_precondition(this->scale_ != 0.0,
5935 "UserRangeHistogram::update(): setMinMax(...) has not been called.");
5937 RangeHistogramBase<BASE, BinCount, U>::update(t, weight);
5951template <
int BinCount>
5958 static std::string name()
5960 return std::string(
"AutoRangeHistogram<") +
asString(BinCount) +
">";
5965 template <
class U,
class BASE>
5967 :
public RangeHistogramBase<BASE, BinCount, U>
5969 static const unsigned int workInPass = LookupDependency<Minimum, BASE>::type::workInPass + 1;
5971 void update(U
const & t)
5976 void update(U
const & t,
double weight)
5978 if(this->scale_ == 0.0)
5979 this->setMinMax(getDependency<Minimum>(*
this), getDependency<Maximum>(*
this));
5981 RangeHistogramBase<BASE, BinCount, U>::update(t, weight);
5995template <
int BinCount>
6002 static std::string name()
6004 return std::string(
"GlobalRangeHistogram<") +
asString(BinCount) +
">";
6009 template <
class U,
class BASE>
6011 :
public RangeHistogramBase<BASE, BinCount, U>
6013 static const unsigned int workInPass = LookupDependency<Minimum, BASE>::type::workInPass + 1;
6015 bool useLocalMinimax_;
6018 : useLocalMinimax_(
false)
6021 void setRegionAutoInit(
bool locally)
6024 useLocalMinimax_ = locally;
6027 void update(U
const & t)
6032 void update(U
const & t,
double weight)
6034 if(this->scale_ == 0.0)
6036 if(useLocalMinimax_)
6037 this->setMinMax(getDependency<Minimum>(*
this), getDependency<Maximum>(*
this));
6042 RangeHistogramBase<BASE, BinCount, U>::update(t, weight);
6051template <
class HistogramAccumulator>
6056 typedef typename StandardizeTag<HistogramAccumulator>::type HistogramTag;
6059 static std::string name()
6061 return std::string(
"StandardQuantiles<") + HistogramTag::name() +
" >";
6066 template <
class U,
class BASE>
6068 :
public CachedResultBase<BASE, TinyVector<double, 7>, U>
6070 typedef typename CachedResultBase<BASE, TinyVector<double, 7>, U>::result_type result_type;
6071 typedef typename CachedResultBase<BASE, TinyVector<double, 7>, U>::value_type value_type;
6073 static const unsigned int workInPass = LookupDependency<HistogramTag, BASE>::type::workInPass;
6075 result_type operator()()
const
6079 double desiredQuantiles[] = {0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 1.0 };
6080 getAccumulator<HistogramTag>(*this).computeStandardQuantiles(getDependency<Minimum>(*
this), getDependency<Maximum>(*
this),
6081 getDependency<Count>(*
this), value_type(desiredQuantiles),
6085 return this->value_;
6091struct feature_RegionContour_can_only_be_computed_for_2D_arrays
6092: vigra::staticAssert::AssertBool<N==2>
6104 static std::string name()
6106 return std::string(
"RegionContour");
6111 template <
class T,
class BASE>
6115 typedef HandleArgSelector<T, LabelArgTag, BASE> LabelHandle;
6118 typedef value_type
const & result_type;
6121 value_type contour_;
6128 void setCoordinateOffset(point_type
const & offset)
6133 template <
class U,
class NEXT>
6136 VIGRA_STATIC_ASSERT((feature_RegionContour_can_only_be_computed_for_2D_arrays<
6138 if(getDependency<Count>(*
this) == 1)
6141 extractContour(LabelHandle::getHandle(t).arrayView(), t.point(), contour_);
6142 contour_ += offset_;
6146 template <
class U,
class NEXT>
6154 vigra_precondition(
false,
6155 "RegionContour::operator+=(): RegionContour cannot be merged.");
6158 result_type operator()()
const
6177 static std::string name()
6179 return std::string(
"RegionPerimeter");
6184 template <
class T,
class BASE>
6188 typedef double value_type;
6189 typedef value_type result_type;
6191 result_type operator()()
const
6193 return getDependency<RegionContour>(*this).length();
6210 static std::string name()
6212 return std::string(
"RegionCircularity");
6217 template <
class T,
class BASE>
6221 typedef double value_type;
6222 typedef value_type result_type;
6224 result_type operator()()
const
6226 return 2.0*
sqrt(M_PI*getDependency<RegionContour>(*this).area()) / getDependency<RegionContour>(*this).length();
6242 static std::string name()
6244 return std::string(
"RegionEccentricity");
6249 template <
class T,
class BASE>
6253 typedef double value_type;
6254 typedef value_type result_type;
6256 result_type operator()()
const
6258 double M = getDependency<RegionRadii>(*this).front(),
6259 m = getDependency<RegionRadii>(*this).back();
6260 return sqrt(1.0 -
sq(m/M));
6280 static std::string name()
6282 return std::string(
"ConvexHull");
6285 template <
class T,
class BASE>
6289 static const unsigned int workInPass = 2;
6290 static const unsigned int dimensions = T::dimensions;
6293 typedef polytope_type value_type;
6294 typedef value_type
const & result_type;
6296 typedef HandleArgSelector<T, CoordArgTag, BASE> coord_handle_type;
6297 typedef typename coord_handle_type::value_type coord_type;
6299 polytope_type convex_hull_;
6304 , initialized_(
false)
6307 template <
class U,
class NEXT>
6314 point_type vec(t.point().begin());
6315 convex_hull_.addExtremeVertex(vec);
6318 template <
class U,
class NEXT>
6326 convex_hull_.addVertex(getDependency<RegionCenter>(*
this));
6327 for (
int dim = 0; dim < dimensions; dim++)
6331 convex_hull_.addVertex(
6332 vec + getDependency<RegionCenter>(*
this));
6334 initialized_ =
true;
6341 "ConvexHull::operator+=(): ConvexHull features cannot be merged.");
6344 result_type operator()()
const
6346 return convex_hull_;
6384 static std::string name()
6386 return std::string(
"ConvexHullFeatures");
6391 template <
class T,
class BASE>
6395 static const unsigned int workInPass = 3;
6396 static const unsigned int dimensions = T::dimensions;
6402 typedef HandleArgSelector<T, CoordArgTag, BASE> coord_handle_type;
6403 typedef typename coord_handle_type::value_type coord_type;
6411 double defect_displacement_mean_;
6412 double defect_volume_mean_;
6413 double defect_volume_variance_;
6414 double defect_volume_skewness_;
6415 double defect_volume_kurtosis_;
6425 , defect_volume_mean_()
6426 , defect_volume_variance_()
6427 , defect_volume_skewness_()
6428 , defect_volume_kurtosis_()
6430 , initialized_(
false)
6435 template <
class U,
class NEXT>
6439 finalized_ ==
false,
6440 "ConvexHullFeatures::update(): "
6441 "Finalize must not be called before update");
6446 const coord_type & coord_min = getDependency<Coord<Minimum> >(*this);
6448 label_array_[coord_handle_type::getValue(t) - coord_min] = 0;
6451 template <
class U,
class NEXT>
6460 const polytope_type & hull = getDependency<ConvexHull>(*
this);
6461 const coord_type & coord_min = getDependency<Coord<Minimum> >(*this);
6462 coord_type coord_max = getDependency<Coord<Maximum> >(*this);
6463 coord_max += coord_type(1);
6466 std::copy(coord_min.begin(), coord_min.end(), offset.
begin());
6468 label_array_.
reshape(coord_max - coord_min, 0);
6469 hull.
fill(label_array_, 1, offset);
6474 hull_acc.ignoreLabel(0);
6476 hull_center_ = get<RegionCenter>(hull_acc, 1) + coord_min;
6477 hull_volume_ = get<Count>(hull_acc, 1);
6479 initialized_ =
true;
6500 "ConvexHullFeatures::finalize(): "
6501 "Feature computation was not initialized.");
6502 const coord_type & coord_min = getDependency<Coord<Minimum> >(*this);
6508 defect_center_ = get<RegionCenter>(defect_acc, 1) + coord_min;
6510 array_type defects_array(label_array_.shape());
6514 defect_volume_mean_ = 0.0;
6515 defect_volume_variance_ = 0.0;
6516 defect_volume_skewness_ = 0.0;
6517 defect_volume_kurtosis_ = 0.0;
6518 if (defect_count_ != 0)
6525 point_type center = getDependency<RegionCenter>(*
this)
6526 -getDependency<Coord<Minimum> >(*this);
6527 for (
int k = 1; k <= defect_count_; k++)
6529 defect_volumes.push_back(get<Count>(defects_acc, k));
6530 defect_displacement_mean_ += get<Count>(defects_acc, k)
6531 *
norm(get<RegionCenter>(defects_acc, k) - center);
6533 defect_displacement_mean_ /= get<Count>(defect_acc, 1);
6541 defect_volumes.
begin(),
6542 defect_volumes.
end(),
6544 defect_volume_mean_ = get<Mean>(volumes_acc);
6545 if (defect_count_ > 1)
6547 defect_volume_variance_ = get<UnbiasedVariance>(volumes_acc);
6549 if (defect_count_ > 2)
6551 defect_volume_skewness_ = get<UnbiasedSkewness>(volumes_acc);
6553 if (defect_count_ > 3)
6555 defect_volume_kurtosis_ = get<UnbiasedKurtosis>(volumes_acc);
6560 void operator+=(
Impl const &)
6564 "ConvexHullFeatures::operator+=(): features cannot be merged.");
6567 result_type operator()()
const
6571 "ConvexHullFeatures::operator(): "
6572 "Finalize must be called before operator()");
6579 return getDependency<RegionCenter>(*
this);
6585 return hull_center_;
6591 return getDependency<Count>(*
this);
6597 return hull_volume_;
6603 return defect_center_;
6609 return defect_volume_mean_;
6615 return defect_volume_variance_;
6621 return defect_volume_skewness_;
6627 return defect_volume_kurtosis_;
6633 return defect_count_;
6640 return defect_displacement_mean_;
const_iterator begin() const
Definition: array_vector.hxx:223
const_iterator end() const
Definition: array_vector.hxx:237
reference back()
Definition: array_vector.hxx:321
Definition: array_vector.hxx:514
Definition: multi_handle.hxx:68
Iterate over multiple images simultaneously in scan order.
Definition: multi_iterator_coupled.hxx:196
Set histogram options.
Definition: histogram.hxx:50
TinyVector< MultiArrayIndex, N > type
Definition: multi_shape.hxx:272
Base class for, and view to, vigra::MultiArray.
Definition: multi_array.hxx:705
Main MultiArray class containing the memory management.
Definition: multi_array.hxx:2477
void reshape(const difference_type &shape)
Definition: multi_array.hxx:2861
virtual unsigned int fill(MultiArrayView< N, unsigned int > &array, const unsigned int label, const point_view_type offset, const point_view_type scale) const
Definition: polytope.hxx:247
iterator begin()
Definition: tinyvector.hxx:861
Class for fixed size vectors.
Definition: tinyvector.hxx:1008
Basic statistic. AbsPowerSum<N> = .
Definition: accumulator.hxx:4062
Create an array of accumulator chains containing the selected per-region and global statistics and th...
Definition: accumulator.hxx:2383
unsigned int regionCount() const
Definition: accumulator.hxx:2421
void updatePassN(T const &t, unsigned int N)
void merge(AccumulatorChainArray const &o)
Definition: accumulator.hxx:2444
void setHistogramOptions(HistogramOptions const ®ionoptions, HistogramOptions const &globaloptions)
void merge(AccumulatorChainArray const &o, ArrayLike const &labelMapping)
Definition: accumulator.hxx:2456
void ignoreLabel(MultiArrayIndex l)
Definition: accumulator.hxx:2393
static ArrayVector< std::string > const & tagNames()
Definition: accumulator.hxx:2465
void setCoordinateOffset(MultiArrayIndex k, SHAPE const &offset)
Definition: accumulator.hxx:2480
MultiArrayIndex ignoredLabel() const
Definition: accumulator.hxx:2400
void setHistogramOptions(HistogramOptions const &options)
MultiArrayIndex maxRegionLabel() const
Definition: accumulator.hxx:2414
void merge(unsigned i, unsigned j)
Definition: accumulator.hxx:2435
void operator+=(AccumulatorChainImpl const &o)
void setMaxRegionLabel(unsigned label)
Definition: accumulator.hxx:2407
void setCoordinateOffset(SHAPE const &offset) void reset(unsigned int reset_to_pass=0)
void updatePassN(T const &t, double weight, unsigned int N)
void operator+=(AccumulatorChainArray const &o)
Definition: accumulator.hxx:2428
Create an accumulator chain containing the selected statistics and their dependencies.
Definition: accumulator.hxx:2046
void updatePassN(T const &t, unsigned int N)
void setCoordinateOffset(SHAPE const &offset)
static ArrayVector< std::string > const & tagNames()
Definition: accumulator.hxx:2064
void setHistogramOptions(HistogramOptions const &options)
void reshape(TinyVector< U, N > const &s)
Definition: accumulator.hxx:2054
unsigned int passesRequired() const
void merge(AccumulatorChainImpl const &o)
void operator+=(AccumulatorChainImpl const &o)
void reset(unsigned int reset_to_pass=0)
void updatePassN(T const &t, double weight, unsigned int N)
Basic statistic. Data where weight assumes its maximal value.
Definition: accumulator.hxx:5460
Basic statistic. Data value where weight assumes its minimal value.
Definition: accumulator.hxx:5385
Histogram where range mapping bounds are defined by minimum and maximum of data.
Definition: accumulator.hxx:5953
Modifier. Substract mean before computing statistic.
Definition: accumulator.hxx:3627
Compute object features related to the convex hull.
Definition: accumulator.hxx:6380
Compute the convex hull of a region.
Definition: accumulator.hxx:6276
Modifier. Compute statistic from pixel coordinates rather than from pixel values.
Definition: accumulator.hxx:3419
Basic statistic. Identity matrix of appropriate size.
Definition: accumulator.hxx:3847
Specifies index of data in CoupledHandle.
Definition: accumulator.hxx:3268
Modifier. Divide statistic by Count: DivideByCount<TAG> = TAG / Count .
Definition: accumulator.hxx:4138
Modifier. Divide statistics by Count-1: DivideUnbiased<TAG> = TAG / (Count-1)
Definition: accumulator.hxx:4174
Create an array of dynamic accumulator chains containing the selected per-region and global statistic...
Definition: accumulator.hxx:2552
ArrayVector< std::string > activeNames() const
Definition: accumulator.hxx:2595
bool isActive() const
Definition: accumulator.hxx:2589
void activate(std::string tag)
Definition: accumulator.hxx:2557
void activate()
Definition: accumulator.hxx:2565
void activateAll()
Definition: accumulator.hxx:2571
unsigned int passesRequired() const
Definition: accumulator.hxx:2605
bool isActive(std::string tag) const
Definition: accumulator.hxx:2578
Create a dynamic accumulator chain containing the selected statistics and their dependencies.
Definition: accumulator.hxx:2159
ArrayVector< std::string > activeNames() const
Definition: accumulator.hxx:2206
bool isActive() const
Definition: accumulator.hxx:2199
void activate(std::string tag)
Definition: accumulator.hxx:2166
void activate()
Definition: accumulator.hxx:2175
void activateAll()
Definition: accumulator.hxx:2182
unsigned int passesRequired() const
Definition: accumulator.hxx:2217
bool isActive(std::string tag) const
Definition: accumulator.hxx:2188
Basic statistic. First data value seen of the object.
Definition: accumulator.hxx:5286
Basic statistic. Flattened uppter-triangular part of scatter matrix.
Definition: accumulator.hxx:4650
Like AutoRangeHistogram, but use global min/max rather than region min/max.
Definition: accumulator.hxx:5997
Modifier. Compute statistic globally rather than per region.
Definition: accumulator.hxx:3249
Histogram where data values are equal to bin indices.
Definition: accumulator.hxx:5798
Basic statistic. Kurtosis.
Definition: accumulator.hxx:4518
Specifies index of labels in CoupledHandle.
Definition: accumulator.hxx:466
Basic statistic. Maximum value.
Definition: accumulator.hxx:5207
Basic statistic. Minimum value.
Definition: accumulator.hxx:5129
Basic statistic. PowerSum<N> = .
Definition: accumulator.hxx:3996
Modifier. Project onto PCA eigenvectors.
Definition: accumulator.hxx:3779
Return both the minimum and maximum in std::pair.
Definition: accumulator.hxx:5354
Compute the circularity of a 2D region.
Definition: accumulator.hxx:6206
Compute the contour of a 2D region.
Definition: accumulator.hxx:6100
Compute the eccentricity of a 2D region in terms of its prinipal radii.
Definition: accumulator.hxx:6238
Compute the perimeter of a 2D region.
Definition: accumulator.hxx:6173
Modifier. RootDivideByCount<TAG> = sqrt( TAG/Count )
Definition: accumulator.hxx:4206
Modifier. RootDivideUnbiased<TAG> = sqrt( TAG / (Count-1) )
Definition: accumulator.hxx:4239
Definition: accumulator.hxx:4820
Basic statistic. Skewness.
Definition: accumulator.hxx:4446
Create an accumulator chain that works independently of a MultiArray.
Definition: accumulator.hxx:2271
Create an accumulator chain that works independently of a MultiArray.
Definition: accumulator.hxx:2321
Compute (0%, 10%, 25%, 50%, 75%, 90%, 100%) quantiles from given histogram.
Definition: accumulator.hxx:6053
Basic statistic. Unbiased Kurtosis.
Definition: accumulator.hxx:4554
Basic statistic. Unbiased Skewness.
Definition: accumulator.hxx:4482
Histogram where user provides bounds for linear range mapping from values to indices.
Definition: accumulator.hxx:5911
Specifies index of data in CoupledHandle.
Definition: accumulator.hxx:3481
Compute weighted version of the statistic.
Definition: accumulator.hxx:3509
Definition: matrix.hxx:125
LookupTag< TAG, A >::reference getAccumulator(A &a)
Definition: accumulator.hxx:2910
PowerSum< 1 > Sum
Alias. Sum.
Definition: accumulator-grammar.hxx:168
LookupTag< TAG, A >::result_type get(A const &a)
Definition: accumulator.hxx:2942
void activate(A &a)
Definition: accumulator.hxx:2994
Coord< Mean > RegionCenter
Alias. Region center.
Definition: accumulator-grammar.hxx:223
bool isActive(A const &a)
Definition: accumulator.hxx:3005
PowerSum< 0 > Count
Alias. Count.
Definition: accumulator-grammar.hxx:166
DivideUnbiased< Central< PowerSum< 2 > > > UnbiasedVariance
Alias. Unbiased variance.
Definition: accumulator-grammar.hxx:199
DivideByCount< Sum > Mean
Alias. Mean.
Definition: accumulator-grammar.hxx:173
void extractFeatures(...)
Definition: fftw3.hxx:623
std::string normalizeString(std::string const &s)
Definition: utilities.hxx:110
FFTWComplex< R >::NormType norm(const FFTWComplex< R > &a)
norm (= magnitude)
Definition: fftw3.hxx:1037
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root.
Definition: fixedpoint.hxx:616
NumericTraits< T >::Promote sq(T t)
The square function.
Definition: mathutil.hxx:382
Iterator argMax(Iterator first, Iterator last)
Find the maximum element in a sequence.
Definition: algorithm.hxx:96
FFTWComplex< R > & operator+=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
add-assignment
Definition: fftw3.hxx:859
unsigned int labelMultiArrayWithBackground(...)
Find the connected components of a MultiArray with arbitrary many dimensions, excluding the backgroun...
void extractContour(MultiArrayView< 2, T, S > const &label_image, Shape2 const &anchor_point, PointArray &contour_points)
Create a polygon from the interpixel contour of a labeled region.
Definition: polygon.hxx:766
doxygen_overloaded_function(template<... > void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
NumericTraits< V >::Promote prod(TinyVectorBase< V, SIZE, D1, D2 > const &l)
product of the vector's elements
Definition: tinyvector.hxx:2097
FFTWComplex< R >::NormType abs(const FFTWComplex< R > &a)
absolute value (= magnitude)
Definition: fftw3.hxx:1002
std::ptrdiff_t MultiArrayIndex
Definition: multi_fwd.hxx:60
std::string asString(T t)(...)
Definition: multi_iterator_coupled.hxx:731
Result type of the covex hull feature calculation.
Definition: accumulator.hxx:6394
double defectDisplacementMean() const
Average displacement of the convexity defects from the input region center weighted by their size.
Definition: accumulator.hxx:6639
double defectVolumeVariance() const
Variance of the volumes of the convexity defects.
Definition: accumulator.hxx:6614
double defectVolumeSkewness() const
Skewness of the volumes of the convexity defects.
Definition: accumulator.hxx:6620
int inputVolume() const
Volume of the input region.
Definition: accumulator.hxx:6590
double defectVolumeMean() const
Average volume of the convexity defects.
Definition: accumulator.hxx:6608
const point_type & hullCenter() const
Center of the convex hull of the input region.
Definition: accumulator.hxx:6584
double convexity() const
Convexity of the input region.
Definition: accumulator.hxx:6648
int defectCount() const
Number of convexity defects.
Definition: accumulator.hxx:6632
const point_type & defectCenter() const
Weighted center of mass of the convexity defects.
Definition: accumulator.hxx:6602
double defectVolumeKurtosis() const
Kurtosis of the volumes of the convexity defects.
Definition: accumulator.hxx:6626
int hullVolume() const
Volume of the convex hull of the input region.
Definition: accumulator.hxx:6596
const point_type & inputCenter() const
Center of the input region.
Definition: accumulator.hxx:6578
Wrapper for MakeTypeList that additionally performs tag standardization.
Definition: accumulator.hxx:408