vibespatial.raster.algebra

GPU raster algebra: local and focal operations.

Local operations use CuPy element-wise broadcasting. Focal operations use custom NVRTC shared-memory tiled stencil kernels. Fused expressions use custom NVRTC kernels compiled at runtime from user-supplied expression strings (raster_expression).

ADR-0039: GPU Raster Algebra Dispatch

Functions

raster_add(→ vibespatial.raster.buffers.OwnedRasterArray)

Element-wise addition of two rasters.

raster_apply(→ vibespatial.raster.buffers.OwnedRasterArray)

Apply an arbitrary element-wise function to a raster.

raster_aspect(...)

Compute aspect (degrees, 0=north, clockwise) from a DEM raster.

raster_band_math(...)

Arbitrary band math on a multiband raster.

raster_band_ratio(...)

Generic band ratio: band_a / band_b.

raster_classify(...)

Reclassify raster values into discrete classes.

raster_convolve(...)

Apply a 2D convolution kernel to a raster on GPU.

raster_curvature(...)

Compute profile curvature from a DEM raster.

raster_divide(...)

Element-wise division of two rasters. Division by zero yields nodata.

raster_expression(...)

Evaluate a fused element-wise expression over one or more rasters.

raster_focal_max(...)

Compute focal (neighborhood) maximum.

raster_focal_mean(...)

Compute focal (neighborhood) mean.

raster_focal_min(...)

Compute focal (neighborhood) minimum.

raster_focal_range(...)

Compute focal (neighborhood) range (max - min).

raster_focal_std(...)

Compute focal (neighborhood) standard deviation (population, ddof=0).

raster_focal_variety(...)

Compute focal (neighborhood) variety (count of unique values).

raster_gaussian_filter(...)

Apply a Gaussian filter to a raster on GPU.

raster_hillshade(...)

Compute hillshade from a DEM raster.

raster_multiply(...)

Element-wise multiplication of two rasters.

raster_ndvi(→ vibespatial.raster.buffers.OwnedRasterArray)

Normalized Difference Vegetation Index: (NIR - RED) / (NIR + RED).

raster_slope(→ vibespatial.raster.buffers.OwnedRasterArray)

Compute slope (degrees) from a DEM raster.

raster_subtract(...)

Element-wise subtraction of two rasters.

raster_tpi(→ vibespatial.raster.buffers.OwnedRasterArray)

Compute Topographic Position Index (TPI) from a DEM raster.

raster_tri(→ vibespatial.raster.buffers.OwnedRasterArray)

Compute Terrain Ruggedness Index (TRI) from a DEM raster.

raster_where(→ vibespatial.raster.buffers.OwnedRasterArray)

Element-wise conditional selection.

Module Contents

