Ejemplo n.º 1
0
def _test_normalization(Simulator, sys, rng, normalizer, l1_lower,
                        lower, radius=5.0, dt=0.0001, T=1.0):
    l1_norms = np.empty(len(sys))
    for i, sub in enumerate(decompose_states(sys)):
        response = impulse(sub, dt=dt, length=int(T / dt))
        assert np.allclose(response[-10:], 0)
        l1_norms[i] = radius * np.sum(abs(response * dt))

    with Network() as model:
        stim = nengo.Node(output=lambda t: rng.choice([-radius, radius])
                          if t < T/2 else radius)
        tau = 0.02
        subnet = LinearNetwork(sys, n_neurons=1, synapse=tau, dt=dt,
                               input_synapse=tau,
                               radii=radius, normalizer=normalizer,
                               neuron_type=nengo.neurons.Direct())
        nengo.Connection(stim, subnet.input, synapse=None)
        p = nengo.Probe(subnet.x.output, synapse=None)

    assert ((l1_lower*subnet.info['radii'] <= l1_norms) |
            ((l1_norms <= 1e-6) & (subnet.info['radii'] <= 1e-6))).all()
    assert (l1_norms <= subnet.info['radii'] + 1e-4).all()

    with Simulator(model, dt=dt) as sim:
        sim.run(T)

    # lower bound includes both approximation error and the gap between
    # random {-1, 1} flip-flop inputs and the true worst-case input
    worst_x = np.max(abs(sim.data[p]), axis=0)
    assert (lower <= worst_x+1e-6).all()
    assert (worst_x <= 1+1e-6).all()
Ejemplo n.º 2
0
def test_state_norm(plt):
    # Choose a filter, timestep, and number of simulation timesteps
    sys = Alpha(0.1)
    dt = 0.000001
    length = 2000000

    # Modify the state-space to read out the state vector
    A, B, C, D = sys2ss(sys)
    old_C = C
    C = np.eye(len(A))
    D = np.zeros((len(A), B.shape[1]))

    response = np.empty((length, len(C)))
    for i in range(len(C)):
        # Simulate the state vector
        response[:, i] = impulse((A, B, C[i, :], D[i, :]), dt, length)

    # Check that the power of each state equals the H2-norm of each state
    # The analog case is the same after scaling since dt is approx 0.
    actual = norm(response, axis=0) * dt
    assert np.allclose(actual, state_norm(cont2discrete(sys, dt)))
    assert np.allclose(actual, state_norm(sys) * np.sqrt(dt))

    plt.figure()
    plt.plot(response[:, 0], label="$x_0$")
    plt.plot(response[:, 1], label="$x_1$")
    plt.plot(np.dot(response, old_C.T), label="$y$")
    plt.legend()
Ejemplo n.º 3
0
def test_box_filter(width, normalized):
    length = 20
    steps = width + 1
    sys = BoxFilter(width, normalized)
    y = impulse(sys, dt=None, length=length)

    amplitude = 1.0 / steps if normalized else 1.0
    y_ideal = amplitude * np.asarray([1]*steps + [0]*(length - steps))
    assert np.allclose(y, y_ideal)
Ejemplo n.º 4
0
def test_pade_delay(c):
    dt = 0.001
    length = 1000

    sys = PureDelay(c, order=4)
    response = impulse(sys, dt, length)

    offset = 10
    assert np.allclose(
        (np.argmax(response[offset:])+offset), c*length, atol=100)
Ejemplo n.º 5
0
def test_highpass(tau, order):
    sys = Highpass(tau, order)

    length = 1000
    dt = 0.001

    response = impulse(sys, dt, length)
    dft = np.fft.rfft(response, axis=0)
    p = abs(dft)

    # Check that the power is monotonically increasing
    assert np.allclose(np.sort(p), p)
Ejemplo n.º 6
0
def test_bandpass(freq, Q):
    sys = Bandpass(freq, Q)

    length = 10000
    dt = 0.0001

    response = impulse(sys, dt, length)
    dft = np.fft.rfft(response, axis=0)
    freqs = np.fft.rfftfreq(length, d=dt)
    cp = abs(dft).cumsum()

    # Check that the cumulative power reaches its mean at Q frequency
    np.allclose(freqs[np.where(cp >= cp[-1] / 2)[0][0]], Q)
Ejemplo n.º 7
0
def test_l1_norm_unknown(sys):
    # These impulse responses have zero-crossings which makes computing their
    # exact L1-norm infeasible without simulation.
    dt = 0.0001
    length = 500000
    response = impulse(sys, dt=dt, length=length)
    assert np.allclose(response[-10:], 0)
    l1_est = np.sum(abs(response) * dt)

    desired_rtol = 1e-6
    l1, rtol = l1_norm(sys, rtol=desired_rtol, max_length=2*length)
    assert np.allclose(l1, l1_est, rtol=1e-3)
    assert rtol <= desired_rtol
Ejemplo n.º 8
0
def test_radii(Simulator, seed, plt):
    sys = canonical(PureDelay(0.1, order=4))
    dt = 0.001
    T = 0.3

    plt.figure()

    # Precompute the exact bounds for an impulse stimulus
    radii = []
    for sub in decompose_states(sys):
        response = impulse(sub, dt=dt, length=int(T / dt))
        amplitude = np.max(abs(response))
        assert amplitude >= 1e-6  # otherwise numerical issues
        radii.append(amplitude)

        plt.plot(response / amplitude, linestyle='--')

    with Network(seed=seed) as model:
        # Impulse stimulus
        stim = nengo.Node(output=lambda t: 1 / dt if t <= dt else 0)

        # Set explicit radii for controllable realization
        subnet = LinearNetwork(sys, n_neurons=1, synapse=0.2,
                               input_synapse=0.2, dt=dt,
                               radii=radii, normalizer=Controllable(),
                               neuron_type=nengo.neurons.Direct())
        nengo.Connection(stim, subnet.input, synapse=None)
        p = nengo.Probe(subnet.x.output, synapse=None)

    assert subnet.info == {}

    sim = nengo.Simulator(model, dt=dt)
    sim.run(T)

    plt.plot(sim.data[p], lw=5, alpha=0.5)

    assert np.allclose(np.max(abs(sim.data[p]), axis=0), 1, atol=1e-3)
Ejemplo n.º 9
0
def test_pure_delay(steps):
    length = 20
    sys = DiscreteDelay(steps)
    y = impulse(sys, dt=None, length=length)
    assert np.allclose(y, [0]*steps + [1] + [0]*(length - steps - 1))