Package topo :: Package base :: Module sheet
[hide private]
[frames] | no frames]

Source Code for Module topo.base.sheet

  1  """ 
  2  Neural sheet objects and associated functions. 
  3   
  4  The Sheet class is the base class for EventProcessors that simulate 
  5  topographically mapped sheets of units (neurons or columns).  A Sheet 
  6  is an EventProcessor that maintains a rectangular array of activity 
  7  values, and sends the contents of this array as the data element in 
  8  events. 
  9   
 10  The Sheet itself is a SheetCoordinateSystem, so that units may be 
 11  accessed by sheet or matrix coordinates. In general, however, sheets 
 12  should be thought of as having arbitrary density and sheet coordinates 
 13  should be used wherever possible, except when the code needs direct 
 14  access to a specific unit.  By adhering to this convention, one should 
 15  be able to write and debug a simulation at a low density, and then 
 16  scale it up to run at higher densities (or down for lower densities) 
 17  simply by changing e.g. Sheet.nominal_density. 
 18   
 19  $Id: sheet.py 11248 2010-07-18 20:40:37Z ceball $ 
 20  """ 
 21   
 22  __version__ = '$Revision: 11248 $' 
 23   
 24   
 25  from numpy import zeros,array,arange,meshgrid 
 26  from numpy import float64 
 27   
 28  import param 
 29   
 30  from simulation import EventProcessor 
 31  from sheetcoords import SheetCoordinateSystem 
 32  from boundingregion import BoundingBox, BoundingRegionParameter 
 33  from functionfamily import TransferFn 
 34   
 35   
 36  activity_type = float64 
 37   
 38  # (disable W0223 because input_event is deliberately still not implemented) 
