diff options
| author | Your Name <[email protected]> | 2026-07-27 20:34:44 -0700 |
|---|---|---|
| committer | Your Name <[email protected]> | 2026-07-27 20:34:44 -0700 |
| commit | 09c8f740da0b833c08c78fa30f80e3dc04e218c4 (patch) | |
| tree | 0342805863c80512a04d5a195cb3dd1f478a1354 /src/spires_interface.c | |
| parent | a0e9d74ec2623a2ed72c4b98d9d1f8f2c28e1fb2 (diff) | |
Trained software weights with ridge regression
Diffstat (limited to 'src/spires_interface.c')
| -rw-r--r-- | src/spires_interface.c | 114 |
1 files changed, 112 insertions, 2 deletions
diff --git a/src/spires_interface.c b/src/spires_interface.c index c920c33..0d69eba 100644 --- a/src/spires_interface.c +++ b/src/spires_interface.c @@ -4,9 +4,11 @@ #include <stdlib.h> #include <stdio.h> #include <stdint.h> +#include <stddef.h> +#include <math.h> int collect_reservoir_states( - const spires_reservoir *reservoir, + spires_reservoir *reservoir, const double *input_series, size_t series_length, Reservoir_State_Matrix *result @@ -15,7 +17,6 @@ int collect_reservoir_states( //RIP //clear the result first - // result->num_samples = 0; result->num_features = 0; result->states = NULL; @@ -67,6 +68,115 @@ int collect_reservoir_states( return 0; } +int map_signed_weights_to_resistance( + const double *weights, + size_t num_neurons, + size_t num_outputs, + double resistance_on, + double resistance_off, + double *resistances, + double *conductance_offset, + double *conductance_scale + ) { + //safety check arguments + if (weights == NULL || resistances == NULL || num_neurons == 0 || + num_outputs == 0 || resistance_on <= 0 || resistance_off <= resistance_on) { + return -1; + } + + const size_t count = num_neurons * num_outputs; + + const double conductance_max = 1.0 / resistance_on; + const double conductance_min = 1.0 / resistance_off; + + double max_absolute_weight = 0.0; + + for (size_t i = 0; i < count; i++) { + double magnitude = fabs(weights[i]); + + if (magnitude > max_absolute_weight) { + max_absolute_weight = magnitude; + } + } + + const double offset = + 0.5 * (conductance_max + conductance_min); + + if (max_absolute_weight == 0.0) { + for (size_t i = 0; i < count; i++) { + resistances[i] = 1.0 / offset; + } + + if (conductance_offset != NULL) { + *conductance_offset = offset; + } + + if (conductance_scale != NULL) { + *conductance_scale = 0.0; + } + + return 0; + } + + const double scale = + (conductance_max - conductance_min) / + (2.0 * max_absolute_weight); + + for (size_t i = 0; i < count; i++) { + double conductance = + offset + scale * weights[i]; + + /* + * Protect against small floating-point excursions. + */ + if (conductance < conductance_min) { + conductance = conductance_min; + } else if (conductance > conductance_max) { + conductance = conductance_max; + } + + resistances[i] = 1.0 / conductance; + } + + if (conductance_offset != NULL) { + *conductance_offset = offset; + } + + if (conductance_scale != NULL) { + *conductance_scale = scale; + } + + return 0; +} + +int train_reservoir( + spires_reservoir *reservoir, + double *input_series, + double *target_series, + size_t series_length, + double lambda +) { + spires_status status = spires_train_ridge( + reservoir, + (double *)input_series, + (double *)target_series, + series_length, + lambda + ); + + if (status != SPIRES_OK) { + fprintf(stderr, "Spires ridge training failed"); + return -1; + } + //need to figure out how to scale weights to conductance values, + + //that are then the reciprocal of the resistances + + //Also need to find some conversion for output column current, and target_series + return 0; + +} + void free_reservoir_state_matrix(Reservoir_State_Matrix *matrix) { if (!matrix) { return; |
