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 withmalloc. You own the memory and must callfree()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
./quickstartYou 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:
- Configure — Fill in a
spires_reservoir_configstruct with your desired network size, neuron model, and topology. - Create — Call
spires_reservoir_create()to allocate and initialize the reservoir. - 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. - Infer — Call
spires_run()with new input data. The reservoir processes each time step and multiplies the resulting states by the trained readout weights. - Clean up — Free the prediction buffer and destroy the reservoir.
Key Configuration Choices
| Field | Value Used | Why |
|---|---|---|
num_neurons | 400 | Large enough to capture the sine dynamics without being slow |
spectral_radius | 0.95 | Close to 1.0 gives good short-term memory; above 1.0 risks instability |
ei_ratio | 0.8 | 80% excitatory / 20% inhibitory is a biologically plausible default |
connectivity | 0.1 | Sparse connectivity keeps computation fast |
neuron_type | SPIRES_NEURON_LIF_DISCRETE | Simplest 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.
Last updated on