Skip to contentSkip to Content

Quickstart

This page walks you through a complete SPIRES program in under five minutes. By the end you will have a reservoir that trains on a sine wave and predicts future values.

The Minimal Program

Here is the shortest useful SPIRES program. It configures a reservoir, drives it with a sine-wave input, trains a readout with ridge regression, and runs inference on a fresh input sequence.

#include <spires.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #define N_TRAIN 500 #define N_TEST 100 #define PI 3.14159265358979323846 int main(void) { /* 1. Configure the reservoir */ spires_reservoir_config cfg = { .num_neurons = 400, .num_inputs = 1, .num_outputs = 1, .spectral_radius = 0.95, .ei_ratio = 0.8, .input_strength = 0.1, .connectivity = 0.1, .dt = 1.0, .connectivity_type = SPIRES_CONN_RANDOM, .neuron_type = SPIRES_NEURON_LIF_DISCRETE, .neuron_params = NULL, }; /* 2. Create the reservoir */ spires_reservoir *r = NULL; spires_status s = spires_reservoir_create(&cfg, &r); if (s != SPIRES_OK) { fprintf(stderr, "Failed to create reservoir: %d\n", s); return 1; } /* 3. Generate training data — predict sin(t+1) from sin(t) */ double input_train[N_TRAIN]; double target_train[N_TRAIN]; for (int i = 0; i < N_TRAIN; i++) { input_train[i] = sin(2.0 * PI * i / 50.0); target_train[i] = sin(2.0 * PI * (i + 1) / 50.0); } /* 4. Train with ridge regression */ s = spires_train_ridge(r, input_train, target_train, N_TRAIN, 1e-6); if (s != SPIRES_OK) { fprintf(stderr, "Training failed: %d\n", s); spires_reservoir_destroy(r); return 1; } /* 5. Generate test input */ double input_test[N_TEST]; for (int i = 0; i < N_TEST; i++) { input_test[i] = sin(2.0 * PI * (N_TRAIN + i) / 50.0); } /* 6. Run inference */ double *predictions = spires_run(r, input_test, N_TEST); if (!predictions) { fprintf(stderr, "Inference failed\n"); spires_reservoir_destroy(r); return 1; } /* 7. Print a few predictions vs. expected values */ printf("Step | Predicted | Expected\n"); printf("-----+-----------+---------\n"); for (int i = 0; i < 10; i++) { double expected = sin(2.0 * PI * (N_TRAIN + i + 1) / 50.0); printf("%4d | %+.5f | %+.5f\n", i, predictions[i], expected); } /* 8. Clean up */ free(predictions); spires_reservoir_destroy(r); return 0; }

Tip: spires_run() allocates its return buffer with malloc. You own the memory and must call free() when you are finished with it.

Compile and Run

gcc -O2 -o quickstart quickstart.c \ -I/path/to/spires/include \ -L/path/to/spires/build \ -lspires -lopenblas -llapacke -lm -fopenmp ./quickstart

You should see output like:

Step | Predicted | Expected -----+-----------+--------- 0 | +0.95080 | +0.95106 1 | +0.92928 | +0.92978 2 | +0.90451 | +0.90483 ...

What Just Happened?

The program above follows the standard SPIRES workflow:

  1. Configure — Fill in a spires_reservoir_config struct with your desired network size, neuron model, and topology.
  2. Create — Call spires_reservoir_create() to allocate and initialize the reservoir.
  3. Train — Feed an input/target pair to spires_train_ridge(). The library drives the reservoir with the input series internally, collects neuron states, and solves for readout weights using Tikhonov (ridge) regression.
  4. Infer — Call spires_run() with new input data. The reservoir processes each time step and multiplies the resulting states by the trained readout weights.
  5. Clean up — Free the prediction buffer and destroy the reservoir.

Key Configuration Choices

FieldValue UsedWhy
num_neurons400Large enough to capture the sine dynamics without being slow
spectral_radius0.95Close to 1.0 gives good short-term memory; above 1.0 risks instability
ei_ratio0.880% excitatory / 20% inhibitory is a biologically plausible default
connectivity0.1Sparse connectivity keeps computation fast
neuron_typeSPIRES_NEURON_LIF_DISCRETESimplest spiking model; good starting point

Next Steps

  • Read the First Reservoir tutorial for a detailed walkthrough of every configuration option and both training methods.
  • See Building from Source for advanced build options, platform notes, and cross-compilation.
  • Browse the API Reference for the full function and type documentation.

← Installation | First Reservoir →

Last updated on