faber_nn_nifs (faber_tweann v2.0.1)

View Source

High-performance Rust NIFs for faber_tweann.

This module provides native implementations of compute-intensive operations for neuroevolution. It was absorbed into faber_tweann in v2.0.0 from the separate faber-nn-nifs package, and is built from source by priv/build-nifs.sh during compilation.

Do not call this module directly. Use tweann_nif, which dispatches to either this module or tweann_nif_fallback according to the {faber_tweann, [{nif_impl, _}]} setting, and reports the active path via tweann_nif:impl/0.

Every function here that also exists in tweann_nif_fallback must produce the same result. That is enforced by test/unit/nif_fallback_conformance_tests.erl, which exists because the two implementations silently disagreed for months while both test suites passed.

Summary

Functions

Apply specified activation function to batch of values. Activation: tanh | sigmoid | relu | linear | sin | cos | gaussian

Align genes by innovation number.

Assign genomes to species in batch.

Compute weight counts per layer from topology.

Count excess and disjoint genes between two genomes.

Evaluate CfC over a sequence of inputs with state persistence.

Find representative for a species.

Check if NIF is loaded successfully.

K-means clustering for genomes.

Single layer forward pass with activation.

Batch LTC state update for multiple neurons.

Matrix multiply with bias addition.

Multi-layer forward pass through network.

NEAT-style crossover between two genomes.

Batch Oja's rule update (normalized Hebbian).

Compute all pairwise distances in batch.

Compute population diversity metrics.

Apply ReLU activation to a batch of values elementwise.

Apply sigmoid activation to a batch of values elementwise.

Apply softmax to a batch of values (normalized exponential).

Spike-Timing Dependent Plasticity (STDP) update.

Apply tanh activation to a batch of values elementwise.

Compute weight covariance matrix.

Functions

activation_batch(Values, Activation)

-spec activation_batch([float()], atom()) -> [float()].

Apply specified activation function to batch of values. Activation: tanh | sigmoid | relu | linear | sin | cos | gaussian

align_genes_by_innovation(GenomeA, GenomeB)

-spec align_genes_by_innovation([{integer(), float(), boolean()}], [{integer(), float(), boolean()}]) ->
                                   [{term(), term()}].

Align genes by innovation number.

Returns aligned gene lists for crossover or comparison. Each position contains {GeneA, GeneB} where Gene is either the actual gene or 'none' if missing.

Returns: [{GeneA | none, GeneB | none}, ...]

assign_species_batch(Genomes, Representatives, Threshold)

-spec assign_species_batch([[float()]], [[float()]], float()) -> [non_neg_integer()].

Assign genomes to species in batch.

Assigns each genome to the most compatible existing species, or creates a new species if no compatible species exists.

Genomes: list of weight vectors Representatives: current species representatives Threshold: compatibility threshold for same-species assignment

Returns: list of species indices (0-based)

benchmark_evaluate(Network, Inputs, Iterations)

-spec benchmark_evaluate(reference(), [float()], pos_integer()) -> float().

build_cumulative_fitness(Fitnesses)

-spec build_cumulative_fitness([float()]) -> {[float()], float()}.

compatibility_distance(ConnectionsA, ConnectionsB, C1, C2, C3)

-spec compatibility_distance(list(), list(), float(), float(), float()) -> float().

compile_network(Nodes, InputCount, OutputIndices)

-spec compile_network(list(), non_neg_integer(), [non_neg_integer()]) -> reference().

compute_layer_weight_counts(Topology)

-spec compute_layer_weight_counts([non_neg_integer()]) -> [non_neg_integer()].

Compute weight counts per layer from topology.

Given a topology structure (list of layer sizes), returns the number of weights in each layer. Useful for layer-specific mutation.

Topology format: [InputSize, Hidden1Size, Hidden2Size, ..., OutputSize] Returns: [Layer1Weights, Layer2Weights, ...] where Layer N weights = LayerN_size * LayerN-1_size (fully connected assumption)

compute_reward_component(History, Current)

-spec compute_reward_component([float()], float()) -> {float(), float(), float()}.

compute_weighted_reward(Components)

-spec compute_weighted_reward([{[float()], float(), float()}]) -> float().

count_excess_disjoint(GenomeA, GenomeB)

-spec count_excess_disjoint([{integer(), float(), boolean()}], [{integer(), float(), boolean()}]) ->
                               {non_neg_integer(), non_neg_integer(), non_neg_integer()}.

