Squashed 'vendor/ruvector/' content from commit b64c2172
git-subtree-dir: vendor/ruvector git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
This commit is contained in:
570
npm/packages/ruvector-wasm-unified/src/nervous.ts
Normal file
570
npm/packages/ruvector-wasm-unified/src/nervous.ts
Normal file
@@ -0,0 +1,570 @@
|
||||
/**
|
||||
* RuVector WASM Unified - Nervous System Engine
|
||||
*
|
||||
* Provides biological neural network simulation including:
|
||||
* - Spiking neural networks (SNN)
|
||||
* - Synaptic plasticity rules (STDP, BTSP, Hebbian)
|
||||
* - Neuron dynamics (LIF, Izhikevich, Hodgkin-Huxley)
|
||||
* - Network topology management
|
||||
* - Signal propagation
|
||||
*/
|
||||
|
||||
import type {
|
||||
Neuron,
|
||||
Synapse,
|
||||
PlasticityRule,
|
||||
NervousState,
|
||||
PropagationResult,
|
||||
NervousConfig,
|
||||
} from './types';
|
||||
|
||||
// ============================================================================
|
||||
// Nervous System Engine Interface
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Core nervous system engine for biological neural network simulation
|
||||
*/
|
||||
export interface NervousEngine {
|
||||
// -------------------------------------------------------------------------
|
||||
// Neuron Management
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a new neuron in the network
|
||||
* @param config Neuron configuration
|
||||
* @returns Neuron ID
|
||||
*/
|
||||
createNeuron(config: NeuronConfig): string;
|
||||
|
||||
/**
|
||||
* Remove a neuron from the network
|
||||
* @param neuronId Neuron to remove
|
||||
*/
|
||||
removeNeuron(neuronId: string): void;
|
||||
|
||||
/**
|
||||
* Get neuron by ID
|
||||
* @param neuronId Neuron ID
|
||||
* @returns Neuron state
|
||||
*/
|
||||
getNeuron(neuronId: string): Neuron | undefined;
|
||||
|
||||
/**
|
||||
* Update neuron parameters
|
||||
* @param neuronId Neuron to update
|
||||
* @param params New parameters
|
||||
*/
|
||||
updateNeuron(neuronId: string, params: Partial<NeuronConfig>): void;
|
||||
|
||||
/**
|
||||
* List all neurons
|
||||
* @param filter Optional filter criteria
|
||||
* @returns Array of neurons
|
||||
*/
|
||||
listNeurons(filter?: NeuronFilter): Neuron[];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Synapse Management
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a synapse between neurons
|
||||
* @param presynapticId Source neuron
|
||||
* @param postsynapticId Target neuron
|
||||
* @param config Synapse configuration
|
||||
* @returns Synapse ID
|
||||
*/
|
||||
createSynapse(
|
||||
presynapticId: string,
|
||||
postsynapticId: string,
|
||||
config?: SynapseConfig
|
||||
): string;
|
||||
|
||||
/**
|
||||
* Remove a synapse
|
||||
* @param presynapticId Source neuron
|
||||
* @param postsynapticId Target neuron
|
||||
*/
|
||||
removeSynapse(presynapticId: string, postsynapticId: string): void;
|
||||
|
||||
/**
|
||||
* Get synapse between neurons
|
||||
* @param presynapticId Source neuron
|
||||
* @param postsynapticId Target neuron
|
||||
* @returns Synapse or undefined
|
||||
*/
|
||||
getSynapse(presynapticId: string, postsynapticId: string): Synapse | undefined;
|
||||
|
||||
/**
|
||||
* Update synapse parameters
|
||||
* @param presynapticId Source neuron
|
||||
* @param postsynapticId Target neuron
|
||||
* @param params New parameters
|
||||
*/
|
||||
updateSynapse(
|
||||
presynapticId: string,
|
||||
postsynapticId: string,
|
||||
params: Partial<SynapseConfig>
|
||||
): void;
|
||||
|
||||
/**
|
||||
* List synapses for a neuron
|
||||
* @param neuronId Neuron ID
|
||||
* @param direction 'incoming' | 'outgoing' | 'both'
|
||||
* @returns Array of synapses
|
||||
*/
|
||||
listSynapses(neuronId: string, direction?: 'incoming' | 'outgoing' | 'both'): Synapse[];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Simulation
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Step the simulation forward
|
||||
* @param dt Time step in milliseconds
|
||||
* @returns Simulation result
|
||||
*/
|
||||
step(dt?: number): SimulationResult;
|
||||
|
||||
/**
|
||||
* Inject current into neurons
|
||||
* @param injections Map of neuron ID to current value
|
||||
*/
|
||||
injectCurrent(injections: Map<string, number>): void;
|
||||
|
||||
/**
|
||||
* Propagate signal through network
|
||||
* @param sourceIds Source neuron IDs
|
||||
* @param signal Signal strength
|
||||
* @returns Propagation result
|
||||
*/
|
||||
propagate(sourceIds: string[], signal: number): PropagationResult;
|
||||
|
||||
/**
|
||||
* Get current network state
|
||||
* @returns Complete nervous system state
|
||||
*/
|
||||
getState(): NervousState;
|
||||
|
||||
/**
|
||||
* Set network state
|
||||
* @param state State to restore
|
||||
*/
|
||||
setState(state: NervousState): void;
|
||||
|
||||
/**
|
||||
* Reset network to initial state
|
||||
* @param keepTopology Keep neurons and synapses, reset potentials
|
||||
*/
|
||||
reset(keepTopology?: boolean): void;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Plasticity
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Apply plasticity rule to all synapses
|
||||
* @param rule Plasticity rule to apply
|
||||
* @param learningRate Global learning rate modifier
|
||||
*/
|
||||
applyPlasticity(rule?: PlasticityRule, learningRate?: number): void;
|
||||
|
||||
/**
|
||||
* Apply STDP (Spike-Timing Dependent Plasticity)
|
||||
* @param config STDP configuration
|
||||
*/
|
||||
applyStdp(config?: StdpConfig): void;
|
||||
|
||||
/**
|
||||
* Apply homeostatic plasticity
|
||||
* @param targetRate Target firing rate
|
||||
*/
|
||||
applyHomeostasis(targetRate?: number): void;
|
||||
|
||||
/**
|
||||
* Get plasticity statistics
|
||||
* @returns Plasticity metrics
|
||||
*/
|
||||
getPlasticityStats(): PlasticityStats;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Topology
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a feedforward network
|
||||
* @param layerSizes Neurons per layer
|
||||
* @param connectivity Connection probability between layers
|
||||
*/
|
||||
createFeedforward(layerSizes: number[], connectivity?: number): void;
|
||||
|
||||
/**
|
||||
* Create a recurrent network
|
||||
* @param size Number of neurons
|
||||
* @param connectivity Recurrent connection probability
|
||||
*/
|
||||
createRecurrent(size: number, connectivity?: number): void;
|
||||
|
||||
/**
|
||||
* Create a reservoir network (Echo State Network style)
|
||||
* @param size Reservoir size
|
||||
* @param spectralRadius Target spectral radius
|
||||
* @param inputSize Number of input neurons
|
||||
*/
|
||||
createReservoir(size: number, spectralRadius?: number, inputSize?: number): void;
|
||||
|
||||
/**
|
||||
* Create small-world network topology
|
||||
* @param size Number of neurons
|
||||
* @param k Number of nearest neighbors
|
||||
* @param beta Rewiring probability
|
||||
*/
|
||||
createSmallWorld(size: number, k?: number, beta?: number): void;
|
||||
|
||||
/**
|
||||
* Get network statistics
|
||||
* @returns Topology metrics
|
||||
*/
|
||||
getTopologyStats(): TopologyStats;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Recording
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Start recording neuron activity
|
||||
* @param neuronIds Neurons to record (empty = all)
|
||||
*/
|
||||
startRecording(neuronIds?: string[]): void;
|
||||
|
||||
/**
|
||||
* Stop recording
|
||||
* @returns Recorded activity
|
||||
*/
|
||||
stopRecording(): RecordedActivity;
|
||||
|
||||
/**
|
||||
* Get spike raster
|
||||
* @param startTime Start time
|
||||
* @param endTime End time
|
||||
* @returns Spike times per neuron
|
||||
*/
|
||||
getSpikeRaster(startTime?: number, endTime?: number): Map<string, number[]>;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Supporting Types
|
||||
// ============================================================================
|
||||
|
||||
/** Neuron configuration */
|
||||
export interface NeuronConfig {
|
||||
id?: string;
|
||||
neuronType?: 'excitatory' | 'inhibitory' | 'modulatory';
|
||||
model?: NeuronModel;
|
||||
threshold?: number;
|
||||
restPotential?: number;
|
||||
resetPotential?: number;
|
||||
refractoryPeriod?: number;
|
||||
leakConductance?: number;
|
||||
capacitance?: number;
|
||||
}
|
||||
|
||||
/** Neuron model type */
|
||||
export type NeuronModel =
|
||||
| 'lif' // Leaky Integrate-and-Fire
|
||||
| 'izhikevich' // Izhikevich model
|
||||
| 'hh' // Hodgkin-Huxley
|
||||
| 'adex' // Adaptive Exponential
|
||||
| 'srm' // Spike Response Model
|
||||
| 'if'; // Integrate-and-Fire
|
||||
|
||||
/** Synapse configuration */
|
||||
export interface SynapseConfig {
|
||||
weight?: number;
|
||||
delay?: number;
|
||||
plasticity?: PlasticityRule;
|
||||
synapseType?: 'ampa' | 'nmda' | 'gaba_a' | 'gaba_b' | 'generic';
|
||||
timeConstant?: number;
|
||||
}
|
||||
|
||||
/** STDP configuration */
|
||||
export interface StdpConfig {
|
||||
tauPlus: number; // Time constant for potentiation
|
||||
tauMinus: number; // Time constant for depression
|
||||
aPlus: number; // Amplitude for potentiation
|
||||
aMinus: number; // Amplitude for depression
|
||||
wMax: number; // Maximum weight
|
||||
wMin: number; // Minimum weight
|
||||
}
|
||||
|
||||
/** Neuron filter criteria */
|
||||
export interface NeuronFilter {
|
||||
type?: 'excitatory' | 'inhibitory' | 'modulatory';
|
||||
model?: NeuronModel;
|
||||
minPotential?: number;
|
||||
maxPotential?: number;
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
/** Simulation result */
|
||||
export interface SimulationResult {
|
||||
timestep: number;
|
||||
spikes: string[]; // IDs of neurons that spiked
|
||||
averagePotential: number;
|
||||
averageFiringRate: number;
|
||||
energyConsumed: number;
|
||||
}
|
||||
|
||||
/** Plasticity statistics */
|
||||
export interface PlasticityStats {
|
||||
averageWeightChange: number;
|
||||
potentiationCount: number;
|
||||
depressionCount: number;
|
||||
synapsesPruned: number;
|
||||
synapsesCreated: number;
|
||||
}
|
||||
|
||||
/** Topology statistics */
|
||||
export interface TopologyStats {
|
||||
neuronCount: number;
|
||||
synapseCount: number;
|
||||
averageConnectivity: number;
|
||||
clusteringCoefficient: number;
|
||||
averagePathLength: number;
|
||||
spectralRadius: number;
|
||||
}
|
||||
|
||||
/** Recorded neural activity */
|
||||
export interface RecordedActivity {
|
||||
duration: number;
|
||||
neuronIds: string[];
|
||||
potentials: Float32Array[]; // Time series per neuron
|
||||
spikeTimes: Map<string, number[]>;
|
||||
samplingRate: number;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Factory and Utilities
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Create a nervous system engine instance
|
||||
* @param config Optional configuration
|
||||
* @returns Initialized nervous engine
|
||||
*/
|
||||
export function createNervousEngine(config?: NervousConfig): NervousEngine {
|
||||
const defaultConfig: NervousConfig = {
|
||||
maxNeurons: 10000,
|
||||
simulationDt: 0.1,
|
||||
enablePlasticity: true,
|
||||
...config,
|
||||
};
|
||||
|
||||
// Internal state
|
||||
const neurons = new Map<string, Neuron>();
|
||||
const synapses: Synapse[] = [];
|
||||
let neuronIdCounter = 0;
|
||||
let currentTime = 0;
|
||||
|
||||
return {
|
||||
createNeuron: (neuronConfig) => {
|
||||
const id = neuronConfig.id || `neuron_${neuronIdCounter++}`;
|
||||
const neuron: Neuron = {
|
||||
id,
|
||||
potential: neuronConfig.restPotential ?? -70,
|
||||
threshold: neuronConfig.threshold ?? -55,
|
||||
refractory: 0,
|
||||
neuronType: neuronConfig.neuronType ?? 'excitatory',
|
||||
};
|
||||
neurons.set(id, neuron);
|
||||
return id;
|
||||
},
|
||||
removeNeuron: (neuronId) => {
|
||||
neurons.delete(neuronId);
|
||||
},
|
||||
getNeuron: (neuronId) => neurons.get(neuronId),
|
||||
updateNeuron: (neuronId, params) => {
|
||||
const neuron = neurons.get(neuronId);
|
||||
if (neuron) {
|
||||
Object.assign(neuron, params);
|
||||
}
|
||||
},
|
||||
listNeurons: (filter) => {
|
||||
let result = Array.from(neurons.values());
|
||||
if (filter) {
|
||||
if (filter.type) {
|
||||
result = result.filter(n => n.neuronType === filter.type);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
createSynapse: (presynapticId, postsynapticId, synapseConfig) => {
|
||||
const synapse: Synapse = {
|
||||
presynapticId,
|
||||
postsynapticId,
|
||||
weight: synapseConfig?.weight ?? 1.0,
|
||||
delay: synapseConfig?.delay ?? 1.0,
|
||||
plasticity: synapseConfig?.plasticity ?? { type: 'stdp', params: {} },
|
||||
};
|
||||
synapses.push(synapse);
|
||||
return `${presynapticId}->${postsynapticId}`;
|
||||
},
|
||||
removeSynapse: (presynapticId, postsynapticId) => {
|
||||
const idx = synapses.findIndex(
|
||||
s => s.presynapticId === presynapticId && s.postsynapticId === postsynapticId
|
||||
);
|
||||
if (idx >= 0) synapses.splice(idx, 1);
|
||||
},
|
||||
getSynapse: (presynapticId, postsynapticId) => {
|
||||
return synapses.find(
|
||||
s => s.presynapticId === presynapticId && s.postsynapticId === postsynapticId
|
||||
);
|
||||
},
|
||||
updateSynapse: (presynapticId, postsynapticId, params) => {
|
||||
const synapse = synapses.find(
|
||||
s => s.presynapticId === presynapticId && s.postsynapticId === postsynapticId
|
||||
);
|
||||
if (synapse) {
|
||||
Object.assign(synapse, params);
|
||||
}
|
||||
},
|
||||
listSynapses: (neuronId, direction = 'both') => {
|
||||
return synapses.filter(s => {
|
||||
if (direction === 'outgoing') return s.presynapticId === neuronId;
|
||||
if (direction === 'incoming') return s.postsynapticId === neuronId;
|
||||
return s.presynapticId === neuronId || s.postsynapticId === neuronId;
|
||||
});
|
||||
},
|
||||
step: (dt = defaultConfig.simulationDt!) => {
|
||||
currentTime += dt;
|
||||
const spikes: string[] = [];
|
||||
// Placeholder: actual simulation delegated to WASM
|
||||
return {
|
||||
timestep: currentTime,
|
||||
spikes,
|
||||
averagePotential: 0,
|
||||
averageFiringRate: 0,
|
||||
energyConsumed: 0,
|
||||
};
|
||||
},
|
||||
injectCurrent: (injections) => {
|
||||
// WASM call: ruvector_nervous_inject(injections)
|
||||
},
|
||||
propagate: (sourceIds, signal) => {
|
||||
// WASM call: ruvector_nervous_propagate(sourceIds, signal)
|
||||
return {
|
||||
activatedNeurons: [],
|
||||
spikeTimings: new Map(),
|
||||
totalActivity: 0,
|
||||
};
|
||||
},
|
||||
getState: () => ({
|
||||
neurons,
|
||||
synapses,
|
||||
globalModulation: 1.0,
|
||||
timestamp: currentTime,
|
||||
}),
|
||||
setState: (state) => {
|
||||
neurons.clear();
|
||||
state.neurons.forEach((v, k) => neurons.set(k, v));
|
||||
synapses.length = 0;
|
||||
synapses.push(...state.synapses);
|
||||
currentTime = state.timestamp;
|
||||
},
|
||||
reset: (keepTopology = false) => {
|
||||
if (!keepTopology) {
|
||||
neurons.clear();
|
||||
synapses.length = 0;
|
||||
} else {
|
||||
neurons.forEach(n => {
|
||||
n.potential = -70;
|
||||
n.refractory = 0;
|
||||
});
|
||||
}
|
||||
currentTime = 0;
|
||||
},
|
||||
applyPlasticity: (rule, learningRate = 1.0) => {
|
||||
// WASM call: ruvector_nervous_plasticity(rule, learningRate)
|
||||
},
|
||||
applyStdp: (stdpConfig) => {
|
||||
// WASM call: ruvector_nervous_stdp(config)
|
||||
},
|
||||
applyHomeostasis: (targetRate = 10) => {
|
||||
// WASM call: ruvector_nervous_homeostasis(targetRate)
|
||||
},
|
||||
getPlasticityStats: () => ({
|
||||
averageWeightChange: 0,
|
||||
potentiationCount: 0,
|
||||
depressionCount: 0,
|
||||
synapsesPruned: 0,
|
||||
synapsesCreated: 0,
|
||||
}),
|
||||
createFeedforward: (layerSizes, connectivity = 1.0) => {
|
||||
// WASM call: ruvector_nervous_create_feedforward(layerSizes, connectivity)
|
||||
},
|
||||
createRecurrent: (size, connectivity = 0.1) => {
|
||||
// WASM call: ruvector_nervous_create_recurrent(size, connectivity)
|
||||
},
|
||||
createReservoir: (size, spectralRadius = 0.9, inputSize = 10) => {
|
||||
// WASM call: ruvector_nervous_create_reservoir(size, spectralRadius, inputSize)
|
||||
},
|
||||
createSmallWorld: (size, k = 4, beta = 0.1) => {
|
||||
// WASM call: ruvector_nervous_create_small_world(size, k, beta)
|
||||
},
|
||||
getTopologyStats: () => ({
|
||||
neuronCount: neurons.size,
|
||||
synapseCount: synapses.length,
|
||||
averageConnectivity: neurons.size > 0 ? synapses.length / neurons.size : 0,
|
||||
clusteringCoefficient: 0,
|
||||
averagePathLength: 0,
|
||||
spectralRadius: 0,
|
||||
}),
|
||||
startRecording: (neuronIds) => {
|
||||
// WASM call: ruvector_nervous_start_recording(neuronIds)
|
||||
},
|
||||
stopRecording: () => ({
|
||||
duration: 0,
|
||||
neuronIds: [],
|
||||
potentials: [],
|
||||
spikeTimes: new Map(),
|
||||
samplingRate: 1000,
|
||||
}),
|
||||
getSpikeRaster: (startTime = 0, endTime = currentTime) => {
|
||||
// WASM call: ruvector_nervous_get_raster(startTime, endTime)
|
||||
return new Map();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create default STDP configuration
|
||||
*/
|
||||
export function createStdpConfig(): StdpConfig {
|
||||
return {
|
||||
tauPlus: 20,
|
||||
tauMinus: 20,
|
||||
aPlus: 0.01,
|
||||
aMinus: 0.012,
|
||||
wMax: 1.0,
|
||||
wMin: 0.0,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Izhikevich neuron parameters for different types
|
||||
*/
|
||||
export function izhikevichParams(type: 'regular' | 'bursting' | 'chattering' | 'fast'): {
|
||||
a: number;
|
||||
b: number;
|
||||
c: number;
|
||||
d: number;
|
||||
} {
|
||||
const params = {
|
||||
regular: { a: 0.02, b: 0.2, c: -65, d: 8 },
|
||||
bursting: { a: 0.02, b: 0.2, c: -50, d: 2 },
|
||||
chattering: { a: 0.02, b: 0.2, c: -50, d: 2 },
|
||||
fast: { a: 0.1, b: 0.2, c: -65, d: 2 },
|
||||
};
|
||||
return params[type];
|
||||
}
|
||||
Reference in New Issue
Block a user