35 #ifndef VIGRA_METRIC_HXX
36 #define VIGRA_METRIC_HXX
38 #include <vigra/numerictraits.hxx>
39 #include <vigra/multi_array.hxx>
54 T operator()(
const T & a,
const T & b)
const{
55 return opImpl(&a,&a+1,&b);
58 T operator()(
const A & a,
const A & b)
const{
59 return opImpl(a.begin(),a.end(),b.begin());
62 template<
class ITER_A,
class ITER_B>
64 ITER_A iterA ,ITER_A endA ,ITER_B iterB
68 const T aa=
static_cast<T
>(*iterA);
69 const T bb=
static_cast<T
>(*iterB);
70 const T
sum = aa + bb;
71 const T diff = aa - bb;
72 if(sum> static_cast<T>(0.0000001))
83 class HellingerDistance{
86 T operator()(
const T & a,
const T & b)
const{
87 return opImpl(&a,&a+1,&b);
90 T operator()(
const A & a,
const A & b)
const{
91 return opImpl(a.begin(),a.end(),b.begin());
94 template<
class ITER_A,
class ITER_B>
96 ITER_A iterA ,ITER_A endA ,ITER_B iterB
100 const T aa=
std::sqrt(static_cast<T>(*iterA));
101 const T bb=
std::sqrt(static_cast<T>(*iterB));
102 const T diff = aa - bb;
111 template<
class T,
unsigned int NORM,
bool TAKE_ROOT=true>
115 T operator()(
const T & a,
const T & b)
const{
116 return opImpl(&a,&a+1,&b);
119 T operator()(
const A & a,
const A & b)
const{
120 return opImpl(a.begin(),a.end(),b.begin());
123 template<
class ITER_A,
class ITER_B>
125 ITER_A iterA ,ITER_A endA ,ITER_B iterB
127 T res =
static_cast<T
>(0.0);
129 const T aa=
static_cast<T
>(*iterA);
130 const T bb=
static_cast<T
>(*iterB);
131 const T diff = aa-bb;
132 res+=
std::abs(std::pow((
double)diff,(
int)NORM));
136 return TAKE_ROOT ? std::pow(res,static_cast<T>(1)/static_cast<T>(NORM)) : res;
142 :
public PNorm<T,2,false>{
145 : PNorm<T,2,false>(){
151 :
public PNorm<T,2,true>{
160 :
public PNorm<T,1,false>{
163 : PNorm<T,1,false>(){
168 class SymetricKlDivergenz{
170 SymetricKlDivergenz(){}
171 T operator()(
const T & a,
const T & b)
const{
172 return opImpl(&a,&a+1,&b);
175 T operator()(
const A & a,
const A & b)
const{
176 return opImpl(a.begin(),a.end(),b.begin());
179 template<
class ITER_A,
class ITER_B>
181 ITER_A iterA ,ITER_A endA ,ITER_B iterB
183 T res =
static_cast<T
>(0.0);
185 const T aa=
static_cast<T
>(*iterA);
186 const T bb=
static_cast<T
>(*iterB);
187 if(aa>static_cast<T>(0.0000001) && bb>
static_cast<T
>(0.0000001) ){
189 if(!isinf(val) && !isnan(val))
195 return res/
static_cast<T
>(2.0);
200 class BhattacharyaDistance{
202 BhattacharyaDistance(){}
203 T operator()(
const T & a,
const T & b)
const{
204 return opImpl(&a,&a+1,&b);
207 T operator()(
const A & a,
const A & b)
const{
208 return opImpl(a.begin(),a.end(),b.begin());
211 template<
class ITER_A,
class ITER_B>
213 ITER_A iterA ,ITER_A endA ,ITER_B iterB
215 T res =
static_cast<T
>(0.0);
217 const T aa=
static_cast<T
>(*iterA);
218 const T bb=
static_cast<T
>(*iterB);
223 return std::sqrt( static_cast<T>(1.0)-res);
242 Metric(
const MetricType metricType = ManhattanMetric)
243 : metricType_(metricType){
248 T operator()(
const A & a,
const A & b)
const{
249 switch(static_cast<unsigned int>(metricType_)){
251 return chiSquared_(a,b);
253 return hellingerDistance_(a,b);
255 return squaredNorm_(a,b);
259 return manhattan_(a,b);
261 return symetricKlDivergenz_(a,b);
263 return bhattacharyaDistance_(a,b);
269 MetricType metricType_;
270 ChiSquared<T> chiSquared_;
271 HellingerDistance<T> hellingerDistance_;
272 SquaredNorm<T> squaredNorm_;
274 Manhattan<T> manhattan_;
275 SymetricKlDivergenz<T> symetricKlDivergenz_;
276 BhattacharyaDistance<T> bhattacharyaDistance_;
283 #endif //VIGRA_METRIC_HXX