
Pilar 3 — 4D Pedometry: Stacked ConvLSTM Forecasts of SOC
Hugo Rodrigues
Source:vignettes/pilar3-4d-soc.Rmd
pilar3-4d-soc.RmdAbstract
Most digital soil maps report a time-invariant property field, which
ignores the evidence that topsoil Soil Organic Carbon (SOC) responds
measurably to climate forcing on monthly to annual scales (Lehmann and Kleber
2015; Minasny et al. 2017).
The Pillar 3 of edaphos addresses that gap
with a stacked Convolutional LSTM (Shi et al. 2015) trained in
sequence-to-sequence mode plus a multi-step rollout wrapper for forward
forecasting under known future drivers. A physics-informed mass-balance
regulariser optionally penalises violations of an analytical SOC
kinetic, fusing Pillar 2 into Pillar 3 (Raissi, Perdikaris, and Karniadakis 2019; Reichstein et al. 2019).
1. From 3D to 4D pedometry
Let denote a topsoil property at location and time . Traditional DSM (McBratney, Mendonça Santos, and Minasny 2003) estimates by collapsing over time. A 4D model retains the time dimension and predicts the full spatio-temporal field , where is the driver stack (climate, vegetation, static topography).
The Convolutional LSTM cell (Shi et al. 2015)
operationalises spatial memory: at each time step the hidden state
and the cell state
are tensors of the same spatial size as the input, so memory propagates
with its location:
with * a 2-D convolution
and
the Hadamard product. Stacking
cells feeds
as the input to layer
,
yielding a hierarchy of spatial receptive fields.
2. Synthetic SOC dynamics cube
To keep the vignette self-contained and reproducible,
[temporal_synth_soc_cube()][temporal_synth_soc_cube]
integrates the driver-response kinetic
with
the monthly precipitation field and
its long-term mean. The numerator
models organic input proportional to wet-season biomass turnover; the
denominator
captures humidity-modulated decomposition (Lehmann and Kleber 2015; Minasny et al. 2017).
library(edaphos)
.torch_ok <- requireNamespace("torch", quietly = TRUE) &&
isTRUE(tryCatch(torch::torch_is_installed(),
error = function(e) FALSE))
if (!.torch_ok) {
knitr::knit_exit(
"torch runtime (libtorch) not available — skipping vignette."
)
}
cube <- temporal_synth_soc_cube(H = 12L, W = 12L, T_total = 18L,
seed = 7L)
str(cube)
#> List of 3
#> $ elev : num [1:12, 1:12] 42.8 32.6 42.4 51.1 55.6 ...
#> $ precip: num [1:18, 1:12, 1:12] 16.3 28.7 53.2 71.1 87.7 ...
#> $ soc : num [1:18, 1:12, 1:12] 18.9 19.4 20.1 21.3 23.3 ...torch runtime (libtorch) not available — skipping vignette.