const ParametersType oldParameters = this->m_Transform->GetParameters();
const auto numPara = this->m_Transform->GetNumberOfParameters();
const auto numSamples = static_cast<const int>(this->m_SamplePoints.size());
std::vector<glm::dvec3> oldMappedVoxels(numSamples);
for (int c = 0; c < numSamples; c++)
{
auto point = this->m_SamplePoints[c];
oldMappedVoxels[c] = this->m_Transform->TransformPoint(point);
}
ParametersType deltaParameters(numPara);
ScalesType tmpParamScales(numPara);
for (int p = 0; p < numPara; p++)
{
ScalesType sampleShifts(numSamples);
std::fill(deltaParameters.begin(), deltaParameters.end(), 0);
deltaParameters[p] = this->m_SmallParameterVariation;
this->m_Transform->SetParameters(deltaParameters);
for (int c = 0; c < numSamples; c++)
{
auto point = this->m_SamplePoints[c];
glm::dvec3 newMappedVoxel = this->m_Transform->TransformPoint(point);
sampleShifts[c] = glm::distance(oldMappedVoxels[c], newMappedVoxel);
}
tmpParamScales[p] = *max_element(sampleShifts.begin(), sampleShifts.end());
this->m_Transform->SetParameters(oldParameters);
}
for (int i = 0; i < numPara; i++)
{
tmpParamScales[i] *= tmpParamScales[i];
//normalize to unit variation
tmpParamScales[i] *= 1/ glm::sqrt(this->m_SmallParameterVariation);
}
double maxStep = 0 ;
double maxShift = 0;
double factor = 1;
if (this->m_SamplePoints.size() > 0 && this->m_Transform != nullptr)
{
const auto numPara = step.size();
const auto numSamples = static_cast<const int>(this->m_SamplePoints.size());
for (int p = 0; p < numPara; p++)
{
if (maxStep < std::abs(step[p]))
{
maxStep = std::abs(step[p]);
}
}
factor = this->m_SmallParameterVariation / maxStep;
ParametersType smallStep(this->m_Transform->GetParameters());
std::fill(smallStep.begin(), smallStep.end(), 0);
//Use a small step to have a linear approximation.
smallStep[0] = step[0] * factor;
smallStep[1] = step[1] * factor;
smallStep[2] = step[2] * factor;
smallStep[3] = step[3] * factor;
smallStep[4] = step[4] * factor;
smallStep[5] = step[5] * factor;
//ComputeMaximumVoxelShift
const ParametersType oldParameters = this->m_Transform->GetParameters();
//
//printf("oldParameters : ");
//for (int i = 0; i < oldParameters.size(); i++)
// printf(" %f , ", oldParameters[i]);
//printf(" \n ");
std::vector<glm::dvec3> oldMappedVoxels(numSamples);
for (int c = 0; c < numSamples; c++)
{
auto point = this->m_SamplePoints[c];
oldMappedVoxels[c] = this->m_Transform->TransformPoint(point);
}
//printf("smallStep : ");
//for (int i = 0; i < smallStep.size(); i++)
// printf(" %f , ", smallStep[i]);
//printf(" \n ");
this->m_Transform->SetParameters(smallStep);
ScalesType sampleShifts(numSamples);
for (int c = 0; c < numSamples; c++)
{
auto point = this->m_SamplePoints[c];
glm::dvec3 newMappedVoxel = this->m_Transform->TransformPoint(point);
sampleShifts[c] = glm::distance(oldMappedVoxels[c], newMappedVoxel);
}
maxShift = *max_element(sampleShifts.begin(), sampleShifts.end());
}
double stepScale = maxShift / factor;
double compensatedSummation=0;
double m_LearningRate = this->m_MaximumStepSizeInPhysicalUnits / stepScale;
for (int dim = 0; dim < step.size(); ++dim)
{
const double weighted = step[dim];
compensatedSummation += weighted * weighted;
}
const double gradientMagnitude = std::sqrt(compensatedSummation);
m_LearningRate *= gradientMagnitude;