Skip to content

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

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

Fix SAVI formula: (1+L) was in denominator instead of numerator (#1094)#1095
brendancol merged 2 commits into
masterfrom
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
@brendancol brendancol deleted the issue-1094 branch May 4, 2026 13:06
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