Poisson Process vs. GAN-Based Point Generation

Choosing how to synthesize a set of geographic points is a decision with a wide cost spread: one path is a fifty-line statistical model that runs in milliseconds and carries a closed-form privacy argument, the other is a trained neural network that can reproduce structure no parametric model captures but demands GPUs, labelled data, and an evaluation regime to trust its output. This page is part of Spatial Distribution & Pattern Generation: where the individual generators are documented under point process simulation models and GAN-based spatial data generation, this page is the head-to-head that tells you which one to reach for. The wrong choice is expensive in both directions — a GAN where a Thomas process would have sufficed burns weeks of engineering and a defensible privacy story, while a parametric model where the data genuinely has learned structure ships point sets that fail realism review the moment a downstream model touches them.

Decision matrix scoring a statistical point process against a GAN across five criteria A five-row comparison matrix. The five criteria are spatial fidelity, formal privacy, reproducibility, compute cost, and data hunger. The point-process column is marked as the stronger choice for formal privacy, reproducibility, compute cost, and data hunger; the GAN column is the stronger choice for high-order spatial fidelity where the target distribution has learned structure that no closed-form intensity captures. A routing bar at the bottom sends problems with little training data, strict audit requirements, or a known analytic intensity to the point process, and sends problems with abundant real exemplars, fidelity-critical consumers, and structure beyond second-order statistics to the GAN. Statistical point process GAN generator Spatial fidelity high-order structure 2nd-order only (K, pair-corr.) learned high-order structure stronger Formal privacy closed-form, no real points stronger needs DP-SGD + audit Reproducibility seed → byte-identical stronger checkpoint + kernel nondeterminism Compute cost CPU, milliseconds stronger GPU-hours to train Data hunger a few parameters stronger thousands of exemplars low data · audit-heavy · analytic intensity → process rich data · fidelity-critical · learned structure → GAN
The five criteria that decide the choice, and where each generator wins.

Problem Framing: A Choice Made by Default Is a Choice Made Wrong

The failure this page prevents is the defaulted generator — a team that picks one technique because it is the one they know, then discovers the mismatch downstream where it is expensive to reverse.

Two symmetric failure stories recur:

  • The over-engineered process. A team needs synthetic delivery-drop points that cluster around depots. The real spatial structure is a clustered point pattern with a handful of parameters, but someone reaches for a generative adversarial network because “GANs are how you make synthetic data.” Six weeks later they have a fragile training loop, an unresolved mode-collapse investigation, and no formal privacy argument — for a pattern a Thomas process reproduces in an afternoon.
  • The under-powered process. A team fits an inhomogeneous Poisson model to real retail-visit points, calibrates the intensity to a population raster, and ships. The point set passes a first-order density check and fails everything else: the real data has visit clustering driven by opening hours, co-location of complementary stores, and repeat-visit bursts — high-order structure that a Poisson intensity function cannot express. A graph model trained on the synthetic points learns relationships that do not exist in reality.

Both teams skipped the decision. The correct process is to score the specific problem against five axes — spatial fidelity, formal privacy, reproducibility, compute cost, and data hunger — and let the scores route the choice. The rest of this page defines those axes precisely, gives a runnable decision procedure, and shows the validation that must sit behind whichever generator wins, because the choice is only defensible if a gate proves the output actually meets the fidelity and privacy bar the problem set.

Prerequisites & Toolchain

Evaluating both candidates fairly means being able to run both. The statistical side needs only the scientific-Python core; the GAN side adds a deep-learning stack and, for a defensible privacy claim, a private-training library.

python >= 3.10
numpy == 1.26.*
scipy == 1.11.*          # spatial.distance, stats for K-function baselines
geopandas == 0.14.*
shapely == 2.*           # GEOS 3.11+ for clipping and within tests
pyproj == 3.*
pointpats                # Ripley's K / L, pair-correlation estimators
torch                    # GAN training (major pin only)
opacus                   # DP-SGD accounting for the private-GAN path

Two environment facts shape the comparison. First, do the geometry in a metric CRS. Nearest-neighbour distances, Ripley’s K, and any noise scale are meaningless in degrees; reproject to a metric or equal-area CRS (EPSG:6933 globally, a UTM zone regionally) before estimating any second-order statistic, the same discipline the realism metrics evaluation stage assumes. Second, GAN determinism is not free: CUDA convolution and reduction kernels are nondeterministic by default, so a reproducibility comparison must set torch.use_deterministic_algorithms(True) and pin the cuDNN workspace, or the GAN will lose the reproducibility axis for a reason that has nothing to do with the model.

Core Concept: What Each Generator Can and Cannot Represent

The two families differ at the level of what they model, and that difference drives every entry in the decision matrix.

