summaryrefslogtreecommitdiff
path: root/src/mind/topology.js
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-06-11 22:20:04 -0500
committersanine <sanine.not@pm.me>2023-06-11 22:20:04 -0500
commit3b0b005b952b1092404fdd5ae1732ec9561794af (patch)
tree1121694d35ad513d816cba7759eef7ea04d647d2 /src/mind/topology.js
parent2fdb91f84f6de8c03dcc9c50c20ea2fa79e255c1 (diff)
add basic computations
Diffstat (limited to 'src/mind/topology.js')
-rw-r--r--src/mind/topology.js56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/mind/topology.js b/src/mind/topology.js
index 755fe4a..1cd52d3 100644
--- a/src/mind/topology.js
+++ b/src/mind/topology.js
@@ -8,6 +8,9 @@ const graph_proto = {
connect: function(source, sink, weight) {
return network_connect(this, source, sink, weight);
},
+ compute: function(inputs, state) {
+ return network_compute(this, inputs, state);
+ },
};
export function network(input_count, internal_count, output_count, weight_max = 4) {
@@ -58,3 +61,56 @@ function network_connect(n, source, sink, weight) {
return Object.freeze(nn);
}
+
+
+function incident_edges(n, adj) {
+ const incident = adj
+ .map((edge, index) => edge < 0 ? index : null)
+ .filter(index => index !== null);
+
+ return incident;
+}
+
+
+function edge_ends(n, edge) {
+ const ends = n.adjacency
+ .map((adj, index) => adj[edge] !== 0 ? index : null)
+ .filter(index => index != null);
+
+ ends.sort((a, b) => n.adjacency[a][edge] < n.adjacency[b][edge] ? -1 : 1);
+
+ return ends;
+}
+
+
+function get_value(n, index, input) {
+ if (is_input(n, index)) {
+ return input[index];
+ }
+ const adj = n.adjacency[index];
+ const incident = incident_edges(n, adj);
+ const weight = incident.map(x => n.weight[x]);
+ const sources = incident
+ .map(x => edge_ends(n, x))
+ .map(x => x.length === 2 ? x[1] : x[0]);
+
+ const sum = sources
+ .reduce((acc, x, i) => acc + (weight[i] * get_value(n, x, input)), 0);
+
+ return Math.tanh(sum);
+}
+
+
+function network_compute(n, input, state) {
+ const outputs = n.adjacency
+ .map((x, i) => is_output(n, i) ? i : null)
+ .filter(i => i !== null);
+
+ const output = Object.freeze(
+ outputs.map(x => get_value(n, x, input))
+ );
+
+ const newstate = Object.freeze([]);
+
+ return Object.freeze([output, newstate]);
+}