39 -class Sheet(EventProcessor,SheetCoordinateSystem): # pylint: disable-msg=W0223
40 """ 41 The generic base class for neural sheets. 42 43 See SheetCoordinateSystem for how Sheet represents space, and 44 EventProcessor for how Sheet handles time. 45 46 output_fns are functions that take an activity matrix and produce 47 an identically shaped output matrix. The default is having no 48 output_fns. 49 """ 50 __abstract = True 51 52 nominal_bounds = BoundingRegionParameter(BoundingBox(radius=0.5),constant=True,doc=""" 53 User-specified BoundingBox of the Sheet coordinate area 54 covered by this Sheet. The left and right bounds--if 55 specified--will always be observed, but the top and bottom 56 bounds may be adjusted to ensure the density in the y 57 direction is the same as the density in the x direction. 58 In such a case, the top and bottom bounds are adjusted 59 so that the center y point remains the same, and each 60 bound is as close as possible to its specified value. The 61 actual value of this Parameter is not adjusted, but the 62 true bounds may be found from the 'bounds' attribute 63 of this object. 64 """) 65 66 nominal_density = param.Number(default=10,constant=True,doc=""" 67 User-specified number of processing units per 1.0 distance 68 horizontally or vertically in Sheet coordinates. The actual 69 number may be different because of discretization; the matrix 70 needs to tile the plane exactly, and for that to work the 71 density might need to be adjusted. For instance, an area of 3x2 72 cannot have a density of 2 in each direction. The true density 73 may be obtained from either the xdensity or ydensity attribute 74 (since these are identical for a Sheet). 75 """) 76 77 plastic = param.Boolean(True,doc=""" 78 Setting this to False tells the Sheet not to change its 79 permanent state (e.g. any connection weights) based on 80 incoming events. 81 """) 82 83 precedence = param.Number(default = 0.1, softbounds=(0.0,1.0),doc=""" 84 Allows a sorting order for Sheets, e.g. in the GUI.""") 85 86 row_precedence = param.Number(default = 0.5, softbounds=(0.0,1.0),doc=""" 87 Allows grouping of Sheets before sorting precedence is 88 applied, e.g. for two-dimensional plots in the GUI.""") 89 90 layout_location = param.NumericTuple(default = (-1,-1),precedence=-1,doc=""" 91 Location for this Sheet in an arbitrary pixel-based space 92 in which Sheets can be laid out for visualization.""") 93 94 output_fns = param.HookList(default=[],class_=TransferFn, 95 doc="Output function(s) to apply (if apply_output_fns is true) to this Sheet's activity.") 96 97 apply_output_fns=param.Boolean(default=True, 98 doc="Whether to apply the output_fn after computing an Activity matrix.") 99 100
101 - def _get_density(self):
102 return self.xdensity
103 104 density = property(_get_density,doc="""The sheet's true density (i.e. the xdensity, which is equal to the ydensity for a Sheet.)""") 105
106 - def __init__(self,**params):
107 """ 108 Initialize this object as an EventProcessor, then also as 109 a SheetCoordinateSystem with equal xdensity and ydensity. 110 111 sheet_views is a dictionary that stores SheetViews, 112 i.e. representations of the sheet for use by analysis or plotting 113 code. 114 """ 115 EventProcessor.__init__(self,**params) 116 117 # Initialize this object as a SheetCoordinateSystem, with 118 # the same density along y as along x. 119 SheetCoordinateSystem.__init__(self,self.nominal_bounds,self.nominal_density) 120 121 n_units = round((self.lbrt[2]-self.lbrt[0])*self.xdensity,0) 122 if n_units<1: raise ValueError( 123 "Sheet bounds and density must be specified such that the "+ \ 124 "sheet has at least one unit in each direction; " \ 125 +self.name+ " does not.") 126 127 # setup the activity matrix 128 self.activity = zeros(self.shape,activity_type) 129 130 # For non-plastic inputs 131 self.__saved_activity = [] 132 self._plasticity_setting_stack = [] 133 self.sheet_views = {}
134 135 136 ### JABALERT: This should be deleted now that sheet_views is public 137 ### JC: shouldn't we keep that, or at least write a function in 138 ### utils that deletes a value in a dictinnary without returning an 139 ### error if the key is not in the dict? I leave for the moment, 140 ### and have to ask Jim to advise.
141 - def release_sheet_view(self,view_name):
142 """ 143 Delete the dictionary entry with key entry 'view_name' to save 144 memory. 145 """ 146 if self.sheet_views.has_key(view_name): 147 del self.sheet_views[view_name]
148 149 150 # CB: what to call this? sheetcoords()? sheetcoords_of_grid()? idxsheetcoords()?
151 - def sheetcoords_of_idx_grid(self):
152 """ 153 Return an array of x-coordinates and an array of y-coordinates 154 corresponding to the activity matrix of the sheet. 155 """ 156 nrows,ncols=self.activity.shape 157 158 C,R = meshgrid(arange(ncols), 159 arange(nrows)) 160 161 X,Y = self.matrixidx2sheet(R,C) 162 return X,Y
163 164 165 # CB: check whether we need this function any more.
166 - def row_col_sheetcoords(self):
167 """ 168 Return an array of Y-coordinates corresponding to the rows of 169 the activity matrix of the sheet, and an array of 170 X-coordinates corresponding to the columns. 171 """ 172 # The row and column centers are returned in matrix (not 173 # sheet) order (hence the reversals below). 174 nrows,ncols = self.activity.shape 175 return self.matrixidx2sheet(arange(nrows-1,-1,-1),arange(ncols))[::-1]
176 177 178 # CBALERT: to be removed once other code uses 179 # row_col_sheetcoords() or sheetcoords_of_idx_grid().
180 - def sheet_rows(self):
181 return self.row_col_sheetcoords()[0]
182 - def sheet_cols(self):
183 return self.row_col_sheetcoords()[1]
184 185 186 # CEBALERT: haven't really thought about what to put in this. The 187 # way it is now, subclasses could make a super.activate() call to 188 # avoid repeating some stuff.
189 - def activate(self):
190 """ 191 Collect activity from each projection, combine it to calculate 192 the activity for this sheet, and send the result out. 193 194 Subclasses will need to override this method to whatever it 195 means to calculate activity in that subclass. 196 """ 197 if self.apply_output_fns: 198 for of in self.output_fns: 199 of(self.activity) 200 201 self.send_output(src_port='Activity',data=self.activity)
202 203
204 - def state_push(self):
205 """ 206 Save the current state of this sheet to an internal stack. 207 208 This method is used by operations that need to test the 209 response of the sheet without permanently altering its state, 210 e.g. for measuring maps or probing the current behavior 211 non-invasively. By default, only the activity pattern of this 212 sheet is saved, but subclasses should add saving for any 213 additional state that they maintain, or strange bugs are 214 likely to occur. The state can be restored using state_pop(). 215 216 Note that Sheets that do learning need not save the 217 values of all connection weights, if any, because 218 plasticity can be turned off explicitly. Thus this method 219 is intended only for shorter-term state. 220 """ 221 self.__saved_activity.append(array(self.activity)) 222 EventProcessor.state_push(self) 223 for of in self.output_fns: 224 if hasattr(of,'state_push'): 225 of.state_push()
226 227
228 - def state_pop(self):
229 """ 230 Pop the most recently saved state off the stack. 231 232 See state_push() for more details. 233 """ 234 self.activity = self.__saved_activity.pop() 235 EventProcessor.state_pop(self) 236 for of in self.output_fns: 237 if hasattr(of,'state_pop'): 238 of.state_pop()
239 240
241 - def activity_len(self):
242 """Return the number of items that have been saved by state_push().""" 243 return len(self.__saved_activity)
244 245
246 - def override_plasticity_state(self, new_plasticity_state):
247 """ 248 Temporarily override plasticity of medium and long term internal state. 249 250 This function should be implemented by all subclasses so that 251 it preserves the ability of the Sheet to compute activity, 252 i.e. to operate over a short time scale, while preventing any 253 lasting changes to the state (if new_plasticity_state=False). 254 255 Any operation that does not have any lasting state, such as 256 those affecting only the current activity level, should not 257 be affected by this call. 258 259 By default, simply saves a copy of the plastic flag to an 260 internal stack (so that it can be restored by 261 restore_plasticity_state()), and then sets plastic to 262 new_plasticity_state. 263 """ 264 self._plasticity_setting_stack.append(self.plastic) 265 self.plastic=new_plasticity_state
266 267
268 - def restore_plasticity_state(self):
269 """ 270 Restores plasticity of medium and long term internal state after 271 a override_plasticity_state call. 272 273 This function should be implemented by all subclasses to 274 remove the effect of the most recent override_plasticity_state call, 275 i.e. to restore plasticity of any type that was overridden. 276 """ 277 self.plastic = self._plasticity_setting_stack.pop()
278 279
280 - def n_bytes(self):
281 """ 282 Return a lower bound for the memory taken by this sheet, in bytes. 283 284 Typically, this number will include the activity array and any 285 similar arrays, plus any other significant data owned (in some 286 sense) by this Sheet. It will not usually include memory 287 taken by the Python dictionary or various "housekeeping" 288 attributes, which usually contribute only a small amount to 289 the memory requirements. 290 291 Subclasses should reimplement this method if they store a 292 significant amount of data other than in the activity array. 293 """ 294 return self.activity.nbytes
295