vibespatial.raster.algebra.raster_add(a: vibespatial.raster.buffers.OwnedRasterArray, b: vibespatial.raster.buffers.OwnedRasterArray, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Element-wise addition of two rasters.

vibespatial.raster.algebra.raster_apply(raster: vibespatial.raster.buffers.OwnedRasterArray, func, *, nodata: float | int | None = None, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Apply an arbitrary element-wise function to a raster.

Parameters

rasterOwnedRasterArray

Input raster.

funccallable

Function that accepts a numpy or CuPy array and returns an array of the same type. When use_gpu=True this must accept CuPy arrays; when use_gpu=False it must accept numpy arrays.

nodatafloat | int | None

Nodata value for the output. If None, inherits from input.

use_gpubool or None

Force GPU (True), force CPU (False), or auto-detect (None).

vibespatial.raster.algebra.raster_aspect(dem: vibespatial.raster.buffers.OwnedRasterArray, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Compute aspect (degrees, 0=north, clockwise) from a DEM raster.

Uses a fused NVRTC kernel with shared-memory tiled 3x3 Horn method when GPU is available, or a numpy CPU fallback otherwise.

Parameters

demOwnedRasterArray

Digital Elevation Model raster.

use_gpubool or None

Force GPU (True), force CPU (False), or auto-dispatch (None). Auto uses GPU when CuPy and CUDA runtime are available and the raster exceeds the pixel-count threshold.

vibespatial.raster.algebra.raster_band_math(raster: vibespatial.raster.buffers.OwnedRasterArray, expression: str, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Arbitrary band math on a multiband raster.

The expression uses 0-indexed band references with the variable b: b[0], b[1], etc. This is a thin wrapper around raster_expression() that binds the input raster as variable b.

Parameters

rasterOwnedRasterArray

Multiband raster.

expressionstr

Arithmetic expression using b[N] band references (0-indexed). Supported operators: +, -, *, /. Supported functions: abs, sqrt, pow, min, max, clamp, log, log2, log10, exp, sin, cos, tan, floor, ceil.

Example: "(b[3] - b[2]) / (b[3] + b[2] + 0.5 * b[1])"

use_gpubool or None

Force GPU (True), force CPU (False), or auto-detect (None).

Returns

OwnedRasterArray

Single-band raster with the computed result.

Raises

ValueError

If the expression is empty or contains invalid tokens.

IndexError

If a band index exceeds the raster’s band count.

vibespatial.raster.algebra.raster_band_ratio(raster: vibespatial.raster.buffers.OwnedRasterArray, *, band_a: int, band_b: int, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Generic band ratio: band_a / band_b.

Parameters

rasterOwnedRasterArray

Multiband raster.

band_aint

1-indexed band number for the numerator.

band_bint

1-indexed band number for the denominator.

use_gpubool or None

Force GPU (True), force CPU (False), or auto-detect (None).

Returns

OwnedRasterArray

Single-band raster with the ratio values. Pixels where band_b == 0 are set to nodata.

Raises

ValueError

If band indices are less than 1.

IndexError

If band indices exceed the raster’s band count.

vibespatial.raster.algebra.raster_classify(raster: vibespatial.raster.buffers.OwnedRasterArray, bins: list[float], labels: list[int | float], *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Reclassify raster values into discrete classes.

Parameters

rasterOwnedRasterArray

Input raster.

binslist[float]

Bin edges (N edges define N-1 bins). Values below bins[0] get labels[0], values in [bins[i], bins[i+1]) get labels[i+1], etc.

labelslist[int | float]

Class labels. Must have len(bins) + 1 elements.

use_gpubool or None

Force GPU (True), force CPU (False), or auto-detect (None).

vibespatial.raster.algebra.raster_convolve(raster: vibespatial.raster.buffers.OwnedRasterArray, kernel: numpy.ndarray) vibespatial.raster.buffers.OwnedRasterArray

Apply a 2D convolution kernel to a raster on GPU.

Parameters

rasterOwnedRasterArray

Input raster (single-band).

kernelnp.ndarray

2D convolution kernel (e.g., 3x3, 5x5).

vibespatial.raster.algebra.raster_curvature(dem: vibespatial.raster.buffers.OwnedRasterArray, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Compute profile curvature from a DEM raster.

Uses second-order finite differences from the 3x3 window per Zevenbergen & Thorne (1987). Positive curvature indicates concave surfaces, negative indicates convex.

Parameters

demOwnedRasterArray

Digital Elevation Model raster.

use_gpubool or None

Force GPU (True), CPU (False), or auto-dispatch (None).

vibespatial.raster.algebra.raster_divide(a: vibespatial.raster.buffers.OwnedRasterArray, b: vibespatial.raster.buffers.OwnedRasterArray, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Element-wise division of two rasters. Division by zero yields nodata.

vibespatial.raster.algebra.raster_expression(expression: str, *, use_gpu: bool | None = None, **rasters: vibespatial.raster.buffers.OwnedRasterArray) vibespatial.raster.buffers.OwnedRasterArray

Evaluate a fused element-wise expression over one or more rasters.

Compiles the expression into a single NVRTC kernel at runtime so that multiple arithmetic operations execute in a single GPU pass with one read and one write to global memory.

Parameters

expressionstr

Arithmetic expression using single-letter variable names that correspond to the keyword arguments. Supported operators: +, -, *, /. Supported functions: abs, sqrt, pow, min, max, clamp, log, log2, log10, exp, sin, cos, tan, floor, ceil.

Band indexing is supported for multiband rasters: a[0], a[3], etc. (0-indexed). Band references can be mixed with standalone single-band raster variables.

use_gpubool or None

Force GPU (True), force CPU (False), or auto-detect (None).

**rastersOwnedRasterArray

Named input rasters. Variable names must be single lowercase letters a-h. All rasters must have the same spatial dimensions (height, width).

Returns

OwnedRasterArray

Result raster with the same affine and CRS as the first input. Output is single-band. Output dtype is float64 unless all inputs are float32.

Examples

NDVI from separate single-band rasters:

>>> result = raster_expression("(a - b) / (a + b)", a=nir, b=red)

NDVI from a multiband raster (band 3 = NIR, band 2 = red, 0-indexed):

>>> result = raster_expression("(a[3] - a[2]) / (a[3] + a[2])", a=multiband)

Mixed multiband and single-band:

>>> result = raster_expression("a[0] * b + a[1]", a=multiband, b=scalar)

Raises

ValueError

If the expression is invalid, variable names are out of range, or raster spatial dimensions do not match.

IndexError

If a band index exceeds the referenced raster’s band count.

vibespatial.raster.algebra.raster_focal_max(raster: vibespatial.raster.buffers.OwnedRasterArray, radius: int | tuple[int, int] = 1, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Compute focal (neighborhood) maximum.

Parameters

rasterOwnedRasterArray

Input raster (single-band).

radiusint or tuple[int, int]

Window radius. If int, symmetric. If tuple, (radius_y, radius_x).

use_gpubool or None

Force GPU (True), CPU (False), or auto-select (None).

vibespatial.raster.algebra.raster_focal_mean(raster: vibespatial.raster.buffers.OwnedRasterArray, radius: int | tuple[int, int] = 1, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Compute focal (neighborhood) mean.

Parameters

rasterOwnedRasterArray

Input raster (single-band).

radiusint or tuple[int, int]

Window radius. If int, symmetric. If tuple, (radius_y, radius_x).

use_gpubool or None

Force GPU (True), CPU (False), or auto-select (None).

vibespatial.raster.algebra.raster_focal_min(raster: vibespatial.raster.buffers.OwnedRasterArray, radius: int | tuple[int, int] = 1, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Compute focal (neighborhood) minimum.

Parameters

rasterOwnedRasterArray

Input raster (single-band).

radiusint or tuple[int, int]

Window radius. If int, symmetric. If tuple, (radius_y, radius_x). Window size = 2*radius + 1 in each dimension.

use_gpubool or None

Force GPU (True), CPU (False), or auto-select (None).

vibespatial.raster.algebra.raster_focal_range(raster: vibespatial.raster.buffers.OwnedRasterArray, radius: int | tuple[int, int] = 1, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Compute focal (neighborhood) range (max - min).

Parameters

rasterOwnedRasterArray

Input raster (single-band).

radiusint or tuple[int, int]

Window radius. If int, symmetric. If tuple, (radius_y, radius_x).

use_gpubool or None

Force GPU (True), CPU (False), or auto-select (None).

vibespatial.raster.algebra.raster_focal_std(raster: vibespatial.raster.buffers.OwnedRasterArray, radius: int | tuple[int, int] = 1, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Compute focal (neighborhood) standard deviation (population, ddof=0).

Uses Welford’s online algorithm on GPU to avoid catastrophic cancellation.

Parameters

rasterOwnedRasterArray

Input raster (single-band).

radiusint or tuple[int, int]

Window radius. If int, symmetric. If tuple, (radius_y, radius_x).

use_gpubool or None

Force GPU (True), CPU (False), or auto-select (None).

vibespatial.raster.algebra.raster_focal_variety(raster: vibespatial.raster.buffers.OwnedRasterArray, radius: int | tuple[int, int] = 1, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Compute focal (neighborhood) variety (count of unique values).

Uses register-based unique counting on GPU. Practical for windows up to ~7x7 (49 unique values max).

Parameters

rasterOwnedRasterArray

Input raster (single-band).

radiusint or tuple[int, int]

Window radius. If int, symmetric. If tuple, (radius_y, radius_x).

use_gpubool or None

Force GPU (True), CPU (False), or auto-select (None).

vibespatial.raster.algebra.raster_gaussian_filter(raster: vibespatial.raster.buffers.OwnedRasterArray, sigma: float, *, kernel_size: int | None = None) vibespatial.raster.buffers.OwnedRasterArray

Apply a Gaussian filter to a raster on GPU.

Parameters

rasterOwnedRasterArray

Input raster.

sigmafloat

Standard deviation of the Gaussian. Must be positive.

kernel_sizeint or None

Size of the kernel. Default: 2 * ceil(3*sigma) + 1.

Raises

ValueError

If sigma is not positive.

vibespatial.raster.algebra.raster_hillshade(dem: vibespatial.raster.buffers.OwnedRasterArray, *, azimuth: float = 315.0, altitude: float = 45.0, z_factor: float = 1.0, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Compute hillshade from a DEM raster.

Uses the Horn method to compute slope and aspect from a 3x3 neighborhood, then applies the standard hillshade illumination formula.

Parameters

demOwnedRasterArray

Digital Elevation Model raster (single-band).

azimuthfloat

Direction of the light source in degrees (0=north, clockwise). Default 315 (northwest).

altitudefloat

Altitude of the light source in degrees above the horizon. Default 45.

z_factorfloat

Vertical exaggeration factor. Default 1.0.

use_gpubool or None

Force GPU (True) or CPU (False). None auto-detects.

Returns

OwnedRasterArray

Hillshade raster with uint8 dtype (0-255). Nodata value is 0 when the input has nodata, otherwise None.

vibespatial.raster.algebra.raster_multiply(a: vibespatial.raster.buffers.OwnedRasterArray, b: vibespatial.raster.buffers.OwnedRasterArray, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Element-wise multiplication of two rasters.

vibespatial.raster.algebra.raster_ndvi(raster: vibespatial.raster.buffers.OwnedRasterArray, *, nir_band: int = 4, red_band: int = 3, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Normalized Difference Vegetation Index: (NIR - RED) / (NIR + RED).

Parameters

rasterOwnedRasterArray

Multiband raster containing NIR and RED bands.

nir_bandint

1-indexed band number for the NIR band (default 4, Landsat/Sentinel-2 convention).

red_bandint

1-indexed band number for the RED band (default 3).

use_gpubool or None

Force GPU (True), force CPU (False), or auto-detect (None).

Returns

OwnedRasterArray

Single-band raster with NDVI values in [-1, 1]. Pixels where NIR + RED == 0 are set to nodata.

Raises

ValueError

If band indices are less than 1.

IndexError

If band indices exceed the raster’s band count.

vibespatial.raster.algebra.raster_slope(dem: vibespatial.raster.buffers.OwnedRasterArray, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Compute slope (degrees) from a DEM raster.

Uses a fused NVRTC kernel with shared-memory tiled 3x3 Horn method when GPU is available, or a numpy CPU fallback otherwise.

Parameters

demOwnedRasterArray

Digital Elevation Model raster.

use_gpubool or None

Force GPU (True), force CPU (False), or auto-dispatch (None). Auto uses GPU when CuPy and CUDA runtime are available and the raster exceeds the pixel-count threshold.

vibespatial.raster.algebra.raster_subtract(a: vibespatial.raster.buffers.OwnedRasterArray, b: vibespatial.raster.buffers.OwnedRasterArray, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Element-wise subtraction of two rasters.

vibespatial.raster.algebra.raster_tpi(dem: vibespatial.raster.buffers.OwnedRasterArray, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Compute Topographic Position Index (TPI) from a DEM raster.

TPI is the center cell elevation minus the mean of its 8 neighbors. Positive values indicate ridges/hilltops, negative values indicate valleys.

Parameters

demOwnedRasterArray

Digital Elevation Model raster.

use_gpubool or None

Force GPU (True), CPU (False), or auto-dispatch (None).

vibespatial.raster.algebra.raster_tri(dem: vibespatial.raster.buffers.OwnedRasterArray, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Compute Terrain Ruggedness Index (TRI) from a DEM raster.

TRI is the mean absolute difference between the center cell and its 8 neighbors. Riley et al. (1999).

Parameters

demOwnedRasterArray

Digital Elevation Model raster.

use_gpubool or None

Force GPU (True), CPU (False), or auto-dispatch (None).

vibespatial.raster.algebra.raster_where(condition: vibespatial.raster.buffers.OwnedRasterArray, true_val: vibespatial.raster.buffers.OwnedRasterArray | float | int, false_val: vibespatial.raster.buffers.OwnedRasterArray | float | int, *, use_gpu: bool | None = None) vibespatial.raster.buffers.OwnedRasterArray

Element-wise conditional selection.

Parameters

conditionOwnedRasterArray

Boolean-like raster (nonzero = True).

true_val, false_valOwnedRasterArray or scalar

Values to use where condition is True/False.

use_gpubool or None

Force GPU (True), force CPU (False), or auto-detect (None).