Description
Continuing from #1461...
We attempt to avoid zero or negatives in the log
(or division be zero or negatives in the gradient) by thresholding the quotient. Unfortunately, the code is not consistent, even after many attempts.
First introducing notation:
(i.e. lower threshold on
formulas
A strategy could be
This function has a gradient w.r.t.
with
This gradient is equivalent to back-projecting
e >= y/Q ? y/e : 0
[4]
Log-likelihood code
The function [1] is what is computed by PoissonLogLikelihoodWithLinearModelForMeanAndProjData
for the value via
STIR/src/buildblock/recon_array_functions.cxx
Lines 367 to 371 in 12bfa87
where the arguments are computed
STIR/src/recon_buildblock/PoissonLogLikelihoodWithLinearModelForMeanAndProjData.cxx
Lines 1451 to 1467 in 12bfa87
Gradient code
For the gradient we use the optimisation that any multiplicative factors drop out.
STIR/src/recon_buildblock/PoissonLogLikelihoodWithLinearModelForMeanAndProjData.cxx
Lines 1407 to 1433 in 12bfa87
Unfortunately, the divide_and_truncate
method (which implements the division [4]) does not know about the multiplicative factors, and is therefore using a different threshold than the logL value.
Gradient formulas
Writing the full forward projection as
G.back_project((f >= y/Q ? y/f : 0) - m)
This is equivalent to
P.back_project((e >= m*y/Q ? y/e : 0) - 1)
Conclusion
There are 2 inconsistencies:
- In both
divide_and_truncate
andaccumulate_likelihood
,Q=10000
, such that the quotient in the gradient computation is not consistent with the log-term in the logL value wherever only one of those reaches the threshold, so if$m<1$ where$m y/Q < e < y/Q $ . - the "sensitivity" term uses a threshold in the current logL computation, but not in the gradient computation.