| -- 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