User Manual
Home News Downloads Tutorials User Manual Reference Manual Developer Manual Forums Team Members Future Work FAQ Links Parameters
The behavior of most of the objects making up a Topographica simulation can be controlled by variables called Parameters. A Parameter is a special type of Python attribute extended to have features such as type and range checking, dynamically generated values, documentation strings, default values, etc., each of which is inherited from parent classes if not specified in a subclass.
Objects that can contain Parameters are called Parameterized objects. For instance, Sheets, Projections, and PatternGenerators are all Parameterized. The Parameters of a Sheet include its
nominal_densityandnominal_bounds, and the Parameters of a PatternGenerator include itsscaleandoffset.Basic usage
For the most part, Parameters can be used just like Python attributes. For instance, consider
G=topo.pattern.Gaussian(). This is a two-dimensional Gaussian pattern generator, which has the Parametersscale,offset,x,y,size,aspect_ratio, andorientation. (To see this list, you can select Gaussian in a Test Pattern window, or typeG.params().keys()at a Topographica command prompt.) From a Topographica command prompt, you can typeG.scaleto see its scale (e.g. 1.0), and e.g.G.scale=0.8to set it. Alternatively, you can set the value via thescalewidget in a Test Pattern window.The biggest difference from a standard Python attribute is visible when one tries to set a Parameter to a value that is not allowed. For instance, you can try to enter
-1in theaspect_ratiobox, or typeG.aspect_ratio=-0.5at the command prompt, but in either case you should get a ValueError. Similarly, trying to set it to anything but a number (e.g.G.aspect_ratio="big") should produce an error. These errors are detected because theaspect_ratiohas been declared as aNumberParameter with bounds '(0,None)' (i.e. a minimum value of 0.0, and no maximum value).To provide reasonable checking for parameters of different types, a large number of other Parameter types are provided besides Number, such as Integer, Filename, Enumeration, and Boolean. Each of these types can be declared to be constant, in which case the value cannot be changed after the Parameterized object that owns the Parameter has been created. Some classes, such as Number, allow the parameter values to be generated from a sequence or random distribution, such as for generating random input patterns; in this case the random number will be updated at most once for each unique value of simulation time.
Some Parameter types or instances can also be declared to have
softbounds, which are used to suggest the sizes of GUI sliders for the object,precedence, which determines the sorting order for the Parameter in the GUI or in lists, and adocstring, which is a brief explanation of what the Parameter does.Inheritance and class Parameters
Parameterized objects inherit Parameter values from their parent classes, allowing Parameterized objects to use default values for most Parameters. This is designed to work just as Python attribute inheritance normally works, but also inheriting any documentation, bounds, etc. associated with the Parameter, even when the default value is overridden. For instance, the Gaussian PatternGenerator parameters
xandyare not actually specified in the Gaussian class, but are inherited from the base class, PatternGenerator. If the value for x or y is set on the Gaussian objectG(as inG.x=0.5) or the Gaussian class itself (by typingGaussian.x=0.5orx=0.5in the source code for the Gaussian class), the values will overwrite the defaults, yet the same documentation and bounds will still apply.Note that there is an important difference between setting the Parameter on the class and on the object. If we do
G.x=0.5, only object G will be affected. If we doGaussian.x=0.5, all future objects of type Gaussian will have a default x value of 0.5. Moreover, all existing objects of type Gaussian will also get the new x value of 0.5, unless the user has previously set the value of x on that object explicitly. That is, setting a Parameter at the class level typically affects all existing and future objects from that class, unless the object has overriden the value for that Parameter. To affect only one object, set the value on that object by itself.In certain cases, it can be confusing to have objects inherit from a single shared class Parameter. For instance, constant parameters are expected to keep the same value even if the class Parameter is later changed. Also, mutable Parameter objects, i.e. values that have internal state (such as lists, arrays, or class instances) can have very confusing behavior if they are shared between Parameterized objects, because changes to one Parameterized object's value can affect all the others. In both of these cases (constants and Parameters whose values may be mutable objects) the Parameter is typically set to
instantiate=True, which forces every Parameterized object owning that Parameter to instantiate its own private, independent copy when the Parameterized object is created. This avoids much confusion, but does prevent existing objects from being controlled as a group by changing the class Parameters.Inheritance examples
The following examples should clarify how Parameter values are inherited and instantiated. In Python, attributes (including but not limited to Parameters) declared at the class level are shared by all instances of that class, unless an instance overwrites the attribute with its own copy of the variable. For example:class Example(object): a = 10Hereais a class attribute, because it is declared at the class level (outside of any method like__init__). Creating two instances of Example demonstrates that the valueais shared between the instances:Topographica> example1 = Example() Topographica> example2 = Example() Topographica> example1.a 10 Topographica> example2.a 10 Topographica> Example.a=7 Topographica> example1.a 7 Topographica> example2.a 7Note that setting the class attribute on the Example class changed the value held in both instances. For an Example instance to have its own, independent copy of the variable, it is necessary to set the variable directly on the instance:Topographica> example2.a=19 Topographica> Example.a=40 Topographica> example1.a 40 Topographica> example2.a 19Because instances share the object held in the class attribute, any changes to attributes of the object will show up in all the instances. The same general rules apply to Parameters declared at the class level:import param class ExampleP(param.Parameterized): a = param.Parameter(default=10)Topographica> example1 = ExampleP() Topographica> example1.a 10 Topographica> ExampleP.a = 40 Topographica> example1.a 40However, if a specific Parameter value is passed in when creating the object, there will be a separate and independent copy containing that value:Topographica> e1 = ExampleP(a=8) Topographica> e1.a 8 Topographica> ExampleP.a = 12 Topographica> e1.a 8The author of a class can also force this behavior even when no value is supplied by declaringawitha = Parameter(default=10,instantiate=True). As mentioned above, this is useful when the Parameter will hold a mutable object, when sharing between instances would lead to confusion.For instance, consider a Parameter whose value is the learning function
Oja, which itself has the Parameteralpha. A user might want to declare that allCFSheets should have a single output function,Oja, by settingCFSheet.learning_fn=Oja(). Withoutinstantiate=True, instances of the classCFSheetwould share a singleOjaobject. A user with a number ofCFSheets might be surprised to find that settingalphaon one particularCFSheet's learning_fn would change it on them all.To avoid this confusion, the author of
CFSheetcan declare that the learning_fn Parameter always be instantiated:learning_fn = Parameter(default=Oja(),instantiate=True)In this case, each instance of CFSheet will have its own instance of Oja, independent of otherCFSheets'Oja()instances. In fact, learning_fn parameters (like others taking mutable objects) are typically declared not as Parameter but as ClassSelector, which setsinstantiate=Trueautomatically. Thus in most cases users can use Parameters without worrying about the details of inheritance and instantiation, but the details have been included here because the behavior in unusual cases may be surprising.
Hosted by: ![]()
James A. Bednar (jbednar@inf.ed.ac.uk) Last update: Tue Nov 1 9:50:30 UTC 2011.