expconv
expconv
¶
Exponential convolution functions for pharmacokinetic modeling.
This module implements efficient recursive formulas for convolving signals with exponential and multi-exponential functions. These are the core building blocks for compartmental pharmacokinetic models.
GPU/CPU agnostic using the xp array module pattern. NO scipy dependency - see XP Compatibility Requirements in plan.md.
References
Flouri D, Lesnic D, Mayrovitz HN (2016). Numerical solution of the convolution integral equations in pharmacokinetics. Comput Methods Biomech Biomed Engin. 19(13):1359-1367.
dcmri library: https://github.com/dcmri/dcmri
expconv
¶
Convolve a signal with exponential decay function(s).
Computes the convolution: (f * exp(-t/T))(t) = integral_0^t f(u) * exp(-(t-u)/T) du
using an efficient recursive formula that avoids explicit numerical integration. This is the fundamental operation for compartmental pharmacokinetic models.
Handles both single-voxel (scalar T) and batch (array T) cases. When T is an array, every voxel is processed in a single pass with the loop running over time points — efficient on CPU and GPU.
| PARAMETER | DESCRIPTION |
|---|---|
f
|
Input signal (e.g., arterial input function).
Shape
TYPE:
|
T
|
Time constant(s) of the exponential decay in seconds.
Scalar for a single convolution, or array of shape
TYPE:
|
t
|
Time points in seconds. Shape
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ndarray
|
Convolution result. Shape |
Notes
The recursive formula from Flouri et al. (2016) is used:
E[i] = E[i-1] * exp(-dt/T) + integral_{t[i-1]}^{t[i]} f(u) * exp(-(t[i]-u)/T) du
where the integral within each interval is evaluated analytically assuming piecewise-linear interpolation of f.
This is O(n) in computation time, compared to O(n^2) for naive numerical integration.
Examples:
>>> import numpy as np
>>> from osipy.common.convolution import expconv
>>> t = np.linspace(0, 10, 101)
>>> aif = np.exp(-t / 2) # Input function
>>> T = 5.0 # 5 second time constant
>>> result = expconv(aif, T, t)
References
.. [1] Flouri D, Lesnic D, Mayrovitz HN (2016). Comput Methods Biomech Biomed Engin. 19(13):1359-1367.
biexpconv
¶
Convolve a signal with a bi-exponential function.
Computes the convolution of f with the bi-exponential function: h(t) = (exp(-t/T1) - exp(-t/T2)) / (T1 - T2)
This is useful for two-compartment exchange models.
| PARAMETER | DESCRIPTION |
|---|---|
f
|
Input signal. Shape: (n_times,).
TYPE:
|
T1
|
First time constant in seconds. Must be positive.
TYPE:
|
T2
|
Second time constant in seconds. Must be positive and different from T1.
TYPE:
|
t
|
Time points in seconds. Shape: (n_times,).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ndarray
|
Convolution result. Shape: (n_times,). |
Notes
The bi-exponential convolution is computed as: biexpconv(f, T1, T2, t) = (expconv(f, T1, t) - expconv(f, T2, t)) / (T1 - T2)
For T1 -> T2, uses the limiting form involving the derivative.
Examples:
>>> import numpy as np
>>> from osipy.common.convolution import biexpconv
>>> t = np.linspace(0, 10, 101)
>>> aif = np.exp(-t / 2)
>>> result = biexpconv(aif, 3.0, 5.0, t)
References
.. [1] dcmri library: https://github.com/dcmri/dcmri
nexpconv
¶
Convolve a signal with an n-exponential (gamma variate) function.
Computes the convolution of f with the n-exponential function: h(t) = (t/T)^(n-1) * exp(-t/T) / (T * (n-1)!)
This represents a chain of n identical compartments, each with time constant T. Also known as the gamma variate function.
| PARAMETER | DESCRIPTION |
|---|---|
f
|
Input signal. Shape: (n_times,).
TYPE:
|
T
|
Time constant of each compartment in seconds. Must be positive.
TYPE:
|
n_exp
|
Number of exponentials (compartments). Must be >= 1.
TYPE:
|
t
|
Time points in seconds. Shape: (n_times,).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ndarray
|
Convolution result. Shape: (n_times,). |
Notes
For n=1, this is equivalent to expconv. For n>1, the function is computed recursively: nexpconv(f, T, n, t) = expconv(nexpconv(f, T, n-1, t), T, t) / T
For large n, the gamma variate approaches a Gaussian centered at t = nT with standard deviation sqrt(n)T.
For n > 20, numerical overflow may occur in the factorial term. In this case, a Gaussian approximation is used.
Examples:
>>> import numpy as np
>>> from osipy.common.convolution import nexpconv
>>> t = np.linspace(0, 20, 201)
>>> aif = np.exp(-t / 2)
>>> result = nexpconv(aif, 2.0, 3, t) # 3-compartment chain
References
.. [1] dcmri library: https://github.com/dcmri/dcmri