Describe the bug
The SAVI implementation has the (1+L) factor on the wrong side of the division. The standard formula from Huete (1988) is:
SAVI = ((NIR - Red) / (NIR + Red + L)) * (1 + L)
The code computes:
(NIR - Red) / ((NIR + Red + L) * (1 + L))
This puts (1+L) in the denominator instead of the numerator. With the default L=0.5, every SAVI result is too small by a factor of (1+L)^2 = 2.25.
Both _savi_cpu (line 1065) and _savi_gpu (line 1080) have the same bug.
Separately, the EBBI GPU kernel uses nb.int64(10) where the CPU version uses plain 10. Minor type inconsistency worth fixing at the same time.
Expected behavior
For NIR=0.8, Red=0.2, L=0.5:
- Correct: ((0.8 - 0.2) / (0.8 + 0.2 + 0.5)) * 1.5 = 0.6 / 1.5 * 1.5 = 0.6
- Current code: 0.6 / (1.5 * 1.5) = 0.6 / 2.25 = 0.267
Affected code
xrspatial/multispectral.py line 1065: denominator = soma * (1.0 + soil_factor)
xrspatial/multispectral.py line 1080: denominator = soma * (nb.float32(1.0) + soil_factor)
xrspatial/multispectral.py line 1370: nb.int64(10) type inconsistency in EBBI
Describe the bug
The SAVI implementation has the (1+L) factor on the wrong side of the division. The standard formula from Huete (1988) is:
The code computes:
This puts (1+L) in the denominator instead of the numerator. With the default L=0.5, every SAVI result is too small by a factor of (1+L)^2 = 2.25.
Both
_savi_cpu(line 1065) and_savi_gpu(line 1080) have the same bug.Separately, the EBBI GPU kernel uses
nb.int64(10)where the CPU version uses plain10. Minor type inconsistency worth fixing at the same time.Expected behavior
For NIR=0.8, Red=0.2, L=0.5:
Affected code
xrspatial/multispectral.pyline 1065:denominator = soma * (1.0 + soil_factor)xrspatial/multispectral.pyline 1080:denominator = soma * (nb.float32(1.0) + soil_factor)xrspatial/multispectral.pyline 1370:nb.int64(10)type inconsistency in EBBI