Libs/Optimize/Function/CorrespondenceFunction.h
Namespaces
| Name |
|---|
| shapeworks User usage reporting (telemetry) |
Classes
| Name | |
|---|---|
| class | shapeworks::CorrespondenceFunction Correspondence term. |
Source code
```cpp
pragma once
include
include
include
include
include "Libs/Optimize/Matrix/ShapeGradientMatrix.h"
include "Libs/Optimize/Matrix/ShapeMatrix.h"
include "VectorFunction.h"
namespace shapeworks {
class CorrespondenceFunction : public VectorFunction { public: constexpr static int VDimension = 3; constexpr static unsigned int Dimension = VDimension;
typedef shapeworks::ShapeMatrix ShapeDataType; typedef shapeworks::ShapeGradientMatrix ShapeGradientType;
typedef ShapeDataType::DataType DataType;
typedef VectorFunction::VectorType VectorType;
typedef ParticleSystem::PointType PointType;
typedef vnl_vector
static std::shared_ptr
void SetShapeData(ShapeDataType s) { m_ShapeData = s; } ShapeDataType GetShapeData() { return m_ShapeData.GetPointer(); } const ShapeDataType* GetShapeData() const { return m_ShapeData.GetPointer(); }
void SetShapeGradient(ShapeGradientType s) { m_ShapeGradient = s; } ShapeGradientType GetShapeGradient() { return m_ShapeGradient.GetPointer(); } const ShapeGradientType* GetShapeGradient() const { return m_ShapeGradient.GetPointer(); }
virtual VectorType evaluate(unsigned int, unsigned int, const ParticleSystem*, double&, double&) const;
virtual VectorType evaluate(unsigned int a, unsigned int b, const ParticleSystem* c, double& d) const { double e; return this->evaluate(a, b, c, d, e); }
virtual double energy(unsigned int a, unsigned int b, const ParticleSystem* c) const { double e, d; this->evaluate(a, b, c, d, e); return e; }
virtual void before_iteration() { this->ComputeUpdates(this->particle_system_); }
virtual void after_iteration() { // Update the annealing parameter. if (m_HoldMinimumVariance != true && !m_UseMeanEnergy) { m_Counter++; if (m_Counter >= m_RecomputeCovarianceInterval) { m_Counter = 0; m_MinimumVariance *= m_MinimumVarianceDecayConstant; } } } void SetMinimumVarianceDecay(double initial_value, double final_value, double time_period) { m_MinimumVarianceDecayConstant = exp(log(final_value / initial_value) / time_period); m_MinimumVariance = initial_value; m_HoldMinimumVariance = false; }
void SetMinimumVariance(double d) { m_MinimumVariance = d; } double GetMinimumVariance() const { return m_MinimumVariance; }
bool GetHoldMinimumVariance() const { return m_HoldMinimumVariance; } void SetHoldMinimumVariance(bool b) { m_HoldMinimumVariance = b; }
void SetRecomputeCovarianceInterval(int i) { m_RecomputeCovarianceInterval = i; } int GetRecomputeCovarianceInterval() const { return m_RecomputeCovarianceInterval; }
void SetAttributeScales(const std::vector
void SetDomainsPerShape(int i) { m_DomainsPerShape = i; } int GetDomainsPerShape() const { return m_DomainsPerShape; }
void SetAttributesPerDomain(const std::vector
void UseMeanenergy() { m_UseMeanEnergy = true; } void UseEntropy() { m_UseMeanEnergy = false; }
void SetXYZ(int i, bool val) { if (m_UseXYZ.size() != m_DomainsPerShape) m_UseXYZ.resize(m_DomainsPerShape); m_UseXYZ[i] = val; } void SetNormals(int i, bool val) { if (m_UseNormals.size() != m_DomainsPerShape) m_UseNormals.resize(m_DomainsPerShape); m_UseNormals[i] = val; }
void PrecomputeForFixedDomains(const ParticleSystem* ps);
bool HasPrecomputedFixedDomains() const { return m_HasPrecomputedFixedDomains; }
void ClearPrecomputedFixedDomains();
void RequestPrecomputeForFixedDomains() { m_NeedsPrecomputation = true; }
bool CheckForNans(vnl_matrix_type mat) { bool flag = false; for (int i = 0; i < mat.rows(); i++) { for (int j = 0; j < mat.cols(); j++) { if (std::isnan(mat(i, j))) { flag = true; break; } } } return flag; }
std::shared_ptr
// from itkParticleVectorFunction
copy->domain_number_ = this->domain_number_;
copy->particle_system_ = this->particle_system_;
// local
copy->m_AttributeScales = this->m_AttributeScales;
copy->m_Counter = this->m_Counter;
copy->m_CurrentEnergy = this->m_CurrentEnergy;
copy->m_HoldMinimumVariance = this->m_HoldMinimumVariance;
copy->m_MinimumEigenValue = this->m_MinimumEigenValue;
copy->m_MinimumVariance = this->m_MinimumVariance;
copy->m_MinimumVarianceDecayConstant = this->m_MinimumVarianceDecayConstant;
copy->m_PointsUpdate = this->m_PointsUpdate;
copy->m_RecomputeCovarianceInterval = this->m_RecomputeCovarianceInterval;
copy->m_AttributesPerDomain = this->m_AttributesPerDomain;
copy->m_DomainsPerShape = this->m_DomainsPerShape;
copy->m_UseMeanEnergy = this->m_UseMeanEnergy;
copy->m_points_mean = this->m_points_mean;
copy->m_UseNormals = this->m_UseNormals;
copy->m_UseXYZ = this->m_UseXYZ;
copy->m_ShapeData = this->m_ShapeData;
copy->m_ShapeGradient = this->m_ShapeGradient;
// Copy fixed shape space members
copy->m_NeedsPrecomputation = this->m_NeedsPrecomputation;
copy->m_HasPrecomputedFixedDomains = this->m_HasPrecomputedFixedDomains;
copy->m_PrecomputedNumFixedSamples = this->m_PrecomputedNumFixedSamples;
copy->m_PrecomputedNumDims = this->m_PrecomputedNumDims;
copy->m_FixedY = this->m_FixedY;
copy->m_FixedMean = this->m_FixedMean;
copy->m_FixedPinvMat = this->m_FixedPinvMat;
copy->m_FixedGradientBasis = this->m_FixedGradientBasis;
copy->m_FixedU = this->m_FixedU;
copy->m_FixedW = this->m_FixedW;
copy->m_FixedDomainIndices = this->m_FixedDomainIndices;
return copy;
}
CorrespondenceFunction() {
// m_MinimumVarianceBase = 1.0;//exp(log(1.0e-5)/10000.0);
m_HoldMinimumVariance = true;
m_MinimumVariance = 1.0e-5;
m_MinimumEigenValue = 0.0;
m_MinimumVarianceDecayConstant = 1.0; // log(2.0) / 50000.0;
m_RecomputeCovarianceInterval = 1;
m_Counter = 0;
m_UseMeanEnergy = true;
m_UseNormals.clear();
m_UseXYZ.clear();
num_dims = 0;
num_samples = 0;
m_PointsUpdate = std::make_shared
protected: CorrespondenceFunction(const CorrespondenceFunction&) = delete; CorrespondenceFunction& operator=(const CorrespondenceFunction&) = delete;
typename ShapeDataType::Pointer m_ShapeData; typename ShapeGradientType::Pointer m_ShapeGradient;
virtual void ComputeUpdates(const ParticleSystem* c);
std::shared_ptr
double m_MinimumVariance;
double m_MinimumEigenValue;
// double m_MinimumVarianceBase;
bool m_HoldMinimumVariance;
int m_RecomputeCovarianceInterval;
double m_MinimumVarianceDecayConstant;
int m_Counter;
std::vector
// ============================================================================ // Fixed Shape Space / Fixed Domain Precomputation // ============================================================================ // When most domains are fixed and only a few are being optimized, // we can precompute the shape space (mean, pinvMat, gradient basis) from the fixed domains // and reuse it, avoiding expensive recomputation each iteration.
bool m_NeedsPrecomputation = false; bool m_HasPrecomputedFixedDomains = false;
// Number of fixed and total samples when precomputation was done int m_PrecomputedNumFixedSamples = 0; int m_PrecomputedNumDims = 0;
// Precomputed from fixed domains:
// μ_fixed: mean of fixed shapes (dM × 1)
std::shared_ptr
// Y_fixed: centered fixed shape data (dM × N_fixed)
std::shared_ptr
// pinvMat_fixed: (Y_fixed^T Y_fixed + αI)^{-1}, size (N_fixed × N_fixed)
std::shared_ptr
// Precomputed gradient basis: Y_fixed × pinvMat_fixed (dM × N_fixed)
// This allows computing gradients for new shapes as linear combinations
std::shared_ptr
// SVD components from fixed shapes (for potential reuse)
std::shared_ptr
// Which domains are fixed (indices into the particle system)
std::vector
Updated on 2026-03-31 at 16:02:11 +0000