Skip to content

Fix SAVI formula: (1+L) was in denominator instead of numerator (#1094)#1095

Merged
brendancol merged 2 commits intomasterfrom
issue-1094
Mar 30, 2026
Merged

Fix SAVI formula: (1+L) was in denominator instead of numerator (#1094)#1095
brendancol merged 2 commits intomasterfrom
issue-1094

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

Summary

Fixes #1094. The SAVI formula (Huete 1988) had (1+L) on the wrong side of the division.

Correct: ((NIR - Red) / (NIR + Red + L)) * (1 + L)
Was: (NIR - Red) / ((NIR + Red + L) * (1 + L))

With the default L=0.5, every SAVI result was too small by a factor of (1+L)^2 = 2.25. Both _savi_cpu and _savi_gpu had the same error.

Also fixed a minor type inconsistency in the EBBI GPU kernel (nb.int64(10) -> 10.0).

Test plan

  • Updated qgis_savi fixture with correct reference values (4x larger with L=1)
  • Updated data_uint_dtype_savi fixture with correct values
  • Added test_savi_formula_1094: spot-checks the formula on all 4 backends with hand-computed values (NIR=0.8, Red=0.2, L=0.5 should give 0.6)
  • All existing SAVI tests updated and passing (zero soil factor, uint dtypes, GPU)
  • Full test_multispectral.py suite: 147 passed

SAVI: The (1+L) factor was in the denominator instead of the numerator.
The standard formula (Huete 1988) is ((NIR-Red)/(NIR+Red+L))*(1+L).
The code computed (NIR-Red)/((NIR+Red+L)*(1+L)), making all results
too small by (1+L)^2 = 2.25 with default L=0.5.

EBBI GPU: Changed nb.int64(10) to 10.0 to match CPU path's type
behavior.
SAVI had (1+L) in the denominator instead of the numerator. The
Huete (1988) formula is ((NIR-Red)/(NIR+Red+L))*(1+L). The code
computed (NIR-Red)/((NIR+Red+L)*(1+L)), making results too small
by (1+L)^2.

Updated the qgis_savi fixture and uint dtype fixture with correct
reference values. Added test_savi_formula_1094 which checks all 4
backends against the formula directly.

Also fixed EBBI GPU: nb.int64(10) -> 10.0 for type consistency.
@github-actions github-actions bot added the performance PR touches performance-sensitive code label Mar 30, 2026
@brendancol brendancol merged commit aa74fbb into master Mar 30, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance PR touches performance-sensitive code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SAVI formula divides by (1+L) instead of multiplying

1 participant