In [1]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import nengo

In [30]:
dt = 0.001

class System(object):
    def __init__(self):
        self.value = 0.0
    def update(self, x):
        self.value += dt * x * 20
        if abs(self.value) > 1:
            self.value *= 0.99
        #self.value = np.clip(self.value, -1, 1)
        return self.value
    def make_node(self):
        return nengo.Node(lambda t, x: self.update(x), size_in=1, size_out=1)
        
class Target(object):
    def __init__(self):
        self.target = 0.5
        self.chosen = 0
    def update_target(self, x):
        self.target = x
        return x
    def make_target_node(self):
        return nengo.Node(lambda t, x: self.update_target(x), size_in=1, size_out=1)
    def make_chosen_node(self):
        return nengo.Node(lambda t: self.chosen)
    
target = Target()
        
sys = System()
        
N = 3
times = np.linspace(0, 0.1, N)
#times = [0]
model = nengo.Network()
with model:
    system = sys.make_node()
    
    targ = target.make_target_node()
    #ctrl_target = nengo.Node(lambda t: np.sign(np.sin(t*2*np.pi*2))*0.5)
    ctrl_target = nengo.Node(lambda t: np.sin(t*2*np.pi*2)*0.5)
    
    nengo.Connection(ctrl_target, targ, synapse=None)
    my_choice = nengo.Node(None, size_in=1)
    
    predictor = nengo.Ensemble(n_neurons=500, dimensions=2, neuron_type=nengo.LIFRate())
    nengo.Connection(system, predictor[0], synapse=0)
    
    #ctrl = nengo.Node(np.cos)
    
    nengo.Connection(my_choice, system, synapse=None)
    nengo.Connection(my_choice, predictor[1], synapse=None)
    
    future = nengo.Node(None, size_in=len(times))
    
    
    conns = []
    probes = []
    for i, t in enumerate(times):
        def ideal(x, t=t):
            return 0
            theta = np.arctan2(x[1], x[0])
            return np.cos(theta-t)
        
        c = nengo.Connection(predictor, future[i], function=ideal,
                             synapse=None,
                             learning_rule_type=nengo.PES(
                                                          pre_synapse=t,
                                                          #pre_synapse=nengolib.synapses.DiscreteDelay(int(t/dt)),
                                                          learning_rate=1e-4))
        conns.append(c)
        probes.append(nengo.Probe(c, 'weights'))        
    
    error = nengo.Node(None, size_in=len(times))
    nengo.Connection(system, error, transform=-np.ones((len(times), 1)), synapse=None)
    for i, t in enumerate(times):
        nengo.Connection(future[i], error[i], 
                         synapse=t
                         #synapse=nengolib.synapses.DiscreteDelay(int(t/dt))
                        )
        nengo.Connection(error[i], conns[i].learning_rule, synapse=None)
        
        
    result = nengo.Node(None, size_in=2)
    nengo.Connection(system, result[0], synapse=None)
    nengo.Connection(ctrl_target, result[1])
    
    loss = nengo.networks.EnsembleArray(n_neurons=100, n_ensembles=len(times))
    nengo.Connection(future, loss.input, synapse=None)
    nengo.Connection(targ, loss.input, transform=-np.ones((len(times), 1)))
    loss_total = loss.add_output('loss', lambda x: x**2)
    
    y = nengo.Node(None, size_in=1)
    nengo.Connection(loss_total, y, transform=np.ones((1,len(times))), synapse=None)
    
    
    q = nengo.networks.EnsembleArray(n_neurons=100, n_ensembles=2)
    error = nengo.networks.EnsembleArray(n_neurons=100, n_ensembles=2)
    c_up = nengo.Connection(predictor, q.input[0], function=lambda x: 0, learning_rule_type=nengo.PES(learning_rate=1e-3))
    c_dn = nengo.Connection(predictor, q.input[1], function=lambda x: 0, learning_rule_type=nengo.PES(learning_rate=1e-3))
    inh = -1
    
    choice = nengo.networks.EnsembleArray(n_neurons=100, n_ensembles=2, encoders=nengo.dists.Choice([[1]]),
                                     intercepts=nengo.dists.Uniform(0,1))
    nengo.Connection(q.output, choice.input)
    nengo.Connection(choice.output, choice.input, transform=[[0,inh],[inh,0]])
    nengo.Connection(choice.output[0], error.all_ensembles[1].neurons, transform=-10*np.ones((100, 1)))
    nengo.Connection(choice.output[1], error.all_ensembles[0].neurons, transform=-10*np.ones((100, 1)))
    nengo.Connection(q.output, error.input)
    
    dydt = nengo.Node(None, size_in=1)
    nengo.Connection(y, dydt, synapse=0.005, transform=-1)
    nengo.Connection(y, dydt, synapse=0.050, transform=1)
    nengo.Connection(dydt, error.input, transform=-np.ones((2,1)))
    nengo.Connection(error.output[0], c_up.learning_rule)
    nengo.Connection(error.output[1], c_dn.learning_rule)
    
    
    internal = nengo.Ensemble(n_neurons=500, dimensions=1)
    nengo.Connection(internal, internal, synapse=0.1)
    nengo.Connection(choice.output, internal, synapse=0.1, transform=[[-1,1]])
    nengo.Connection(internal, my_choice, synapse=None)
    
    bias = nengo.Node(0.5)
    nengo.Connection(bias, choice.input, transform=np.ones((2,1)))

In [31]:
import nengo_gui.jupyter
nengo_gui.jupyter.InlineGUI(model, cfg='mpc.cfg')


c:\users\terry\documents\github\nengo_gui\nengo_gui\jupyter.py:70: ConfigReuseWarning: Reusing config. Only the most recent visualization will update the config.
  "Reusing config. Only the most recent visualization will "

In [ ]: