Created
August 5, 2020 00:43
-
-
Save synthetiv/e6c4a15187de85597d97921260fa8352 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- discipline + punish | |
-- | |
-- four outputs (subjects) process input 1 through randomized transfer functions (disciplines) | |
-- a trigger in input 2 selects a subject based on a fifth, secret discipline, | |
-- and punishes it, altering its transfer function | |
function rand10vpp() | |
return math.random() * 10 - 5 | |
end | |
local Discipline = {} | |
Discipline.__index = Discipline | |
function Discipline.new() | |
local self = setmetatable({}, Discipline) | |
local points = {} | |
local n_points = math.random(5) | |
for p = 1, n_points do | |
points[p] = { | |
max = rand10vpp() | |
} | |
end | |
table.sort(points, function(a, b) | |
return a.max < b.max | |
end) | |
for p = 1, n_points do | |
points[p].out_min = rand10vpp() | |
points[p].out_max = rand10vpp() | |
end | |
self.points = points | |
return self | |
end | |
function Discipline:__call(v) | |
local min = -5 | |
for p = 1, #self.points do | |
local point = self.points[p] | |
if point.max >= v then | |
v = (v - min) / (point.max - min) | |
v = (1 - v) * point.out_min + v * point.out_max | |
return v | |
end | |
min = point.max | |
end | |
return v | |
end | |
local Subject = {} | |
Subject.__index = Subject | |
function Subject.new(o) | |
local self = setmetatable({}, Subject) | |
output[o].slew = rate | |
output[o].shape = 'linear' | |
self.output = output[o] | |
self:punish() | |
return self | |
end | |
function Subject:punish() | |
self.discipline = Discipline.new() | |
end | |
function Subject:process(v) | |
self.output.volts = self.discipline(v) | |
end | |
subjects = { | |
Subject.new(1), | |
Subject.new(2), | |
Subject.new(3), | |
Subject.new(4) | |
} | |
surveyor = { | |
query = 0, | |
discipline = Discipline.new() | |
} | |
function surveyor:choose() | |
local v = self.discipline(self.query) | |
v = (v + 5) * 4 / 10 | |
v = math.ceil(v) | |
return v | |
end | |
local rate = 0.01 | |
input[1].mode('stream', rate) | |
input[1].stream = function(v) | |
surveyor.query = v | |
for o = 1, 4 do | |
subjects[o]:process(v) | |
end | |
end | |
input[2].mode('change') | |
input[2].change = function(state) | |
if state then | |
local s = surveyor:choose() | |
print('punishing subject ' .. s) | |
subjects[s]:punish() | |
surveyor.discipline = Discipline.new() | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment