Skip to content

Commit 3eedc5e

Browse files
committed
BUG: ScaleLogarithmicTransform Jacobian ignores the center
ComputeJacobianWithRespectToParameters() returned scale * p, while the transform maps p to scale * (p - center) + center. The base ScaleTransform already differentiates about the center. Registration with a non-zero center was fed a wrong gradient. Differentiate about the center, and cover the Jacobian in the test, which previously exercised none of it.
1 parent 70cc06a commit 3eedc5e

2 files changed

Lines changed: 51 additions & 2 deletions

File tree

Modules/Core/Transform/include/itkScaleLogarithmicTransform.hxx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,16 @@ ScaleLogarithmicTransform<TParametersValueType, VDimension>::ComputeJacobianWith
7777
const InputPointType & p,
7878
JacobianType & jacobian) const
7979
{
80-
const ScaleType & scales = this->GetScale();
80+
const ScaleType & scales = this->GetScale();
81+
const InputPointType & center = this->GetCenter();
8182

8283
jacobian.SetSize(SpaceDimension, this->GetNumberOfLocalParameters());
8384
jacobian.Fill(0);
8485
for (unsigned int dim = 0; dim < SpaceDimension; ++dim)
8586
{
8687
// the derivative with respect to Log(scale) = scale * derivative with
8788
// respect to scale.
88-
jacobian(dim, dim) = scales[dim] * p[dim];
89+
jacobian(dim, dim) = scales[dim] * (p[dim] - center[dim]);
8990
}
9091
}
9192

Modules/Core/Transform/test/itkScaleLogarithmicTransformTest.cxx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*
1717
*=========================================================================*/
1818

19+
#include <cmath>
1920
#include <iostream>
2021

2122
#include "itkScaleLogarithmicTransform.h"
@@ -266,6 +267,53 @@ itkScaleLogarithmicTransformTest(int, char *[])
266267
}
267268

268269

270+
// Exercise the Jacobian about a non-zero center
271+
{
272+
auto centeredTransform = TransformType::New();
273+
274+
TransformType::InputPointType center;
275+
center[0] = 5;
276+
center[1] = 6;
277+
center[2] = 7;
278+
centeredTransform->SetCenter(center);
279+
280+
TransformType::ParametersType parameters = centeredTransform->GetParameters();
281+
parameters[0] = std::log(2.0);
282+
parameters[1] = std::log(3.0);
283+
parameters[2] = std::log(4.0);
284+
centeredTransform->SetParameters(parameters);
285+
286+
constexpr TransformType::InputPointType::ValueType pInit[3]{ 10, 10, 10 };
287+
const TransformType::InputPointType p = pInit;
288+
289+
TransformType::JacobianType jacobian;
290+
centeredTransform->ComputeJacobianWithRespectToParameters(p, jacobian);
291+
292+
const TransformType::ScaleType & scales = centeredTransform->GetScale();
293+
294+
testStatus = true;
295+
for (unsigned int i = 0; i < N; ++i)
296+
{
297+
// d/dLog(scale[i]) of scale[i] * (p[i] - center[i]) + center[i]
298+
const double expected = scales[i] * (p[i] - center[i]);
299+
if (itk::Math::Absolute(jacobian(i, i) - expected) > epsilon)
300+
{
301+
testStatus = false;
302+
break;
303+
}
304+
}
305+
if (!testStatus)
306+
{
307+
std::cerr << "Error in ComputeJacobianWithRespectToParameters()." << std::endl;
308+
std::cerr << "The center of the transformation was ignored." << std::endl;
309+
std::cerr << "Jacobian: " << jacobian << std::endl;
310+
return EXIT_FAILURE;
311+
}
312+
313+
std::cout << "Successful ComputeJacobianWithRespectToParameters() " << std::endl;
314+
}
315+
316+
269317
std::cout << "Test finished" << std::endl;
270318
return EXIT_SUCCESS;
271319
}

0 commit comments

Comments
 (0)