1 """
2 Transfer functions with more complex dependencies.
3
4 $Id: basic.py 10790 2009-11-21 17:51:33Z antolikjan $
5 """
6 __version__='$Revision: 10790 $'
7
8 import copy
9
10 import numpy, numpy.random
11 from numpy import ones
12
13 import param
14
15 import topo
16 import topo.base.functionfamily
17
18 from topo.base.arrayutil import clip_lower,array_argmax
19 from topo.base.patterngenerator import PatternGenerator,Constant
20 from topo.base.boundingregion import BoundingBox
21 from topo.base.sheetcoords import SheetCoordinateSystem
22
23 from topo.transferfn.basic import TransferFn,TransferFnWithState
24 from topo.pattern.basic import Gaussian
25
26
27
29 """
30 Combine the supplied pattern with one generated using a
31 PatternGenerator.
32
33 Useful for operations like adding noise or masking out lesioned
34 items or around the edges of non-rectangular shapes.
35 """
36 generator = param.ClassSelector(PatternGenerator,
37 default=Constant(), doc="""
38 Pattern to combine with the supplied matrix.""")
39
40 operator = param.Parameter(numpy.multiply,precedence=0.98,doc="""
41 Binary Numeric function used to combine the two patterns.
42
43 Any binary Numeric array "ufunc" returning the same type of
44 array as the operands and supporting the reduce operator is
45 allowed here. See topo.pattern.basic.Composite.operator for
46 more details.
47 """)
48
59
60
61
62
64 """
65 Replaces the given matrix with a kernel function centered around the maximum value.
66
67 This operation is usually part of the Kohonen SOM algorithm, and
68 approximates a series of lateral interactions resulting in a
69 single activity bubble.
70
71 The radius of the kernel (i.e. the surround) is specified by the
72 parameter 'radius', which should be set before using __call__.
73 The shape of the surround is determined by the
74 neighborhood_kernel_generator, and can be any PatternGenerator
75 instance, or any function accepting bounds, density, radius, and
76 height to return a kernel matrix.
77 """
78 kernel_radius = param.Number(default=0.0,bounds=(0,None),doc="""
79 Kernel radius in Sheet coordinates.""")
80
81 neighborhood_kernel_generator = param.ClassSelector(PatternGenerator,
82 default=Gaussian(x=0.0,y=0.0,aspect_ratio=1.0),
83 doc="Neighborhood function")
84
85 crop_radius_multiplier = param.Number(default=3.0,doc="""
86 Factor by which the radius should be multiplied, when deciding
87 how far from the winner to keep evaluating the kernel.""")
88
89 density=param.Number(1.0,bounds=(0,None),doc="""
90 Density of the Sheet whose matrix we act on, for use
91 in converting from matrix to Sheet coordinates.""")
92
94 rows,cols = x.shape
95 radius = self.density*self.kernel_radius
96 crop_radius = int(max(1.25,radius*self.crop_radius_multiplier))
97
98
99 wr,wc = array_argmax(x)
100
101
102 wy = rows-wr-1
103
104
105
106 cmin = max(wc-crop_radius, 0)
107 cmax = min(wc+crop_radius+1,cols)
108 rmin = max(wr-crop_radius, 0)
109 rmax = min(wr+crop_radius+1,rows)
110 ymin = max(wy-crop_radius, 0)
111 ymax = min(wy+crop_radius+1,rows)
112 bb = BoundingBox(points=((cmin,ymin), (cmax,ymax)))
113
114
115
116 kernel = self.neighborhood_kernel_generator(bounds=bb,xdensity=1,ydensity=1,
117 size=2*radius,x=wc+0.5,y=wy+0.5)
118 x *= 0.0
119 x[rmin:rmax,cmin:cmax] = kernel
120
121
122
156
157
158
230
231
232
234 """
235 Keeps track of attributes of a specified Parameterized over time, for analysis or plotting.
236
237 Useful objects to track include sheets (e.g. "topo.sim['V1']"),
238 projections ("topo.sim['V1'].projections['LateralInhibitory']"),
239 or an output_function.
240
241 Any attribute whose value is a matrix the same size as the
242 activity matrix can be tracked. Only specified units within this
243 matrix will be tracked.
244
245 If no object is specified, this function will keep track of the
246 incoming activity over time.
247
248 The results are stored in a dictionary named 'values', as (time,
249 value) pairs indexed by the parameter name and unit. For
250 instance, if the value of attribute 'x' is v for unit (0.0,0.0)
251 at time t, values['x'][(0.0,0.0)]=(t,v).
252
253 Updating of the tracked values can be disabled temporarily using
254 the plastic parameter.
255 """
256
257
258
259
260
261 object = param.Parameter(default=None, doc="""
262 Parameterized instance whose parameters will be tracked.
263
264 If this parameter's value is a string, it will be evaluated first
265 (by calling Python's eval() function). This feature is designed to
266 allow circular references, so that the OF can track the object that
267 owns it, without causing problems for recursive traversal (as for
268 script_repr()).""")
269
270
271
272 attrib_names = param.List(default=[], doc="""
273 List of names of the function object's parameters that should be stored.""")
274
275 units = param.List(default=[(0.0,0.0)], doc="""
276 Sheet coordinates of the unit(s) for which parameter values will be stored.""")
277
278 step = param.Number(default=1, doc="""
279 How often to update the tracked values.
280
281 For instance, step=1 means to update them every time this OF is
282 called; step=2 means to update them every other time.""")
283
284 coordframe = param.Parameter(default=None,doc="""
285 The SheetCoordinateSystem to use to convert the position
286 into matrix coordinates. If this parameter's value is a string,
287 it will be evaluated first(by calling Python's eval() function).
288 This feature is designed to allow circular references,
289 so that the OF can track the object that
290 owns it, without causing problems for recursive traversal (as for
291 script_repr()).""")
292
303
304
305
307
308 if self._object==None:
309 if isinstance(self.object,str):
310 self._object=eval(self.object)
311 else:
312 self._object=self.object
313
314 if self._coordframe == None:
315 if isinstance(self.coordframe,str) and isinstance(self._object,SheetCoordinateSystem):
316 raise ValueError(str(self._object)+"is already a coordframe, no need to specify coordframe")
317 elif isinstance(self._object,SheetCoordinateSystem):
318 self._coordframe=self._object
319 elif isinstance(self.coordframe,str):
320 self._coordframe=eval(self.coordframe)
321 else:
322 raise ValueError("A coordinate frame (e.g. coordframe=topo.sim['V1']) must be specified in order to track"+str(self._object))
323
324
325
326 self.n_step += 1
327
328 if self.n_step == self.step:
329 self.n_step = 0
330 if self.plastic:
331 for p in self.attrib_names:
332 if p=="x":
333 value_matrix=x
334 else:
335 value_matrix= getattr(self._object, p)
336
337 for u in self.units:
338 mat_u=self._coordframe.sheet2matrixidx(u[0],u[1])
339 self.values[p][u].append((topo.sim.time(),value_matrix[mat_u]))
340
341
342
343 __all__ = list(set([k for k,v in locals().items() if isinstance(v,type) and issubclass(v,TransferFn)]))
344