pulsatrix
Loading...
Searching...
No Matches
pulsatrix Namespace Reference

Namespaces

namespace  datalog
 
namespace  detail
 
namespace  explainer_detail
 Shared helpers for the post-hoc explainers' host boundary.
 
namespace  lrp_composite
 Zennit 1.0.0's composite presets (zennit.composites), mapped onto pulsatrix modules by type: LinearModule = torch Linear, Conv2DModule = torch Conv2d; every other module gets the epsilon rule (the pass-through modules – ReLU, Flatten, Dropout, MaxPool – ignore it, as Zennit's Pass rule / plain gradient does).
 

Classes

class  ActivationSnapshot
 A copyable, self-contained record of every activation cached during one forward pass, plus the node ids in topological order and each node's op_type/label metadata. More...
 
class  AdamOptimizer
 Adam (Kingma & Ba, 2015): per-parameter moving averages of gradient (m) and squared gradient (v), with bias correction. More...
 
class  Agent
 Base class for anything that maps an observation to an action. More...
 
class  AggregatorModule
 y = (mean(x^p))^(1/p), reduced over the leading (batch/grounding) axis – not the last axis. Rank-agnostic: input shape (N, ...rest) reduces to output shape (...rest) (rank 0 – a scalar – when input is rank 1, i.e. a single formula's groundings with no other axes). More...
 
struct  ASHAResult
 The best configuration/metric found, the total epoch budget spent, and how many distinct configurations were ever started (as opposed to promoted). More...
 
struct  Attribution
 An explanation result: the raw attribution values, the method that produced them, and any relevant metadata (charter Part 2 SS4). More...
 
class  AttributionBarChart
 Draws a horizontal bar chart of an Attribution's top-k features (hc_information_visualization.md SS1/SS5: position-on-shared-axis is the most accurately perceived encoding for magnitude – Cleveland-McGill rank 1 – and horizontal bars read naturally with long feature names). Bar length encodes magnitude; hue (DivergingColormap) encodes sign, never magnitude. Bars start at zero (Tufte lie-factor = 1). More...
 
class  AttributionBeeswarmView
 Draws a beeswarm plot for one feature's attribution values across many samples/predictions – the global "how does the model behave overall" view (hc_information_visualization.md SS5), complementing AttributionBarChart's single-prediction "why this one" view. More...
 
class  AttributionWaterfallChart
 Draws a waterfall chart cascading from baseline_value to the final prediction (hc_information_visualization.md SS5: "correct for local explanation with directional attribution... bars cascade from base rate to prediction; color encodes direction; length encodes magnitude"). This is the one bar chart in this module that legitimately does not start at zero – Tufte's lie-factor rule is satisfied relative to baseline_value, the meaningful reference point, not zero. More...
 
class  AudioFolderDataset
 Dataset over a directory tree of the form root_dir/<class_name>/<audio_file.wav>, structurally identical to ImageFolderDataset (Phase 2): sorted subdirectory names are classes, sorted filenames within each are samples, decoded lazily per get() via WavReader. More...
 
class  Autograd
 Computes gradients by walking a ComputationGraph in reverse topological order. More...
 
class  AvgPool2DModule
 Average pooling, rank-4 (N, channels, H, W), matching Conv2DModule's convention. Stride fixed equal to kernel size (non-overlapping windows), no padding, no dilation – same minimal-cut discipline as MaxPool2DModule/Conv2DModule. More...
 
struct  BarSeries
 One feature-importance bar: a label and a signed value (sign carries direction). More...
 
struct  Batch
 One collated batch: one stacked Tensor per Sample field position. More...
 
class  BatchNormFold
 While alive, merges bn's affine map into conv's weights and makes bn an exact identity; on destruction, restores both bit for bit. More...
 
class  BatchNormModule
 y_{n,c,h,w} = gamma_c * (x_{n,c,h,w} - mu_c)/std_c + beta_c, mu_c/std_c computed per channel c over every (n, h, w) element jointly – BatchNorm's defining statistic, and the reason this module didn't exist before campaign_exai_dl_library_batch_dimension_support: it has nothing to compute over without a real batch dimension. Input/output are rank-4 (N, channels, H, W), the same convention Conv2DModule/GroupNormModule already establish. More...
 
class  BCEWithLogitsLoss
 loss = mean( max(x,0) - x*y + log(1 + exp(-|x|)) ), over all N*k elements of a (N, k) logit tensor x against a target tensor y of the same shape. More...
 
struct  BeeswarmPoint
 One beeswarm point: the attribution value (x) and a collision-avoidance vertical offset (y). More...
 
class  BoundedQueue
 Fixed-capacity thread-safe queue with blocking push/pop – the bounded buffer between pulsatrix data-pipeline stages (campaign_exai_dl_library_data_pipeline). Not tied to any Dataset/DataLoader type; deliberately generic. More...
 
class  CalibrationLoss
 BS = mean_n( Σ_k (p[n,k] − y[n,k])² ), y one-hot at target_class[n] – Brier's original multi-class proper scoring rule. More...
 
class  CartPoleEnv
 The classic cart-pole balancing task (Barto, Sutton & Anderson 1983), the same equations OpenAI Gym's own CartPoleEnv implements – cited as the canonical, independently-verifiable reference for this class's correctness tests, not reused as a code or runtime dependency. More...
 
class  CategoricalPolicyAgent
 Samples an action from softmax(policy_network(observation)) – the discrete-action stochastic policy every policy-gradient method in this phase (REINFORCE, A2C, PPO) is built on. More...
 
class  CenterCropTransform
 Crops the centered (crop_height, crop_width) region of the image. More...
 
struct  CircuitEdge
 One directed edge of a CircuitGraph, carrying a scalar weight. More...
 
class  CircuitGraph
 A copyable, self-contained circuit graph: every node of one forward pass with an ablation importance score, plus the weighted edges between them. More...
 
class  CircuitGraphView
 Draws a CircuitGraph as a node-link diagram: node position is topological depth (x-axis), node size and color encode ablation_effect via length/area AND Viridis (unsigned magnitude – never hue-for-magnitude, hc_information_visualization.md SS1), edge thickness encodes weight. Each node is captioned with CircuitNodeDisplayLabel (its own label, else op type + id) above and its ablation effect below. More...
 
struct  CircuitNode
 One node of a CircuitGraph: a computation-graph node plus its importance score. More...
 
class  CMAES
 RNG-driven ask-tell wrapper: caches the z-samples an Ask() call draws so a matching Tell() call can reuse them without the caller needing to track them. More...
 
struct  CMAESState
 This algorithm's full adaptive state: the search mean, the global step size, and each dimension's own variance (the diagonal of the covariance matrix). More...
 
class  Compose
 Eager, ordered list of Transforms applied in sequence – pulsatrix's analogue of torchvision.transforms.Compose. Deliberately simple: no fusion/graph, matching Compose's own upstream design; unlike Python, there is no GIL here for that simplicity to cost anything. More...
 
class  ComputationGraph
 Owns every Node in a computation graph and exposes read access for graph-walking code (autograd's backward pass, Phase 2+ explainers). More...
 
class  ConfidenceMeter
 Draws a filled bar whose fill length encodes confidence (position/length, never color alone – hc_information_visualization.md SS1/SS5: "confidence bar/meter... fastest to process"). The exact percentage is always rendered as text alongside the fill – never a color-only encoding (also satisfies WCAG: a colorblind user must be able to read the value without relying on hue). More...
 
class  ConjunctionModule
 y = a T b for a selected t-norm T, over two independent fuzzy-truth-valued operand tensors (values intended in [0,1]; out-of-range values are not rejected – see propagate_relevance()'s note and mission_0_tnorm_operators.md's adversarial section). More...
 
struct  ConnectionGene
 One connection in a NEAT genome: an edge between two node IDs, its weight, whether it is currently active, and its historical marking (innovation number). Disabled connections are kept, not removed – NEAT's own design, preserving historical alignment for crossover (a future mission's concern, not built here). More...
 
struct  ConservationResult
 The result of comparing a relevance-propagation step's input and output totals. More...
 
class  ContinuousCartPoleEnv
 The cart-pole balancing task with a continuous action: the action is a single force fraction in [-1, 1] rather than a discrete left/right choice. More...
 
class  Conv2DModule
 2D convolution, batched (input/output are rank-4: N x channels x H x W) – migrated from the original unbatched (rank-3) scope by campaign_exai_dl_library_batch_dimension_support. Stride 1, no padding, no dilation – deferred until a real use case needs them, same pattern as LinearModule's original unbatched scope cut. More...
 
struct  ConvGeometry
 Window geometry for DeviceBackend::im2col / col2im_add: kernel size, stride and zero padding per axis. Defaults are stride 1 and no padding. Passed to kernels by value. More...
 
class  CPUBackend
 CPU-resident DeviceBackend implementation. Reference implementation every other backend (CUDABackend, HIPBackend) is checked for numerical equivalence against. More...
 
class  CrossEntropyLoss
 loss = -log(softmax(logits)[target_class]), combined for numerical stability (subtract the max logit before exponentiating) rather than computing softmax and log separately. More...
 
class  CsvDataset
 Dataset over a CSV file's numeric columns: N named feature columns -> one (1, num_features) Tensor per row, plus one named label column -> one (1,) Tensor. Requires a header row (feature/label columns are resolved by name). More...
 
class  CsvReader
 Minimal RFC-4180-ish CSV parser: comma-delimited, double-quote-quoted fields, "" as an escaped quote,
or \r
line endings. Whole file loaded into memory at once – no streaming/chunked reading in this phase, matching MnistIdxLoader's own whole-file-at-once precedent. More...
 
struct  CsvTable
 One parsed CSV file's contents: raw string cells, row-major, plus an optional header. More...
 
class  CUDABackend
 CUDA-resident DeviceBackend implementation. More...
 
class  DataLoader
 Orchestrates sampling and collation into batches – pulsatrix's DataLoader (PyTorch DataLoader / torch::data::DataLoader analogue). More...
 
struct  DataLoaderOptions
 Configuration for a DataLoader. More...
 
class  Dataset
 Random-access dataset abstraction – pulsatrix's analogue of PyTorch's torch.utils.data.Dataset / LibTorch's torch::data::Dataset (len/__getitem__). Every concrete modality (CsvDataset, MnistDatasetAdapter, future image/text/audio readers) subclasses this; DataLoader depends only on this interface. More...
 
struct  DatasetStatistics
 One Dataset's per-field descriptive statistics. More...
 
class  DatasetStatisticsView
 Draws one histogram per Sample field (small multiples, hc_information_visualization.md SS6) plus a flagged-issue count, using DatasetValidator's existing production API (ComputeStatistics/DetectIssues) – no new core code needed, this is purely a consumer of data that already exists. More...
 
class  DatasetValidator
 Generic data validation over any Dataset implementation – descriptive statistics and missingness/outlier detection only (campaign_exai_dl_library_data_pipeline Decision Point 5: distributional drift detection and bias/fairness metrics are explicitly out of scope, named follow-ups for a future campaign). More...
 
class  DataThreadPool
 Minimal, generic thread pool for CPU-side data pipeline work (fetch, decode, transform, collate stages) – campaign_exai_dl_library_data_pipeline's staged- pipeline backbone alongside BoundedQueue. Deliberately not tied to Dataset/DataLoader types. More...
 
class  DetailedBalanceLoss
 ‘Δ(s,s’) = log F(s) + log P_F(s'|s) − log F(s') − log P_B(s|s'),loss = Δ(s,s')²-- the per-*transition* credit-assignment alternative toTrajectoryBalanceLoss`'s per-trajectory constraint. More...
 
class  DeviceBackend
 Vendor-agnostic compute/memory backend. CPUBackend, CUDABackend (Phase 1.5), and HIPBackend (Phase 1.6) all implement this contract; Tensor and ComputationGraph depend only on this interface, never on a concrete backend's types. More...
 
class  DisjunctionModule
 y = a S b for a selected t-conorm S, over two independent fuzzy-truth-valued operand tensors (values intended in [0,1]; out-of-range values are not rejected – see conjunction_module.hpp's identical note). More...
 
struct  DominantEigenResult
 PowerIteration()'s result. More...
 
class  DQNAgent
 The epsilon-greedy behaviour policy of Mnih et al. 2015: with probability epsilon act uniformly at random, otherwise take argmax_a Q(observation, a). More...
 
class  DQNLoss
 loss = mean_b( (q_values[b, a_b] - targets[b,0])^2 ), where a_b is the action actually taken on transition b – the semi-gradient TD update of Mnih et al. 2015. More...
 
class  DropoutModule
 y = (mask_i ? x_i / (1 - p) : 0) at training time (inverted dropout – scaling happens at training time so eval-time forward needs no rescaling); y = x at eval time or when p == 0. No parameters. More...
 
struct  EigenResult
 SymmetricEigen()'s result. More...
 
class  EmbeddingModule
 Embedding lookup table, rank-2 input (N, L) of float-encoded indices -> rank-3 output (N, L, embedding_dim). Structurally unlike every other module in this codebase: forward is a pure selection (row copy), with no arithmetic mixing across input features. More...
 
class  Environment
 Base class for every RL environment (CartPoleEnv, and whatever later phases add). More...
 
struct  ESResult
 Result of a full Evolution Strategies run. More...
 
class  ExplainerContext
 Wraps an ordered chain of Modules, running them via Module::forward_traced to build a real ComputationGraph and Autograd backward wiring – graph-native explainers (Missions 2-3) use graph()/backward_pass()/activation(); surrogate explainers (Phase 3) would use only forward_pass(), per the charter's stated interface segregation. More...
 
class  ExplanationScoreCard
 Aggregates, per prediction, a 2x2 panel: top row is "what was shown, how confident was the model" (input label + ConfidenceMeter), bottom row is "how trustworthy is this explanation" (LRP conservation delta + explainer stability), visually separated by a rule (Gestalt proximity grouping – these are two different semantic questions, not one undifferentiated block of numbers). More...
 
struct  FieldStatistics
 Descriptive statistics for one Sample field position, aggregated across a whole Dataset. More...
 
class  FlattenModule
 y = reshape(x, {N, x.numel()/N}), N = x.shape().dim(0). No parameters, no gradient math beyond reshaping. More...
 
struct  GAEResult
 ComputeGAE()'s two outputs: the advantage estimate per step and the critic's regression target per step. More...
 
class  GaussianProcessRegressor
 A fitted (or queryable-before-fitting-throws) Gaussian Process regressor with a squared-exponential kernel: k(x, x') = sigma_f^2 * exp(-||x - x'||^2 / (2 * length_scale^2)), plus additive observation noise (a small noise_variance is also standard GP practice purely as numerical "jitter" to keep the kernel matrix well-conditioned, independent of whether the underlying objective is actually noisy). More...
 
class  GeneratorPopulation
 Owns N independently-parameterized generator Modules. More...
 
class  GFlowNetForwardPolicy
 Samples from softmax(mask(policy_network(observation))) – a categorical policy restricted to a caller-supplied set of valid actions at the current state. More...
 
struct  GFlowNetSampledAction
 One sample from GFlowNetForwardPolicy::sample: the chosen action and the log-probability the masked distribution assigned to it. More...
 
struct  GFlowNetTrajectory
 One full sampled trajectory: every state the forward policy acted from, the action taken at each, and the trajectory-level quantities Trajectory Balance (and Detailed Balance/SubTB, in later missions) need. More...
 
struct  GpuSample
 One GPU's readings within a SystemSample. More...
 
class  GradCAM
 L^c = ReLU(sum_k alpha^c_k * A^k), where alpha^c_k = mean_ij(d(y^c)/d(A^k_ij)) and A is the last OpType::Conv node's activation. More...
 
class  GroupNormModule
 Splits num_channels into num_groups equal-size groups; each group's mean/std is computed over every (channel-in-group, H, W) element jointly, per batch row n, then y_{n,c,h,w} = gamma_c * (x_{n,c,h,w} - mu_{n,g})/std_{n,g} + beta_c, gamma/beta per-channel (shape (num_channels,), not per-group, not per-batch-row). Batched – input/output are rank-4 (N, channels, H, W), migrated from the original unbatched (rank-3) scope by campaign_exai_dl_library_batch_dimension_support, matching Conv2DModule's own (not-yet-migrated) rank-3 convention plus a leading batch dim. H/W are not fixed at construction (only num_groups/num_channels are), so this module accepts any spatial size at forward() time, exactly like Conv2DModule does. More...
 
class  GRUModule
 Standard GRU recurrence (Cho et al. 2014), h_0 = 0 (zero-initialized, not learnable – the same deliberate scope cut RNNModule/LSTMModule made, and the same thing that makes this module's conservation exact; see the LRP note below): z_t = sigmoid(x_t @ W_xz + h_{t-1} @ W_hz + b_z) (update gate), r_t = sigmoid(x_t @ W_xr + h_{t-1} @ W_hr + b_r) (reset gate), hn_prev_t = h_{t-1} @ W_hn (internal projection, no bias), n_t = tanh(x_t @ W_xn + r_t * hn_prev_t + b_n) (candidate), h_t = (1 - z_t) * h_{t-1} + z_t * n_t. Note the reset gate multiplies the projected previous hidden state hn_prev_t, not h_{t-1} itself – that projection is a distinct cached intermediate, and it is what gives GRU's LRP rule a different shape from LSTM's. Input (N, L, input_size) -> output (N, L, hidden_size), the full hidden-state sequence (matches RNNModule's/LSTMModule's convention). Single layer, no bidirectional/multi-layer/variable-length support. More...
 
struct  HeatmapColorScale
 The color-scale range and colormap family a heatmap's values call for. More...
 
struct  HeatmapGrid
 A row-major 2D grid of unsigned magnitude values, ready for a heatmap plot. More...
 
class  HIPBackend
 HIP-resident DeviceBackend implementation, targeting AMD GPUs via ROCm. More...
 
struct  HistogramBins
 Equal-width histogram bins: rows.size() == counts.size() + 1 edges. More...
 
class  HorizontalFlipTransform
 Mirrors the image left-right. In-place, no backend needed (same shape). More...
 
struct  HyperbandBracket
 One bracket's own (num_configs, initial_budget) trade-off point; s is the bracket index (s_max = most configs/smallest budget, down to s=0 = fewest configs/largest budget, matching the original paper's own naming). More...
 
struct  HyperbandResult
 The best configuration/metric found across every bracket, and the total epoch budget spent summed across all of them. More...
 
class  HyperGridEnv
 An n-dimensional grid: state is an integer coordinate in [0, H-1]^ndim, actions increment one coordinate or stop the episode, reward is concentrated near the grid's corners. More...
 
class  ImageDecoder
 Decodes an image file into a Tensor – pulsatrix's generalization beyond MnistIdxLoader's IDX-format-only precedent (campaign_exai_dl_library_data_pipeline, Phase 2). Powered by stb_image (public-domain, single-header, vendored via FetchContent – Decision Point 2): supports PNG/JPEG/BMP/GIF/TGA/HDR and more. More...
 
class  ImageFolderDataset
 Dataset over a directory tree of the form root_dir/<class_name>/<image_file>, mirroring torchvision's ImageFolder convention. Class names are the sorted subdirectory names; each class's label is its index in that sorted order. Images are decoded lazily (per get() call) via ImageDecoder. More...
 
class  ImageGridView
 Draws a grid of image samples from a Dataset whose first Sample field is a decoded (1,C,H,W) or (C,H,W) image tensor (e.g. ImageFolderDataset) – the data-loading "preview what you're about to train on" touchpoint. More...
 
class  ImPlotMetricsSink
 A concrete MetricsSink (metrics_sink.hpp's own doc comment names this the expected extension point: "Concrete writers... implement this") that buffers every logged scalar into a per-tag time series, and keeps the latest histogram snapshot per tag, for live rendering by a training dashboard. Zero core changes needed – MetricsSink* is already threaded through every training loop in this codebase (XorNetwork::train_step, MnistConvNet::train_step). More...
 
struct  Individual
 A single candidate solution in a genetic algorithm population. More...
 
class  InnovationTracker
 The global historical-marking registry: the same structural mutation (an identical new connection, or an identical connection-split creating a new node) occurring in different genomes receives the same innovation number / new node ID if it has already been recorded, and a fresh one otherwise. This is the concrete mechanism that lets two differently-shaped genomes' genes be meaningfully aligned by innovation number – NEAT's own defining idea (not built here: crossover itself is a future mission; this class only maintains the registry crossover would eventually consume). More...
 
class  IntegratedGradients
 IG_i(x) = (x_i - baseline_i) * (1/steps) * sum_{k=1}^{steps} d(F(baseline + (k/steps)(x - baseline)))/dx_i – a Riemann-sum approximation of the straight-line path integral from baseline to input. More...
 
class  IterableDataset
 Streaming dataset abstraction for sources with no random access or no known length (sharded files, generators) – pulsatrix's analogue of PyTorch's IterableDataset / tf.data's source-op model. DataLoader treats this and Dataset via a common internal adapter (data_loader.hpp) so both share one fetch/collate path. More...
 
class  KernelSHAP
 Approximates Shapley values via full coalition enumeration + SHAP-kernel-weighted linear regression, reusing fit_weighted_linear_regression for the reduced (n-1)-dimensional problem the efficiency-axiom substitution produces. More...
 
class  KLDivergenceLoss
 Closed-form KL(N(mu, sigma^2) || N(0, I)) for a diagonal Gaussian posterior (Kingma & Welling 2013, arXiv:1312.6114, Appendix B): loss = mean_b( 0.5 * sum_d( mu[b,d]^2 + exp(2*log_sigma[b,d]) - 2*log_sigma[b,d] - 1 ) ) i.e. summed over the latent dimension per example, averaged over the batch – the standard VAE ELBO normalization, matching how the reconstruction term is typically summed-per-example/averaged-over-batch too. More...
 
class  LayerNormModule
 y_{n,i} = gamma_i * (x_{n,i} - mu_n)/std_n + beta_i, mu_n = mean_i(x_{n,i}), std_n = sqrt(var_i(x_{n,i}) + eps), computed independently per batch row n. Batched ((N, num_features)), migrated from the original unbatched (rank-1) scope by campaign_exai_dl_library_batch_dimension_support. More...
 
class  LearnableScalar
 A bare learnable scalar (e.g. a GFlowNet loss's log Z), outside the Module/LRP hierarchy entirely. More...
 
class  LIME
 Fits a locality-weighted linear surrogate around one input: perturb x with Gaussian noise, weight each perturbed sample by an exponential locality kernel pi(z) = exp(-||z-x||^2 / (2*sigma^2)), fit w* = argmin_w sum_i pi_i*(f(z_i) - f(x) - w^T(z_i-x))^2 + l2_lambda*||w||^2 via fit_weighted_linear_regression. More...
 
class  LinearModule
 y = x @ W + b, batched (x is (N, in_features), y is (N, out_features)) – migrated from the original unbatched (rank-1) scope by campaign_exai_dl_library_batch_dimension_support (breaking migration to always-batched; a single example is N=1, not a structurally different case). More...
 
class  LinearProbe
 A linear probe: LinearModule(activation_dim, 1) + BCEWithLogitsLoss, trained on (activation, binary concept label) pairs. High post-training accuracy means the concept is linearly decodable from those activations; chance-level accuracy means it is not (at least not linearly). More...
 
class  LRP
 Whole-model LRP: runs the forward pass, seeds relevance at the chosen output(s), and propagates it to the input through every module's own propagate_relevance() rule. More...
 
struct  LRPRuleConfig
 Configuration for LRP relevance propagation: which rule a module applies and its hyperparameters. A module that does not implement the requested rule throws (see Module::supports_lrp_rule()) – the rule is never silently substituted. More...
 
struct  LRPTarget
 What LRP explains: one target class (and optionally one contrast class) per row of the network's (N, num_classes) output. More...
 
class  LSTMModule
 Standard 4-gate LSTM recurrence, h_0 = c_0 = 0 (zero-initialized, not learnable – the same deliberate scope cut RNNModule made, and the same thing that makes this module's conservation exact; see the LRP note below): i_t = sigmoid(x_t @ W_xi + h_{t-1} @ W_hi + b_i), f_t = sigmoid(x_t @ W_xf + h_{t-1} @ W_hf + b_f), g_t = tanh(x_t @ W_xg + h_{t-1} @ W_hg + b_g), o_t = sigmoid(x_t @ W_xo + h_{t-1} @ W_ho + b_o), c_t = f_t * c_{t-1} + i_t * g_t, h_t = o_t * tanh(c_t). Input (N, L, input_size) -> output (N, L, hidden_size), the full hidden-state sequence (matches RNNModule's convention). Single layer, no bidirectional/ multi-layer/variable-length/peephole support. More...
 
class  MambaModule
 Core Mamba/S6 selective-scan recurrence (Gu & Dao 2023, arXiv:2312.00752), input (N, L, d_model) -> output (N, L, d_model). More...
 
class  MaxPool2DModule
 Max pooling, rank-4 (N, channels, H, W), matching Conv2DModule's convention. Stride fixed equal to kernel size (non-overlapping windows), no padding, no dilation – deferred until a real use case needs them, same minimal-cut discipline as Conv2DModule's original stride-1/no-padding scope cut. More...
 
struct  MetricCapability
 Whether one metric can be read on this machine, and from where – or why not. More...
 
struct  MetricRecord
 One recorded metric value: a named tag, its value, and the training step it was logged at (mirrors MetricsSink::log_scalar's own (tag, value, step) shape). More...
 
class  MetricsSink
 Interface the training loop logs scalars/histograms through. Concrete writers (TensorBoard event format, W&B, CSV, ...) implement this; the training loop and Phase 4 validation harness only ever see MetricsSink. More...
 
class  MnistConvNet
 Conv2D(1,8,5,5) -> ReLU -> Flatten -> Linear(4608,10), trained via CrossEntropyLoss + Adam, one real MNIST image at a time (this library has no batch dimension anywhere, same constraint XorNetwork already works under). More...
 
struct  MnistDataset
 One IDX file pair's contents: parallel images/labels, same length. More...
 
class  MnistDatasetAdapter
 Adapts a pre-loaded MnistDataset (MnistIdxLoader::Load's output) onto the generic Dataset interface – minimal-diff retrofit (campaign_exai_dl_library_data_pipeline, Mission 4): MnistIdxLoader/MnistDataset themselves are unchanged, still exercised directly by mnist_loader_test.cpp; this adapter is purely additive, fulfilling mnist_loader.hpp's own note that a second real dataset is the moment to generalize. More...
 
class  MnistIdxLoader
 Reads MNIST's original IDX-format files directly – no format conversion, no generic Dataset abstraction. MNIST-specific by deliberate scope decision (see plan_mnist_classification_training_example.md's Recon); if a future mission needs a second real dataset, generalize then. More...
 
class  Module
 Base class for every layer type (LinearModule, Conv2DModule, activations, ...). More...
 
class  MSELoss
 MSE = mean((prediction - target)^2). More...
 
class  MultiHeadAttentionModule
 softmax(Q @ K^T / sqrt(head_dim)) @ V, multi-head, with optional RoPE and optional QK-Norm. Shape (N, L, d_model) -> (N, L, d_model). More...
 
class  MutationLoss
 Computes one of E-GAN's three named mutation objectives against a discriminator's own raw logit output, and its gradient w.r.t. those logits. Every objective trains the generator to make the discriminator's output move toward the "real" (1) class – they differ only in how that pressure is shaped (saturating vs. non-saturating vs. quadratic). More...
 
struct  NamedParamRef
 A parameter together with its hierarchical, dot-separated name relative to the module that reported it (weight, mha.q_proj.bias, 0.weight). More...
 
struct  NEATEvolutionResult
 Result of a full NEAT evolutionary run. More...
 
class  NEATGenome
 A NEAT genome: its node and connection genes, growable via structural mutation. More...
 
class  NegationModule
 y = 1 - x, elementwise. No parameters, no parameter gradients. More...
 
class  Node
 A single computation graph node. Owned exclusively by its ComputationGraph (see computation_graph.hpp); parent/child edges here are non-owning raw pointers into nodes the same graph owns. More...
 
struct  NodeGene
 One node in a NEAT genome's topology. More...
 
class  NoiseSchedule
 The DDPM (Ho et al. 2020, arXiv:2006.11239) linear variance schedule plus the two tensor operations defined directly on top of it – closed-form forward noising and the reverse (sampling) step. More...
 
class  NoOpMetricsSink
 Does nothing. The charter's stated minimum viable MetricsSink implementation. More...
 
class  NormalizeTransform
 Per-channel normalization: pixel = (pixel - mean[c]) / std[c]. In-place, no backend needed (same shape in and out). More...
 
struct  ParameterSpec
 One named parameter's description: its kind plus the bounds/categories that kind needs. Only the fields relevant to kind are meaningful (e.g. categories is empty/unused for Continuous) – this is a description, not a union, since a SearchSpace's own accessors (below) are the only place callers read it back. More...
 
struct  ParamRef
 A trainable parameter and its accumulated gradient, as owned by some Module. More...
 
struct  PBTResult
 The best-performing trial's index, its metric, and how many generations ran. More...
 
class  PBTResumableTrial
 A ResumableTrial that additionally exposes its live weights (a flat vector) and its current hyperparameter Configuration, both readable and replaceable mid-training. More...
 
struct  PBTTruncationGroups
 Indices of the population's current worst- and best-performing members. More...
 
class  PDP
 PDP_j(v) = (1/|B|) * sum_{b in B} f(x_j=v, x_{-j}=b_{-j}) – for each grid value v, replace every background instance's feature j with v (keeping its other features), average the model's output over the whole background set. More...
 
class  PolicyGradientLoss
 loss = mean_b( -log pi(a_b | s_b) * G_b ), where a_b is the action actually taken on step b of a rollout and G_b its return – the REINFORCE policy-gradient surrogate of Williams 1992. More...
 
class  PPOClippedLoss
 loss = mean_b( -min( r_b * A_b, clamp(r_b, 1-eps, 1+eps) * A_b ) ), where r_b = pi_new(a_b|s_b) / pi_old(a_b|s_b) – the clipped surrogate objective of Schulman et al. 2017 (arXiv:1707.06347), negated so that minimizing it maximizes the objective the paper states. More...
 
struct  QRResult
 QR()'s result, the thin factorization A = Q R. More...
 
struct  RecurrentCellArgs
 Operand pointers for DeviceBackend::recurrent_cell (passed to kernels by value). More...
 
class  ReluModule
 y = max(x, 0), elementwise. No parameters, no parameter gradients. More...
 
class  Reparameterize
 VAE reparameterization trick (Kingma & Welling 2013, arXiv:1312.6114), z[b,d] = mu[b,d] + exp(log_sigma[b,d]) * epsilon[b,d]. More...
 
struct  ReparamGrad
 The (grad_mu, grad_log_sigma) pair both VAE building blocks produce. More...
 
struct  ReplayBatch
 One uniformly-sampled minibatch of transitions, one Tensor per transition field. More...
 
class  ReplayBuffer
 Fixed-capacity circular replay buffer of (observation, action, reward, next_observation, done) transitions, with uniform-random-with-replacement batch sampling – the off-policy experience store of Mnih et al. 2015 (DQN), reused unchanged by SAC and every other off-policy learner in this campaign. More...
 
class  ResampleTransform
 Resamples a waveform (sample.fields[0], shape (1, channels, num_samples) – WavReader's/AudioFolderDataset's convention) from source_sample_rate to target_sample_rate via linear interpolation. More...
 
class  ResidualModule
 y = x + inner->forward(x) for an arbitrary already-built Module. The classic ResNet shortcut connection, owning its own native relevance-split rule – the charter's explicitly named failure mode to avoid is Captum/Zennit's "Canonizer surgery" (an external post-hoc graph rewrite for residual connections). More...
 
class  ResizeTransform
 Every transform in this file operates on sample.fields[0], assumed to be an image Tensor of shape (1, channels, height, width) – the convention MnistDatasetAdapter, CsvDataset, and ImageDecoder all already share (image/features first, label last). More...
 
class  ResumableTrial
 A single hyperparameter configuration's live, resumable training state – own whatever network/optimizer/dataset a concrete trial needs, and train it incrementally across multiple calls rather than all at once. More...
 
class  RetNetModule
 Core RetNet retention block (Sun et al. 2023, arXiv:2307.08621), recurrent mode, input (N, L, d_model) -> output (N, L, d_model). More...
 
struct  RgbColor
 An RGB color, each channel in [0, 1]. More...
 
struct  RgbImageBuffer
 An interleaved-RGB, row-major byte buffer ready for a texture upload. More...
 
struct  RlRowArgs
 Operand pointers and dims for DeviceBackend::rl_rows (passed to kernels by value). More...
 
class  RMSNormModule
 y_{n,i} = gamma_i * x_{n,i} / rms(x_n), rms(x_n) = sqrt(mean_i(x_{n,i}^2) + eps), computed independently per batch row n. Batched ((N, num_features)), migrated from the original unbatched (rank-1) scope by campaign_exai_dl_library_batch_dimension_support – no mean-centering, no beta/bias term (RMSNorm's defining simplification vs. LayerNorm). More...
 
class  RNNModule
 h_t = tanh(x_t @ W_xh + h_{t-1} @ W_hh + b_h), h_0 = 0 (zero-initialized, not learnable – a deliberate scope cut, see the class-level conservation note below). Input (N, L, input_size) -> output (N, L, hidden_size), the full hidden-state sequence. Single layer, tanh only, no bidirectional/multi-layer/ variable-length support. More...
 
struct  RolloutBatch
 One whole stored rollout, reduced to what a policy-gradient update consumes: the visited observations, the actions taken, the discounted return-to-go of each step, and the log-probability the acting policy assigned to each action. More...
 
class  RolloutBuffer
 Fixed-length, fill-once on-policy trajectory buffer of (observation, action, reward, log_prob, done) steps, with discounted return-to-go computation – the storage REINFORCE/A2C/PPO collect a rollout into. More...
 
class  RoPEModule
 Rotary Position Embedding (RoPE, Su et al. 2021): a fixed, non-learnable, position-dependent rotation of each adjacent feature pair of a Q/K-shaped tensor. More...
 
class  RWKVModule
 Core RWKV-4 time-mixing block (Peng et al. 2023, arXiv:2305.13048), input (N, L, d_model) -> output (N, L, d_model). More...
 
class  SafetensorsFile
 A parsed, fully validated safetensors file held in memory. More...
 
struct  SafetensorsTensorInfo
 One tensor's header entry. Offsets are relative to the start of the data section. More...
 
class  Saliency
 Raw-gradient saliency: d(output[target_index])/d(input), computed by seeding ExplainerContext::backward_pass with a one-hot vector at target_index. More...
 
class  SaliencyHeatmapView
 Draws a 2D saliency heatmap plus a colormap scale bar. Unsigned magnitudes (e.g. Grad-CAM) use Viridis (perceptually uniform, colorblind-safe – hc_information_visualization.md SS4) over [0, max]; signed attributions (any negative value – gradients, IG, LRP, LIME, SHAP) use the blue-white-red DivergingColormap over the symmetric range [-max|v|, +max|v|], so zero is always the neutral midpoint. The choice is ComputeHeatmapColorScale's (plot_data.hpp, unit-tested). Row 0 of the grid is drawn at the top (image convention) with square cells. More...
 
struct  Sample
 One dataset sample: an ordered list of Tensor fields (e.g. {features, label} or {image, label}). Field order/count is a contract between a Dataset implementation and whatever CollateFn (collate.hpp) later assembles samples into a Batch. More...
 
class  Sampler
 Produces the order in which a DataLoader visits a Dataset's indices for one epoch. More...
 
class  SatisfactionLoss
 loss = 1 - agg_p(truth_values) – the standard LTN "Real Logic" training objective (research_2026_neuro_symbolic_ai.md §1/§2): maximizing a knowledge base's aggregated satisfaction via ordinary gradient descent is the same as minimizing this loss. More...
 
struct  ScalarSeries
 One scalar tag's logged (step, value) pairs, in log order. More...
 
struct  ScoreCardScaleContext
 Shared axis/color-scale state across several ExplanationScoreCard instances shown together (small multiples – hc_information_visualization.md SS6), so each card's attribution bar chart uses a comparable scale rather than independently auto-scaling and silently making cross-card comparison invalid. More...
 
class  SearchSpace
 Describes a hyperparameter search space as an ordered list of named, typed parameters. Every HPO algorithm (grid/random search, GP-BO, TPE, Hyperband/ASHA) consumes a SearchSpace to know what it may propose; this type itself has no sampling logic (that is each algorithm's own job, e.g. RandomSample/GridSample). More...
 
class  SequentialModule
 Composes layers_[0..n-1] in forward() order; backward()/propagate_relevance() chain layers_[n-1..0] in reverse – correct reverse-mode composition order. More...
 
class  SequentialSampler
 Visits indices [0, dataset_size) in ascending order. More...
 
class  SGDOptimizer
 param -= learning_rate * grad, per parameter, for every parameter a Module exposes. More...
 
class  Shape
 An N-dimensional shape. A plain aggregate of dimensions with no invariant beyond "non-negative dimensions" – see oop_design/context_oop_design_fundamentals.md's struct-vs-class discussion for why this is still a class (numel()/is_reshape_compatible() are derived queries, not raw public fields the caller could desync from dims_). More...
 
class  ShuffleSampler
 Visits indices [0, dataset_size) in a seeded pseudo-random permutation – reproducible across runs given the same seed (std::mt19937), re-shuffled fresh each reset() call (a new epoch is a new permutation, not the same one repeated). More...
 
class  SoftmaxModule
 Softmax over the tensor's last dimension, applied independently to every "row" (every fixed combination of all leading dimensions). More...
 
class  SparseAutoencoder
 A sparse autoencoder (SAE): LinearModule(dim, hidden_dim) -> ReluModule -> LinearModule(hidden_dim, dim), trained with MSELoss to reconstruct its own input while an L1 penalty on the hidden ReLU activation pushes most hidden units to zero on any given example. More...
 
struct  SpeciesAssignment
 Population grouping into species: each inner vector is a list of indices into the population vector that were passed to SpeciatePopulation. More...
 
struct  SsmPassArgs
 Operand pointers and dims for DeviceBackend::ssm_pass (passed to kernels by value). More...
 
struct  StabilityResult
 The result of measuring an explainer's variance across repeated runs on the same input. More...
 
struct  StepResult
 What one Environment::step() produces: the next observation, this step's reward, and whether the episode ended. More...
 
class  SubTBLoss
 One sub-trajectory pair's contribution to the SubTB(λ) loss: Δ(i,j) = log F(s_i) + Σ log P_F − log F(s_j) − Σ log P_B (summed over the edges spanned by [i,j)), weighted by ‘pair_weight_ratio = λ^{j-i} / Σ_{i’<j'} λ^{j'-i'}` (the pre-normalized share of the total weighted-average loss this specific pair contributes). More...
 
struct  SuccessiveHalvingResult
 The winning configuration, its final metric, and the total epoch-budget actually spent across every trial/rung (the exit-gate's own "reduces total training compute" measure). More...
 
struct  SVDResult
 SVD()'s result, the thin factorization A = U diag(S) V^T with k = min(m, n). More...
 
class  SwiGLUModule
 down_proj(silu(gate_proj(x)) * up_proj(x)), the gated feedforward block used in place of a plain two-linear-layer MLP in most modern transformers. Rank-agnostic over (..., d_model) -> (..., d_model), matching MultiHeadAttentionModule's I/O contract so Phase 3 Mission 5 (TransformerBlock) can chain them directly. More...
 
class  SystemMonitor
 Samples CPU/GPU utilization, memory use and temperatures on a background thread, keeps a bounded in-memory history, and streams every sample to a log file. More...
 
struct  SystemSample
 One point-in-time measurement of the host. More...
 
struct  TanhGaussianGrad
 The (grad_mean, grad_log_std) pair TanhGaussianPolicy::backward() produces – both (N, action_dim), the shape of the forward's own mean/log_std. More...
 
class  TanhGaussianPolicy
 SAC's reparameterized, tanh-squashed Gaussian policy sample (Haarnoja et al. 2018, arXiv:1801.01290, Appendix C "Enforcing Action Bounds"): u = mean + exp(log_std) * epsilon, action = tanh(u), with the change-of-variables corrected log-density log_prob = sum_d [ -0.5*epsilon^2 - log_std - 0.5*log(2*pi) - log(1 - action^2 + 1e-6) ]. More...
 
struct  TanhGaussianSample
 The (action, log_prob) pair TanhGaussianPolicy::forward() produces. More...
 
class  Tensor
 N-dimensional tensor. Owns its data buffer exclusively; a DeviceBackend* is injected (not owned) – the backend must outlive every Tensor constructed against it, per cpp_style_guide/context_style_project_conventions.md's ownership table. More...
 
class  TextDataset
 Dataset over a line-delimited text corpus: each line becomes one sample, tokenized via Tokenizer::Tokenize and indexed via a Vocabulary into a (1, seq_len) float32 Tensor of token indices – Decision Point 6's resolved representation (token IDs as float32 values, the same integer-as-float32 pattern CsvDataset's label column and MnistDatasetAdapter's class label already use). seq_len varies per sample; no padding here (see PadCollate, Mission 10) – an empty line produces a zero-element (1, 0) Tensor, a valid, non-error Tensor state. More...
 
class  TextureCache
 Uploads decoded image Tensors to OpenGL textures, keyed and cached by an arbitrary integer key (e.g. a Dataset index) so a scrolling image grid doesn't re-upload the same image every frame. More...
 
class  Tokenizer
 Splits text into lowercase word/punctuation tokens – pulsatrix's first text primitive (campaign_exai_dl_library_data_pipeline, Phase 3, Decision Point 6: a minimal whitespace/punctuation tokenizer, not BPE – training a real subword-merge algorithm is a project-sized undertaking on its own). More...
 
struct  TopKResult
 top_k()'s result: the selected values and their positions along the last dimension. More...
 
class  ToyKnowledgeBase
 A small, hand-traceable knowledge base: two neural predicates A(x)/B(x) (each a sigmoid-squashed LinearModule(1,1), producing a fuzzy truth degree in (0,1)), one logical rule A(x) -> not(B(x)), expressed via De Morgan (not(A(x)) or not(B(x)), Product t-conorm/t-negation) using only NegationModule/DisjunctionModule (Mission 0) – no dedicated Implication Module – aggregated across synthetic groundings into one scalar via SatisfactionLoss (Mission 1). More...
 
class  TrainingDashboard
 Draws a live training dashboard: a data-ink-minimal per-tag summary line (last/min/max value, current step – Tufte SS6: no chartjunk, just the numbers that matter) followed by ImPlotMetricsSink's line charts and histogram snapshots. More...
 
class  TrajectoryBalanceLoss
 Δ(τ) = log Zθ + Σ log P_F(s_{t+1}|s_t) − log R(x) − Σ log P_B(s_t|s_{t+1}), loss = Δ(τ)². More...
 
class  Transform
 A single sample-level preprocessing step (normalize, augment, tokenize, ...). More...
 
class  TransformDataset
 Decorates a Dataset with a Transform, applied to every sample get() returns – lets Transform/Compose compose with any Dataset without modifying it or DataLoader. More...
 
class  TransformerBlock
 y1 = x + MHA(RMSNorm(x)), y2 = y1 + SwiGLU(RMSNorm(y1)). Shape (N, L, d_model) -> (N, L, d_model). More...
 
class  Trial
 A configuration paired with the metric history observed while evaluating it (instantiate a network under this configuration, train it, record whatever metrics the training loop reports). Deliberately decoupled from SearchSpace – a Trial records what actually happened, a SearchSpace describes what could be proposed; neither needs to reference the other directly. More...
 
class  UniformFrameSampleTransform
 Samples num_frames evenly-spaced frames from a clip Tensor (sample.fields[0], shape (T, C, H, W) – VideoFrameDirectoryDataset's convention), producing an (N, C, H, W) Tensor – deliberately identical in shape convention to Phase 2's image Dataset/Transform outputs (ImageFolderDataset, ResizeTransform, etc.): a video clip, once frame-sampled, is just a batch of images from this codebase's perspective. More...
 
struct  ValidationIssue
 One detected data-quality issue: a missing (NaN) value or a statistical outlier. More...
 
class  VideoFrameDirectoryDataset
 Dataset over a directory tree of the form root_dir/<class_name>/<clip_name>/<sequentially-named-frame-image>, decoding each clip's frames (via ImageDecoder) into one (T, C, H, W) Tensor per sample. More...
 
class  VizWindow
 Owns a GLFW window, OpenGL3 context, and ImGui/ImPlot context for the lifetime of one demo app. Every examples/viz/*_demo.cpp uses this instead of hand-rolling the standard imgui_impl_glfw_opengl3 boilerplate. More...
 
class  Vocabulary
 Token<->index lookup table. Index 0 is always the reserved "<unk>" token – guaranteed by construction, not caller convention: the constructor takes the ranked list of real tokens and prepends "<unk>" itself. More...
 
struct  WaterfallBar
 One floating waterfall bar: spans [bottom, top] on the value axis. More...
 
struct  WaterfallStep
 One waterfall step: a labeled delta and the running cumulative value after it. More...
 
struct  WavData
 One decoded WAV file's contents: waveform Tensor plus its sample rate. More...
 
class  WavReader
 Reads uncompressed 16-bit PCM WAV files directly – pulsatrix's first audio primitive (campaign_exai_dl_library_data_pipeline, Phase 4, Decision Point 4: hand-rolled over libsndfile, same "narrowest thing that satisfies the exit gate" reasoning as Decision Points 1/2/6). More...
 
class  XorNetwork
 A tiny MLP (Linear(2,4) -> ReLU -> Linear(4,1)) trained on XOR – the canonical not-linearly-separable case, exactly representable by a small MLP, giving an unambiguous convergence target for Phase 1's "prove the training loop works" goal. More...
 

Typedefs

using CollateFn = std::function< Batch(std::vector< Sample >, DeviceBackend *)>
 A function assembling a list of Samples into one Batch – pulsatrix's analogue of PyTorch's collate_fn. The standard extension point for ragged/variable-length modalities (text padding, variable-length audio): a caller-supplied CollateFn replacing DefaultCollate, not a subclass hierarchy.
 
using LRPComposite = std::function< LRPRuleConfig(size_t layer_index, const Module &module)>
 Per-layer LRP rule choice: maps (top-level module index in forward order, module) to the LRPRuleConfig that module applies.
 
using NodeId = size_t
 Stable identifier for a Node within its owning ComputationGraph.
 
using Objectives = std::vector< double >
 
using ConfigValue = std::variant< double, int64_t, std::string >
 A concrete value for one parameter – a double (Continuous/LogUniform), an int64_t (Integer), or a std::string (Categorical, naming one of that parameter's categories).
 
using Configuration = std::map< std::string, ConfigValue >
 A concrete hyperparameter configuration: parameter name -> concrete value.
 
using TrialFactory = std::function< std::unique_ptr< ResumableTrial >(const Configuration &)>
 Builds a fresh ResumableTrial for a given configuration.
 
using TextureId = unsigned int
 Opaque GL texture handle, typed to avoid a GL header include in this public header.
 

Enumerations

enum class  DeviceType { Cpu , Cuda , Hip }
 Which physical device a Tensor's buffer resides on. More...
 
enum class  CopyDirection { HostToDevice , DeviceToHost , DeviceToDevice , HostToHost }
 Direction of a DeviceBackend::copy() call. More...
 
enum class  ElementwiseOp {
  Relu , Neg , Tanh , Sigmoid ,
  Silu , Exp
}
 Unary elementwise operations supported by DeviceBackend::elementwise(). More...
 
enum class  LrpGate { None , Positive , Negative }
 Elementwise boolean gate for DeviceBackend::lrp_stabilized_divide(). More...
 
enum class  LogicOp {
  ConjunctionForward , ConjunctionBackward , ConjunctionLrp , DisjunctionForward ,
  DisjunctionBackward , DisjunctionLrp
}
 Elementwise passes of the fuzzy-logic modules, for DeviceBackend::logic_pointwise. More...
 
enum class  RecurrentCellOp {
  RnnBackward , LstmForward , LstmBackward , LstmLrp ,
  GruBackward , GruLrp
}
 Fused per-element recurrent-cell passes, for DeviceBackend::recurrent_cell. Slots (in[] / out[]), all (rows x hidden) per timestep unless noted: More...
 
enum class  SsmPassOp {
  MambaForward , MambaBackward , MambaGradBC , MambaLrp ,
  RwkvTokenShift , RwkvForward , RwkvBackward , RwkvShiftBackward ,
  RwkvLrp , RwkvShiftLrp , StabilizedDiv , RetnetForward ,
  RetnetStateGrad , RetnetGradQK , RetnetGradV , RetnetScores ,
  RetnetReadout , RetnetLrpInput , ReverseTimeSum
}
 Fused passes of the state-space / linear-recurrence modules (MambaModule, RWKVModule, RetNetModule), for DeviceBackend::ssm_pass. Dims come from SsmPassArgs: n batch, l sequence length, d d_model (or C for ReverseTimeSum), s Mamba's state_size / RetNet's key_dim. Sequences are (n, l, X) row-major; "states" buffers are (n, l + 1, ...) with the zero initial state at index 0. Lanes and slots (in[] -> out[]): More...
 
enum class  RlRowOp {
  DqnLoss , DqnGrad , PgLoss , PgGrad ,
  PpoLoss , PpoGrad , DqnTarget , PolyakBlend
}
 Fused per-row reinforcement-learning passes, for DeviceBackend::rl_rows. One lane per batch row (per element for PolyakBlend); rows x cols from RlRowArgs. Index slots hold validated whole-number action indices as floats. Slots (in[] -> out[]): More...
 
enum class  MutationObjective { Minimax , Heuristic , LeastSquares }
 E-GAN's three named mutation objectives. More...
 
enum class  AcquisitionKind { ExpectedImprovement , ProbabilityOfImprovement , UpperConfidenceBound }
 Which acquisition function RunGPBOLoop maximizes over candidates each iteration. More...
 
enum class  LRPSeed { OutputValue , OneHot }
 How LRP seeds relevance at the target output. More...
 
enum class  LRPRule { Epsilon , Gamma , AlphaBeta , ZBox }
 The LRP rule family a module applies. Semantics follow Zennit 1.0.0 exactly (Anders et al. 2021); every rule other than Epsilon is defined only for affine layers (LinearModule, Conv2DModule) – see Module::supports_lrp_rule(). More...
 
enum class  OpType {
  Linear , Conv , Activation , Elementwise ,
  Reduction , Normalization , Pooling , Embedding ,
  Composite , Recurrent , Attention
}
 The op-type tag a Node carries. Charter Part 2 §3: nodes are tagged by a small closed set of op types rather than by concrete layer class, so a query like "find the last conv layer's activations" (Grad-CAM) works by querying op type, not by string-matching a layer name. More...
 
enum class  SafetensorsDtype {
  Bool , U8 , I8 , I16 ,
  U16 , I32 , U32 , I64 ,
  U64 , F8_E4M3 , F8_E5M2 , F16 ,
  BF16 , F32 , F64
}
 Element types a safetensors file can declare. Only F32 converts to a Tensor so far. More...
 
enum class  ParameterKind { Continuous , LogUniform , Integer , Categorical }
 Which family of values a named parameter draws from. More...
 
enum class  LogFormat { LogFormat::JsonLines , LogFormat::Csv }
 Log record encoding. More...
 

Functions

double StandardNormalPdf (double z)
 Standard normal PDF, phi(z) = (1/sqrt(2*pi)) * exp(-z^2/2).
 
double StandardNormalCdf (double z)
 Standard normal CDF, Phi(z) = 0.5 * (1 + erf(z / sqrt(2))).
 
double ExpectedImprovement (double mean, double variance, double best_value, double xi=0.01)
 Expected Improvement: the expected amount by which a candidate exceeds best_value + xi, under the posterior N(mean, variance).
 
double ProbabilityOfImprovement (double mean, double variance, double best_value, double xi=0.01)
 Probability of Improvement: P(candidate's value > best_value + xi) under the posterior N(mean, variance).
 
double UpperConfidenceBound (double mean, double variance, double kappa=2.0)
 GP-Upper-Confidence-Bound: mean + kappa * sqrt(variance).
 
ASHAResult RunASHAOnConfigQueue (std::vector< Configuration > config_queue, const TrialFactory &make_trial, int initial_epoch_budget, double eta, int num_rungs)
 Runs ASHA, drawing new configurations from an explicit, ordered queue (rather than sampling indefinitely) – the pure, deterministic core; RunASHA (below) is the thin SearchSpace/RNG-sampling wrapper around it.
 
template<typename RNG >
ASHAResult RunASHA (const SearchSpace &space, const TrialFactory &make_trial, size_t max_configs_started, int initial_epoch_budget, double eta, int num_rungs, RNG &rng)
 RNG-driven wrapper: draws max_configs_started configurations from space via RandomSample to serve as the queue, then runs RunASHAOnConfigQueue.
 
CollateFn AudioPadCollate ()
 Builds a CollateFn that zero-pads (silence) variable-length waveforms (sample.fields[0], shape (1, channels, num_samples) – WavReader's/ AudioFolderDataset's convention) to the batch's own max sample count, producing one (N, channels, max_samples) Tensor, plus a (N,) length field. Phase 4's version of PadCollate (Phase 3, text) – a second proof that the CollateFn extension point handles ragged/variable-length modalities with zero Dataset/DataLoader/Batch interface changes.
 
std::vector< std::vector< double > > AskGivenSamples (const CMAESState &state, const std::vector< std::vector< double > > &z_samples)
 Pure core: decodes an explicit set of standard-normal sample vectors into offspring points, x_i = mean + sigma * sqrt(variances) (elementwise) * z_i.
 
CMAESState TellGivenSamples (const CMAESState &state, const std::vector< std::vector< double > > &z_samples, const std::vector< std::vector< double > > &offspring, const std::vector< double > &fitness, double step_size_learning_rate, double scale_learning_rate)
 Pure core: given the offspring AskGivenSamples produced (same order), their maximization-convention fitness values, and the z_samples that produced them, returns the next generation's state.
 
Batch DefaultCollate (std::vector< Sample > samples, DeviceBackend *backend)
 Stacks a list of samples into one Batch, field-by-field, via Tensor::Stack – pulsatrix's default CollateFn (PyTorch's default_collate analogue).
 
template<typename T >
std::pair< std::vector< T >, std::vector< T > > OnePointCrossoverAtPoint (const std::vector< T > &parent1, const std::vector< T > &parent2, size_t point)
 Splits both parents at point and swaps tails.
 
template<typename T , typename RNG >
std::pair< std::vector< T >, std::vector< T > > OnePointCrossover (const std::vector< T > &parent1, const std::vector< T > &parent2, RNG &rng)
 RNG-driven wrapper: draws an interior point in [1, size-1] uniformly.
 
template<typename T >
std::pair< std::vector< T >, std::vector< T > > TwoPointCrossoverAtPoints (const std::vector< T > &parent1, const std::vector< T > &parent2, size_t point1, size_t point2)
 Swaps the [point1, point2) segment between both parents.
 
template<typename T , typename RNG >
std::pair< std::vector< T >, std::vector< T > > TwoPointCrossover (const std::vector< T > &parent1, const std::vector< T > &parent2, RNG &rng)
 RNG-driven wrapper: draws two points in [0, size], sorted ascending.
 
template<typename T >
std::pair< std::vector< T >, std::vector< T > > UniformCrossoverByMask (const std::vector< T > &parent1, const std::vector< T > &parent2, const std::vector< bool > &swap_mask)
 Swaps each gene independently wherever swap_mask is true.
 
template<typename T , typename RNG >
std::pair< std::vector< T >, std::vector< T > > UniformCrossover (const std::vector< T > &parent1, const std::vector< T > &parent2, double swap_probability, RNG &rng)
 RNG-driven wrapper: each gene swaps independently with probability swap_probability.
 
std::pair< std::vector< double >, std::vector< double > > BlendCrossoverByGamma (const std::vector< double > &parent1, const std::vector< double > &parent2, const std::vector< double > &gamma)
 Blends each gene pair via an explicit per-gene gamma: child1_i = (1-gamma_i)*x1_i + gamma_i*x2_i, child2_i = gamma_i*x1_i + (1-gamma_i)*x2_i.
 
template<typename RNG >
std::pair< std::vector< double >, std::vector< double > > BlendCrossover (const std::vector< double > &parent1, const std::vector< double > &parent2, double alpha, RNG &rng)
 RNG-driven wrapper (DEAP's cxBlend): draws gamma_i = (1+2*alpha)*u_i - alpha per gene, u_i ~ Uniform(0, 1).
 
std::pair< std::vector< double >, std::vector< double > > SimulatedBinaryCrossoverByDraw (const std::vector< double > &parent1, const std::vector< double > &parent2, double eta, const std::vector< double > &draws)
 Simulated binary crossover (Deb & Agrawal 1995; DEAP's cxSimulatedBinary), given an explicit per-gene draw in [0, 1).
 
template<typename RNG >
std::pair< std::vector< double >, std::vector< double > > SimulatedBinaryCrossover (const std::vector< double > &parent1, const std::vector< double > &parent2, double eta, RNG &rng)
 RNG-driven wrapper: draws u_i ~ Uniform(0, 1) per gene (std::uniform_real_distribution is documented to produce values in [0, 1), matching the pure core's requirement).
 
void set_seed (uint64_t seed)
 Sets the global seed and restarts the seed stream next_seed() draws from.
 
uint64_t global_seed ()
 The seed most recently passed to set_seed() (0 by default).
 
uint64_t next_seed ()
 The next seed in the global stream: a distinct, well-mixed 64-bit value per call, reproducible for a given global seed. Components built without an explicit seed take theirs from here, so two of them never share a random stream by accident.
 
void set_deterministic (bool enabled)
 Turns deterministic mode on (the default) or off.
 
bool deterministic ()
 Whether deterministic mode is on.
 
void check_deterministic_allowed (const char *operation)
 Guard for a nondeterministic code path: call it before running one.
 
Tensor ComputeDQNTarget (const Tensor &next_q_target, const Tensor &rewards, const Tensor &dones, float gamma, DeviceBackend *backend)
 Vanilla DQN Bellman target (Mnih et al. 2015): targets[b,0] = rewards[b,0] + gamma * (1 - dones[b,0]) * max_a next_q_target[b,a].
 
Tensor ComputeDoubleDQNTarget (const Tensor &next_q_online, const Tensor &next_q_target, const Tensor &rewards, const Tensor &dones, float gamma, DeviceBackend *backend)
 Double DQN Bellman target (van Hasselt et al. 2016, arXiv:1509.06461): a* = argmax_a next_q_online[b,a], then targets[b,0] = rewards[b,0] + gamma * (1 - dones[b,0]) * next_q_target[b, a*].
 
void SyncTargetNetwork (Module &source, Module &destination)
 Hard target-network update: copies every parameter value of source into destination, element-wise and in place (Mnih et al. 2015's periodic full copy).
 
float QualityFitness (const Tensor &logits)
 E-GAN's own quality fitness Fq: mean sigmoid(D(fake)) over the batch – how convincingly "real" the discriminator currently rates these samples. Higher is better (the discriminator being fooled more).
 
float DiversityFitness (Module &discriminator, const Tensor &fake, DeviceBackend *backend)
 E-GAN's own diversity fitness Fd = -log(||grad||): the negative log of the L2 norm of the discriminator's own parameter gradient from its fake-recognition loss term (BCEWithLogitsLoss(D(fake), 0)), evaluated on fake. A smaller discriminator gradient here means the discriminator is already close to a local optimum against these particular samples – the paper's own signal that this offspring is contributing mode coverage the discriminator can't easily exploit further (discourages mode collapse).
 
float CombinedFitness (float quality, float diversity, float gamma=0.05f)
 Combined E-GAN fitness: Fq + gamma*Fd (Wang et al. 2019's own weighted combination). gamma's default (0.05) is this mission's own reasonable working value, not a literal reproduction of the paper's own tuned constant (never stated precisely enough there to reproduce exactly) – a deliberate, documented choice, not an assumed one.
 
template<typename OptimizerT >
float RunMutationStep (Module &offspring, Module &discriminator, const Tensor &noise, MutationObjective objective, OptimizerT &g_optimizer, DeviceBackend *backend, float gamma=0.05f)
 Runs one E-GAN mutation training step: trains offspring (an already-independent Module instance – typically initialized as a copy of some parent's current weights, which this function does not itself construct or assume anything about) for one step against discriminator using the given objective, then scores the mutated result via CombinedFitness on offspring's own post-mutation samples.
 
template<typename MakeGenerator , typename DOptimizerT >
std::vector< float > RunEGANGeneration (GeneratorPopulation &population, Module &discriminator, const Tensor &real_batch, const std::vector< Tensor > &noise_per_generator, const std::vector< MutationObjective > &objectives, MakeGenerator make_generator, float g_learning_rate, DOptimizerT &d_optimizer, DeviceBackend *backend, float gamma=0.05f)
 Runs one E-GAN generation: for every population member, attempts every objective in objectives (each against a fresh weight-copy offspring built by make_generator + RestoreParameters), keeps the best-combined-fitness offspring, replaces that population slot with it, then trains discriminator on real_batch plus the now-mutated population's own pooled fake output.
 
template<typename MakeGenerator , typename DOptimizerT , typename RNG >
void RunEGANTraining (GeneratorPopulation &population, Module &discriminator, const Tensor &real_batch, int num_generations, int64_t noise_dim, int64_t per_generator_batch, const std::vector< MutationObjective > &objectives, MakeGenerator make_generator, float g_learning_rate, DOptimizerT &d_optimizer, DeviceBackend *backend, RNG &rng, float gamma=0.05f)
 RNG-driven wrapper: draws fresh standard-normal noise for every population member every generation, then runs RunEGANGeneration num_generations times.
 
std::vector< double > ESUpdateGivenPerturbations (const std::vector< double > &theta, const std::vector< std::vector< double > > &epsilons, const std::vector< double > &fitnesses, double alpha, double sigma)
 Pure core: the exact ES parameter update given already-sampled perturbations and their fitness scores – ‘theta’ = theta + (alpha / (N*sigma)) * sum_i(F_i * epsilon_i)`.
 
template<typename FitnessFn , typename RNG >
std::vector< double > ESStep (const std::vector< double > &theta, FitnessFn fitness_fn, int population_size, double sigma, double alpha, RNG &rng)
 RNG-driven wrapper: samples population_size/2 standard-normal perturbation vectors, scores theta+sigma*epsilon and theta-sigma*epsilon for each (mirrored sampling), and returns the updated theta via ESUpdateGivenPerturbations.
 
template<typename FitnessFn , typename RNG >
ESResult RunEvolutionStrategies (std::vector< double > theta, FitnessFn fitness_fn, int num_iterations, int population_size, double sigma, double alpha, RNG &rng)
 Runs num_iterations of Evolution Strategies starting from theta, tracking the best (theta, fitness) pair seen across every evaluated center point (global elitism, the same precedent this campaign's NEAT evolutionary loop already established) – vanilla ES itself has no such tracking, but a returnable "best point found" is genuinely necessary for this to be usable as an optimizer, so it is added here as a small, logged addition beyond the paper's own bare update rule.
 
template<typename Genotype , typename FitnessT , typename FitnessFn >
void EvaluatePopulation (std::vector< Individual< Genotype, FitnessT > > &population, FitnessFn &fitness_fn, DataThreadPool *thread_pool)
 Evaluates (or re-evaluates) every individual's fitness in place via fitness_fn.
 
template<typename Genotype , typename FitnessT , typename FitnessFn , typename OffspringFn , typename SurvivorFn >
std::vector< Individual< Genotype, FitnessT > > RunEvolutionaryLoop (std::vector< Individual< Genotype, FitnessT > > population, size_t num_generations, size_t lambda_size, FitnessFn fitness_fn, OffspringFn produce_offspring_genotype, SurvivorFn survivor_selector, DataThreadPool *thread_pool=nullptr)
 Runs num_generations of the shared evolutionary-loop skeleton: evaluate -> produce lambda_size offspring (via produce_offspring_genotype, called once per offspring) -> evaluate offspring -> survivor-select mu individuals for the next generation.
 
StabilityResult ComputeAttributionStability (const std::vector< Attribution > &repeated_runs)
 Measures an explainer's stability across repeated runs on the same input (charter's "repeated-run variance measured and documented" audit category). Known-unstable methods (LIME, KernelSHAP) are expected to show is_deterministic == false; every other native/surrogate explainer in this codebase is deterministic by construction.
 
double FixedTopologyXORForward (const std::vector< double > &theta, const std::array< double, 2 > &inputs)
 Forward pass: theta layout is [w1_00, w1_01, b1_0, w1_10, w1_11, b1_1, w2_0, w2_1, b2] – h_j = sigmoid(w1_j0*x0 + w1_j1*x1 + b1_j) for j in {0,1}, y = sigmoid(w2_0*h0 + w2_1*h1 + b2).
 
double FixedTopologyXORFitness (const std::vector< double > &theta)
 Scores theta against all four XOR patterns as 4.0 minus the sum of squared errors – identical convention to XORFitness (neat_xor_fitness.hpp), so an all-zero theta scores exactly 3.0 (every pattern outputs sigmoid(0)=0.5), the same fixed point NEAT's own fresh, all-zero-weight genome scores.
 
GAEResult ComputeGAE (const Tensor &rewards, const Tensor &dones, const Tensor &values, float bootstrap_value, float gamma, float lambda, DeviceBackend *backend)
 Generalized Advantage Estimation (Schulman et al. 2016, arXiv:1506.02438): the exponentially-weighted average of k-step advantage estimators, computed in one reverse pass.
 
Tensor SliceBatch (const Tensor &t, int64_t start, int64_t count, DeviceBackend *backend)
 Extracts rows [start, start+count) along t's leading dimension into a new Tensor – the inverse of Tensor::Stack, needed to split a pooled discriminator gradient back into each population member's own slice.
 
std::vector< float > FlattenParameters (Module &module)
 Flattens every parameter tensor module.parameters() reports (in that order) into one vector – the concrete mechanism Phase 5 Mission 2's mutation-offspring construction uses to copy a parent generator's current weights into a freshly-constructed (architecturally identical) offspring instance before mutating the copy.
 
void RestoreParameters (Module &module, const std::vector< float > &flat)
 Overwrites every parameter tensor module.parameters() reports (in that order) from flat – the inverse of FlattenParameters.
 
void ZeroModuleGradients (Module &module)
 Zeros every gradient tensor module.parameters() reports – a standalone alternative to calling some optimizer's own zero_grad(module) when no persistent per-module optimizer instance is being kept around (Phase 5 Mission 2's own mutation-attempt loop constructs a fresh optimizer per attempt, so there is no single optimizer instance left to call zero_grad on between generations).
 
Tensor GeneratePooledFakeSamples (GeneratorPopulation &population, const std::vector< Tensor > &noise_per_generator, DeviceBackend *backend)
 Runs every population member's generator forward on its own noise batch (noise_per_generator[i] for population member i), then pools the results (Tensor::Stack, concatenated along the batch dimension, in population order) into one combined fake-sample batch – the discriminator's own training input in E-GAN.
 
void BackwardThroughPopulation (GeneratorPopulation &population, const Tensor &pooled_grad, const std::vector< int64_t > &batch_sizes, DeviceBackend *backend)
 Given pooled_grad (the gradient w.r.t. the pooled fake batch GeneratePooledFakeSamples produced – e.g. from discriminator.backward() called after a forward on that pooled batch), routes each population member's own slice back through that member's own backward() – the concrete mechanism that lets one shared discriminator train against every generator's own output while each generator's own parameters still receive exactly its own correct gradient.
 
GFlowNetTrajectory sample_gflownet_trajectory (HyperGridEnv &env, GFlowNetForwardPolicy &forward_policy)
 Samples one full trajectory: resets env, then repeatedly samples a masked action from forward_policy and steps env until termination (an explicit stop or env's own max_steps cap).
 
Configuration UnitCubeToConfiguration (const SearchSpace &space, const std::vector< float > &t)
 Maps a unit-hypercube point (one value per parameter, each in [0, 1]) to a Configuration, using space's own declared bounds.
 
template<typename ObjectiveFn , typename RNG >
std::vector< Trial > RunGPBOLoop (const SearchSpace &space, ObjectiveFn objective_fn, size_t num_initial_random, size_t num_iterations, AcquisitionKind acquisition, size_t num_candidates, RNG &rng)
 Runs GP-BO: num_initial_random uniformly-random trials, then num_iterations trials each chosen by fitting a GP to every trial so far and maximizing acquisition over num_candidates random points in the unit hypercube.
 
Configuration DecodeGenotype (const SearchSpace &space, const std::vector< double > &genotype)
 Decodes a unit-hypercube genotype into a Configuration using space's own declared bounds: Continuous linearly, LogUniform geometrically (both identical to gp_bo.hpp's UnitCubeToConfiguration); Integer by linear interpolation then rounding to the nearest integer (std::round – ties away from zero, portable); Categorical by linear interpolation into an index, floored, clamped to the last category (handles the gene == 1.0 boundary, which would otherwise floor to one-past-the-end).
 
template<typename RNG >
Configuration RandomSample (const SearchSpace &space, RNG &rng)
 Draws one configuration uniformly at random from space: Continuous parameters uniform over [lower, upper]; LogUniform parameters uniform in log-space (so e.g. [0.001, 1.0] gives 0.001-0.01, 0.01-0.1, and 0.1-1.0 equal probability, not the top decade 90% of the draws); Integer parameters uniform over the inclusive integer range; Categorical parameters uniform over the category list.
 
std::vector< Configuration > GridSample (const SearchSpace &space, size_t points_per_continuous_dimension)
 Enumerates the full cartesian-product grid over space.
 
std::vector< HyperbandBracket > ComputeHyperbandBrackets (int max_resource, double eta)
 Computes the classic Hyperband bracket schedule: s_max = floor(log_eta(max_resource)), B = (s_max + 1) * max_resource; for s from s_max down to 0, num_configs = ceil((B / max_resource) * (eta^s / (s + 1))), initial_budget = round(max_resource / eta^s) (each floored at 1).
 
template<typename RNG >
HyperbandResult RunHyperband (const SearchSpace &space, const TrialFactory &make_trial, int max_resource, double eta, RNG &rng)
 Runs one Successive Halving bracket (successive_halving.hpp) per ComputeHyperbandBrackets(max_resource, eta), keeping the best result across all of them.
 
std::vector< float > SolveLinearSystem (std::vector< std::vector< float > > a, std::vector< float > b)
 Solves A*x = b via Gaussian elimination with partial pivoting.
 
ConservationResult ComputeConservation (const Tensor &relevance_in, const Tensor &relevance_out)
 Sums relevance_in and relevance_out independently and reports their gap.
 
std::string lrp_rule_name (LRPRule rule)
 Lower-case rule name ("epsilon", "gamma", "alpha_beta", "zbox") for messages/metadata.
 
EigenResult SymmetricEigen (const Tensor &a)
 All eigenvalues and eigenvectors of a symmetric matrix, by Householder reduction to tridiagonal form followed by QL with implicit shifts.
 
DominantEigenResult PowerIteration (const Tensor &a, int64_t max_iterations=1000, float tolerance=1e-6f, uint64_t seed=0)
 The dominant eigenpair of a symmetric matrix by power iteration – cheaper than SymmetricEigen() when only the top eigenpair is needed (spectral norm, stable rank).
 
QRResult QR (const Tensor &a)
 Thin QR factorization by Householder reflections.
 
SVDResult SVD (const Tensor &a)
 Thin singular value decomposition by one-sided (Hestenes) Jacobi rotations.
 
void append_named_parameters (std::vector< NamedParamRef > &out, const std::string &prefix, Module &child)
 Appends child's named parameters to out, each renamed to prefix.name – the one step every container's named_parameters() repeats per child.
 
std::vector< bool > BitFlipMutationByMask (const std::vector< bool > &genotype, const std::vector< bool > &flip_mask)
 Flips each gene where flip_mask is true, leaves the rest unchanged.
 
template<typename RNG >
std::vector< bool > BitFlipMutation (const std::vector< bool > &genotype, double mutation_probability, RNG &rng)
 RNG-driven wrapper: each gene flips independently with probability mutation_probability.
 
std::vector< double > GaussianMutationByNoise (const std::vector< double > &genotype, const std::vector< double > &noise, const std::vector< bool > &apply_mask)
 Adds noise[i] to genotype[i] wherever apply_mask[i] is true, leaves the rest unchanged.
 
template<typename RNG >
std::vector< double > GaussianMutation (const std::vector< double > &genotype, double sigma, double mutation_probability, RNG &rng)
 RNG-driven wrapper: each gene independently receives N(0, sigma^2) noise with probability mutation_probability.
 
double PolynomialMutationByDraw (double x, double lower, double upper, double eta, double u)
 Polynomial-mutates a single bounded gene given an explicit draw.
 
template<typename RNG >
std::vector< double > PolynomialMutation (const std::vector< double > &genotype, const std::vector< double > &lower_bounds, const std::vector< double > &upper_bounds, double eta, double mutation_probability, RNG &rng)
 RNG-driven wrapper: each gene independently mutates (via PolynomialMutationByDraw) with probability mutation_probability.
 
std::vector< int > AllocateOffspringCounts (const std::vector< double > &species_adjusted_fitness_sums, int population_size)
 Pure core: allocates population_size offspring slots across species proportionally to each species' own adjusted-fitness sum, using the largest-remainder (Hamilton) apportionment method so the total always sums to exactly population_size (ties in fractional remainder broken by species index, earliest first). Falls back to an equal split (remainder to the earliest species, by index) if every species sum is non-positive, rather than dividing by zero.
 
template<typename RNG >
NEATGenome ReproduceOffspring (const NEATGenome &parent, InnovationTracker &tracker, RNG &rng, double weight_mutation_sigma, double weight_mutation_probability, double add_connection_probability, double add_node_probability)
 RNG-driven wrapper: clones parent, then applies weight mutation (gated per-connection by weight_mutation_probability inside MutateWeights itself) and, independently, one attempt each at the two structural mutations, each gated by its own probability.
 
template<typename FitnessFn , typename RNG >
NEATEvolutionResult RunNEATEvolution (std::vector< NEATGenome > population, FitnessFn fitness_fn, int num_generations, double compatibility_threshold, double c1, double c2, double c3, double weight_mutation_sigma, double weight_mutation_probability, double add_connection_probability, double add_node_probability, InnovationTracker &tracker, RNG &rng)
 Runs num_generations of speciated, mutation-only NEAT evolution. Each generation: evaluates every genome's fitness via fitness_fn, tracks the best genome seen across the whole run so far (global elitism – best_fitness never decreases generation to generation), speciates the population, applies fitness sharing, allocates each species a share of the next generation proportional to its adjusted-fitness sum, and fills that share with one unmutated species-champion copy plus mutated copies of uniformly-randomly chosen species members.
 
std::vector< double > EvaluateNEATPhenotype (const NEATGenome &genome, const std::vector< double > &inputs)
 Evaluates genome's phenotype forward pass on inputs (one value per Input node, ordered by ascending node ID; the Bias node, if present, is always implicitly 1.0 and is not part of inputs).
 
double CompatibilityDistance (const NEATGenome &a, const NEATGenome &b, double c1, double c2, double c3)
 Compatibility distance: delta = c1*E/N + c2*D/N + c3*W_bar, where E is the count of excess genes (innovation numbers beyond the other genome's own highest), D is the count of disjoint genes (innovation numbers within the overlapping range but present in only one genome), N is the larger genome's gene count (or 1 if both genomes have fewer than 20 connection genes – the original paper's own small-genome exception), and W_bar is the average weight difference over genes with matching innovation numbers (present in both genomes, regardless of enabled/disabled status).
 
SpeciesAssignment SpeciatePopulation (const std::vector< NEATGenome > &population, double compatibility_threshold, double c1, double c2, double c3)
 Groups population into species: each genome joins the first existing species whose representative (that species' own first member) it is compatible with (distance < compatibility_threshold); otherwise it founds a new species with itself as representative.
 
std::vector< double > ComputeAdjustedFitness (const std::vector< double > &raw_fitness, const std::vector< std::vector< size_t > > &species)
 Fitness sharing: each individual's adjusted fitness is its own raw fitness divided by the size of its species – protects small, structurally novel species from being immediately out-competed by a large, already-optimized one.
 
double XORFitness (const NEATGenome &genome)
 Evaluates genome's phenotype on all four XOR patterns ((0,0)->0, (0,1)->1, (1,0)->1, (1,1)->0, in that order) and scores it as 4.0 minus the sum of squared errors – a perfect fit scores 4.0; a genome producing exactly 0.5 for every pattern (e.g. a fresh, all-zero-weight genome, before any weight differentiation has emerged) scores exactly 3.0 (4.0 - 4*0.25).
 
bool Dominates (const Objectives &a, const Objectives &b)
 Pareto dominance (maximization convention): a dominates b iff a[i] >= b[i] for every objective i, and a[i] > b[i] for at least one objective.
 
std::vector< std::vector< size_t > > FastNonDominatedSort (const std::vector< Objectives > &objectives)
 Fast non-dominated sort (Deb et al. 2002, Algorithm: fast-non-dominated-sort): partitions [0, objectives.size()) into fronts – front 0 is the non-dominated set, front 1 is non-dominated after removing front 0, and so on.
 
std::vector< double > CrowdingDistance (const std::vector< Objectives > &front_objectives)
 Crowding distance within a single front.
 
template<typename Genotype >
std::vector< Individual< Genotype, Objectives > > NSGA2Replacement (const std::vector< Individual< Genotype, Objectives > > &population, std::vector< Individual< Genotype, Objectives > > offspring, size_t mu)
 NSGA-II survivor selection: combines population and offspring, fast-non-dominated- sorts the pool, includes whole fronts (best first) until the next front would overflow mu, then fills the remainder from that final front by crowding distance (largest first – more diverse/isolated solutions preferred).
 
PBTTruncationGroups ComputeTruncationGroups (const std::vector< double > &metrics, double truncation_fraction)
 Pure core: identifies the bottom and top truncation_fraction of the population by metric (higher is better). Ties are broken by a stable sort on descending metric, so the earlier index among equal values sorts toward "top." At least one individual is always selected on each end, even if floor(size*fraction) would be 0.
 
Configuration ExploreConfigurationGivenFactors (const Configuration &config, const SearchSpace &space, const std::map< std::string, double > &factors)
 Pure core: applies an explicit per-parameter multiplicative factor to every Continuous/LogUniform/Integer parameter in config, clamped to that parameter's own bounds – PBT's own "explore" step (Jaderberg et al.'s own simple perturbation: multiply by 0.8 or 1.2). Categorical parameters are left unchanged (explore, in its original form, perturbs numeric hyperparameters only – a deliberate, logged scope decision, not an oversight). Integer results are rounded to the nearest integer.
 
template<typename RNG >
Configuration ExploreConfiguration (const Configuration &config, const SearchSpace &space, RNG &rng)
 RNG-driven wrapper: draws each non-categorical parameter's factor uniformly from {0.8, 1.2} (Jaderberg et al.'s own standard explore perturbation), then applies ExploreConfigurationGivenFactors.
 
template<typename RNG >
std::vector< double > RunPBTGeneration (std::vector< std::unique_ptr< PBTResumableTrial > > &trials, const SearchSpace &space, int num_epochs, double truncation_fraction, RNG &rng)
 Runs one PBT generation: trains every live trial for num_epochs, then exploits+explores the bottom truncation_fraction of the population from a uniformly-randomly-chosen member of the top truncation_fraction. Individuals outside both groups are left running untouched. Returns each trial's metric as of this generation (post exploit/explore for any trial that was replaced) – the value to feed into the next generation's own truncation.
 
template<typename RNG >
PBTResult RunPBT (std::vector< std::unique_ptr< PBTResumableTrial > > &trials, const SearchSpace &space, int num_generations, int epochs_per_generation, double truncation_fraction, RNG &rng)
 Runs num_generations of RunPBTGeneration in sequence.
 
void PolyakUpdate (Module &source, Module &destination, float tau)
 Soft target-network update (Lillicrap et al. 2016 / Haarnoja et al. 2018): destination_param[i] = tau * source_param[i] + (1 - tau) * destination_param[i], element-wise and in place.
 
std::vector< uint8_t > SerializeSafetensors (const std::vector< std::pair< std::string, const Tensor * > > &tensors, const std::map< std::string, std::string > &metadata={})
 Serializes tensors (as F32) and string metadata into safetensors bytes.
 
void WriteSafetensors (const std::string &path, const std::vector< std::pair< std::string, const Tensor * > > &tensors, const std::map< std::string, std::string > &metadata={})
 SerializeSafetensors() written to path.
 
template<typename Genotype , typename FitnessT , typename RNG >
size_t TournamentSelect (const std::vector< Individual< Genotype, FitnessT > > &population, size_t tournament_size, RNG &rng)
 Tournament selection: draw tournament_size individuals without replacement from population and return the index of the fittest among them.
 
template<typename Genotype , typename FitnessT >
size_t RouletteSelectByDraw (const std::vector< Individual< Genotype, FitnessT > > &population, FitnessT draw)
 Fitness-proportionate ("roulette wheel") selection given an explicit draw in [0, total_fitness). Pure and deterministic – the hand-testable core RouletteSelect wraps with an RNG-generated draw.
 
template<typename Genotype , typename FitnessT , typename RNG >
size_t RouletteSelect (const std::vector< Individual< Genotype, FitnessT > > &population, RNG &rng)
 RNG-driven wrapper around RouletteSelectByDraw: draws uniformly from [0, total_fitness) and selects accordingly.
 
template<typename Genotype , typename FitnessT >
size_t RankSelectByDraw (const std::vector< Individual< Genotype, FitnessT > > &population, double draw)
 Linear-rank selection given an explicit draw in [0, total_weight). Individuals are ranked ascending by fitness (worst = rank 1, best = rank population.size()); each rank's selection weight equals its rank, so the best individual is population.size() times as likely to be drawn as the worst. Pure and deterministic – the hand-testable core RankSelect wraps with an RNG-generated draw.
 
template<typename Genotype , typename FitnessT , typename RNG >
size_t RankSelect (const std::vector< Individual< Genotype, FitnessT > > &population, RNG &rng)
 RNG-driven wrapper around RankSelectByDraw: draws uniformly from [0, total_weight) and selects accordingly.
 
Tensor SinusoidalTimestepEmbedding (int64_t t, int64_t embedding_dim, DeviceBackend *backend, float base=10000.0f)
 Standard Transformer-style sinusoidal encoding of a diffusion timestep t: emb[2i] = sin(t / base^(2i/embedding_dim)), emb[2i+1] = cos(t / base^(2i/embedding_dim)) for i in [0, embedding_dim/2).
 
SuccessiveHalvingResult RunSuccessiveHalvingOnConfigs (std::vector< Configuration > configs, const TrialFactory &make_trial, int initial_epoch_budget, double eta)
 Runs Successive Halving over an explicit, caller-supplied list of configurations – the pure, deterministic core; RunSuccessiveHalving (below) is the thin SearchSpace/RNG-sampling wrapper around it.
 
template<typename RNG >
SuccessiveHalvingResult RunSuccessiveHalving (const SearchSpace &space, const TrialFactory &make_trial, size_t num_configs, int initial_epoch_budget, double eta, RNG &rng)
 RNG-driven wrapper: draws num_configs configurations from space via RandomSample, then runs RunSuccessiveHalvingOnConfigs.
 
template<typename Genotype , typename FitnessT >
std::vector< Individual< Genotype, FitnessT > > GenerationalReplacement (const std::vector< Individual< Genotype, FitnessT > > &, std::vector< Individual< Genotype, FitnessT > > offspring, size_t mu)
 Generational replacement (DEAP's eaSimple): the offspring pool becomes the entire next generation; population is ignored (parents never survive).
 
template<typename Genotype , typename FitnessT >
std::vector< Individual< Genotype, FitnessT > > MuPlusLambdaReplacement (const std::vector< Individual< Genotype, FitnessT > > &population, std::vector< Individual< Genotype, FitnessT > > offspring, size_t mu)
 (mu+lambda) replacement: the next generation is the fittest mu individuals from population union offspring (parents may survive) – more exploitative than (mu,lambda), since a fit parent is never discarded just for being old.
 
template<typename Genotype , typename FitnessT >
std::vector< Individual< Genotype, FitnessT > > MuCommaLambdaReplacement (const std::vector< Individual< Genotype, FitnessT > > &, std::vector< Individual< Genotype, FitnessT > > offspring, size_t mu)
 (mu,lambda) replacement: the next generation is the fittest mu individuals from offspring only (population/parents are always discarded) – more explorative than (mu+lambda), since it cannot get stuck re-selecting the same elite parent forever.
 
std::string format_iso8601_utc (std::chrono::system_clock::time_point tp)
 Formats tp as ISO-8601 UTC with milliseconds, e.g. "2026-10-02T12:34:56.789Z".
 
std::string sample_to_json (const SystemSample &sample)
 Encodes sample as one JSON object (no trailing newline), the JSON Lines log record.
 
void require_device (const Tensor &t, DeviceType expected, const char *where)
 Throws unless t lives on expected – the check every module and loss runs on the tensors handed to it (roadmap FND-8, gpu_review #1).
 
CollateFn PadCollate (float pad_index=0.0f)
 Builds a CollateFn that right-pads variable-length token sequences (sample.fields[0], shape (1, seq_len) – TextDataset::get()'s output) to the batch's own max length, producing one (N, max_len) Tensor, plus a (N,) length field recording each sample's real (pre-padding) length. This is the CollateFn extension point Phase 1's architecture design reserved for ragged/variable-length modalities (PyTorch's collate_fn equivalent) – exercised here for the first time, with zero changes needed to Dataset/DataLoader/Batch themselves.
 
TopKResult top_k (const Tensor &input, int64_t k, bool largest=true)
 Selects the k largest (or smallest) entries of every row along the last dimension.
 
double GaussianKdeDensity (const std::vector< double > &observations, double bandwidth, double x)
 Fixed-bandwidth Gaussian KDE: density(x) = mean over every observation o of N(x; o, bandwidth^2).
 
double CategoricalDensity (const std::vector< std::string > &observations, size_t num_categories, const std::string &category)
 Laplace(add-one)-smoothed empirical probability of category among observations.
 
double LogDensityRatio (const SearchSpace &space, const Configuration &candidate, const std::vector< Configuration > &good_configs, const std::vector< Configuration > &bad_configs)
 log(l(candidate)) - log(g(candidate)): the TPE scoring function, summed independently over every parameter in space (so a candidate's mixed continuous/categorical parameters each contribute their own term, composing naturally rather than needing a joint density over the whole space).
 
template<typename ObjectiveFn , typename RNG >
std::vector< Trial > RunTPELoop (const SearchSpace &space, ObjectiveFn objective_fn, size_t num_initial_random, size_t num_iterations, double gamma, size_t num_candidates, RNG &rng)
 Runs TPE: num_initial_random uniformly-random trials (RandomSample), then num_iterations trials each chosen by splitting all trials so far into good/bad by the gamma quantile (maximization convention: good = highest objective values) and picking, among num_candidates uniformly-random candidates, the one maximizing LogDensityRatio.
 
float NormalizeUnsigned (float value, float max_abs)
 Normalizes value into [0, 1] against a known maximum magnitude, for unsigned (magnitude-only) quantities such as saliency intensity or ablation effect.
 
float NormalizeSigned (float value, float max_abs)
 Normalizes value into [-1, 1] against a known maximum absolute magnitude, for signed quantities such as attribution direction (positive/negative contribution).
 
RgbColor ViridisColormap (float normalized_value)
 Viridis colormap – perceptually uniform, colorblind-safe – for sequential/unsigned magnitude (hc_information_visualization.md SS4: "Recommended Color Systems").
 
RgbColor DivergingColormap (float signed_normalized_value)
 Blue-White-Red diverging colormap for signed attribution (positive/negative contribution) – hue encodes direction only, never magnitude (hc_information_visualization.md SS1's Cleveland-McGill rule: color hue is categorical/directional, magnitude must be position or length).
 
BarSeries ToFeatureImportanceBars (const Attribution &attr, int top_k)
 Converts an Attribution's per-feature values into labeled, magnitude-sorted bars for a horizontal bar chart – the canonical XAI feature-importance encoding (hc_information_visualization.md SS5: position on a shared axis, Cleveland-McGill rank 1).
 
std::vector< WaterfallStep > ToWaterfallSteps (const Attribution &attr, float baseline_value)
 Converts an Attribution's per-feature values into a cascading waterfall from a real baseline to the final prediction (hc_information_visualization.md SS5/SS6: the one case where a bar chart legitimately does not start at zero, since the baseline itself is the meaningful reference point – Tufte's lie-factor rule is satisfied relative to that baseline, not to zero).
 
std::vector< WaterfallBar > ToWaterfallBars (const std::vector< WaterfallStep > &steps, float baseline_value)
 Converts waterfall steps into floating bars, each spanning from the previous running total to its own running total – i.e. bar i covers [min(c_{i-1}, c_i), max(c_{i-1}, c_i)] with c_{-1} = baseline_value. Correct for any sign of baseline or running total: a cascade that starts below zero, crosses zero, or stays negative (e.g. explaining a negative logit) floats exactly where the running total is, rather than being anchored at zero the way stacked bar segments are.
 
HeatmapGrid ToSaliencyHeatmap (const Attribution &attr)
 Reshapes an Attribution's values into a 2D grid for a saliency overlay heatmap.
 
HeatmapColorScale ComputeHeatmapColorScale (const HeatmapGrid &grid)
 Chooses a heatmap's color scale from its values (hc_information_visualization.md SS4: sequential maps for unsigned magnitude, diverging maps centred on the meaningful midpoint – zero – for signed quantities).
 
std::vector< BeeswarmPoint > ToBeeswarmPoints (const std::vector< Attribution > &runs, int64_t feature_index)
 Converts one feature's attribution value across many repeated/independent runs into jittered (x, y) points for a beeswarm plot – the global-explanation distribution view (hc_information_visualization.md SS5: "SHAP beeswarm plot... each point is one prediction; x-position is the SHAP value"). Deterministic, density-based jitter: points are binned along x, then colliding points within a bin are alternately offset above/below y=0 so they read as spread rather than overlapping – not a random jitter, so two calls with the same input always produce the same layout.
 
std::string CircuitNodeDisplayLabel (const CircuitNode &node)
 Human-readable label for a CircuitGraph node: the node's own label when it has one, otherwise its operation type and id (e.g. "Conv #1", "Activation #2") – so an unlabeled ComputationGraph still renders as a readable layer diagram rather than a row of anonymous "node_<id>" markers.
 
HistogramBins ToFieldHistogramBins (const Dataset &dataset, int64_t field_index, int num_bins)
 Bins one Sample field's values (flattened across every sample's Tensor at that field position, mirroring DatasetValidator's aggregation convention) into num_bins equal-width bins, for a per-field distribution histogram (hc_information_visualization.md's data-preview touchpoint).
 
RgbImageBuffer ToRgbImageBuffer (const Tensor &image_chw)
 Converts a decoded image Tensor into an interleaved-RGB byte buffer for GPU texture upload (the data-preview "image grid" touchpoint's pure half – the actual glTexImage2D call lives in TextureCache, which is GL-dependent and untestable here).
 
Vocabulary BuildVocabulary (const std::vector< std::vector< std::string > > &tokenized_corpus, int64_t max_vocab_size=-1)
 Builds a Vocabulary from a tokenized corpus, ranked by descending token frequency (ties broken by first-seen order, for determinism).
 
std::vector< float > fit_weighted_linear_regression (const std::vector< std::vector< float > > &samples, const std::vector< float > &targets, const std::vector< float > &weights, float l2_lambda)
 Fits w* = argmin_w sum_i weight_i*(target_i - w^T sample_i)^2 + l2_lambda*||w||^2 via the normal equations (X^T W X + l2_lambda*I) w = X^T W y.
 

Variables

constexpr size_t kFixedTopologyXORNumParams = 9
 Total flat-parameter count: 2*2 (input->hidden weights) + 2 (hidden biases) + 2 (hidden->output weights) + 1 (output bias) = 9.
 

Typedef Documentation

◆ CollateFn

using pulsatrix::CollateFn = typedef std::function<Batch(std::vector<Sample>, DeviceBackend*)>

A function assembling a list of Samples into one Batch – pulsatrix's analogue of PyTorch's collate_fn. The standard extension point for ragged/variable-length modalities (text padding, variable-length audio): a caller-supplied CollateFn replacing DefaultCollate, not a subclass hierarchy.

◆ Configuration

using pulsatrix::Configuration = typedef std::map<std::string, ConfigValue>

A concrete hyperparameter configuration: parameter name -> concrete value.

◆ ConfigValue

using pulsatrix::ConfigValue = typedef std::variant<double, int64_t, std::string>

A concrete value for one parameter – a double (Continuous/LogUniform), an int64_t (Integer), or a std::string (Categorical, naming one of that parameter's categories).

◆ LRPComposite

using pulsatrix::LRPComposite = typedef std::function<LRPRuleConfig(size_t layer_index, const Module& module)>

Per-layer LRP rule choice: maps (top-level module index in forward order, module) to the LRPRuleConfig that module applies.

Note
LRP calls a composite exactly once per module, in ascending index order starting at 0, on every explain() – presets that depend on position (epsilon_gamma_box's "first Conv2D") rely on that order.
Applied to the ExplainerContext's top-level modules: a SequentialModule receives one config, which it forwards to all of its layers (it supports a rule only if they all do).

◆ NodeId

using pulsatrix::NodeId = typedef size_t

Stable identifier for a Node within its owning ComputationGraph.

◆ Objectives

using pulsatrix::Objectives = typedef std::vector<double>

◆ TextureId

using pulsatrix::TextureId = typedef unsigned int

Opaque GL texture handle, typed to avoid a GL header include in this public header.

◆ TrialFactory

using pulsatrix::TrialFactory = typedef std::function<std::unique_ptr<ResumableTrial>(const Configuration&)>

Builds a fresh ResumableTrial for a given configuration.

Enumeration Type Documentation

◆ AcquisitionKind

enum class pulsatrix::AcquisitionKind
strong

Which acquisition function RunGPBOLoop maximizes over candidates each iteration.

Enumerator
ExpectedImprovement 
ProbabilityOfImprovement 
UpperConfidenceBound 

◆ CopyDirection

enum class pulsatrix::CopyDirection
strong

Direction of a DeviceBackend::copy() call.

Enumerator
HostToDevice 
DeviceToHost 
DeviceToDevice 
HostToHost 

◆ DeviceType

enum class pulsatrix::DeviceType
strong

Which physical device a Tensor's buffer resides on.

Note
CPUBackend, CUDABackend and HIPBackend implement Cpu, Cuda and Hip respectively. Tensor::to(target, target_backend) moves a buffer between them.
Enumerator
Cpu 
Cuda 
Hip 

◆ ElementwiseOp

enum class pulsatrix::ElementwiseOp
strong

Unary elementwise operations supported by DeviceBackend::elementwise().

Note
Binary elementwise ops (add, mul) are intentionally not part of this Phase 0 interface — Tensor's arithmetic operators are designed in Mission 1 (Shape & Tensor Core), and a binary-op signature added speculatively now would likely need to change once that design exists.
Every op here computes the forward value only – no derivative variant exists in this interface. A module that needs an activation's derivative (ReluModule, RNNModule, LSTMModule, GRUModule) computes it locally from its own cached forward output, which is why adding Tanh/Sigmoid/Silu here removes those modules' raw forward loops but not their backward/LRP derivative math.
Enumerator
Relu 
Neg 
Tanh 

tanh(x)

Sigmoid 

1 / (1 + exp(-x))

Silu 

x * sigmoid(x) – a.k.a. swish; the gate half of SwiGLU

Exp 

exp(x) – GPU-native-kernels Mission 1b (Reparameterize, KL divergence)

◆ LogicOp

enum class pulsatrix::LogicOp
strong

Elementwise passes of the fuzzy-logic modules, for DeviceBackend::logic_pointwise.

Note
Paired with a norm index: 0 Product, 1 Lukasiewicz, 2 Godel – the declaration order of ConjunctionModule::TNorm and DisjunctionModule::TConorm.
Enumerator
ConjunctionForward 
ConjunctionBackward 
ConjunctionLrp 
DisjunctionForward 
DisjunctionBackward 
DisjunctionLrp 

◆ LrpGate

enum class pulsatrix::LrpGate
strong

Elementwise boolean gate for DeviceBackend::lrp_stabilized_divide().

Enumerator
None 

every element passes

Positive 

passes where gate > 0

Negative 

passes where gate < 0

◆ LRPRule

enum class pulsatrix::LRPRule
strong

The LRP rule family a module applies. Semantics follow Zennit 1.0.0 exactly (Anders et al. 2021); every rule other than Epsilon is defined only for affine layers (LinearModule, Conv2DModule) – see Module::supports_lrp_rule().

Enumerator
Epsilon 

R_in = x * ((R / stab(z)) @ W^T). The bias is left out of z unless LRPRuleConfig::epsilon_bias_in_denominator is set (Zennit's Epsilon includes it).

Gamma 

Zennit's generalized Gamma rule: weights W + gamma W^+ / W + gamma W^-, split by the sign of the input and of the original output (Montavon et al. 2019, generalized to negative activations).

AlphaBeta 

Alpha-beta rule (Bach et al. 2015) with alpha - beta == 1; alpha 1, beta 0 is ZPlus.

ZBox 

Z^B rule (Montavon et al. 2017) for a box-bounded input [low, high]; meant for the input layer.

◆ LRPSeed

enum class pulsatrix::LRPSeed
strong

How LRP seeds relevance at the target output.

Enumerator
OutputValue 

R[n, t] = y[n, t]: the total relevance is the explained logit itself (the classic Bach et al. 2015 setup, where conservation reads "attributions sum to the output").

OneHot 

R[n, t] = 1: unit relevance at the target, the convention Zennit / LXT attributors use when handed a one-hot output gradient. Use this to compare against those libraries.

◆ MutationObjective

enum class pulsatrix::MutationObjective
strong

E-GAN's three named mutation objectives.

Enumerator
Minimax 
Heuristic 
LeastSquares 

◆ OpType

enum class pulsatrix::OpType
strong

The op-type tag a Node carries. Charter Part 2 §3: nodes are tagged by a small closed set of op types rather than by concrete layer class, so a query like "find the last conv layer's activations" (Grad-CAM) works by querying op type, not by string-matching a layer name.

Note
This enum grows only when a genuinely new operation category is needed – it is not meant to enumerate every concrete Module subtype (LinearModule and a future EmbeddingModule might both tag their nodes Linear if they're mathematically the same operation).
Enumerator
Linear 
Conv 
Activation 
Elementwise 
Reduction 
Normalization 
Pooling 
Embedding 
Composite 
Recurrent 
Attention 

Multi-head (scaled dot-product) attention – Phase 3's MultiHeadAttentionModule.

Note
Justification for growing the enum here (contrast RoPEModule, which deliberately reused Elementwise): attention is a genuinely new operation category, not a new spelling of an existing one. It contracts two learned projections against each other (Q @ K^T) and re-mixes a third along the sequence axis – an input-dependent, content-addressed mixing across positions that no existing category describes. It is not Linear (the mixing weights are computed from the input, not stored), not Composite (Composite means "a container of other modules with no math of its own", which SequentialModule is and this is not – this module owns the two batched matmuls, the scale and the bilinear LRP rule), and not Recurrent (no state carried across steps; all positions are attended in parallel). The charter's stated reason for the enum – "find the last conv layer"-style graph queries – is exactly the use case that needs "find the attention blocks" to be answerable.

◆ ParameterKind

enum class pulsatrix::ParameterKind
strong

Which family of values a named parameter draws from.

Enumerator
Continuous 
LogUniform 
Integer 
Categorical 

◆ RecurrentCellOp

enum class pulsatrix::RecurrentCellOp
strong

Fused per-element recurrent-cell passes, for DeviceBackend::recurrent_cell. Slots (in[] / out[]), all (rows x hidden) per timestep unless noted:

  • RnnBackward: in g, dh_next, h -> out dz
  • LstmForward: in i, f, g, o (activated gates), c_prev -> out c, tanh(c), h
  • LstmBackward: in g, dh_next, dc_next, i, f, g, o, tanh_c, c_prev -> out dz_i, dz_f, dz_g, dz_o, dc_prev
  • LstmLrp: in r, R_h_next, R_c_next, i, f, g, c_prev, c -> out R_g, R_c_prev
  • GruBackward: in g, dh_next, z, r, n, hn, h_prev -> out dh_prev_direct, dz_pre, dn_pre, dr_pre, dhn_prev
  • GruLrp: in r, R_h_next, z, r_gate, n, hn, h_prev, h, n_pre -> out R_hprev_direct, R_n, R_term_b
Enumerator
RnnBackward 
LstmForward 
LstmBackward 
LstmLrp 
GruBackward 
GruLrp 

◆ RlRowOp

enum class pulsatrix::RlRowOp
strong

Fused per-row reinforcement-learning passes, for DeviceBackend::rl_rows. One lane per batch row (per element for PolyakBlend); rows x cols from RlRowArgs. Index slots hold validated whole-number action indices as floats. Slots (in[] -> out[]):

  • DqnLoss: in q (rows, cols), indices, targets -> out per-row squared TD error
  • DqnGrad: in q, indices, targets -> out grad (rows, cols), caller-zeroed; only the taken action's element is written (uses scale)
  • PgLoss: in logits, indices, returns -> out probs (rows, cols), per-row loss term
  • PgGrad: in probs, indices, returns -> out grad (dense; uses scale)
  • PpoLoss: in logits, indices, old_log_probs, advantages -> out probs, per-row loss term, ratio, mask (uses lower, upper)
  • PpoGrad: in probs, indices, advantages, ratios, masks -> out grad (dense; uses scale)
  • DqnTarget: in q_select, q_eval (both rows x cols), rewards, dones -> out target (uses gamma)
  • PolyakBlend: in source, destination -> out tau*source + (1 - tau)*destination over rows elements (out may alias destination; uses tau)
Enumerator
DqnLoss 
DqnGrad 
PgLoss 
PgGrad 
PpoLoss 
PpoGrad 
DqnTarget 
PolyakBlend 

◆ SafetensorsDtype

enum class pulsatrix::SafetensorsDtype
strong

Element types a safetensors file can declare. Only F32 converts to a Tensor so far.

Enumerator
Bool 
U8 
I8 
I16 
U16 
I32 
U32 
I64 
U64 
F8_E4M3 
F8_E5M2 
F16 
BF16 
F32 
F64 

◆ SsmPassOp

enum class pulsatrix::SsmPassOp
strong

Fused passes of the state-space / linear-recurrence modules (MambaModule, RWKVModule, RetNetModule), for DeviceBackend::ssm_pass. Dims come from SsmPassArgs: n batch, l sequence length, d d_model (or C for ReverseTimeSum), s Mamba's state_size / RetNet's key_dim. Sequences are (n, l, X) row-major; "states" buffers are (n, l + 1, ...) with the zero initial state at index 0. Lanes and slots (in[] -> out[]):

  • MambaForward (n*d lanes, t ascending): in input, z_delta (bias added), B, C, A (d, s), D (d) -> out delta, Abar, Bbar (n, l, d, s), states (n, l+1, d, s), output
  • MambaBackward (n*d lanes, t descending): in grad_output, input, delta, z_delta, states, Abar, Bbar, B, C, A, D -> out dx_direct, dz_delta, dh_total, A_terms (n, l, d, s), carry scratch (n, d, s), zero-filled by the caller
  • MambaGradBC (n*l*s lanes): in grad_output, input, delta, states, dh_total -> out dB, dC
  • MambaLrp (n*d lanes, t descending): in input, output, relevance_out, states, Abar, Bbar, C, D -> out relevance_in, carry scratch (n, d, s), zero-filled (uses eps)
  • RwkvTokenShift (n*l*d): in input, mu_r, mu_k, mu_v -> out xr, xk, xv
  • RwkvForward (n*d lanes, t ascending): in z_r, k, v, u, w -> out r, e, num, den, wkv, kk, a states, b states (n, l+1, d), gated
  • RwkvBackward (n*d lanes, t descending): in g_gated, r, v, e, kk, num, den, a states, b states, wkv, w -> out dz_r, dk, dv, u_terms, w_terms
  • RwkvShiftBackward (n*l*d): in input, g_xr, g_xk, g_xv, mu_r, mu_k, mu_v -> out grad_input, mu_r_terms, mu_k_terms, mu_v_terms
  • RwkvLrp (n*d lanes, t descending): in r_gated, a states, den, e, v, wkv, kk, w -> out v_relevance (uses eps)
  • RwkvShiftLrp (n*l*d): in input, xv, r_xv_raw, mu_v -> out relevance_in (uses eps)
  • StabilizedDiv (n*l*d): in r, z -> out r / (z + eps*sign(z))
  • RetnetForward (n*d lanes, t ascending): in q, k, v -> out states (n, l+1, s, d), output (uses gamma)
  • RetnetStateGrad (n*s*d lanes, t descending): in grad_output, q -> out dS (n, l, s, d) (uses gamma)
  • RetnetGradQK (n*l*s): in grad_output, states, dS, v -> out dq, dk
  • RetnetGradV (n*l*d): in dS, k -> out dv
  • RetnetScores (n*l*l): in q, k -> out QK, G = gamma^(t-s) QK (both 0 for s > t)
  • RetnetReadout (n*l*d): in G, v -> out Y = G @ V over s <= t
  • RetnetLrpInput (n*l*d): in input, W_q, W_k, W_v, q, k, v, r_q, r_k, r_v -> out relevance_in (uses eps)
  • ReverseTimeSum (d lanes): in terms (n, l, d) -> out[c] = sum over t descending, b ascending – a backward loop's parameter-gradient accumulation order
Enumerator
MambaForward 
MambaBackward 
MambaGradBC 
MambaLrp 
RwkvTokenShift 
RwkvForward 
RwkvBackward 
RwkvShiftBackward 
RwkvLrp 
RwkvShiftLrp 
StabilizedDiv 
RetnetForward 
RetnetStateGrad 
RetnetGradQK 
RetnetGradV 
RetnetScores 
RetnetReadout 
RetnetLrpInput 
ReverseTimeSum 

Function Documentation

◆ AllocateOffspringCounts()

std::vector< int > pulsatrix::AllocateOffspringCounts ( const std::vector< double > &  species_adjusted_fitness_sums,
int  population_size 
)
inline

Pure core: allocates population_size offspring slots across species proportionally to each species' own adjusted-fitness sum, using the largest-remainder (Hamilton) apportionment method so the total always sums to exactly population_size (ties in fractional remainder broken by species index, earliest first). Falls back to an equal split (remainder to the earliest species, by index) if every species sum is non-positive, rather than dividing by zero.

Exceptions
std::invalid_argumentif species_adjusted_fitness_sums is empty or population_size is not positive.

◆ append_named_parameters()

void pulsatrix::append_named_parameters ( std::vector< NamedParamRef > &  out,
const std::string &  prefix,
Module &  child 
)
inline

Appends child's named parameters to out, each renamed to prefix.name – the one step every container's named_parameters() repeats per child.

Note
A child that overrides only the legacy parameters() hook reports no names; its parameters are appended under positional names (prefix.0, prefix.1, ...) so a container never hides them from an optimizer that used to see them.

◆ AskGivenSamples()

std::vector< std::vector< double > > pulsatrix::AskGivenSamples ( const CMAESState &  state,
const std::vector< std::vector< double > > &  z_samples 
)
inline

Pure core: decodes an explicit set of standard-normal sample vectors into offspring points, x_i = mean + sigma * sqrt(variances) (elementwise) * z_i.

Exceptions
std::invalid_argumentif any z_sample's dimension doesn't match state.mean's.

◆ AudioPadCollate()

CollateFn pulsatrix::AudioPadCollate ( )

Builds a CollateFn that zero-pads (silence) variable-length waveforms (sample.fields[0], shape (1, channels, num_samples) – WavReader's/ AudioFolderDataset's convention) to the batch's own max sample count, producing one (N, channels, max_samples) Tensor, plus a (N,) length field. Phase 4's version of PadCollate (Phase 3, text) – a second proof that the CollateFn extension point handles ragged/variable-length modalities with zero Dataset/DataLoader/Batch interface changes.

Returns
A CollateFn producing Batch{ {padded_waveforms (N,channels,max_samples), lengths (N,)} }.
Exceptions
std::invalid_argument(from the returned CollateFn, at call time) if samples is empty, or if samples have differing channel counts – external boundary, matching DefaultCollate's/PadCollate's own convention.

◆ BackwardThroughPopulation()

void pulsatrix::BackwardThroughPopulation ( GeneratorPopulation &  population,
const Tensor &  pooled_grad,
const std::vector< int64_t > &  batch_sizes,
DeviceBackend *  backend 
)
inline

Given pooled_grad (the gradient w.r.t. the pooled fake batch GeneratePooledFakeSamples produced – e.g. from discriminator.backward() called after a forward on that pooled batch), routes each population member's own slice back through that member's own backward() – the concrete mechanism that lets one shared discriminator train against every generator's own output while each generator's own parameters still receive exactly its own correct gradient.

Parameters
batch_sizesEach population member's own noise batch's leading-dimension size, in the same order GeneratePooledFakeSamples pooled them (not assumed uniform across members).
Exceptions
std::invalid_argumentif batch_sizes.size() != population.size(), or the batch sizes don't sum to pooled_grad's own leading dimension (delegates to SliceBatch/each generator's own backward() for their own further preconditions).

◆ BitFlipMutation()

template<typename RNG >
std::vector< bool > pulsatrix::BitFlipMutation ( const std::vector< bool > &  genotype,
double  mutation_probability,
RNG &  rng 
)

RNG-driven wrapper: each gene flips independently with probability mutation_probability.

Exceptions
std::invalid_argumentif mutation_probability is outside [0, 1].
Note
mutation_probability == 0.0 or 1.0 make std::bernoulli_distribution deterministic (never / always flips) – exact, RNG-independent correctness cases.

◆ BitFlipMutationByMask()

std::vector< bool > pulsatrix::BitFlipMutationByMask ( const std::vector< bool > &  genotype,
const std::vector< bool > &  flip_mask 
)
inline

Flips each gene where flip_mask is true, leaves the rest unchanged.

Exceptions
std::invalid_argumentif genotype and flip_mask sizes differ.

◆ BlendCrossover()

template<typename RNG >
std::pair< std::vector< double >, std::vector< double > > pulsatrix::BlendCrossover ( const std::vector< double > &  parent1,
const std::vector< double > &  parent2,
double  alpha,
RNG &  rng 
)

RNG-driven wrapper (DEAP's cxBlend): draws gamma_i = (1+2*alpha)*u_i - alpha per gene, u_i ~ Uniform(0, 1).

Exceptions
std::invalid_argumentif parent sizes differ or alpha < 0.

◆ BlendCrossoverByGamma()

std::pair< std::vector< double >, std::vector< double > > pulsatrix::BlendCrossoverByGamma ( const std::vector< double > &  parent1,
const std::vector< double > &  parent2,
const std::vector< double > &  gamma 
)
inline

Blends each gene pair via an explicit per-gene gamma: child1_i = (1-gamma_i)*x1_i + gamma_i*x2_i, child2_i = gamma_i*x1_i + (1-gamma_i)*x2_i.

Exceptions
std::invalid_argumentif parent1/parent2/gamma sizes are not all equal.
Note
child1_i + child2_i == parent1_i + parent2_i for any gamma_i – an algebraic invariant, not just a property at specific gamma values, useful for testing the RNG-driven wrapper without controlling its draws directly.

◆ BuildVocabulary()

Vocabulary pulsatrix::BuildVocabulary ( const std::vector< std::vector< std::string > > &  tokenized_corpus,
int64_t  max_vocab_size = -1 
)

Builds a Vocabulary from a tokenized corpus, ranked by descending token frequency (ties broken by first-seen order, for determinism).

Parameters
tokenized_corpusOne token sequence per document/line (e.g. Tokenizer::Tokenize's output for each line of a corpus).
max_vocab_sizeIf >= 0, keeps only the top max_vocab_size most frequent real tokens (the reserved <unk> at index 0 doesn't count against this limit). -1 (default) keeps every distinct token seen.
Returns
The built Vocabulary. An empty corpus produces a Vocabulary containing only <unk> (size() == 1) – not an error, just nothing to rank.

◆ CategoricalDensity()

double pulsatrix::CategoricalDensity ( const std::vector< std::string > &  observations,
size_t  num_categories,
const std::string &  category 
)
inline

Laplace(add-one)-smoothed empirical probability of category among observations.

Exceptions
std::invalid_argumentif num_categories == 0.
Note
observations may be empty (probability reduces to the uniform prior 1/num_categories).

◆ check_deterministic_allowed()

void pulsatrix::check_deterministic_allowed ( const char *  operation)

Guard for a nondeterministic code path: call it before running one.

Parameters
operationNames the operation in the error message.
Exceptions
std::logic_errorif deterministic mode is on.

◆ CircuitNodeDisplayLabel()

std::string pulsatrix::CircuitNodeDisplayLabel ( const CircuitNode &  node)

Human-readable label for a CircuitGraph node: the node's own label when it has one, otherwise its operation type and id (e.g. "Conv #1", "Activation #2") – so an unlabeled ComputationGraph still renders as a readable layer diagram rather than a row of anonymous "node_<id>" markers.

◆ CombinedFitness()

float pulsatrix::CombinedFitness ( float  quality,
float  diversity,
float  gamma = 0.05f 
)
inline

Combined E-GAN fitness: Fq + gamma*Fd (Wang et al. 2019's own weighted combination). gamma's default (0.05) is this mission's own reasonable working value, not a literal reproduction of the paper's own tuned constant (never stated precisely enough there to reproduce exactly) – a deliberate, documented choice, not an assumed one.

◆ CompatibilityDistance()

double pulsatrix::CompatibilityDistance ( const NEATGenome &  a,
const NEATGenome &  b,
double  c1,
double  c2,
double  c3 
)
inline

Compatibility distance: delta = c1*E/N + c2*D/N + c3*W_bar, where E is the count of excess genes (innovation numbers beyond the other genome's own highest), D is the count of disjoint genes (innovation numbers within the overlapping range but present in only one genome), N is the larger genome's gene count (or 1 if both genomes have fewer than 20 connection genes – the original paper's own small-genome exception), and W_bar is the average weight difference over genes with matching innovation numbers (present in both genomes, regardless of enabled/disabled status).

Exceptions
std::invalid_argumentif either genome has zero connection genes.

◆ ComputeAdjustedFitness()

std::vector< double > pulsatrix::ComputeAdjustedFitness ( const std::vector< double > &  raw_fitness,
const std::vector< std::vector< size_t > > &  species 
)
inline

Fitness sharing: each individual's adjusted fitness is its own raw fitness divided by the size of its species – protects small, structurally novel species from being immediately out-competed by a large, already-optimized one.

Exceptions
std::invalid_argumentif raw_fitness's size doesn't match the total number of individuals named across every species (i.e. every population index must appear in exactly one species).

◆ ComputeAttributionStability()

StabilityResult pulsatrix::ComputeAttributionStability ( const std::vector< Attribution > &  repeated_runs)

Measures an explainer's stability across repeated runs on the same input (charter's "repeated-run variance measured and documented" audit category). Known-unstable methods (LIME, KernelSHAP) are expected to show is_deterministic == false; every other native/surrogate explainer in this codebase is deterministic by construction.

Parameters
repeated_runsTwo or more Attribution results from independent calls to the same explainer on the same input (varying only, e.g., a stochastic method's seed).
Exceptions
std::invalid_argumentif repeated_runs is empty, or if the runs' Attribution values do not all share the same element count – external boundary: the caller assembles this list from independent explainer invocations, not an internal invariant.

◆ ComputeConservation()

ConservationResult pulsatrix::ComputeConservation ( const Tensor &  relevance_in,
const Tensor &  relevance_out 
)

Sums relevance_in and relevance_out independently and reports their gap.

Parameters
relevance_inA module's propagate_relevance() input-side relevance tensor.
relevance_outThe same call's output-side relevance tensor.
Note
Deliberately does not call Module::propagate_relevance itself – the caller has already produced both tensors (from whichever module/config it used); this function is a pure summation over already-computed results, reusable regardless of which module type or LRP rule produced them.

◆ ComputeDoubleDQNTarget()

Tensor pulsatrix::ComputeDoubleDQNTarget ( const Tensor &  next_q_online,
const Tensor &  next_q_target,
const Tensor &  rewards,
const Tensor &  dones,
float  gamma,
DeviceBackend *  backend 
)

Double DQN Bellman target (van Hasselt et al. 2016, arXiv:1509.06461): a* = argmax_a next_q_online[b,a], then targets[b,0] = rewards[b,0] + gamma * (1 - dones[b,0]) * next_q_target[b, a*].

Vanilla DQN both selects and evaluates the next action with the same network, so any positive noise in a Q-estimate is systematically picked up by the max and propagated into the target – the well-documented overestimation bias. Double DQN decouples the two: the online network says which action looks best, the target network says what it is worth. The two only agree when the networks agree, and the divergence when they disagree is exactly the property this function exists for (and is directly tested against ComputeDQNTarget).

Parameters
next_q_onlineThe online network's Q-values for the next state, shape (N, action_dim) – used for action selection only.
next_q_targetThe target network's Q-values for the next state, same shape – used for evaluation only.
rewardsImmediate rewards, shape (N, 1).
donesEpisode-termination flags as 0.0f/1.0f floats, shape (N, 1).
gammaDiscount factor, in [0, 1].
backendBackend to allocate the result through. Not owned; must outlive the result.
Returns
The Bellman targets, shape (N, 1).
Exceptions
std::invalid_argumenton the same conditions as ComputeDQNTarget, plus if next_q_online and next_q_target have different shapes – external boundaries.
Note
Ties in next_q_online resolve to the lowest index, matching ComputeDQNTarget's own max scan and DQNAgent's argmax, so the three are consistent by construction.
A free function rather than a class or an enum-flagged variant of ComputeDQNTarget: it is a pure computation with no state to carry, and the extra next_q_online argument – not a mode flag – is the whole difference. Mission 1's training loop picks which of the two to call; nothing downstream needs to branch.

◆ ComputeDQNTarget()

Tensor pulsatrix::ComputeDQNTarget ( const Tensor &  next_q_target,
const Tensor &  rewards,
const Tensor &  dones,
float  gamma,
DeviceBackend *  backend 
)

Vanilla DQN Bellman target (Mnih et al. 2015): targets[b,0] = rewards[b,0] + gamma * (1 - dones[b,0]) * max_a next_q_target[b,a].

Parameters
next_q_targetThe target network's Q-values for the next state, shape (N, action_dim). Both the action selection (the max) and its evaluation come from this one tensor – which is precisely the coupling Double DQN breaks.
rewardsImmediate rewards, shape (N, 1).
donesEpisode-termination flags as 0.0f/1.0f floats, shape (N, 1) – ReplayBatch's own encoding, so a sampled batch feeds straight in.
gammaDiscount factor, in [0, 1].
backendBackend to allocate the result through. Not owned; must outlive the result. Passed explicitly because Tensor exposes no accessor for the backend it was built against, and this codebase's convention is an injected, non-owned DeviceBackend* rather than a global default.
Returns
The Bellman targets, shape (N, 1) – ready to hand straight to DQNLoss::forward().
Exceptions
std::invalid_argumentif next_q_target is not rank-2 with N >= 1 and action_dim >= 1, if rewards/dones are not (N, 1) for that same N, or if gamma is outside [0, 1] – all external boundaries.
Note
A dones[b,0] == 1 row zeroes the bootstrapped term exactly: a terminal state has no successor whose value could be backed up, so its target is the reward alone. This is a hard cut, not a heavy discount, and is tested as an exact equality.
dones is used as a plain multiplier, not thresholded – 0.0f/1.0f is the documented encoding, and silently reinterpreting anything else would hide a caller's bug.
Device-generic (GPU-native-kernels Mission 7): one DeviceBackend::rl_rows(DqnTarget) lane per transition (row argmax, ties to the lowest index) through backend, which must address the inputs' device; the result is allocated through it too.

◆ ComputeGAE()

GAEResult pulsatrix::ComputeGAE ( const Tensor &  rewards,
const Tensor &  dones,
const Tensor &  values,
float  bootstrap_value,
float  gamma,
float  lambda,
DeviceBackend *  backend 
)

Generalized Advantage Estimation (Schulman et al. 2016, arXiv:1506.02438): the exponentially-weighted average of k-step advantage estimators, computed in one reverse pass.

Per step:

  • delta[t] = rewards[t] + gamma * (1 - dones[t]) * V_next[t] - values[t], where V_next[t] = values[t+1] for t < N-1 and V_next[N-1] = bootstrap_value.
  • advantages[t] = delta[t] + gamma * lambda * (1 - dones[t]) * advantages[t+1], with advantages[N] := 0 (nothing exists past the end of the rollout).
  • returns[t] = advantages[t] + values[t].

lambda interpolates between the two ends of the bias/variance trade-off: lambda == 0 collapses the recursion to advantages[t] == delta[t], the single-step TD residual (low variance, biased by whatever the critic gets wrong); lambda == 1 accumulates every discounted residual to the end of the episode, which telescopes to the Monte-Carlo advantage sum gamma^k r - V(s_t) (unbiased, high variance). Both ends are directly tested.

Parameters
rewardsImmediate rewards, shape (N, 1).
donesEpisode-termination flags as 0.0f/1.0f floats, shape (N, 1) – the same encoding ReplayBatch and ComputeDQNTarget use.
valuesThe critic's value estimate V(s_t) for each stored step, shape (N, 1).
bootstrap_valueV of the state immediately following the last stored step. Supplied by the caller as a plain scalar rather than read from the buffer: RolloutBuffer stores no next_observation (unlike ReplayBuffer), and the training loop already holds that observation from its own most recent env.step(). Ignored in effect when the last step is terminal, since (1 - dones[N-1]) zeroes it exactly. Conventionally 0.0f when the rollout ends on a terminal step.
gammaDiscount factor, in [0, 1].
lambdaGAE trace-decay parameter, in [0, 1].
backendBackend to allocate the results through. Not owned; must outlive them. Passed explicitly for ComputeDQNTarget()'s reason: Tensor exposes no accessor for the backend it was built against, and this codebase injects a non-owned DeviceBackend* rather than consulting a global default.
Returns
The advantages and the critic's targets, both (N, 1).
Exceptions
std::invalid_argumentif rewards is not rank-2 (N, 1) with N >= 1, if dones or values is not (N, 1) for that same N, or if gamma or lambda is outside [0, 1] – all external boundaries.
Note
returns is advantages + values, not the raw discounted return-to-go RolloutBuffer::compute_returns() computes, and this function never calls that method: it consumes raw rewards/dones directly. The GAE identity is the whole point – regressing the critic onto A_t + V(s_t) keeps the critic's target consistent with the very advantage the actor is being updated with, at the same lambda. Feeding compute_returns()'s Monte-Carlo return instead would silently train the critic against a lambda == 1 target while the actor used a different one.
A dones[t] == 1 row cuts both the bootstrap and the trace recursion exactly – an advantage must not propagate backwards across a terminal state, the same hard cut (not heavy discount) RolloutBuffer::compute_returns()'s reset-at-done performs. The recurrence shape is that reverse pass's; the recurrence itself is different.
dones is used as a plain multiplier, not thresholded – 0.0f/1.0f is the documented encoding, and silently reinterpreting anything else would hide a caller's bug. Same convention as ComputeDQNTarget().
A free function rather than a class: a pure reduction with no state to carry, matching ComputeDQNTarget()/ComputeDoubleDQNTarget()'s own free-function precedent.
Host boundary (GPU-native-kernels Mission 7): a strictly sequential reverse recursion over one rollout. The inputs may live on any device – one device->host copy of each of rewards, dones and values per call – and both results are uploaded through backend.

◆ ComputeHeatmapColorScale()

HeatmapColorScale pulsatrix::ComputeHeatmapColorScale ( const HeatmapGrid &  grid)

Chooses a heatmap's color scale from its values (hc_information_visualization.md SS4: sequential maps for unsigned magnitude, diverging maps centred on the meaningful midpoint – zero – for signed quantities).

Returns
For an all-non-negative grid, [0, max] with is_signed == false. For a grid with any negative value, the symmetric range [-max|v|, +max|v|] with is_signed == true, so zero always lands on the diverging map's neutral midpoint and equal magnitudes of opposite sign get equal color intensity. A degenerate all-zero (or empty) grid returns [0, 1] rather than a zero-width range.

◆ ComputeHyperbandBrackets()

std::vector< HyperbandBracket > pulsatrix::ComputeHyperbandBrackets ( int  max_resource,
double  eta 
)
inline

Computes the classic Hyperband bracket schedule: s_max = floor(log_eta(max_resource)), B = (s_max + 1) * max_resource; for s from s_max down to 0, num_configs = ceil((B / max_resource) * (eta^s / (s + 1))), initial_budget = round(max_resource / eta^s) (each floored at 1).

Exceptions
std::invalid_argumentif max_resource <= 0 or eta <= 1.0.

◆ ComputeTruncationGroups()

PBTTruncationGroups pulsatrix::ComputeTruncationGroups ( const std::vector< double > &  metrics,
double  truncation_fraction 
)
inline

Pure core: identifies the bottom and top truncation_fraction of the population by metric (higher is better). Ties are broken by a stable sort on descending metric, so the earlier index among equal values sorts toward "top." At least one individual is always selected on each end, even if floor(size*fraction) would be 0.

Exceptions
std::invalid_argumentif metrics has fewer than 2 entries, or truncation_fraction is not in (0, 0.5].

◆ CrowdingDistance()

std::vector< double > pulsatrix::CrowdingDistance ( const std::vector< Objectives > &  front_objectives)
inline

Crowding distance within a single front.

Parameters
front_objectivesObjective vectors for exactly the individuals in one front (any order); the returned distances are indexed identically (distances[i] corresponds to front_objectives[i]), not by any global population index.
Exceptions
std::invalid_argumentif the objective vectors are not all the same size.
Note
Fronts of size 1 or 2: every individual is a boundary individual for every objective by construction – assigned infinity directly, no neighbor-gap computation.
Uses a stable sort per objective so that individuals sharing an identical value for that objective break ties in a fixed, reproducible order rather than an implementation- or input-order-dependent one.
If a front is uniform in some objective (max == min across the whole front), that objective contributes nothing to any individual's distance in this front (skipped outright) rather than dividing by a zero range.

◆ DecodeGenotype()

Configuration pulsatrix::DecodeGenotype ( const SearchSpace &  space,
const std::vector< double > &  genotype 
)
inline

Decodes a unit-hypercube genotype into a Configuration using space's own declared bounds: Continuous linearly, LogUniform geometrically (both identical to gp_bo.hpp's UnitCubeToConfiguration); Integer by linear interpolation then rounding to the nearest integer (std::round – ties away from zero, portable); Categorical by linear interpolation into an index, floored, clamped to the last category (handles the gene == 1.0 boundary, which would otherwise floor to one-past-the-end).

Exceptions
std::invalid_argumentif genotype.size() != space.size(), or any gene is outside [0, 1].

◆ DefaultCollate()

Batch pulsatrix::DefaultCollate ( std::vector< Sample >  samples,
DeviceBackend *  backend 
)

Stacks a list of samples into one Batch, field-by-field, via Tensor::Stack – pulsatrix's default CollateFn (PyTorch's default_collate analogue).

Parameters
samplesNon-empty list of samples, each with the same field count.
backendBackend to allocate stacked field tensors through.
Returns
A Batch with one stacked Tensor per field position.
Exceptions
std::invalid_argumentif samples is empty or samples have differing field counts – external boundary: the list of samples is assembled by a DataLoader from independently constructed Dataset::get() results, not a compile-time-known invariant. Per-field shape/device mismatches are reported by Tensor::Stack.

◆ deterministic()

bool pulsatrix::deterministic ( )

Whether deterministic mode is on.

◆ DivergingColormap()

RgbColor pulsatrix::DivergingColormap ( float  signed_normalized_value)

Blue-White-Red diverging colormap for signed attribution (positive/negative contribution) – hue encodes direction only, never magnitude (hc_information_visualization.md SS1's Cleveland-McGill rule: color hue is categorical/directional, magnitude must be position or length).

Parameters
signed_normalized_valuePosition along the colormap, expected in [-1, 1]; values outside this range are clamped to the nearest end anchor.

◆ DiversityFitness()

float pulsatrix::DiversityFitness ( Module &  discriminator,
const Tensor &  fake,
DeviceBackend *  backend 
)
inline

E-GAN's own diversity fitness Fd = -log(||grad||): the negative log of the L2 norm of the discriminator's own parameter gradient from its fake-recognition loss term (BCEWithLogitsLoss(D(fake), 0)), evaluated on fake. A smaller discriminator gradient here means the discriminator is already close to a local optimum against these particular samples – the paper's own signal that this offspring is contributing mode coverage the discriminator can't easily exploit further (discourages mode collapse).

Note
This function's own backward() pass is a fitness-evaluation probe, not a real training step – its gradient accumulates into discriminator's own parameter-gradient buffers exactly like any other backward() call would, and the caller must zero_grad discriminator's optimizer immediately after calling this function, every time (the same gradient-contamination discipline BCEWithLogitsLoss's own
Warning
already establishes for the generator step).
Exceptions
std::invalid_argumentif discriminator has no parameters.

◆ Dominates()

bool pulsatrix::Dominates ( const Objectives &  a,
const Objectives &  b 
)
inline

Pareto dominance (maximization convention): a dominates b iff a[i] >= b[i] for every objective i, and a[i] > b[i] for at least one objective.

Exceptions
std::invalid_argumentif a.size() != b.size().

◆ ESStep()

template<typename FitnessFn , typename RNG >
std::vector< double > pulsatrix::ESStep ( const std::vector< double > &  theta,
FitnessFn  fitness_fn,
int  population_size,
double  sigma,
double  alpha,
RNG &  rng 
)

RNG-driven wrapper: samples population_size/2 standard-normal perturbation vectors, scores theta+sigma*epsilon and theta-sigma*epsilon for each (mirrored sampling), and returns the updated theta via ESUpdateGivenPerturbations.

Exceptions
std::invalid_argumentif population_size is not a positive even number, or sigma is not positive.

◆ ESUpdateGivenPerturbations()

std::vector< double > pulsatrix::ESUpdateGivenPerturbations ( const std::vector< double > &  theta,
const std::vector< std::vector< double > > &  epsilons,
const std::vector< double > &  fitnesses,
double  alpha,
double  sigma 
)
inline

Pure core: the exact ES parameter update given already-sampled perturbations and their fitness scores – ‘theta’ = theta + (alpha / (N*sigma)) * sum_i(F_i * epsilon_i)`.

Exceptions
std::invalid_argumentif epsilons is empty, epsilons.size() != fitnesses.size(), any epsilon's dimension doesn't match theta's, or sigma is not positive.

◆ EvaluateNEATPhenotype()

std::vector< double > pulsatrix::EvaluateNEATPhenotype ( const NEATGenome &  genome,
const std::vector< double > &  inputs 
)
inline

Evaluates genome's phenotype forward pass on inputs (one value per Input node, ordered by ascending node ID; the Bias node, if present, is always implicitly 1.0 and is not part of inputs).

Returns
One value per Output node, ordered by ascending node ID.
Exceptions
std::invalid_argumentif inputs.size() doesn't match the genome's own number of Input nodes.
Note
Recursive, memoized evaluation over the genome's connection graph – safe against infinite recursion only because every genome constructed via NEATGenome's own public API (AddConnection's cycle check) is guaranteed acyclic; this function trusts that invariant rather than re-checking it, the same "pure core trusts its caller" division of responsibility used throughout this campaign.

◆ EvaluatePopulation()

template<typename Genotype , typename FitnessT , typename FitnessFn >
void pulsatrix::EvaluatePopulation ( std::vector< Individual< Genotype, FitnessT > > &  population,
FitnessFn &  fitness_fn,
DataThreadPool *  thread_pool 
)

Evaluates (or re-evaluates) every individual's fitness in place via fitness_fn.

Parameters
thread_poolIf non-null, each individual's fitness is submitted as an independent task; if null, evaluation runs sequentially on the calling thread. fitness_fn must be safely callable concurrently from multiple threads when a thread_pool is supplied (an ordinary pure function of its genotype argument, per this project's explainer-layer functional-purity convention, satisfies this trivially).

◆ ExpectedImprovement()

double pulsatrix::ExpectedImprovement ( double  mean,
double  variance,
double  best_value,
double  xi = 0.01 
)
inline

Expected Improvement: the expected amount by which a candidate exceeds best_value + xi, under the posterior N(mean, variance).

Parameters
variancePosterior variance (not standard deviation) – must be non-negative.
xiSmall exploration margin (default 0.01, a common practical default – without it, EI can collapse to pure exploitation once the posterior mean exceeds best_value by even a negligible amount).
Exceptions
std::invalid_argumentif variance < 0.
Note
If sigma (sqrt(variance)) is ~0 (a point the GP is fully confident about, e.g. exactly an already-observed point), EI is defined as exactly 0 – no uncertainty means no potential for improvement beyond what standard credit already reflects.

◆ ExploreConfiguration()

template<typename RNG >
Configuration pulsatrix::ExploreConfiguration ( const Configuration &  config,
const SearchSpace &  space,
RNG &  rng 
)

RNG-driven wrapper: draws each non-categorical parameter's factor uniformly from {0.8, 1.2} (Jaderberg et al.'s own standard explore perturbation), then applies ExploreConfigurationGivenFactors.

◆ ExploreConfigurationGivenFactors()

Configuration pulsatrix::ExploreConfigurationGivenFactors ( const Configuration &  config,
const SearchSpace &  space,
const std::map< std::string, double > &  factors 
)
inline

Pure core: applies an explicit per-parameter multiplicative factor to every Continuous/LogUniform/Integer parameter in config, clamped to that parameter's own bounds – PBT's own "explore" step (Jaderberg et al.'s own simple perturbation: multiply by 0.8 or 1.2). Categorical parameters are left unchanged (explore, in its original form, perturbs numeric hyperparameters only – a deliberate, logged scope decision, not an oversight). Integer results are rounded to the nearest integer.

Exceptions
std::invalid_argumentif config is missing a value for any parameter in space, or factors is missing an entry for any non-categorical parameter in space.

◆ FastNonDominatedSort()

std::vector< std::vector< size_t > > pulsatrix::FastNonDominatedSort ( const std::vector< Objectives > &  objectives)
inline

Fast non-dominated sort (Deb et al. 2002, Algorithm: fast-non-dominated-sort): partitions [0, objectives.size()) into fronts – front 0 is the non-dominated set, front 1 is non-dominated after removing front 0, and so on.

Exceptions
std::invalid_argument– propagated from Dominates if objective vectors have inconsistent sizes.

◆ fit_weighted_linear_regression()

std::vector< float > pulsatrix::fit_weighted_linear_regression ( const std::vector< std::vector< float > > &  samples,
const std::vector< float > &  targets,
const std::vector< float > &  weights,
float  l2_lambda 
)
inline

Fits w* = argmin_w sum_i weight_i*(target_i - w^T sample_i)^2 + l2_lambda*||w||^2 via the normal equations (X^T W X + l2_lambda*I) w = X^T W y.

Parameters
samplesEach row is one sample's feature vector; every row must be the same length.
targetsOne target value per sample. Must match samples.size().
weightsOne non-negative weight per sample. Must match samples.size().
l2_lambdaRidge regularization strength. 0 = ordinary weighted least squares.
Returns
Coefficients, one per feature (no intercept – callers that need one center their targets/samples around a reference point first, e.g. LIME's local-model convention).
Exceptions
std::runtime_errorif the normal-equations system is near-singular (e.g. degenerate/collinear samples).
std::invalid_argumentif samples is empty, or targets/weights/any sample row's length doesn't match – external boundary ( campaign_exai_dl_library_adversarial_hardening.md, Mission 2, finding 15 systemic sweep). Escalated from PULSATRIX_ASSERT-only for consistency with this function's own near-singular-system check above, which already throws.
Note
Gaussian elimination, scoped to the small, dense, well-conditioned systems this codebase's explainers actually produce – not a general-purpose numerics library.

◆ FixedTopologyXORFitness()

double pulsatrix::FixedTopologyXORFitness ( const std::vector< double > &  theta)
inline

Scores theta against all four XOR patterns as 4.0 minus the sum of squared errors – identical convention to XORFitness (neat_xor_fitness.hpp), so an all-zero theta scores exactly 3.0 (every pattern outputs sigmoid(0)=0.5), the same fixed point NEAT's own fresh, all-zero-weight genome scores.

◆ FixedTopologyXORForward()

double pulsatrix::FixedTopologyXORForward ( const std::vector< double > &  theta,
const std::array< double, 2 > &  inputs 
)
inline

Forward pass: theta layout is [w1_00, w1_01, b1_0, w1_10, w1_11, b1_1, w2_0, w2_1, b2] – h_j = sigmoid(w1_j0*x0 + w1_j1*x1 + b1_j) for j in {0,1}, y = sigmoid(w2_0*h0 + w2_1*h1 + b2).

Exceptions
std::invalid_argumentif theta.size() != kFixedTopologyXORNumParams.

◆ FlattenParameters()

std::vector< float > pulsatrix::FlattenParameters ( Module &  module)
inline

Flattens every parameter tensor module.parameters() reports (in that order) into one vector – the concrete mechanism Phase 5 Mission 2's mutation-offspring construction uses to copy a parent generator's current weights into a freshly-constructed (architecturally identical) offspring instance before mutating the copy.

◆ format_iso8601_utc()

std::string pulsatrix::format_iso8601_utc ( std::chrono::system_clock::time_point  tp)

Formats tp as ISO-8601 UTC with milliseconds, e.g. "2026-10-02T12:34:56.789Z".

◆ GaussianKdeDensity()

double pulsatrix::GaussianKdeDensity ( const std::vector< double > &  observations,
double  bandwidth,
double  x 
)
inline

Fixed-bandwidth Gaussian KDE: density(x) = mean over every observation o of N(x; o, bandwidth^2).

Exceptions
std::invalid_argumentif observations is empty or bandwidth <= 0.

◆ GaussianMutation()

template<typename RNG >
std::vector< double > pulsatrix::GaussianMutation ( const std::vector< double > &  genotype,
double  sigma,
double  mutation_probability,
RNG &  rng 
)

RNG-driven wrapper: each gene independently receives N(0, sigma^2) noise with probability mutation_probability.

Exceptions
std::invalid_argumentif sigma is negative or mutation_probability is outside [0, 1].
Note
mutation_probability == 0.0 leaves the genotype unchanged exactly (mask always false); sigma == 0.0 with mutation_probability == 1.0 also leaves it unchanged exactly (every draw from N(0, 0) is exactly 0.0) – two independent, RNG-stream- -independent correctness cases.

◆ GaussianMutationByNoise()

std::vector< double > pulsatrix::GaussianMutationByNoise ( const std::vector< double > &  genotype,
const std::vector< double > &  noise,
const std::vector< bool > &  apply_mask 
)
inline

Adds noise[i] to genotype[i] wherever apply_mask[i] is true, leaves the rest unchanged.

Exceptions
std::invalid_argumentif genotype/noise/apply_mask sizes are not all equal.

◆ GeneratePooledFakeSamples()

Tensor pulsatrix::GeneratePooledFakeSamples ( GeneratorPopulation &  population,
const std::vector< Tensor > &  noise_per_generator,
DeviceBackend *  backend 
)
inline

Runs every population member's generator forward on its own noise batch (noise_per_generator[i] for population member i), then pools the results (Tensor::Stack, concatenated along the batch dimension, in population order) into one combined fake-sample batch – the discriminator's own training input in E-GAN.

Exceptions
std::invalid_argumentif noise_per_generator.size() != population.size() (delegates to each generator's own forward() and to Tensor::Stack for their own preconditions).

◆ GenerationalReplacement()

template<typename Genotype , typename FitnessT >
std::vector< Individual< Genotype, FitnessT > > pulsatrix::GenerationalReplacement ( const std::vector< Individual< Genotype, FitnessT > > &  ,
std::vector< Individual< Genotype, FitnessT > >  offspring,
size_t  mu 
)

Generational replacement (DEAP's eaSimple): the offspring pool becomes the entire next generation; population is ignored (parents never survive).

Exceptions
std::invalid_argumentif offspring.size() != mu.

◆ global_seed()

uint64_t pulsatrix::global_seed ( )

The seed most recently passed to set_seed() (0 by default).

◆ GridSample()

std::vector< Configuration > pulsatrix::GridSample ( const SearchSpace &  space,
size_t  points_per_continuous_dimension 
)
inline

Enumerates the full cartesian-product grid over space.

Parameters
points_per_continuous_dimensionNumber of points (inclusive of both bounds) used for every Continuous (linearly spaced) and LogUniform (log-spaced) parameter. Integer parameters always enumerate every integer in [lower, upper]; Categorical parameters always enumerate every category – neither is affected by this parameter.
Exceptions
std::invalid_argumentif points_per_continuous_dimension < 2 (fewer than 2 points cannot include both bounds).
Note
Grid size is the product of every parameter's own point count – grows combinatorially with both the number of parameters and points_per_continuous_dimension; the caller's responsibility to keep the search space small enough for grid search specifically (this is grid search's own well-known scaling limit, not a bug).

◆ LogDensityRatio()

double pulsatrix::LogDensityRatio ( const SearchSpace &  space,
const Configuration &  candidate,
const std::vector< Configuration > &  good_configs,
const std::vector< Configuration > &  bad_configs 
)
inline

log(l(candidate)) - log(g(candidate)): the TPE scoring function, summed independently over every parameter in space (so a candidate's mixed continuous/categorical parameters each contribute their own term, composing naturally rather than needing a joint density over the whole space).

Parameters
good_configs,bad_configsObserved configurations split by objective quantile (RunTPELoop's own job); every config must contain every parameter named in space.
Exceptions
std::invalid_argumentif good_configs or bad_configs is empty.
Note
Per-parameter bandwidth for Continuous is 0.2 * (upper - lower); for LogUniform, 0.2 * (log(upper) - log(lower)), applied after taking the log of both the bandwidth basis and every observed/candidate value (consistent with this campaign's own established log-space convention for LogUniform elsewhere – GridSample/RandomSample/ UnitCubeToConfiguration); for Integer, 0.2 * (upper - lower), floored at 1.0 (a sub-1.0 bandwidth over integer-valued data would make the KDE unreasonably peaked).

◆ lrp_rule_name()

std::string pulsatrix::lrp_rule_name ( LRPRule  rule)
inline

Lower-case rule name ("epsilon", "gamma", "alpha_beta", "zbox") for messages/metadata.

◆ MuCommaLambdaReplacement()

template<typename Genotype , typename FitnessT >
std::vector< Individual< Genotype, FitnessT > > pulsatrix::MuCommaLambdaReplacement ( const std::vector< Individual< Genotype, FitnessT > > &  ,
std::vector< Individual< Genotype, FitnessT > >  offspring,
size_t  mu 
)

(mu,lambda) replacement: the next generation is the fittest mu individuals from offspring only (population/parents are always discarded) – more explorative than (mu+lambda), since it cannot get stuck re-selecting the same elite parent forever.

Exceptions
std::invalid_argumentif offspring.size() < mu.

◆ MuPlusLambdaReplacement()

template<typename Genotype , typename FitnessT >
std::vector< Individual< Genotype, FitnessT > > pulsatrix::MuPlusLambdaReplacement ( const std::vector< Individual< Genotype, FitnessT > > &  population,
std::vector< Individual< Genotype, FitnessT > >  offspring,
size_t  mu 
)

(mu+lambda) replacement: the next generation is the fittest mu individuals from population union offspring (parents may survive) – more exploitative than (mu,lambda), since a fit parent is never discarded just for being old.

Exceptions
std::invalid_argumentif population.size() + offspring.size() < mu.

◆ next_seed()

uint64_t pulsatrix::next_seed ( )

The next seed in the global stream: a distinct, well-mixed 64-bit value per call, reproducible for a given global seed. Components built without an explicit seed take theirs from here, so two of them never share a random stream by accident.

◆ NormalizeSigned()

float pulsatrix::NormalizeSigned ( float  value,
float  max_abs 
)

Normalizes value into [-1, 1] against a known maximum absolute magnitude, for signed quantities such as attribution direction (positive/negative contribution).

Parameters
valueThe raw value to normalize. Values outside [-max_abs, max_abs] are clamped.
max_absThe absolute value that should map to +/-1.0. If 0, returns 0.0 rather than dividing by zero.

◆ NormalizeUnsigned()

float pulsatrix::NormalizeUnsigned ( float  value,
float  max_abs 
)

Normalizes value into [0, 1] against a known maximum magnitude, for unsigned (magnitude-only) quantities such as saliency intensity or ablation effect.

Parameters
valueThe raw value to normalize. Values outside [0, max_abs] are clamped.
max_absThe value that should map to 1.0. If 0 (a degenerate all-zero series), returns 0.0 rather than dividing by zero.

◆ NSGA2Replacement()

template<typename Genotype >
std::vector< Individual< Genotype, Objectives > > pulsatrix::NSGA2Replacement ( const std::vector< Individual< Genotype, Objectives > > &  population,
std::vector< Individual< Genotype, Objectives > >  offspring,
size_t  mu 
)

NSGA-II survivor selection: combines population and offspring, fast-non-dominated- sorts the pool, includes whole fronts (best first) until the next front would overflow mu, then fills the remainder from that final front by crowding distance (largest first – more diverse/isolated solutions preferred).

Exceptions
std::invalid_argumentif population.size() + offspring.size() < mu.
Note
Same (population, offspring, mu) -> next-generation-population signature as GenerationalReplacement/MuPlusLambdaReplacement/MuCommaLambdaReplacement (survivor_selection.hpp) – directly usable as RunEvolutionaryLoop's SurvivorFn.

◆ OnePointCrossover()

template<typename T , typename RNG >
std::pair< std::vector< T >, std::vector< T > > pulsatrix::OnePointCrossover ( const std::vector< T > &  parent1,
const std::vector< T > &  parent2,
RNG &  rng 
)

RNG-driven wrapper: draws an interior point in [1, size-1] uniformly.

Exceptions
std::invalid_argumentif parent sizes differ or parent size < 2 (no interior point exists to draw).

◆ OnePointCrossoverAtPoint()

template<typename T >
std::pair< std::vector< T >, std::vector< T > > pulsatrix::OnePointCrossoverAtPoint ( const std::vector< T > &  parent1,
const std::vector< T > &  parent2,
size_t  point 
)

Splits both parents at point and swaps tails.

Exceptions
std::invalid_argumentif parent sizes differ or point > parent1.size().
Note
point == 0 or point == size() are valid (degenerate, fully-swapped/no-swap) cases – this pure core does not restrict to "interior" points; OnePointCrossover (the RNG wrapper, below) does, since a degenerate point is never a useful recombination.

◆ PadCollate()

CollateFn pulsatrix::PadCollate ( float  pad_index = 0.0f)

Builds a CollateFn that right-pads variable-length token sequences (sample.fields[0], shape (1, seq_len) – TextDataset::get()'s output) to the batch's own max length, producing one (N, max_len) Tensor, plus a (N,) length field recording each sample's real (pre-padding) length. This is the CollateFn extension point Phase 1's architecture design reserved for ragged/variable-length modalities (PyTorch's collate_fn equivalent) – exercised here for the first time, with zero changes needed to Dataset/DataLoader/Batch themselves.

Parameters
pad_indexValue used to fill padding positions (as a float, matching Decision Point 6's token-as-float32 representation). Defaults to 0 – note this numerically collides with <unk>'s reserved index; a consumer that needs to distinguish real <unk> tokens from padding must use the length field, not the token value itself, to locate padding positions.
Returns
A CollateFn producing Batch{ {padded_tokens (N,max_len), lengths (N,)} }.
Exceptions
std::invalid_argument(from the returned CollateFn, at call time) if samples is empty – matching DefaultCollate's own external-boundary convention.

◆ PolyakUpdate()

void pulsatrix::PolyakUpdate ( Module &  source,
Module &  destination,
float  tau 
)

Soft target-network update (Lillicrap et al. 2016 / Haarnoja et al. 2018): destination_param[i] = tau * source_param[i] + (1 - tau) * destination_param[i], element-wise and in place.

A genuinely different mechanism from SyncTargetNetwork's hard periodic copy, not a rename of it. The hard copy leaves the target network frozen for k steps and then moves it a long way at once; this moves it a little on every step, which is what the off-policy actor-critic algorithms (DDPG/TD3/SAC) depend on for a slowly-drifting bootstrapping target. Both are shipped, neither supersedes the other, and tau is not a flag bolted onto the existing function – the formula, not a mode, is the difference.

Parameters
sourceNetwork to blend parameter values from – typically the online network.
destinationNetwork to blend into – typically the target network.
tauBlending coefficient, in (0, 1]. tau near 0 (SAC's usual 0.005) means the target barely moves per step; tau == 1 degenerates to exactly SyncTargetNetwork's hard copy, which is legal (and directly cross-checked in the tests) though an unusual choice for a soft update.
Exceptions
std::invalid_argumentif tau is not in (0, 1] – external boundary. tau == 0 is rejected rather than accepted as a no-op: a target network that provably never moves is a real caller error (typically an uninitialized hyperparameter), and silently doing nothing forever is the worst possible way to report it. NaN is rejected by the same check.
std::invalid_argumentif the two networks expose a different number of parameters, or if any parameter pair's shapes differ, naming the offending index and shapes – the identical validation SyncTargetNetwork performs, deliberately not weakened. Two independently-constructed networks genuinely can have mismatched architectures, and a silent partial blend would leave the target network quietly wrong for the rest of training. A rejected update leaves the offending parameter untouched.
Note
The blend writes element-wise into destination's existing parameter buffers, never replacing its Tensor objects – the same discipline SyncTargetNetwork established. destination's parameters must remain the same objects its own parameters() (and any optimizer already holding ParamRefs into it) point at. Replacing the Tensors would dangle every outstanding ParamRef. Doubly load-bearing here: a soft update reads the destination's current value as an input, so it is the one place where the destination's buffer identity across successive calls is what makes the exponential moving average an average at all.
Gradients are untouched. This is a pure value blend and has nothing to do with zero_grad(); a target network is never backpropagated through.
Device-generic (GPU-native-kernels Mission 7): one DeviceBackend::rl_rows(PolyakBlend) pass per parameter through the destination parameter's own backend, evaluating tau * source + (1 - tau) * destination per element exactly as the original host loop did. A source parameter on a different device is staged onto the destination's first.

◆ PolynomialMutation()

template<typename RNG >
std::vector< double > pulsatrix::PolynomialMutation ( const std::vector< double > &  genotype,
const std::vector< double > &  lower_bounds,
const std::vector< double > &  upper_bounds,
double  eta,
double  mutation_probability,
RNG &  rng 
)

RNG-driven wrapper: each gene independently mutates (via PolynomialMutationByDraw) with probability mutation_probability.

Exceptions
std::invalid_argumentif genotype/lower_bounds/upper_bounds sizes are not all equal, or mutation_probability is outside [0, 1] – per-gene bound/eta validity is enforced by PolynomialMutationByDraw itself.

◆ PolynomialMutationByDraw()

double pulsatrix::PolynomialMutationByDraw ( double  x,
double  lower,
double  upper,
double  eta,
double  u 
)
inline

Polynomial-mutates a single bounded gene given an explicit draw.

Parameters
xCurrent gene value, must be in [lower, upper].
lowerLower bound (must be strictly less than upper).
upperUpper bound.
etaDistribution index (non-negative; larger values concentrate mutations closer to x).
uDraw in [0, 1].
Returns
The mutated, bound-clipped gene value.
Exceptions
std::invalid_argumentif lower >= upper, x is outside [lower, upper], eta is negative, or u is outside [0, 1].
Note
Three draw values give exact, eta-independent results, all algebraically derivable from the formula: u == 0 -> exactly lower; u == 0.5 -> exactly x (unchanged); u == 1 -> exactly upper. Unlike SimulatedBinaryCrossoverByDraw, this formula has no 1/(1-u) term, so u == 1 is a valid, safe draw here (not excluded).

◆ PowerIteration()

DominantEigenResult pulsatrix::PowerIteration ( const Tensor &  a,
int64_t  max_iterations = 1000,
float  tolerance = 1e-6f,
uint64_t  seed = 0 
)

The dominant eigenpair of a symmetric matrix by power iteration – cheaper than SymmetricEigen() when only the top eigenpair is needed (spectral norm, stable rank).

Parameters
aSquare symmetric (n, n) CPU tensor, all finite.
max_iterationsIteration budget; must be >= 1.
toleranceConverged when successive unit vectors differ (up to sign) by at most this.
seedSeeds the deterministic LCG that draws the starting vector.
Note
Converges at the rate |lambda2 / lambda1|. When the two largest eigenvalues tie in magnitude (e.g. +1 and -1) the dominant vector is not unique: the iteration does not settle and the result reports converged = false rather than an arbitrary answer.
Exceptions
std::invalid_argumentfor the same inputs SymmetricEigen() rejects, a max_iterations below 1, or a tolerance that is not positive.

◆ ProbabilityOfImprovement()

double pulsatrix::ProbabilityOfImprovement ( double  mean,
double  variance,
double  best_value,
double  xi = 0.01 
)
inline

Probability of Improvement: P(candidate's value > best_value + xi) under the posterior N(mean, variance).

Exceptions
std::invalid_argumentif variance < 0.
Note
If sigma is ~0, PI is defined as the degenerate limit: 1 if mean already exceeds best_value + xi, else 0.

◆ QR()

QRResult pulsatrix::QR ( const Tensor &  a)

Thin QR factorization by Householder reflections.

Parameters
a(m, n) CPU tensor with m >= n, all finite. Rank-deficient input is fine.
Exceptions
std::invalid_argumentif a is not rank 2, is wide (m < n), is not on the CPU, or has a non-finite entry.

◆ QualityFitness()

float pulsatrix::QualityFitness ( const Tensor &  logits)
inline

E-GAN's own quality fitness Fq: mean sigmoid(D(fake)) over the batch – how convincingly "real" the discriminator currently rates these samples. Higher is better (the discriminator being fooled more).

◆ RandomSample()

template<typename RNG >
Configuration pulsatrix::RandomSample ( const SearchSpace &  space,
RNG &  rng 
)

Draws one configuration uniformly at random from space: Continuous parameters uniform over [lower, upper]; LogUniform parameters uniform in log-space (so e.g. [0.001, 1.0] gives 0.001-0.01, 0.01-0.1, and 0.1-1.0 equal probability, not the top decade 90% of the draws); Integer parameters uniform over the inclusive integer range; Categorical parameters uniform over the category list.

◆ RankSelect()

template<typename Genotype , typename FitnessT , typename RNG >
size_t pulsatrix::RankSelect ( const std::vector< Individual< Genotype, FitnessT > > &  population,
RNG &  rng 
)

RNG-driven wrapper around RankSelectByDraw: draws uniformly from [0, total_weight) and selects accordingly.

Exceptions
std::invalid_argument– see RankSelectByDraw.

◆ RankSelectByDraw()

template<typename Genotype , typename FitnessT >
size_t pulsatrix::RankSelectByDraw ( const std::vector< Individual< Genotype, FitnessT > > &  population,
double  draw 
)

Linear-rank selection given an explicit draw in [0, total_weight). Individuals are ranked ascending by fitness (worst = rank 1, best = rank population.size()); each rank's selection weight equals its rank, so the best individual is population.size() times as likely to be drawn as the worst. Pure and deterministic – the hand-testable core RankSelect wraps with an RNG-generated draw.

Parameters
populationNon-empty population.
drawA value in [0, total_weight), where total_weight = n*(n+1)/2 for n individuals.
Returns
Index into population of the individual occupying the drawn rank.
Exceptions
std::invalid_argumentif population is empty or draw is outside [0, total_weight).

◆ ReproduceOffspring()

template<typename RNG >
NEATGenome pulsatrix::ReproduceOffspring ( const NEATGenome &  parent,
InnovationTracker &  tracker,
RNG &  rng,
double  weight_mutation_sigma,
double  weight_mutation_probability,
double  add_connection_probability,
double  add_node_probability 
)

RNG-driven wrapper: clones parent, then applies weight mutation (gated per-connection by weight_mutation_probability inside MutateWeights itself) and, independently, one attempt each at the two structural mutations, each gated by its own probability.

◆ require_device()

void pulsatrix::require_device ( const Tensor &  t,
DeviceType  expected,
const char *  where 
)
inline

Throws unless t lives on expected – the check every module and loss runs on the tensors handed to it (roadmap FND-8, gpu_review #1).

Parameters
whereNames the entry point in the error message, e.g. "LinearModule::backward".
Exceptions
std::invalid_argumenton a mismatch. Without it, a CPU tensor reaching a GPU kernel is an uncatchable memory fault (HSA abort on gfx1151, a sticky CUDA error), and a GPU tensor reaching the CPU backend segfaults.

◆ RestoreParameters()

void pulsatrix::RestoreParameters ( Module &  module,
const std::vector< float > &  flat 
)
inline

Overwrites every parameter tensor module.parameters() reports (in that order) from flat – the inverse of FlattenParameters.

Exceptions
std::invalid_argumentif flat's size doesn't exactly match the total parameter count module.parameters() reports.

◆ RouletteSelect()

template<typename Genotype , typename FitnessT , typename RNG >
size_t pulsatrix::RouletteSelect ( const std::vector< Individual< Genotype, FitnessT > > &  population,
RNG &  rng 
)

RNG-driven wrapper around RouletteSelectByDraw: draws uniformly from [0, total_fitness) and selects accordingly.

Exceptions
std::invalid_argument– see RouletteSelectByDraw (validation happens there; this wrapper adds no separate checks so the two never disagree on what is malformed).

◆ RouletteSelectByDraw()

template<typename Genotype , typename FitnessT >
size_t pulsatrix::RouletteSelectByDraw ( const std::vector< Individual< Genotype, FitnessT > > &  population,
FitnessT  draw 
)

Fitness-proportionate ("roulette wheel") selection given an explicit draw in [0, total_fitness). Pure and deterministic – the hand-testable core RouletteSelect wraps with an RNG-generated draw.

Parameters
populationNon-empty population with strictly non-negative fitness values summing to a strictly positive total.
drawA value in [0, total_fitness), where total_fitness = sum of population fitness.
Returns
Index into population whose cumulative-fitness bucket contains draw.
Exceptions
std::invalid_argumentif population is empty, any fitness is negative, the total fitness is not strictly positive, or draw is outside [0, total_fitness).

◆ RunASHA()

template<typename RNG >
ASHAResult pulsatrix::RunASHA ( const SearchSpace &  space,
const TrialFactory &  make_trial,
size_t  max_configs_started,
int  initial_epoch_budget,
double  eta,
int  num_rungs,
RNG &  rng 
)

RNG-driven wrapper: draws max_configs_started configurations from space via RandomSample to serve as the queue, then runs RunASHAOnConfigQueue.

Exceptions
std::invalid_argumentif max_configs_started == 0.

◆ RunASHAOnConfigQueue()

ASHAResult pulsatrix::RunASHAOnConfigQueue ( std::vector< Configuration >  config_queue,
const TrialFactory &  make_trial,
int  initial_epoch_budget,
double  eta,
int  num_rungs 
)
inline

Runs ASHA, drawing new configurations from an explicit, ordered queue (rather than sampling indefinitely) – the pure, deterministic core; RunASHA (below) is the thin SearchSpace/RNG-sampling wrapper around it.

Parameters
initial_epoch_budgetRung 0's epoch budget; rung k's budget is initial_epoch_budget * eta^k.
num_rungsTotal number of rungs (>= 2 – at least one promotion opportunity must exist).
Note
Each step does exactly one of: (a) promote the single best-qualifying candidate at the highest rung with a promotable candidate (scanned top-down, so nearly-finished candidates are preferred over starting fresh ones – ASHA's own stated preference), or (b) if no promotion is possible, start the next queued configuration at rung 0. A rung only becomes eligible for promotion decisions once at least eta candidates have completed it (not enough data to identify a meaningful top fraction before that).
Exceptions
std::invalid_argumentif config_queue is empty, initial_epoch_budget <= 0, eta <= 1.0, or num_rungs < 2.

◆ RunEGANGeneration()

template<typename MakeGenerator , typename DOptimizerT >
std::vector< float > pulsatrix::RunEGANGeneration ( GeneratorPopulation &  population,
Module &  discriminator,
const Tensor &  real_batch,
const std::vector< Tensor > &  noise_per_generator,
const std::vector< MutationObjective > &  objectives,
MakeGenerator  make_generator,
float  g_learning_rate,
DOptimizerT &  d_optimizer,
DeviceBackend *  backend,
float  gamma = 0.05f 
)

Runs one E-GAN generation: for every population member, attempts every objective in objectives (each against a fresh weight-copy offspring built by make_generator + RestoreParameters), keeps the best-combined-fitness offspring, replaces that population slot with it, then trains discriminator on real_batch plus the now-mutated population's own pooled fake output.

Parameters
make_generatorConstructs a fresh generator instance with the same architecture as every population member.
g_learning_rateLearning rate for the SGDOptimizer each mutation attempt trains with.
Returns
Each population member's own winning objective's fitness, in population order.
Exceptions
std::invalid_argumentif noise_per_generator.size() != population.size(), or objectives is empty.

◆ RunEGANTraining()

template<typename MakeGenerator , typename DOptimizerT , typename RNG >
void pulsatrix::RunEGANTraining ( GeneratorPopulation &  population,
Module &  discriminator,
const Tensor &  real_batch,
int  num_generations,
int64_t  noise_dim,
int64_t  per_generator_batch,
const std::vector< MutationObjective > &  objectives,
MakeGenerator  make_generator,
float  g_learning_rate,
DOptimizerT &  d_optimizer,
DeviceBackend *  backend,
RNG &  rng,
float  gamma = 0.05f 
)

RNG-driven wrapper: draws fresh standard-normal noise for every population member every generation, then runs RunEGANGeneration num_generations times.

Exceptions
std::invalid_argumentif num_generations is not positive (delegates to RunEGANGeneration for its own preconditions each generation).

◆ RunEvolutionaryLoop()

template<typename Genotype , typename FitnessT , typename FitnessFn , typename OffspringFn , typename SurvivorFn >
std::vector< Individual< Genotype, FitnessT > > pulsatrix::RunEvolutionaryLoop ( std::vector< Individual< Genotype, FitnessT > >  population,
size_t  num_generations,
size_t  lambda_size,
FitnessFn  fitness_fn,
OffspringFn  produce_offspring_genotype,
SurvivorFn  survivor_selector,
DataThreadPool *  thread_pool = nullptr 
)

Runs num_generations of the shared evolutionary-loop skeleton: evaluate -> produce lambda_size offspring (via produce_offspring_genotype, called once per offspring) -> evaluate offspring -> survivor-select mu individuals for the next generation.

Parameters
populationInitial population (its own fitness values are (re-)computed, not trusted, before the loop begins). mu = population.size().
produce_offspring_genotypeCallable Genotype(const std::vector<Individual<Genotype, FitnessT>>& current_population) – composes whichever selection + crossover + mutation recipe the caller wants; called once per offspring needed.
survivor_selectorCallable std::vector<Individual<Genotype, FitnessT>>(const std::vector<Individual<Genotype, FitnessT>>& population, std::vector<Individual<Genotype, FitnessT>> offspring, size_t mu) – pass GenerationalReplacement, MuPlusLambdaReplacement, or MuCommaLambdaReplacement (survivor_selection.hpp) directly, or any compatible callable.
thread_poolOptional – see EvaluatePopulation.
Returns
The final generation's population (fitness values populated).

◆ RunEvolutionStrategies()

template<typename FitnessFn , typename RNG >
ESResult pulsatrix::RunEvolutionStrategies ( std::vector< double >  theta,
FitnessFn  fitness_fn,
int  num_iterations,
int  population_size,
double  sigma,
double  alpha,
RNG &  rng 
)

Runs num_iterations of Evolution Strategies starting from theta, tracking the best (theta, fitness) pair seen across every evaluated center point (global elitism, the same precedent this campaign's NEAT evolutionary loop already established) – vanilla ES itself has no such tracking, but a returnable "best point found" is genuinely necessary for this to be usable as an optimizer, so it is added here as a small, logged addition beyond the paper's own bare update rule.

Exceptions
std::invalid_argumentif theta is empty or num_iterations is not positive (ESStep's own guards apply to population_size/sigma).

◆ RunGPBOLoop()

template<typename ObjectiveFn , typename RNG >
std::vector< Trial > pulsatrix::RunGPBOLoop ( const SearchSpace &  space,
ObjectiveFn  objective_fn,
size_t  num_initial_random,
size_t  num_iterations,
AcquisitionKind  acquisition,
size_t  num_candidates,
RNG &  rng 
)

Runs GP-BO: num_initial_random uniformly-random trials, then num_iterations trials each chosen by fitting a GP to every trial so far and maximizing acquisition over num_candidates random points in the unit hypercube.

Parameters
objective_fnCallable double(const Configuration&) – the value to maximize (a caller minimizing a loss negates it first, per this file's maximization convention).
Returns
Every Trial run, in order (the initial random trials first, then each GP-BO- proposed trial), each with one "objective" metric recorded.
Exceptions
std::invalid_argumentif num_initial_random == 0, or (propagated from UnitCubeToConfiguration) space contains an Integer/Categorical parameter.

◆ RunHyperband()

template<typename RNG >
HyperbandResult pulsatrix::RunHyperband ( const SearchSpace &  space,
const TrialFactory &  make_trial,
int  max_resource,
double  eta,
RNG &  rng 
)

Runs one Successive Halving bracket (successive_halving.hpp) per ComputeHyperbandBrackets(max_resource, eta), keeping the best result across all of them.

Exceptions
std::invalid_argument– propagated from ComputeHyperbandBrackets.

◆ RunMutationStep()

template<typename OptimizerT >
float pulsatrix::RunMutationStep ( Module &  offspring,
Module &  discriminator,
const Tensor &  noise,
MutationObjective  objective,
OptimizerT &  g_optimizer,
DeviceBackend *  backend,
float  gamma = 0.05f 
)

Runs one E-GAN mutation training step: trains offspring (an already-independent Module instance – typically initialized as a copy of some parent's current weights, which this function does not itself construct or assume anything about) for one step against discriminator using the given objective, then scores the mutated result via CombinedFitness on offspring's own post-mutation samples.

Note
Caller must zero_grad discriminator's own optimizer immediately after calling this function – both the objective's own backward-through-discriminator call and DiversityFitness's own probe backward accumulate into discriminator's gradient buffers, exactly like a generator step in this codebase's existing GAN training loop.

◆ RunNEATEvolution()

template<typename FitnessFn , typename RNG >
NEATEvolutionResult pulsatrix::RunNEATEvolution ( std::vector< NEATGenome >  population,
FitnessFn  fitness_fn,
int  num_generations,
double  compatibility_threshold,
double  c1,
double  c2,
double  c3,
double  weight_mutation_sigma,
double  weight_mutation_probability,
double  add_connection_probability,
double  add_node_probability,
InnovationTracker &  tracker,
RNG &  rng 
)

Runs num_generations of speciated, mutation-only NEAT evolution. Each generation: evaluates every genome's fitness via fitness_fn, tracks the best genome seen across the whole run so far (global elitism – best_fitness never decreases generation to generation), speciates the population, applies fitness sharing, allocates each species a share of the next generation proportional to its adjusted-fitness sum, and fills that share with one unmutated species-champion copy plus mutated copies of uniformly-randomly chosen species members.

Exceptions
std::invalid_argumentif population is empty or num_generations is not positive.

◆ RunPBT()

template<typename RNG >
PBTResult pulsatrix::RunPBT ( std::vector< std::unique_ptr< PBTResumableTrial > > &  trials,
const SearchSpace &  space,
int  num_generations,
int  epochs_per_generation,
double  truncation_fraction,
RNG &  rng 
)

Runs num_generations of RunPBTGeneration in sequence.

Exceptions
std::invalid_argumentif num_generations is not positive (delegates to RunPBTGeneration for its own preconditions).

◆ RunPBTGeneration()

template<typename RNG >
std::vector< double > pulsatrix::RunPBTGeneration ( std::vector< std::unique_ptr< PBTResumableTrial > > &  trials,
const SearchSpace &  space,
int  num_epochs,
double  truncation_fraction,
RNG &  rng 
)

Runs one PBT generation: trains every live trial for num_epochs, then exploits+explores the bottom truncation_fraction of the population from a uniformly-randomly-chosen member of the top truncation_fraction. Individuals outside both groups are left running untouched. Returns each trial's metric as of this generation (post exploit/explore for any trial that was replaced) – the value to feed into the next generation's own truncation.

Exceptions
std::invalid_argumentif trials is empty or num_epochs is not positive (delegates to ComputeTruncationGroups for its own preconditions once trials.size() >= 2).

◆ RunSuccessiveHalving()

template<typename RNG >
SuccessiveHalvingResult pulsatrix::RunSuccessiveHalving ( const SearchSpace &  space,
const TrialFactory &  make_trial,
size_t  num_configs,
int  initial_epoch_budget,
double  eta,
RNG &  rng 
)

RNG-driven wrapper: draws num_configs configurations from space via RandomSample, then runs RunSuccessiveHalvingOnConfigs.

Exceptions
std::invalid_argumentif num_configs == 0 – see RunSuccessiveHalvingOnConfigs for the other validated preconditions.

◆ RunSuccessiveHalvingOnConfigs()

SuccessiveHalvingResult pulsatrix::RunSuccessiveHalvingOnConfigs ( std::vector< Configuration >  configs,
const TrialFactory &  make_trial,
int  initial_epoch_budget,
double  eta 
)
inline

Runs Successive Halving over an explicit, caller-supplied list of configurations – the pure, deterministic core; RunSuccessiveHalving (below) is the thin SearchSpace/RNG-sampling wrapper around it.

Parameters
initial_epoch_budgetEpochs trained in the first rung.
etaReduction factor: after each rung, floor(count / eta) configurations survive (at least 1), and the next rung's budget is the previous budget * eta.
Exceptions
std::invalid_argumentif configs is empty, initial_epoch_budget <= 0, or eta <= 1.0.

◆ RunTPELoop()

template<typename ObjectiveFn , typename RNG >
std::vector< Trial > pulsatrix::RunTPELoop ( const SearchSpace &  space,
ObjectiveFn  objective_fn,
size_t  num_initial_random,
size_t  num_iterations,
double  gamma,
size_t  num_candidates,
RNG &  rng 
)

Runs TPE: num_initial_random uniformly-random trials (RandomSample), then num_iterations trials each chosen by splitting all trials so far into good/bad by the gamma quantile (maximization convention: good = highest objective values) and picking, among num_candidates uniformly-random candidates, the one maximizing LogDensityRatio.

Parameters
gammaFraction of trials-so-far classified "good" (e.g. 0.2 = top 20%); at least one trial is always classified good and at least one bad, regardless of gamma, once num_initial_random >= 2.
Exceptions
std::invalid_argumentif num_initial_random < 2 (a quantile split needs at least one good and one bad observation), or gamma is outside (0, 1).

◆ sample_gflownet_trajectory()

GFlowNetTrajectory pulsatrix::sample_gflownet_trajectory ( HyperGridEnv &  env,
GFlowNetForwardPolicy &  forward_policy 
)

Samples one full trajectory: resets env, then repeatedly samples a masked action from forward_policy and steps env until termination (an explicit stop or env's own max_steps cap).

Parameters
envThe environment to roll out on. Reset internally; any existing episode in progress is discarded.
forward_policyThe forward policy sampling each step's action.
Returns
The full trajectory, per GFlowNetTrajectory's fields above.
Note
Host boundary (GPU-native-kernels Mission 7): the rollout loop is host control flow. env and forward_policy may use any backend; each step reads the sampled action back with one device->host copy.

◆ sample_to_json()

std::string pulsatrix::sample_to_json ( const SystemSample &  sample)

Encodes sample as one JSON object (no trailing newline), the JSON Lines log record.

◆ SerializeSafetensors()

std::vector< uint8_t > pulsatrix::SerializeSafetensors ( const std::vector< std::pair< std::string, const Tensor * > > &  tensors,
const std::map< std::string, std::string > &  metadata = {} 
)

Serializes tensors (as F32) and string metadata into safetensors bytes.

Parameters
tensorsName and tensor pairs, stored in this order. Tensors on a GPU are copied back.
metadataStored as __metadata__; omitted when empty.
Note
The header is padded with spaces so the data section starts on an 8-byte boundary, as the reference implementation does.
Exceptions
std::invalid_argumentif a name repeats, is __metadata__, or (like any metadata key or value) is not valid UTF-8.

◆ set_deterministic()

void pulsatrix::set_deterministic ( bool  enabled)

Turns deterministic mode on (the default) or off.

Note
On: the GPU backends forbid atomics in their BLAS libraries (hipBLAS / cuBLAS), and any code path that would give run-to-run different results refuses to run (check_deterministic_allowed()). Off: those paths may run, possibly faster. pulsatrix's own kernels use no atomics and are deterministic either way.

◆ set_seed()

void pulsatrix::set_seed ( uint64_t  seed)

Sets the global seed and restarts the seed stream next_seed() draws from.

Note
Like torch.manual_seed: after set_seed(s), building the same objects in the same order gives the same initial weights, dropout masks and shuffles. Components that take an explicit seed ignore the global one. The default global seed is 0, so a program that never calls set_seed() is reproducible too.
Process-wide state. Call it before building models, not while other threads are constructing seeded components.

◆ SimulatedBinaryCrossover()

template<typename RNG >
std::pair< std::vector< double >, std::vector< double > > pulsatrix::SimulatedBinaryCrossover ( const std::vector< double > &  parent1,
const std::vector< double > &  parent2,
double  eta,
RNG &  rng 
)

RNG-driven wrapper: draws u_i ~ Uniform(0, 1) per gene (std::uniform_real_distribution is documented to produce values in [0, 1), matching the pure core's requirement).

Exceptions
std::invalid_argument– see SimulatedBinaryCrossoverByDraw.

◆ SimulatedBinaryCrossoverByDraw()

std::pair< std::vector< double >, std::vector< double > > pulsatrix::SimulatedBinaryCrossoverByDraw ( const std::vector< double > &  parent1,
const std::vector< double > &  parent2,
double  eta,
const std::vector< double > &  draws 
)
inline

Simulated binary crossover (Deb & Agrawal 1995; DEAP's cxSimulatedBinary), given an explicit per-gene draw in [0, 1).

Exceptions
std::invalid_argumentif parent1/parent2/draws sizes are not all equal, eta is negative, or any draw is outside [0, 1).
Note
draws must exclude 1.0: the u > 0.5 branch divides by (1 - u), which is exactly zero at u == 1 – excluded by validation rather than silently producing inf/nan.
child1_i + child2_i == parent1_i + parent2_i for any beta_q (and therefore any eta, draw) – an algebraic invariant independent of the specific draw, useful for testing the RNG-driven wrapper.

◆ SinusoidalTimestepEmbedding()

Tensor pulsatrix::SinusoidalTimestepEmbedding ( int64_t  t,
int64_t  embedding_dim,
DeviceBackend *  backend,
float  base = 10000.0f 
)

Standard Transformer-style sinusoidal encoding of a diffusion timestep t: emb[2i] = sin(t / base^(2i/embedding_dim)), emb[2i+1] = cos(t / base^(2i/embedding_dim)) for i in [0, embedding_dim/2).

This is how a DDPM denoiser is told which noise level it is looking at. It is a plain deterministic function of t – nothing is learned, nothing is cached, and no gradient flows into it. The same fixed-positional-quantity disposition RoPEModule already established for its rotation angles, one step further: RoPE is at least a Module because it transforms a tensor, whereas this produces one from an integer and so is a free function, not a class.

Parameters
tThe timestep to encode. Any value is legal, including 0 and negatives – sin/cos are defined everywhere and a schedule's valid range is NoiseSchedule's contract to enforce, not this function's.
embedding_dimSize of the produced embedding. Must be positive and even (the encoding fills sin/cos pairs, so an odd size has no valid pairing – the same even-dimension requirement, for the same structural reason, as RoPEModule's head_dim).
backendBackend to allocate the result through. Not owned; must outlive the returned Tensor.
baseFrequency base of the geometric wavelength schedule; 10000.0 is the standard convention shared by the Transformer and DDPM papers.
Returns
The embedding, shape (1, embedding_dim).
Exceptions
std::invalid_argumentif embedding_dim <= 0 or embedding_dim is odd – external boundary, same classification as RoPEModule's head_dim check.
Note
Shape is (1, embedding_dim), not rank-1 (embedding_dim,). This codebase is always-batched (a single example is N = 1, not a structurally different case – campaign_exai_dl_library_batch_dimension_support), and the one thing callers do with this result is concatenate it onto each row of an (N, D) batch of noisy samples. A (1, embedding_dim) row is directly that row; a rank-1 result would make every caller reshape first.
Host boundary (GPU-native-kernels Mission 7): the embedding is computed on the host in double (one sin/cos pair per frequency) and uploaded once through backend, so a GPU backend receives a device-resident result.

◆ SliceBatch()

Tensor pulsatrix::SliceBatch ( const Tensor &  t,
int64_t  start,
int64_t  count,
DeviceBackend *  backend 
)
inline

Extracts rows [start, start+count) along t's leading dimension into a new Tensor – the inverse of Tensor::Stack, needed to split a pooled discriminator gradient back into each population member's own slice.

Exceptions
std::invalid_argumentif t has rank 0, count <= 0, start < 0, or start+count exceeds t's own leading dimension.

◆ SolveLinearSystem()

std::vector< float > pulsatrix::SolveLinearSystem ( std::vector< std::vector< float > >  a,
std::vector< float >  b 
)
inline

Solves A*x = b via Gaussian elimination with partial pivoting.

Exceptions
std::runtime_errorif a pivot is too close to zero (a near-singular system) – a legitimate, caller-triggerable condition (e.g. degenerate/duplicate sample points), not a programmer error, per this codebase's assert-vs-throw convention.
Note
A, b are taken by value – elimination is done in place on the local copies.
Scoped to the small, dense, well-conditioned systems this codebase's callers actually produce – not a general-purpose numerics library.

◆ SpeciatePopulation()

SpeciesAssignment pulsatrix::SpeciatePopulation ( const std::vector< NEATGenome > &  population,
double  compatibility_threshold,
double  c1,
double  c2,
double  c3 
)
inline

Groups population into species: each genome joins the first existing species whose representative (that species' own first member) it is compatible with (distance < compatibility_threshold); otherwise it founds a new species with itself as representative.

Exceptions
std::invalid_argumentif population is empty or compatibility_threshold <= 0.

◆ StandardNormalCdf()

double pulsatrix::StandardNormalCdf ( double  z)
inline

Standard normal CDF, Phi(z) = 0.5 * (1 + erf(z / sqrt(2))).

◆ StandardNormalPdf()

double pulsatrix::StandardNormalPdf ( double  z)
inline

Standard normal PDF, phi(z) = (1/sqrt(2*pi)) * exp(-z^2/2).

◆ SVD()

SVDResult pulsatrix::SVD ( const Tensor &  a)

Thin singular value decomposition by one-sided (Hestenes) Jacobi rotations.

Note
Accurate to high relative precision for small singular values. About 50 ms for a 256 x 128 matrix and 1.6 s for 512 x 256 (Release, one core).
Parameters
a(m, n) CPU tensor of any shape, all finite. Rank-deficient input is fine: left singular vectors for zero singular values are completed to an orthonormal set.
Exceptions
std::invalid_argumentif a is not rank 2, is not on the CPU, or has a non-finite entry.

◆ SymmetricEigen()

EigenResult pulsatrix::SymmetricEigen ( const Tensor &  a)

All eigenvalues and eigenvectors of a symmetric matrix, by Householder reduction to tridiagonal form followed by QL with implicit shifts.

Parameters
aSquare (n, n) CPU tensor, symmetric to within a relative 1e-5, all finite.
Note
O(n^3): about 60 ms at n = 256 and 0.8 s at n = 512 (Release, one core). For a repeated eigenvalue, any orthonormal basis of its eigenspace is returned.
Exceptions
std::invalid_argumentif a is not square rank 2, is not on the CPU, has a non-finite entry, or is not symmetric.
std::runtime_errorif QL fails to converge in 60 iterations for some eigenvalue, which does not happen for finite symmetric input in practice.

◆ SyncTargetNetwork()

void pulsatrix::SyncTargetNetwork ( Module &  source,
Module &  destination 
)

Hard target-network update: copies every parameter value of source into destination, element-wise and in place (Mnih et al. 2015's periodic full copy).

Parameters
sourceNetwork to copy parameter values from – typically the online Q-network.
destinationNetwork to copy into – typically the frozen target network.
Exceptions
std::invalid_argumentif the two networks expose a different number of parameters, or if any parameter pair's shapes differ, naming the offending index and shapes. External boundary: two independently-constructed networks genuinely can have mismatched architectures, and a silent partial copy would leave the target network quietly wrong for the rest of training.
Note
A hard copy, not Polyak/soft averaging – classic DQN. A soft variant would be a different function with an extra tau, not a flag on this one.
The copy is element-wise into destination's existing parameter buffers, not a replacement of its Tensor objects. destination's parameters must remain the same objects its own parameters() (and any optimizer already holding ParamRefs into it) point at, so subsequent forward passes see the synced values through the same storage. Replacing the Tensors would dangle every outstanding ParamRef.
Gradients are untouched. This is a pure value copy and has nothing to do with zero_grad(); a target network is never backpropagated through in DQN anyway.
Device-generic (GPU-native-kernels Mission 7): each parameter is one buffer copy through the destination parameter's own backend (HostToHost / DeviceToDevice), staged through the host only when source and destination live on different devices.

◆ TellGivenSamples()

CMAESState pulsatrix::TellGivenSamples ( const CMAESState &  state,
const std::vector< std::vector< double > > &  z_samples,
const std::vector< std::vector< double > > &  offspring,
const std::vector< double > &  fitness,
double  step_size_learning_rate,
double  scale_learning_rate 
)
inline

Pure core: given the offspring AskGivenSamples produced (same order), their maximization-convention fitness values, and the z_samples that produced them, returns the next generation's state.

Parameters
step_size_learning_rate,scale_learning_rateFixed adaptation rates (this variant's own simplification – full CMA-ES derives these from mu_eff/n instead).
Exceptions
std::invalid_argumentif z_samples/offspring/fitness sizes disagree, or fewer than 2 samples are given (mu = size/2 must be >= 1).

◆ ToBeeswarmPoints()

std::vector< BeeswarmPoint > pulsatrix::ToBeeswarmPoints ( const std::vector< Attribution > &  runs,
int64_t  feature_index 
)

Converts one feature's attribution value across many repeated/independent runs into jittered (x, y) points for a beeswarm plot – the global-explanation distribution view (hc_information_visualization.md SS5: "SHAP beeswarm plot... each point is one prediction; x-position is the SHAP value"). Deterministic, density-based jitter: points are binned along x, then colliding points within a bin are alternately offset above/below y=0 so they read as spread rather than overlapping – not a random jitter, so two calls with the same input always produce the same layout.

Parameters
runsAttribution results across many samples/predictions (not necessarily repeated runs on one input – unlike ComputeAttributionStability, this is the global view across many different inputs).
feature_indexWhich feature (element position) to plot.
Exceptions
std::invalid_argumentif runs is empty.
std::out_of_rangeif feature_index is out of range for any run's Attribution.

◆ ToFeatureImportanceBars()

BarSeries pulsatrix::ToFeatureImportanceBars ( const Attribution &  attr,
int  top_k 
)

Converts an Attribution's per-feature values into labeled, magnitude-sorted bars for a horizontal bar chart – the canonical XAI feature-importance encoding (hc_information_visualization.md SS5: position on a shared axis, Cleveland-McGill rank 1).

Parameters
attrA rank-1 Attribution (one value per feature), or a rank-2 Attribution whose leading (batch) dimension is 1 – every native/surrogate explainer in this codebase is always-batched post campaign_exai_dl_library_batch_dimension_support, so a single-prediction explanation is shape (1, num_features), not (num_features,).
top_kNumber of highest-|value| features to keep, in descending |value| order.
Returns
Bars sorted by descending absolute value, truncated to top_k (or fewer, if attr has fewer features than top_k). Labels come from attr.metadata["feature_names"] (comma-separated) when present, otherwise "feature_<index>".
Exceptions
std::invalid_argumentif attr.values is not rank 1 or batch-1 rank 2, or if top_k <= 0.

◆ ToFieldHistogramBins()

HistogramBins pulsatrix::ToFieldHistogramBins ( const Dataset &  dataset,
int64_t  field_index,
int  num_bins 
)

Bins one Sample field's values (flattened across every sample's Tensor at that field position, mirroring DatasetValidator's aggregation convention) into num_bins equal-width bins, for a per-field distribution histogram (hc_information_visualization.md's data-preview touchpoint).

Parameters
datasetThe dataset to scan. Must be non-empty.
field_indexWhich Sample field position to bin.
num_binsNumber of equal-width bins, must be positive.
Exceptions
std::invalid_argumentif dataset is empty or num_bins <= 0.
std::out_of_rangeif field_index is out of range for the dataset's samples.
Note
A constant field (max == min) places every value in the first bin rather than dividing by a zero-width bin range.

◆ top_k()

TopKResult pulsatrix::top_k ( const Tensor &  input,
int64_t  k,
bool  largest = true 
)

Selects the k largest (or smallest) entries of every row along the last dimension.

Parameters
inputTensor of any rank >= 1. Every slice along its last dimension is one row.
kEntries kept per row; 1 <= k <= the last dimension's size.
largesttrue for the k largest (default), false for the k smallest.
Returns
Values and indices of shape (..., k), in rank order, on input's device.
Note
Order is fully deterministic and identical on every backend: NaN ranks above every number (first when largest, last when smallest), and equal values keep the lower index first. Indices are whole-number floats, like every other index tensor in this library, and so are exact only below 2^24; longer rows are rejected.
Selection only – no gradient. A module that routes gradients through a top-k (a TopK sparse autoencoder, a mixture-of-experts router) scatters through indices itself.
Exceptions
std::invalid_argumentif input is empty or rank 0, k is outside [1, last dimension], or the last dimension exceeds 2^24 – external boundary.

◆ ToRgbImageBuffer()

RgbImageBuffer pulsatrix::ToRgbImageBuffer ( const Tensor &  image_chw)

Converts a decoded image Tensor into an interleaved-RGB byte buffer for GPU texture upload (the data-preview "image grid" touchpoint's pure half – the actual glTexImage2D call lives in TextureCache, which is GL-dependent and untestable here).

Parameters
image_chwA rank-3 (C, H, W) tensor, or a rank-4 tensor with a leading batch dimension of 1 ((1, C, H, W) – ImageFolderDataset::get()'s convention). C must be 1 (replicated across R/G/B) or 3.
Note
Values are assumed already normalized to [0, 1] and clamped before scaling to [0, 255] – out-of-range input (e.g. an un-normalized decoder output) is clamped rather than wrapped, since a wrapped byte would silently invert bright/dark regions.
Exceptions
std::invalid_argumentif image_chw's rank/channel count don't match the above.

◆ ToSaliencyHeatmap()

HeatmapGrid pulsatrix::ToSaliencyHeatmap ( const Attribution &  attr)

Reshapes an Attribution's values into a 2D grid for a saliency overlay heatmap.

Parameters
attrA rank-2 Attribution, a rank-3 Attribution whose leading (channel or batch) dimension is 1 (single-channel saliency map, or Grad-CAM's batch-1 (1, H, W) map, squeezed), or a rank-4 Attribution of shape (1, 1, H, W) – the shape every input-space image explainer (Saliency, IntegratedGradients, LRP, LIME, KernelSHAP) returns for a single batched single-channel image such as an MNIST digit.
Exceptions
std::invalid_argumentif attr.values is not reshapable to a 2D grid by the rules above (e.g. rank 1, rank 3 with more than one channel, or rank 4 with a batch or channel dimension other than 1).

◆ TournamentSelect()

template<typename Genotype , typename FitnessT , typename RNG >
size_t pulsatrix::TournamentSelect ( const std::vector< Individual< Genotype, FitnessT > > &  population,
size_t  tournament_size,
RNG &  rng 
)

Tournament selection: draw tournament_size individuals without replacement from population and return the index of the fittest among them.

Parameters
populationNon-empty population to select from.
tournament_sizeNumber of distinct competitors, in [1, population.size()].
rngAny UniformRandomBitGenerator (e.g. std::mt19937).
Returns
Index into population of the selected individual.
Exceptions
std::invalid_argumentif population is empty, tournament_size is 0, or tournament_size exceeds population.size() – external-boundary malformed input (caller-supplied population/config), not an internal invariant.
Note
tournament_size == population.size() draws every individual exactly once (without replacement), so it always returns the global-best index regardless of the RNG stream – this operator's own hand-verifiable correctness case, independent of which RNG or seed is used.

◆ ToWaterfallBars()

std::vector< WaterfallBar > pulsatrix::ToWaterfallBars ( const std::vector< WaterfallStep > &  steps,
float  baseline_value 
)

Converts waterfall steps into floating bars, each spanning from the previous running total to its own running total – i.e. bar i covers [min(c_{i-1}, c_i), max(c_{i-1}, c_i)] with c_{-1} = baseline_value. Correct for any sign of baseline or running total: a cascade that starts below zero, crosses zero, or stays negative (e.g. explaining a negative logit) floats exactly where the running total is, rather than being anchored at zero the way stacked bar segments are.

Parameters
stepsToWaterfallSteps's output.
baseline_valueThe same baseline passed to ToWaterfallSteps.

◆ ToWaterfallSteps()

std::vector< WaterfallStep > pulsatrix::ToWaterfallSteps ( const Attribution &  attr,
float  baseline_value 
)

Converts an Attribution's per-feature values into a cascading waterfall from a real baseline to the final prediction (hc_information_visualization.md SS5/SS6: the one case where a bar chart legitimately does not start at zero, since the baseline itself is the meaningful reference point – Tufte's lie-factor rule is satisfied relative to that baseline, not to zero).

Parameters
attrA rank-1 Attribution (one value per feature), or a rank-2 Attribution whose leading (batch) dimension is 1 (see ToFeatureImportanceBars's note on always-batched explainer output), in the explainer's own feature order – deliberately NOT sorted by magnitude, since a waterfall's narrative is the accumulation path, not a ranking.
baseline_valueThe starting reference value (e.g. Integrated Gradients' baseline prediction, or the model's mean output).
Exceptions
std::invalid_argumentif attr.values is not rank 1 or batch-1 rank 2.

◆ TwoPointCrossover()

template<typename T , typename RNG >
std::pair< std::vector< T >, std::vector< T > > pulsatrix::TwoPointCrossover ( const std::vector< T > &  parent1,
const std::vector< T > &  parent2,
RNG &  rng 
)

RNG-driven wrapper: draws two points in [0, size], sorted ascending.

Exceptions
std::invalid_argumentif parent sizes differ or parent size < 2.

◆ TwoPointCrossoverAtPoints()

template<typename T >
std::pair< std::vector< T >, std::vector< T > > pulsatrix::TwoPointCrossoverAtPoints ( const std::vector< T > &  parent1,
const std::vector< T > &  parent2,
size_t  point1,
size_t  point2 
)

Swaps the [point1, point2) segment between both parents.

Exceptions
std::invalid_argumentif parent sizes differ, point1 > point2, or point2 exceeds parent size.

◆ UniformCrossover()

template<typename T , typename RNG >
std::pair< std::vector< T >, std::vector< T > > pulsatrix::UniformCrossover ( const std::vector< T > &  parent1,
const std::vector< T > &  parent2,
double  swap_probability,
RNG &  rng 
)

RNG-driven wrapper: each gene swaps independently with probability swap_probability.

Exceptions
std::invalid_argumentif parent sizes differ or swap_probability is outside [0, 1].
Note
swap_probability == 0.0 or 1.0 make std::bernoulli_distribution deterministic (always false / always true respectively) – exact, RNG-independent correctness cases.

◆ UniformCrossoverByMask()

template<typename T >
std::pair< std::vector< T >, std::vector< T > > pulsatrix::UniformCrossoverByMask ( const std::vector< T > &  parent1,
const std::vector< T > &  parent2,
const std::vector< bool > &  swap_mask 
)

Swaps each gene independently wherever swap_mask is true.

Exceptions
std::invalid_argumentif parent1/parent2/swap_mask sizes are not all equal.

◆ UnitCubeToConfiguration()

Configuration pulsatrix::UnitCubeToConfiguration ( const SearchSpace &  space,
const std::vector< float > &  t 
)
inline

Maps a unit-hypercube point (one value per parameter, each in [0, 1]) to a Configuration, using space's own declared bounds.

Exceptions
std::invalid_argumentif t.size() != space.size(), any t[i] is outside [0, 1], or space contains a parameter kind other than Continuous/LogUniform.

◆ UpperConfidenceBound()

double pulsatrix::UpperConfidenceBound ( double  mean,
double  variance,
double  kappa = 2.0 
)
inline

GP-Upper-Confidence-Bound: mean + kappa * sqrt(variance).

Parameters
kappaExploration weight (default 2.0, a common practical default – larger values favor exploring high-uncertainty regions over exploiting the current best mean).
Exceptions
std::invalid_argumentif variance < 0.

◆ ViridisColormap()

RgbColor pulsatrix::ViridisColormap ( float  normalized_value)

Viridis colormap – perceptually uniform, colorblind-safe – for sequential/unsigned magnitude (hc_information_visualization.md SS4: "Recommended Color Systems").

Parameters
normalized_valuePosition along the colormap, expected in [0, 1]; values outside this range are clamped to the nearest end anchor.
Note
Deliberately never a rainbow/jet map – see the design doc's SS4 "Rainbow (Jet) Colormap Problem". Approximates matplotlib's Viridis via a small set of anchor colors with linear interpolation between them; exact per-channel fidelity against ImPlot's own built-in ImPlotColormap_Viridis is an open verification item (plan Open Risk 4), not assumed here.

◆ WriteSafetensors()

void pulsatrix::WriteSafetensors ( const std::string &  path,
const std::vector< std::pair< std::string, const Tensor * > > &  tensors,
const std::map< std::string, std::string > &  metadata = {} 
)

SerializeSafetensors() written to path.

Exceptions
std::runtime_errorif the file can't be written; otherwise as SerializeSafetensors().

◆ XORFitness()

double pulsatrix::XORFitness ( const NEATGenome &  genome)
inline

Evaluates genome's phenotype on all four XOR patterns ((0,0)->0, (0,1)->1, (1,0)->1, (1,1)->0, in that order) and scores it as 4.0 minus the sum of squared errors – a perfect fit scores 4.0; a genome producing exactly 0.5 for every pattern (e.g. a fresh, all-zero-weight genome, before any weight differentiation has emerged) scores exactly 3.0 (4.0 - 4*0.25).

Exceptions
WhateverEvaluateNEATPhenotype throws if genome's Input node count isn't 2.

◆ ZeroModuleGradients()

void pulsatrix::ZeroModuleGradients ( Module &  module)
inline

Zeros every gradient tensor module.parameters() reports – a standalone alternative to calling some optimizer's own zero_grad(module) when no persistent per-module optimizer instance is being kept around (Phase 5 Mission 2's own mutation-attempt loop constructs a fresh optimizer per attempt, so there is no single optimizer instance left to call zero_grad on between generations).

Variable Documentation

◆ kFixedTopologyXORNumParams

constexpr size_t pulsatrix::kFixedTopologyXORNumParams = 9
inlineconstexpr

Total flat-parameter count: 2*2 (input->hidden weights) + 2 (hidden biases) + 2 (hidden->output weights) + 1 (output bias) = 9.