A statistical point process models an intensity and an interaction. A homogeneous Poisson process places points at a constant expected rate with complete spatial randomness — points are independent, and the count in any region is Poisson-distributed with mean equal to intensity times area. An inhomogeneous Poisson process lets the intensity λ(s)\lambda(s) vary over space, capturing density gradients. Cluster processes — Thomas, Matérn — add a second layer: parent points spawn offspring under a dispersal kernel, producing the attraction between nearby points that real geographies show. The complete second-order behaviour is summarized by Ripley’s K-function

K(r)=λ1E[number of further points within r of a typical point],K(r) = \lambda^{-1}\,\mathbb{E}\big[\text{number of further points within } r \text{ of a typical point}\big],

and a process is chosen precisely because its K-function matches the target’s. The urban point-pattern walkthrough works this through end to end. What a process cannot represent is any structure beyond its parametric form: multi-scale clustering with sharp boundaries, points that respect an unmodelled street network, or dependence on a covariate you did not encode. If the truth is not in the model family, no amount of parameter fitting recovers it.

A GAN models the sample distribution directly. A generator network maps noise to point sets and a discriminator scores them against real exemplars; at convergence the generator reproduces whatever structure the training data exhibits — including the high-order dependence a process omits — without you naming that structure in advance. That is the entire value proposition and the entire risk. It captures learned structure, but only if you have enough real exemplars to learn from, only if training converges rather than collapsing to a few modes (the failure investigated under diagnosing mode collapse in spatial GANs), and only if you accept a probabilistic privacy story rather than a closed-form one.

The privacy asymmetry is the sharpest divide. A point process that draws from an analytic intensity never sees a real record, so there is nothing to leak — the privacy argument is definitional. A GAN trains on real points and can memorize them; a defensible release requires training under differential privacy and then proving the bound held, which is the whole subject of the privacy-preserving generation frameworks stage. When a synthetic dataset must withstand a privacy audit, the process starts from a structural advantage the GAN has to spend compute and evaluation effort to approach.

Decision Framework

Rather than a numbered build, this page’s “implementation” is a scoring procedure. Run it against the concrete problem, not against a general preference.

Step 1 — Characterize the target’s spatial order. Estimate Ripley’s K (or the pair-correlation function) on whatever real reference you have. If the empirical K sits inside the envelope of a fitted Poisson or cluster process, the structure is second-order and a process can express it. If K shows features a parametric family cannot match — multi-scale plateaus, network-aligned anisotropy — record that the process will underfit.

python
import numpy as np
from pointpats import PointPattern, k_test

def order_diagnostic(xy: np.ndarray, seed: int = 7) -> dict:
    """Compare empirical K against a complete-spatial-randomness envelope."""
    pp = PointPattern(xy)                      # xy already in a metric CRS
    result = k_test(pp, keep_simulations=True, n_simulations=199, seed=seed)
    # fraction of radii where empirical K escapes the CSR envelope
    outside = np.mean((result.statistic > result.upper) |
                      (result.statistic < result.lower))
    return {"fraction_outside_csr": float(outside)}

Step 2 — Weigh the privacy requirement. If the release must satisfy a formal guarantee against a named adversary, the process wins by construction unless the target structure is unreachable. If the GAN is unavoidable, budget the ε now — plan for training under DP-SGD and for the adversarial privacy testing that confirms the bound empirically.

Step 3 — Score data hunger against what you have. A clustered point process fits from a few hundred points via method-of-moments on its K-function. A GAN needs thousands of exemplars of point sets, not thousands of points, before the discriminator has signal. If you have one real map, the GAN has nothing to generalize from.

Step 4 — Price the compute and reproducibility. A process runs on CPU in milliseconds and is byte-reproducible from an integer seed. A GAN costs GPU-hours to train, must ship a pinned checkpoint plus deterministic-kernel flags to be reproducible, and adds a retraining cost every time the target shifts.

Step 5 — Route on the dominant constraint. Combine the four scores. The routing rule is blunt on purpose:

python
def choose_generator(order, formal_privacy_required, n_exemplars,
                     gpu_budget_hours) -> str:
    structure_beyond_2nd = order["fraction_outside_csr"] > 0.25
    if formal_privacy_required and not structure_beyond_2nd:
        return "point_process"          # closed-form privacy, cheap, sufficient
    if not structure_beyond_2nd:
        return "point_process"          # a process already fits the structure
    if n_exemplars < 1000 or gpu_budget_hours < 8:
        return "point_process_then_revisit"   # GAN would underfit or overrun
    return "gan"                        # learned structure justifies the cost

A hybrid is legitimate and often best: generate the coarse intensity with an inhomogeneous Poisson model for a defensible density backbone, then let a small GAN perturb local structure the process cannot express, keeping the privacy exposure confined to the learned residual.

Validation & Testing

Whichever generator wins, the same evidence must sit behind it before the point set is promoted — the choice is only sound if a gate proves the output meets the bar.

