otbFlexibleDistanceWithMissingValue.txx 3.31 KB
Newer Older
Gregoire Mercier's avatar
Gregoire Mercier committed
1 2 3 4 5 6 7 8 9 10 11
/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$


  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

12 13
  Copyright (c) Institut Mines-Telecom. All rights reserved.
  See IMTCopyright.txt for details.
Gregoire Mercier's avatar
Gregoire Mercier committed
14

15 16
     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Gregoire Mercier's avatar
Gregoire Mercier committed
17 18 19 20 21 22 23 24 25 26 27 28 29
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#ifndef __otbFlexibleDistanceWithMissingValue_txx
#define __otbFlexibleDistanceWithMissingValue_txx

#include "itkNumericTraits.h"

namespace otb {

namespace Statistics {

OTB Bot's avatar
STYLE  
OTB Bot committed
30
template<class TVector>
Gregoire Mercier's avatar
Gregoire Mercier committed
31
inline double
OTB Bot's avatar
STYLE  
OTB Bot committed
32 33
FlexibleDistanceWithMissingValue<TVector>
::Evaluate(const TVector& x1, const TVector& x2) const
Gregoire Mercier's avatar
Gregoire Mercier committed
34
{
OTB Bot's avatar
STYLE  
OTB Bot committed
35
  if (IsEuclidean()) return Superclass::Evaluate(x1, x2);
Gregoire Mercier's avatar
Gregoire Mercier committed
36

37 38
  if (itk::NumericTraits<TVector>::GetLength(x1) !=
      itk::NumericTraits<TVector>::GetLength(x2))
OTB Bot's avatar
STYLE  
OTB Bot committed
39 40 41
    {
    itkExceptionMacro(<< "Vector lengths must be equal.");
    }
Gregoire Mercier's avatar
Gregoire Mercier committed
42

OTB Bot's avatar
STYLE  
OTB Bot committed
43
  double temp, distance = itk::NumericTraits<double>::Zero;
Gregoire Mercier's avatar
Gregoire Mercier committed
44

45
  for (unsigned int i = 0; i < x1.Size(); ++i)
Gregoire Mercier's avatar
Gregoire Mercier committed
46
    {
Emmanuel Christophe's avatar
Emmanuel Christophe committed
47
    if (!this->IsMissingValue(x1[i]) && !this->IsMissingValue(x2[i]))
OTB Bot's avatar
STYLE  
OTB Bot committed
48 49
      {
      temp = vcl_pow(vcl_abs(vcl_pow(x1[i], this->Alpha) - vcl_pow(x2[i], this->Alpha)), this->Beta);
50
      distance += temp;
OTB Bot's avatar
STYLE  
OTB Bot committed
51
      }
Gregoire Mercier's avatar
Gregoire Mercier committed
52 53
    }

54
  return distance;
Gregoire Mercier's avatar
Gregoire Mercier committed
55 56
}

OTB Bot's avatar
STYLE  
OTB Bot committed
57
template<class TVector>
Gregoire Mercier's avatar
Gregoire Mercier committed
58
inline double
OTB Bot's avatar
STYLE  
OTB Bot committed
59 60
FlexibleDistanceWithMissingValue<TVector>
::Evaluate(const TVector& x) const
Gregoire Mercier's avatar
Gregoire Mercier committed
61
{
OTB Bot's avatar
STYLE  
OTB Bot committed
62
  if (IsEuclidean()) return Superclass::Evaluate(x);
Gregoire Mercier's avatar
Gregoire Mercier committed
63

64
  MeasurementVectorSizeType
Gregoire Mercier's avatar
Gregoire Mercier committed
65 66
    measurementVectorSize = this->GetMeasurementVectorSize();

OTB Bot's avatar
STYLE  
OTB Bot committed
67 68 69 70
  if (measurementVectorSize == 0)
    {
    itkExceptionMacro(<< "Please set the MeasurementVectorSize first");
    }
Gregoire Mercier's avatar
Gregoire Mercier committed
71

72
  itk::Statistics::MeasurementVectorTraits::Assert(this->GetOrigin(), measurementVectorSize,
73
                                       "EuclideanDistanceMetric::Evaluate Origin and input vector have different lengths");
Gregoire Mercier's avatar
Gregoire Mercier committed
74

OTB Bot's avatar
STYLE  
OTB Bot committed
75
  double temp, distance = itk::NumericTraits<double>::Zero;
Gregoire Mercier's avatar
Gregoire Mercier committed
76

77
  for (unsigned int i = 0; i < measurementVectorSize; ++i)
Gregoire Mercier's avatar
Gregoire Mercier committed
78
    {
Emmanuel Christophe's avatar
Emmanuel Christophe committed
79
    if (!this->IsMissingValue(this->GetOrigin()[i]) && !this->IsMissingValue(x[i]))
OTB Bot's avatar
STYLE  
OTB Bot committed
80 81
      {
      temp = vcl_pow(vcl_abs(vcl_pow(this->GetOrigin()[i], this->Alpha) - vcl_pow(x[i], this->Alpha)), this->Beta);
82
      distance += temp;
OTB Bot's avatar
STYLE  
OTB Bot committed
83
      }
Gregoire Mercier's avatar
Gregoire Mercier committed
84 85
    }

86
  return distance;
Gregoire Mercier's avatar
Gregoire Mercier committed
87 88
}

OTB Bot's avatar
STYLE  
OTB Bot committed
89
template<class TVector>
Gregoire Mercier's avatar
Gregoire Mercier committed
90
inline double
OTB Bot's avatar
STYLE  
OTB Bot committed
91 92
FlexibleDistanceWithMissingValue<TVector>
::Evaluate(const ValueType& a, const ValueType& b) const
Gregoire Mercier's avatar
Gregoire Mercier committed
93
{
OTB Bot's avatar
STYLE  
OTB Bot committed
94
  if (IsEuclidean()) return Superclass::Evaluate(a, b);
95

96
  // FIXME throw NaN exception instaed of returning 0. ??
Emmanuel Christophe's avatar
Emmanuel Christophe committed
97
  if (this->IsMissingValue(a) || this->IsMissingValue(b)) return 0.0;
Gregoire Mercier's avatar
Gregoire Mercier committed
98

OTB Bot's avatar
STYLE  
OTB Bot committed
99
  double temp = vcl_pow(vcl_abs(vcl_pow(a, this->Alpha) - vcl_pow(b, this->Alpha)), this->Beta);
100
  return temp;
Gregoire Mercier's avatar
Gregoire Mercier committed
101
}
102

OTB Bot's avatar
STYLE  
OTB Bot committed
103
template<class TVector>
Gregoire Mercier's avatar
Gregoire Mercier committed
104
void
OTB Bot's avatar
STYLE  
OTB Bot committed
105 106
FlexibleDistanceWithMissingValue<TVector>
::SetAlphaBeta(double a, double b)
Gregoire Mercier's avatar
Gregoire Mercier committed
107 108 109 110 111
{
  Alpha = a;
  Beta = b;
}

OTB Bot's avatar
STYLE  
OTB Bot committed
112
template<class TVector>
Gregoire Mercier's avatar
Gregoire Mercier committed
113
bool
OTB Bot's avatar
STYLE  
OTB Bot committed
114
FlexibleDistanceWithMissingValue<TVector>
Gregoire Mercier's avatar
Gregoire Mercier committed
115 116 117
::IsEuclidean()
{
  if ((Alpha == 1.0) && (Beta == 2.0))
OTB Bot's avatar
STYLE  
OTB Bot committed
118
    {
Gregoire Mercier's avatar
Gregoire Mercier committed
119
    return true;
OTB Bot's avatar
STYLE  
OTB Bot committed
120
    }
Gregoire Mercier's avatar
Gregoire Mercier committed
121
  else
OTB Bot's avatar
STYLE  
OTB Bot committed
122
    {
Gregoire Mercier's avatar
Gregoire Mercier committed
123
    return false;
OTB Bot's avatar
STYLE  
OTB Bot committed
124
    }
Gregoire Mercier's avatar
Gregoire Mercier committed
125 126 127 128 129 130
}

} // end namespace statistics
} // end namespace otb

#endif