Count excess and disjoint genes between two genomes.

Excess genes: genes with innovation > max of other genome Disjoint genes: non-matching genes within shared innovation range

Returns: {ExcessCount, DisjointCount, MatchingCount}

dot_product_batch(Batch)

-spec dot_product_batch([{[float()], [float()], float()}]) -> [float()].

dot_product_flat(Signals, Weights, Bias)

-spec dot_product_flat([float()], [float()], float()) -> float().

dot_product_preflattened(SignalsFlat, WeightsFlat, Bias)

-spec dot_product_preflattened([float()], [float()], float()) -> float().

euclidean_distance(V1, V2)

-spec euclidean_distance([float()], [float()]) -> float().

euclidean_distance_batch(Target, Others)

-spec euclidean_distance_batch([float()], [[float()]]) -> [{non_neg_integer(), float()}].

evaluate(Network, Inputs)

-spec evaluate(reference(), [float()]) -> [float()].

evaluate_batch(Network, InputsList)

-spec evaluate_batch(reference(), [[float()]]) -> [[float()]].

evaluate_cfc(Input, State, Tau, Bound)

-spec evaluate_cfc(float(), float(), float(), float()) -> {float(), float()}.

evaluate_cfc_batch(Inputs, InitialState, Tau, Bound)

-spec evaluate_cfc_batch([float()], float(), float(), float()) -> [{float(), float()}].

evaluate_cfc_parallel(Input, NeuronParams, BackboneWeights, HeadWeights)

-spec evaluate_cfc_parallel(float(), [{float(), float(), float()}], [float()], [float()]) ->
                               [{float(), float()}].

Evaluate multiple CfC neurons in parallel.

Processes the same input through multiple CfC neurons with different parameters. Useful for ensemble or population-based evaluation.

Input: single input value NeuronParams: list of {State, Tau, Bound} for each neuron Returns: list of {NewState, Output} for each neuron

evaluate_cfc_sequence(Inputs, InitialState, Tau, Bound, BackboneWeights)

-spec evaluate_cfc_sequence([float()], float(), float(), float(), [float()]) -> [{float(), float()}].

Evaluate CfC over a sequence of inputs with state persistence.

Processes a time series through the CfC neuron, maintaining state across timesteps. More efficient than calling evaluate_cfc repeatedly.

Inputs: list of input values (time series) InitialState: starting state value Tau: time constant Bound: output bound BackboneWeights: optional backbone network weights

Returns: list of {State, Output} tuples for each timestep

evaluate_cfc_with_weights(Input, State, Tau, Bound, BackboneWeights, HeadWeights)

-spec evaluate_cfc_with_weights(float(), float(), float(), float(), [float()], [float()]) ->
                                   {float(), float()}.

evaluate_ode(Input, State, Tau, Bound, Dt)

-spec evaluate_ode(float(), float(), float(), float(), float()) -> {float(), float()}.

evaluate_ode_with_weights(Input, State, Tau, Bound, Dt, BackboneWeights, HeadWeights)

-spec evaluate_ode_with_weights(float(), float(), float(), float(), float(), [float()], [float()]) ->
                                   {float(), float()}.

find_representative(Members, Method)

-spec find_representative([[float()]], atom()) -> non_neg_integer().

Find representative for a species.

Finds the genome closest to the centroid (most representative) of the given species members.

Members: list of weight vectors in the species Method: centroid | random | fittest

Returns: index of representative in members list

fitness_stats(Fitnesses)

-spec fitness_stats([float()]) -> {float(), float(), float(), float(), float(), float()}.

flatten_weights(WeightedInputs)

-spec flatten_weights([{term(), [{float(), float(), float(), list()}]}]) ->
                         {[float()], [non_neg_integer()]}.

hebbian_update_batch(WeightActivities, LearningRate, DecayRate, MaxWeight)

-spec hebbian_update_batch([{float(), float(), float()}], float(), float(), float()) -> [float()].

Batch Hebbian weight update.

Implements Hebbian learning rule: dW = eta * pre * post Where eta is the learning rate, pre is presynaptic activity, post is postsynaptic activity.

Input: list of {Weight, PreActivity, PostActivity} tuples LearningRate: global learning rate multiplier Returns: list of updated weights

histogram(Values, NumBins, MinVal, MaxVal)

-spec histogram([float()], pos_integer(), float(), float()) -> [non_neg_integer()].

