18 #ifndef __itkPSMParticleEntropyFunction_hxx 19 #define __itkPSMParticleEntropyFunction_hxx 20 #include "itkPSMParticleEntropyFunction.h" 24 template <
class TGradientNumericType,
unsigned int VDimension>
27 ::AngleCoefficient(
const GradientVectorType& p_i_normal,
const GradientVectorType& p_j_normal)
const 30 TGradientNumericType cosine = dot_product(p_i_normal,p_j_normal) /
31 (p_i_normal.magnitude()*p_j_normal.magnitude() + 1.0e-6);
34 if ( cosine >= m_FlatCutoff )
return 1.0;
37 return ( cos( (m_FlatCutoff - cosine) / (1.0+m_FlatCutoff) * (3.14159265358979/2.0) )) ;
40 template <
class TGradientNumericType,
unsigned int VDimension>
44 const typename ParticleSystemType::PointVectorType &neighborhood,
46 std::vector<double> &weights)
const 48 GradientVectorType posnormal = domain->SampleNormalVnl(pos, 1.0e-10);
49 weights.resize(neighborhood.size());
51 for (
unsigned int i = 0; i < neighborhood.size(); i++)
53 weights[i] = this->AngleCoefficient(posnormal,
54 domain->SampleNormalVnl(neighborhood[i].Point, 1.0e-10));
55 if (weights[i] < 1.0e-5) weights[i] = 0.0;
59 template <
class TGradientNumericType,
unsigned int VDimension>
62 ::EstimateSigma(
unsigned int,
const typename ParticleSystemType::PointVectorType &neighborhood,
63 const std::vector<double> &weights,
64 const PointType &pos,
double initial_sigma,
double precision,
67 const double epsilon = 1.0e-5;
68 const double min_sigma = 1.0e-4;
70 const double M =
static_cast<double>(VDimension);
71 const double MM = M * M * 2.0 + M;
74 double sigma, prev_sigma;
75 sigma = initial_sigma;
77 while (error > precision)
83 double sigma2 = sigma * sigma;
84 double sigma22 = sigma2 * 2.0;
86 for (
unsigned int i = 0; i < neighborhood.size(); i++)
88 if (weights[i] < epsilon)
continue;
91 for (
unsigned int n = 0; n < VDimension; n++)
93 r_vec[n] = pos[n] - neighborhood[i].Point[n];
96 double r = r_vec.magnitude();
98 double alpha = exp(-r2 / sigma22) * weights[i];
101 C += r2 * r2 * alpha;
124 sigma -= (A * (B - A * sigma2 * M)) /
125 ( (-MM * A *A * sigma) - 3.0 * A * B * (1.0 / (sigma + epsilon))
126 - (A*C + B*B) * (1.0 / (sigma2 * sigma + epsilon)) + epsilon);
128 error = 1.0 - fabs((sigma/prev_sigma));
131 if (sigma < min_sigma)
138 if (sigma < 0.0) sigma = min_sigma;
149 template <
class TGradientNumericType,
unsigned int VDimension>
158 TGradientNumericType, VDimension
> *>(system->
GetDomain(d));
159 const double epsilon = 1.0e-6;
164 double sigma = m_SpatialSigmaCache->operator[](d)->
operator[](idx);
166 { sigma = m_MinimumNeighborhoodRadius / m_NeighborhoodToSigmaRatio;}
172 double neighborhood_radius = sigma * m_NeighborhoodToSigmaRatio;
173 if (neighborhood_radius > m_MaximumNeighborhoodRadius)
174 { neighborhood_radius = m_MaximumNeighborhoodRadius; }
180 typename ParticleSystemType::PointVectorType neighborhood
184 std::vector<double> weights;
185 this->ComputeAngularWeights(pos,neighborhood,domain,weights);
192 sigma = this->EstimateSigma(idx, neighborhood,weights,pos, sigma, epsilon, err);
196 neighborhood_radius *= 2.0;
199 if ( neighborhood_radius > this->GetMaximumNeighborhoodRadius())
201 sigma = this->GetMaximumNeighborhoodRadius() / this->GetNeighborhoodToSigmaRatio();
202 neighborhood_radius = this->GetMaximumNeighborhoodRadius();
207 sigma = neighborhood_radius / this->GetNeighborhoodToSigmaRatio();
211 this->ComputeAngularWeights(pos,neighborhood,domain,weights);
212 sigma = this->EstimateSigma(idx, neighborhood, weights, pos, sigma, epsilon, err);
217 if (sigma > this->GetMaximumNeighborhoodRadius())
219 sigma = this->GetMaximumNeighborhoodRadius() / this->GetNeighborhoodToSigmaRatio();
220 neighborhood_radius = this->GetMaximumNeighborhoodRadius();
222 this->ComputeAngularWeights(pos,neighborhood,domain,weights);
230 m_SpatialSigmaCache->operator[](d)->
operator[](idx) = sigma;
235 double sigma2inv = 1.0 / (2.0* sigma * sigma + epsilon);
240 for (
unsigned int n = 0; n < VDimension; n++)
246 for (
unsigned int i = 0; i < neighborhood.size(); i++)
249 if (weights[i] < epsilon)
continue;
251 for (
unsigned int n = 0; n < VDimension; n++)
255 r[n] = pos[n] - neighborhood[i].Point[n];
258 double q = exp( -dot_product(r, r) * sigma2inv);
261 for (
unsigned int n = 0; n < VDimension; n++)
263 gradE[n] += weights[i] * r[n] * q;
270 p = -1.0 / (A * sigma * sigma);
282 for (
unsigned int n = 0; n <VDimension; n++)
virtual VectorType Evaluate(unsigned int, unsigned int, const ParticleSystemType *, double &) const
PointType & GetPosition(unsigned long int k, unsigned int d=0)
void ComputeAngularWeights(const PointType &, const typename ParticleSystemType::PointVectorType &, const PSMImageDomainWithGradients< TGradientNumericType, VDimension > *, std::vector< double > &) const
Superclass::VectorType VectorType
A facade class that manages interactions with a particle system.
DomainType * GetDomain(unsigned int i)
TGradientNumericType AngleCoefficient(const GradientVectorType &, const GradientVectorType &) const
virtual double EstimateSigma(unsigned int, const typename ParticleSystemType::PointVectorType &, const std::vector< double > &, const PointType &, double, double, int &err) const
PointVectorType FindNeighborhoodPoints(const PointType &p, double r, unsigned int d=0) const
vnl_vector_fixed< double, VDimension > VectorType