nengo icon indicating copy to clipboard operation
nengo copied to clipboard

Tiny lowpass synapses break

Open hunse opened this issue 5 years ago • 2 comments

Describe the bug

A tiny value for Lowpass.tau results in an error in Scipy's expm.

To reproduce

import nengo

with nengo.Network() as net:
    a = nengo.Ensemble(1, 1)
    b = nengo.Ensemble(1, 1)
    nengo.Connection(a, b, synapse=1e-99)

with nengo.Simulator(net) as sim:
    pass

Expected behavior

This should act the same as if tau == 0.

Error message and logs

Traceback (most recent call last):
  File "test_short_synapse.py", line 10, in <module>
    with nengo.Simulator(net) as sim:
  File "/data/eric/workspace/nengo/nengo/simulator.py", line 150, in __init__
    self.model.build(network, progress=pt.next_stage("Building", "Build"))
  File "/data/eric/workspace/nengo/nengo/builder/builder.py", line 133, in build
    built = self.builder.build(self, obj, *args, **kwargs)
  File "/data/eric/workspace/nengo/nengo/builder/builder.py", line 227, in build
    return cls.builders[obj_cls](model, obj, *args, **kwargs)
  File "/data/eric/workspace/nengo/nengo/builder/network.py", line 94, in build_network
    model.build(conn)
  File "/data/eric/workspace/nengo/nengo/builder/builder.py", line 133, in build
    built = self.builder.build(self, obj, *args, **kwargs)
  File "/data/eric/workspace/nengo/nengo/builder/builder.py", line 227, in build
    return cls.builders[obj_cls](model, obj, *args, **kwargs)
  File "/data/eric/workspace/nengo/nengo/builder/connection.py", line 309, in build_connection
    weighted = model.build(conn.synapse, weighted, mode="update")
  File "/data/eric/workspace/nengo/nengo/builder/builder.py", line 133, in build
    built = self.builder.build(self, obj, *args, **kwargs)
  File "/data/eric/workspace/nengo/nengo/builder/builder.py", line 227, in build
    return cls.builders[obj_cls](model, obj, *args, **kwargs)
  File "/data/eric/workspace/nengo/nengo/builder/processes.py", line 151, in build_process
    state_init = process.make_state(shape_in, shape_out, model.dt, dtype=dtype)
  File "/data/eric/workspace/nengo/nengo/synapses.py", line 238, in make_state
    A, B, C, D = self._get_ss(dt)
  File "/data/eric/workspace/nengo/nengo/synapses.py", line 222, in _get_ss
    A, B, C, D, _ = cont2discrete((A, B, C, D), dt, method=self.method)
  File "/data/eric/workspace/nengo/nengo/utils/filter_design.py", line 517, in cont2discrete
    ms = expm(dt * em)
  File "/data/eric/workspace/nengo/nengo/_vendor/scipy/sparse/linalg_expm.py", line 546, in expm
    return _expm(A, use_exact_onenorm='auto')
  File "/data/eric/workspace/nengo/nengo/_vendor/scipy/sparse/linalg_expm.py", line 600, in _expm
    s = max(int(np.ceil(np.log2(eta_5 / theta_13))), 0)
ValueError: cannot convert float NaN to integer

hunse avatar Aug 12 '19 19:08 hunse

We used to treat small tau in Lowpass and Alpha as zero, when we used to use a worse expm function. We removed this in 4ea0b0549553134d511e696faf83d5d763f55448. It would be nice if we could do something more general in LinearFilter to fix this, but we could go back to that special behaviour in Lowpass and Alpha for small tau.

hunse avatar Aug 12 '19 19:08 hunse

Linking here for reference #1527.

arvoelke avatar Aug 12 '19 19:08 arvoelke