is_loaded()

-spec is_loaded() -> boolean().

Check if NIF is loaded successfully.

kmeans_cluster(Genomes, K, MaxIterations)

-spec kmeans_cluster([[float()]], pos_integer(), pos_integer()) -> [non_neg_integer()].

K-means clustering for genomes.

Clusters genomes into K groups using k-means algorithm. Useful for diversity-based speciation.

Genomes: list of weight vectors K: number of clusters MaxIterations: maximum iterations for convergence

Returns: list of cluster assignments (0 to K-1)

knn_novelty(Target, Population, Archive, K)

-spec knn_novelty([float()], [[float()]], [[float()]], pos_integer()) -> float().

knn_novelty_batch(Behaviors, Archive, K)

-spec knn_novelty_batch([[float()]], [[float()]], pos_integer()) -> [float()].

layer_forward(X, W, B, Activation)

-spec layer_forward([float()], [float()], [float()], atom()) -> [float()].

Single layer forward pass with activation.

Computes layer output: activation(X * W + B)

X: input vector W: weight matrix (flattened) B: bias vector Activation: tanh | sigmoid | relu | linear

Returns: activated output vector

ltc_state_batch(Inputs, States, Taus, Dt)

-spec ltc_state_batch([float()], [float()], [float()], float()) -> [float()].

Batch LTC state update for multiple neurons.

Efficiently updates states for multiple LTC neurons given inputs. Used when simulating a layer of LTC neurons.

Inputs: input values for each neuron States: current states for each neuron Taus: time constants for each neuron Dt: time step size

Returns: list of new states

matmul_add_bias(X, W, B)

-spec matmul_add_bias([float()], [float()], [float()]) -> [float()].

Matrix multiply with bias addition.

Computes Y = X * W + B efficiently for neural network forward pass.

X: input vector (1 x N) W: weight matrix (N x M, flattened row-major) B: bias vector (1 x M) Dims: {N, M} dimensions

Returns: output vector (1 x M)

modulated_hebbian_batch(WeightActivities, LearningRate, Reward, DecayRate, MaxWeight)

-spec modulated_hebbian_batch([{float(), float(), float()}], float(), float(), float(), float()) ->
                                 [float()].

Batch modulated Hebbian update with reward signal.

Implements reward-modulated Hebbian: dW = eta * reward * pre * post Used for reinforcement learning where weight updates are gated by reward.

multi_layer_forward(Input, Layers, LayerSizes)

-spec multi_layer_forward([float()], [{[float()], [float()], atom()}], [non_neg_integer()]) -> [float()].

Multi-layer forward pass through network.

Efficiently processes input through multiple layers. Avoids crossing NIF boundary for each layer.

Input: input vector Layers: list of {Weights, Biases, Activation} for each layer

Returns: final output vector

mutate_weights(Weights, MutationRate, PerturbRate, PerturbStrength)

-spec mutate_weights([float()], float(), float(), float()) -> [float()].

mutate_weights_batch(Genomes)

-spec mutate_weights_batch([{[float()], float(), float(), float()}]) -> [[float()]].

mutate_weights_batch_uniform(Genomes, MutationRate, PerturbRate, PerturbStrength)

-spec mutate_weights_batch_uniform([[float()]], float(), float(), float()) -> [[float()]].

mutate_weights_layered(Weights, ReservoirWeightCount, ReservoirMutRate, ReservoirStrength, ReadoutMutRate, ReadoutStrength)

-spec mutate_weights_layered([float()], non_neg_integer(), float(), float(), float(), float()) ->
                                [float()].

Mutate weights with different rates for reservoir vs readout layers.

Applies different mutation parameters to reservoir (hidden) layers and readout (output) layer, supporting the reservoir computing paradigm where readout weights often benefit from more aggressive mutation.

ReservoirWeightCount specifies how many weights belong to reservoir layers. The remaining weights are treated as readout layer.

mutate_weights_seeded(Weights, MutationRate, PerturbRate, PerturbStrength, Seed)

-spec mutate_weights_seeded([float()], float(), float(), float(), integer()) -> [float()].

neat_crossover(GenomeA, GenomeB, FitnessA, FitnessB)

-spec neat_crossover([{integer(), float(), boolean()}],
                     [{integer(), float(), boolean()}],
                     float(),
                     float()) ->
                        [{integer(), float(), boolean()}].

