nengo-1.4 icon indicating copy to clipboard operation
nengo-1.4 copied to clipboard

SimpleNodes should have some way of having parameterized dimensionality

Open tcstewar opened this issue 11 years ago • 3 comments

I'd like a way of having the dimensionality of a SimpleNode origin/termination be based on construction parameters.

Right now, I can't do this:

class Delay(nef.SimpleNode):
    def __init__(self, name, steps, dimensions):
        self.steps=steps
        self.dimensions=dimensions
        nef.SimpleNode.__init__(self, name)

    def init(self):
        self.data = [[0]*self.dimensions]*self.steps

    def termination_input(self, x, dimensions=self.dimensions):  # syntax error
        self.data = self.data[1:] + [x]

    def origin_output(self):
        return self.data[0]

The same problem would appear in the decorator approach mentioned in issue #385, which would look something like this:

class Delay(nef.SimpleNode):
    def __init__(self, name, steps, dimensions):
        self.steps=steps
        self.dimensions=dimensions
        nef.SimpleNode.__init__(self, name)

    def init(self):
        self.data = [[0]*self.dimensions]*self.steps

    @nef.simplenode.termination(dimensions=self.dimensions) # syntax error  
    def input(self, x):
        self.data = self.data[1:] + [x]

    @nef.simplenode.origin(dimensions=self.dimensions) # syntax error  
    def output(self):
        return self.data[0]

Right now, you can sorta do this by this horrendous approach

class Delay(nef.SimpleNode):
    def __init__(self, name, steps, dimensions):
        self.steps=steps
        self.dimensions=dimensions
        nef.SimpleNode.__init__(self, name)

        def input(x, self=self, dimensions=dimensions):  # yuck
            self.data = self.data[1:] + [x]
        self.create_termination('input',input)

    def init(self):
        self.data = [[0]*self.dimensions]*self.steps     

    def origin_output(self):
        return self.data[0]

Any suggestions? I'm having trouble coming up with a legit syntax for doing this...

tcstewar avatar Apr 01 '13 22:04 tcstewar

I think the way to do this is class variables? Does this give a syntax error? It means that dimensionality is a part of the class though, and not a parameter. That's perhaps not ideal.

class Delay(nef.SimpleNode):
    dimensions = 1
    def __init__(self, name, steps):
        self.steps=steps
        nef.SimpleNode.__init__(self, name)

    def init(self):
        self.data = [[0]*Delay.dimensions]*self.steps

    def termination_input(self, x, dimensions=Delay.dimensions):
        self.data = self.data[1:] + [x]

    def origin_output(self):
        return self.data[0]

tbekolay avatar Apr 04 '13 15:04 tbekolay

That doesn't give a syntax error, but it also doesn't let you pass in the dimensionality as a parameter, which is what I've wanted to do a few times. Basically it makes it much harder to write general-purpose SimpleNodes.

It's not a big problem, but it'd be nice if there were a way to do this.

tcstewar avatar Apr 04 '13 15:04 tcstewar

You could make dimensionality a property that sets up the origins if it's changed? I'm not sure if it's possible in 2.5...

    @property
    def dimensionality(self):
        # Make sure origin dimensionality matches
        # self._dimensionality, and if not change it
        return self._dimensionality

    @dimensionality.setter
    def dimensionality(self, dims):
        self._dimensionality = dims

Or you can make get/set methods and have in the class

    dimensionality = property(get_dimensionality, set_dimensionality)

which is more likely to be in Python 2.5.

tbekolay avatar Apr 04 '13 16:04 tbekolay