Skip to content

Commit 3ae4b52

Browse files
committed
[Minuit2] Document why covariance transform omits 2nd-derivative term
Int2extCovariance/Ext2intCovariance transform the error matrix between internal and external coordinates using only the first-order Jacobian (dPext/dPint), even on the diagonal. This is intentional and contrasts with the Hessian/G2 transformation in AnalyticalGradientCalculator, which carries an extra diagonal term d^2Pext/dPint^2 * gradient. The Hessian needs that non-tensorial term because it is evaluated at arbitrary, non-stationary points where the external gradient is nonzero. The covariance matrix is the inverse Hessian evaluated at the minimum, where the gradient vanishes; the term is then identically zero and the covariance transforms as a genuine (2,0) tensor with the Jacobian alone. Adding it would also break the exact round-trip between Int2extCovariance and Ext2intCovariance.
1 parent 1b5a496 commit 3ae4b52

1 file changed

Lines changed: 12 additions & 0 deletions

File tree

math/minuit2/src/MnUserTransformation.cxx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,15 @@ MnUserTransformation::Int2extCovariance(const MnAlgebraicVector &vec, const MnAl
140140
// return the external covariance matrix from the internal error matrix and the internal parameter value
141141
// the vector of internal parameter is needed for the derivatives (Jacobian of the transformation)
142142
// Vext(i,j) = Vint(i,j) * dPext(i)/dPint(i) * dPext(j)/dPint(j)
143+
//
144+
// Note: only the first derivative (Jacobian) of the int<->ext transformation enters here, even on the
145+
// diagonal. Unlike the Hessian/G2 transformation (see AnalyticalGradientCalculator), there is no
146+
// d^2Pext/dPint^2 * gradient term. The Hessian needs that extra non-tensorial term because it is
147+
// evaluated at arbitrary, non-stationary points where the external gradient is nonzero. The covariance
148+
// matrix, by contrast, is the inverse Hessian evaluated at the minimum, where the external gradient
149+
// vanishes and that term is identically zero; the covariance then transforms as a genuine (2,0) tensor
150+
// with the Jacobian alone. (Adding the term here would also break the exact round-trip between
151+
// Int2extCovariance and Ext2intCovariance.)
143152

144153
MnUserCovariance result(cov.Nrow());
145154
for (unsigned int i = 0; i < vec.size(); i++) {
@@ -171,6 +180,9 @@ MnUserTransformation::Ext2intCovariance(const MnAlgebraicVector &vec, const MnAl
171180
// return the internal covariance matrix from the external error matrix and the internal parameter value
172181
// the vector of internal parameter is needed for the derivatives (Jacobian of the transformation)
173182
// Vint(i,j) = Vext(i,j) * dPint(i)/dPext(i) * dPint(j)/dPext(j)
183+
//
184+
// As in Int2extCovariance, only the Jacobian enters: no second-derivative (d^2Pint/dPext^2 * gradient)
185+
// term is needed, since the covariance is the inverse Hessian at the minimum where the gradient is zero.
174186

175187
MnUserCovariance result(cov.Nrow());
176188
for (unsigned int i = 0; i < vec.size(); i++) {

0 commit comments

Comments
 (0)