python
import numpy as np
from scipy.stats import wasserstein_distance

def gate_point_set(synth_xy, real_k, radii, k_tol=0.15):
    """Fail the build if second-order fidelity drifts past tolerance."""
    from pointpats import PointPattern
    synth_k = PointPattern(synth_xy).k(radii)          # metric CRS assumed
    # relative L1 deviation of the K-function vs the calibrated reference
    rel = np.mean(np.abs(synth_k - real_k) / np.clip(real_k, 1e-9, None))
    assert rel < k_tol, f"K-function drift {rel:.3f} exceeds {k_tol}"

def gate_reproducibility(generate, seed=42):
    a = generate(seed)
    b = generate(seed)
    assert np.array_equal(a, b), "generator not reproducible under fixed seed"

For the process path, gate_reproducibility is expected to pass trivially — that is the point. For the GAN path it is the canary: if it fails, a nondeterministic kernel or an unpinned checkpoint slipped in, and the “reproducible” claim is false. Beyond second-order fidelity, distributional distance between real and synthetic summaries — the Wasserstein-based check formalized in evaluating spatial realism with Wasserstein distance — should gate both paths, and for any GAN release a membership-inference test must clear before promotion. Wire every gate as a build-failing check through the CI/CD integration for spatial data pipeline so neither an underfit process nor a leaky GAN can be shipped as an artifact.

Performance & Scale Considerations

  • Marginal cost per additional point set. A process is amortized-free: once parameters are fit, each new realization is another CPU draw. A GAN front-loads cost into training but then samples cheaply, so at high realization counts the per-sample cost converges — the deciding factor is how many distinct point sets you need against how much you can spend training once.
  • Parallelism differs in kind. Process realizations are embarrassingly parallel and reproducible per-seed, so they slot directly into the tile-parallel model the async execution for large grids stage uses. GAN sampling parallelizes across the batch dimension on one GPU but does not shard cleanly across a CPU tile grid.
  • Memory profile. A process holds only its parameters and the current realization; a GAN holds model weights, optimizer state, and a batch of exemplars in device memory during training, which is the binding constraint on batch size and therefore on gradient stability.
  • Retraining is a recurring scale cost. Every drift in the target distribution obliges a GAN retrain and a fresh privacy accounting; a parametric process is re-fit in seconds. For a target that moves monthly, the process’s cheap re-fit can dominate the total-cost comparison even when the GAN’s fidelity is higher.
  • Deterministic seeding as a scale enabler. Because a process is byte-reproducible from an integer seed, you can regenerate any historical realization from its seed alone rather than storing it — a storage win that does not exist for GAN samples, which must be checkpointed with the exact model version that produced them.

Failure Modes & Troubleshooting

Frequently Asked Questions

When is a Poisson or cluster process definitely enough?
When the empirical K-function or pair-correlation of your reference data sits inside the envelope of a fitted Poisson, Thomas, or Matern process, the structure is second-order and a process reproduces it exactly with a handful of parameters. Add the requirements of a formal privacy guarantee, scarce training data, or a tight compute budget and the case is decisive. Reach for a GAN only once a diagnostic shows structure the parametric family cannot express.
What spatial structure can a GAN capture that a point process cannot?
A point process is limited to its parametric form — an intensity function plus a single interaction kernel — so it captures density gradients and one scale of clustering but not high-order dependence. A GAN learns whatever the exemplars show: multi-scale clustering with sharp boundaries, network-aligned anisotropy, or co-location patterns you never named. The cost is that it needs thousands of exemplars, GPU training, and an explicit privacy and mode-collapse investigation to trust the result.
Which option is stronger for a formal privacy guarantee?
A statistical process drawing from an analytic intensity never touches a real record, so its privacy argument is definitional — there is nothing to leak. A GAN trains on real points and can memorize them, so a defensible release requires differentially private training such as DP-SGD plus an empirical membership-inference audit to confirm the bound held. When the release must survive a privacy review, the process starts with a structural advantage the GAN must spend compute to approach.
How do I make a GAN reproducible for a CI gate?
A process is byte-reproducible from an integer seed with no extra work. A GAN needs three things pinned: the exact model checkpoint, the RNG seeds for both data loading and the noise input, and deterministic compute via torch.use_deterministic_algorithms(True) with a fixed cuDNN workspace. Miss any one and two runs diverge for reasons unrelated to the model, and the reproducibility gate will correctly fail the release.
Is a hybrid of the two ever the right answer?
Often. Generate the coarse density backbone with an inhomogeneous Poisson model, which gives a defensible, cheap, reproducible intensity, then let a small GAN model only the local residual structure the process cannot express. This confines the privacy exposure and the training cost to the learned component while keeping the bulk of the point set on the closed-form path, and it lets each half be validated with the technique suited to it.