chore: remove unused prototypes/ and spike/ dirs

This commit is contained in:
2026-08-27 18:16:34 +02:00
parent b9877bfff5
commit f8c0c871c6
4 changed files with 0 additions and 183 deletions
-111
View File
@@ -1,111 +0,0 @@
## ga_spike.nim — throwaway GA neuroevolution spike: evolve ANN to predict sin(x)
## Validates: population init, fitness eval, truncation selection, gaussian
## mutation on all weights, single-elite preservation, champion tracking.
## Issue #66.
import std/[math, random, algorithm, strformat]
const
InputDim = 10 # sliding window of 10 past sin values
HiddenDim = 4
OutputDim = 1
NumWeights = (InputDim * HiddenDim + HiddenDim) + # W1 + b1
(HiddenDim * OutputDim + OutputDim) # W2 + b2 = 49
PopSize = 200
Generations = 200
TopFrac = 0.2 # keep top 20%
Sigma = 0.01 # gaussian mutation sigma on ALL weights
EvalPoints = 50 # fitness eval sample size
type Individual = object
weights: seq[float64]
fitness: float64
proc forward(w: seq[float64]; input: array[InputDim, float64]): float64 =
## 10->4->1 tanh ANN, flat weight layout: W1[40], b1[4], W2[4], b2[1]
var hidden: array[HiddenDim, float64]
for h in 0..<HiddenDim:
var s = w[InputDim * HiddenDim + h] # b1[h]
for i in 0..<InputDim:
s += w[h * InputDim + i] * input[i] # W1[h,i]
hidden[h] = tanh(s)
var s = w[InputDim * HiddenDim + HiddenDim + HiddenDim] # b2[0]
for h in 0..<HiddenDim:
s += w[InputDim * HiddenDim + HiddenDim + h] * hidden[h] # W2[h]
result = tanh(s)
proc evaluate(ind: var Individual; rng: var Rand) =
## Fitness = -MSE on EvalPoints random samples of sin prediction.
var mse = 0.0
for _ in 0..<EvalPoints:
let x = rng.rand(0.0 .. 20.0 * PI)
var input: array[InputDim, float64]
for i in 0..<InputDim:
input[i] = sin(x - float64(InputDim - 1 - i))
let target = sin(x)
let pred = forward(ind.weights, input)
mse += (pred - target) * (pred - target)
ind.fitness = -mse / EvalPoints.float64
proc mutate(ind: var Individual; rng: var Rand) =
## Additive gaussian on ALL weights, per GA-parameters research.
for i in 0..<ind.weights.len:
ind.weights[i] += rng.gauss(0.0, Sigma)
when isMainModule:
var rng = initRand(42)
# Init population: random weights in [-0.5, 0.5]
var pop = newSeq[Individual](PopSize)
for i in 0..<PopSize:
pop[i].weights = newSeq[float64](NumWeights)
for j in 0..<NumWeights:
pop[i].weights[j] = rng.rand(-0.5 .. 0.5)
echo &"GA spike: {PopSize} individuals, {NumWeights} weights, {Generations} gens, sigma={Sigma}"
for gen in 0..<Generations:
# Evaluate
for i in 0..<PopSize:
pop[i].evaluate(rng)
# Sort descending by fitness (higher = better)
pop.sort(proc(a, b: Individual): int = cmp(b.fitness, a.fitness))
if gen mod 20 == 0 or gen == Generations - 1:
echo &" gen {gen:3d} best_fitness={pop[0].fitness:.6f} (MSE={-pop[0].fitness:.6f})"
# Selection: keep top 20%
let nParents = max(1, int(PopSize.float64 * TopFrac))
# Next generation: elite(1) + mutated children from parents
var next = newSeq[Individual](PopSize)
next[0] = pop[0] # single elite, unchanged
for i in 1..<PopSize:
let parent = rng.rand(0..<nParents)
next[i].weights = pop[parent].weights # clone parent
next[i].mutate(rng)
pop = next
# Final evaluation of champion
pop[0].evaluate(rng)
echo &"\nChampion fitness: {pop[0].fitness:.6f} (MSE={-pop[0].fitness:.6f})"
# Print predictions vs actual
echo "\nPredictions (sample):"
var totalErr = 0.0
let nSamples = 20
for i in 0..<nSamples:
let x = float64(i) * 1.0
var input: array[InputDim, float64]
for j in 0..<InputDim:
input[j] = sin(x - float64(InputDim - 1 - j))
let target = sin(x)
let pred = forward(pop[0].weights, input)
totalErr += abs(pred - target)
echo &" x={x:5.1f} sin(x)={target:+.4f} pred={pred:+.4f} err={abs(pred-target):.4f}"
let avgErr = totalErr / nSamples.float64
echo &"\nAverage absolute error: {avgErr:.4f}"
assert avgErr < 0.1, &"Champion avg error {avgErr:.4f} >= 0.1 — evolution did not converge"
echo "PASS: assert avgErr < 0.1"
@@ -1,9 +0,0 @@
# Package
version = "0.1.0"
author = "SirStone"
description = "Arraymancer viability spike — XOR perceptron"
license = "MIT"
# Dependencies
requires "nim >= 2.0.0"
requires "arraymancer >= 0.7.0"
Binary file not shown.
-63
View File
@@ -1,63 +0,0 @@
import arraymancer
import std/[strformat, times]
# XOR dataset — [4,2] inputs, [4,1] targets
let xData = [[0.0'f32, 0.0'f32],
[0.0'f32, 1.0'f32],
[1.0'f32, 0.0'f32],
[1.0'f32, 1.0'f32]].toTensor()
let yData = [[0.0'f32], [1.0'f32], [1.0'f32], [0.0'f32]].toTensor()
var ctx = newContext Tensor[float32]
let l1 = ctx.init(Linear[float32], 2, 4)
let l2 = ctx.init(Linear[float32], 4, 1)
type XorNet = object
l1: Linear[float32]
l2: Linear[float32]
var net = XorNet(l1: l1, l2: l2)
var adam = optimizer(net, Adam, learning_rate = 0.01'f32)
let t0 = cpuTime()
for epoch in 1..1000:
let xVar = ctx.variable(xData)
let yVar = ctx.variable(yData)
# Forward
let h = l1.forward(xVar).sigmoid()
let pred = l2.forward(h).sigmoid()
# MSE loss: mean((pred - y)^2)
let diff = pred - yVar
let loss = mean(diff *. diff)
if epoch mod 200 == 0:
echo &"Epoch {epoch:4d} loss = {loss.value[0]:.6f}"
loss.backprop()
adam.update()
let trainTime = cpuTime() - t0
# Inference (no grad)
echo ""
echo "Final predictions:"
let xVar = ctx.variable(xData)
let hInf = l1.forward(xVar).sigmoid()
let preds = l2.forward(hInf).sigmoid()
var allCorrect = true
for i in 0..<4:
let p = preds.value[i, 0]
let rounded = if p >= 0.5'f32: 1 else: 0
let expected = [0,1,1,0][i]
if rounded != expected: allCorrect = false
echo &" [{xData[i,0].int},{xData[i,1].int}] -> {p:.4f} (rounded: {rounded}, expected: {expected})"
echo ""
echo &"All correct: {allCorrect}"
echo &"Training time: {trainTime:.2f}s"