summaryrefslogtreecommitdiff
path: root/src/spires_interface.c
diff options
context:
space:
mode:
authorYour Name <[email protected]>2026-07-27 20:34:44 -0700
committerYour Name <[email protected]>2026-07-27 20:34:44 -0700
commit09c8f740da0b833c08c78fa30f80e3dc04e218c4 (patch)
tree0342805863c80512a04d5a195cb3dd1f478a1354 /src/spires_interface.c
parenta0e9d74ec2623a2ed72c4b98d9d1f8f2c28e1fb2 (diff)
Trained software weights with ridge regression
Diffstat (limited to 'src/spires_interface.c')
-rw-r--r--src/spires_interface.c114
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;