Skip to content

Instantly share code, notes, and snippets.

@synthetiv
Created August 5, 2020 00:43
Show Gist options
  • Save synthetiv/e6c4a15187de85597d97921260fa8352 to your computer and use it in GitHub Desktop.
Save synthetiv/e6c4a15187de85597d97921260fa8352 to your computer and use it in GitHub Desktop.
-- 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