NEAT-style crossover between two genomes.

Performs NEAT crossover where genes are aligned by innovation number: - Matching genes: randomly select from either parent - Disjoint/Excess genes: taken from more fit parent

Genome format: list of {InnovationNum, Weight, Enabled} tuples FitnessA, FitnessB: fitness values to determine which parent's disjoint/excess genes to use

Returns: offspring genome

oja_update_batch(WeightActivities, LearningRate, DecayRate, MaxWeight)

-spec oja_update_batch([{float(), float(), float()}], float(), float(), float()) -> [float()].

Batch Oja's rule update (normalized Hebbian).

Implements Oja's rule: dW = eta * (post * pre - post^2 * W) This is a normalized Hebbian rule that prevents unbounded weight growth and extracts principal components.

pairwise_distances_batch(Population, DistType)

-spec pairwise_distances_batch([[float()]], l1 | l2) -> [float()].

Compute all pairwise distances in batch.

Efficiently computes distances between all pairs in a population. DistType: l1 | l2 | euclidean

Returns: flattened distance matrix (upper triangular, row-major)

population_diversity(Population)

-spec population_diversity([[float()]]) -> {float(), float(), float(), float()}.

Compute population diversity metrics.

Analyzes a population of weight vectors and computes diversity metrics: - Mean pairwise distance - Standard deviation of pairwise distances - Minimum distance (most similar pair) - Maximum distance (most different pair)

Returns: {MeanDist, StdDist, MinDist, MaxDist}

random_weights(N)

-spec random_weights(non_neg_integer()) -> [float()].

random_weights_batch(Specs)

-spec random_weights_batch([{non_neg_integer(), float(), float()}]) -> [[float()]].

random_weights_gaussian(N, Mean, StdDev)

-spec random_weights_gaussian(non_neg_integer(), float(), float()) -> [float()].

random_weights_seeded(N, Seed)

-spec random_weights_seeded(non_neg_integer(), integer()) -> [float()].

relu_batch(Values)

-spec relu_batch([float()]) -> [float()].

Apply ReLU activation to a batch of values elementwise.

roulette_select(Cumulative, Total, RandomVal)

-spec roulette_select([float()], float(), float()) -> non_neg_integer().

roulette_select_batch(Cumulative, Total, RandomVals)

-spec roulette_select_batch([float()], float(), [float()]) -> [non_neg_integer()].

shannon_entropy(Values)

-spec shannon_entropy([float()]) -> float().

sigmoid_batch(Values)

-spec sigmoid_batch([float()]) -> [float()].

Apply sigmoid activation to a batch of values elementwise.

softmax_batch(Values)

-spec softmax_batch([float()]) -> [float()].

Apply softmax to a batch of values (normalized exponential).

stdp_update(Weight, DeltaT, Aplus, Aminus, TauPlus)

-spec stdp_update(float(), float(), float(), float(), float()) -> float().

Spike-Timing Dependent Plasticity (STDP) update.

Implements STDP rule where weight change depends on relative timing of pre and post synaptic spikes: - Pre before post (positive delta_t): potentiation (strengthen) - Post before pre (negative delta_t): depression (weaken)

A_plus, A_minus: amplitude of potentiation/depression Tau_plus, Tau_minus: time constants for decay

tanh_batch(Values)

-spec tanh_batch([float()]) -> [float()].

Apply tanh activation to a batch of values elementwise.

tournament_select(Contestants, Fitnesses)

-spec tournament_select([non_neg_integer()], [float()]) -> non_neg_integer().

weight_covariance_matrix(Population)

-spec weight_covariance_matrix([[float()]]) -> [float()].

Compute weight covariance matrix.

Computes the covariance matrix of weights across a population. Used for CMA-ES and other covariance-aware evolution strategies.

Population: list of weight vectors (all same length) Returns: flattened covariance matrix (row-major order)

weight_distance_batch(Target, Others, DistanceType)

-spec weight_distance_batch([float()], [[float()]], l1 | l2) -> [float()].

weight_distance_l1(Weights1, Weights2)

-spec weight_distance_l1([float()], [float()]) -> float().

weight_distance_l2(Weights1, Weights2)

-spec weight_distance_l2([float()], [float()]) -> float().

weighted_moving_average(Values, Decay)

-spec weighted_moving_average([float()], float()) -> float().

z_score(Value, Mean, StdDev)

-spec z_score(float(), float(), float()) -> float().