Nonlinear oscillator

This example implements a nonlinear harmonic oscillator in a 2D neural population. Unlike the simple oscillator whose recurrent connection implements a linear transformation, this model approximates a nonlinear function in the recurrent connection to yield oscillatory behavior.

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

import nengo
import nengo_loihi
nengo_loihi.set_defaults()
/home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/tensorflow/python/framework/dtypes.py:516: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint8 = np.dtype([("qint8", np.int8, 1)])
/home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/tensorflow/python/framework/dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_quint8 = np.dtype([("quint8", np.uint8, 1)])
/home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/tensorflow/python/framework/dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint16 = np.dtype([("qint16", np.int16, 1)])
/home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/tensorflow/python/framework/dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_quint16 = np.dtype([("quint16", np.uint16, 1)])
/home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/tensorflow/python/framework/dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint32 = np.dtype([("qint32", np.int32, 1)])
/home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/tensorflow/python/framework/dtypes.py:525: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  np_resource = np.dtype([("resource", np.ubyte, 1)])
/home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:541: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint8 = np.dtype([("qint8", np.int8, 1)])
/home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:542: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_quint8 = np.dtype([("quint8", np.uint8, 1)])
/home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:543: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint16 = np.dtype([("qint16", np.int16, 1)])
/home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:544: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_quint16 = np.dtype([("quint16", np.uint16, 1)])
/home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:545: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  _np_qint32 = np.dtype([("qint32", np.int32, 1)])
/home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py:550: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
  np_resource = np.dtype([("resource", np.ubyte, 1)])
WARNING: Logging before flag parsing goes to stderr.
W0812 13:20:35.527203 139840178767680 deprecation_wrapper.py:119] From /home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/nengo_dl/compat.py:30: The name tf.random_uniform is deprecated. Please use tf.random.uniform instead.

W0812 13:20:35.528610 139840178767680 deprecation_wrapper.py:119] From /home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/nengo_dl/__init__.py:39: The name tf.logging.set_verbosity is deprecated. Please use tf.compat.v1.logging.set_verbosity instead.

W0812 13:20:35.529559 139840178767680 deprecation_wrapper.py:119] From /home/travis/virtualenv/python3.5.2/lib/python3.5/site-packages/nengo_dl/__init__.py:39: The name tf.logging.WARN is deprecated. Please use tf.compat.v1.logging.WARN instead.

Creating the network in Nengo

Our model consists of one recurrently connected ensemble. Unlike the simple oscillator, we do not need to give this nonlinear oscillator an initial kick.

[2]:
tau = 0.1


def recurrent_func(x):
    x0, x1 = x
    r = np.sqrt(x0**2 + x1**2)
    a = np.arctan2(x1, x0)
    dr = -(r - 1)
    da = 3.0
    r = r + tau*dr
    a = a + tau*da
    return [r*np.cos(a), r*np.sin(a)]


with nengo.Network(label='Oscillator') as model:
    ens = nengo.Ensemble(200, dimensions=2)
    nengo.Connection(ens, ens,
                     function=recurrent_func,
                     synapse=tau)
    ens_probe = nengo.Probe(ens, synapse=0.1)

Running the network in Nengo

We can use Nengo to see the desired model output.

[3]:
with nengo.Simulator(model) as sim:
    sim.run(10)
t = sim.trange()
0%
 
0%
 
[4]:
def plot_over_time(t, data):
    plt.figure()
    plt.plot(t, data[ens_probe])
    plt.xlabel('Time (s)', fontsize='large')
    plt.legend(['$x_0$', '$x_1$'])


plot_over_time(t, sim.data)
../_images/examples_oscillator_nonlinear_6_0.png
[5]:
def plot_xy(data):
    plt.figure()
    plt.plot(data[ens_probe][:, 0], data[ens_probe][:, 1])
    plt.xlabel('$x_0$', fontsize='x-large')
    plt.ylabel('$x_1$', fontsize='x-large')


plot_xy(sim.data)
../_images/examples_oscillator_nonlinear_7_0.png

Running the network with Nengo Loihi

[6]:
with nengo_loihi.Simulator(model) as sim:
    sim.run(10)
t = sim.trange()
/home/travis/build/nengo/nengo-loihi/nengo_loihi/discretize.py:471: UserWarning: Lost 2 extra bits in weight rounding
  warnings.warn("Lost %d extra bits in weight rounding" % (-s2,))
[7]:
plot_over_time(t, sim.data)
../_images/examples_oscillator_nonlinear_10_0.png
[8]:
plot_xy(sim.data)
../_images/examples_oscillator_nonlinear_11_0.png