1 """
2 Inline-optimized Sheet classes
3
4 $Id: optimized.py 11315 2010-07-27 17:43:01Z ceball $
5 """
6 __version__='$Revision: 11315 $'
7
8 import param
9
10 from topo.base.cf import MaskedCFIter
11 from topo.base.projection import NeighborhoodMask
12 from topo.misc.inlinec import inline,provide_unoptimized_equivalent,c_header
13 from topo.sheet.lissom import LISSOM
14 from topo.sheet.basic import compute_joint_norm_totals
15
17 """
18 Compute norm_total for each CF in each projections from a
19 group to be normalized jointly. The same assumptions are
20 made as in the original function.
21 """
22
23 length = len(projlist)
24 assert length>=1
25
26 proj = projlist[0]
27 iterator = MaskedCFIter(proj,active_units_mask=active_units_mask)
28 num_cfs = len(proj.flatcfs)
29 active_units_mask = iterator.get_active_units_mask()
30 sheet_mask = iterator.get_sheet_mask()
31
32 code = c_header + """
33 npfloat *x = active_units_mask;
34 npfloat *m = sheet_mask;
35 for (int r=0; r<num_cfs; ++r) {
36 double load = *x++;
37 double msk = *m++;
38 if (msk!=0 && load != 0) {
39 double nt = 0;
40
41 for(int p=0; p<length; p++) {
42 PyObject *proj = PyList_GetItem(projlist,p);
43 PyObject *cfs = PyObject_GetAttrString(proj,"flatcfs");
44 PyObject *cf = PyList_GetItem(cfs,r);
45 PyObject *o = PyObject_GetAttrString(cf,"norm_total");
46 nt += PyFloat_AsDouble(o);
47 Py_DECREF(cfs);
48 Py_DECREF(o);
49 }
50
51 for(int p=0; p<length; p++) {
52 PyObject *proj = PyList_GetItem(projlist,p);
53 PyObject *cfs = PyObject_GetAttrString(proj,"flatcfs");
54 PyObject *cf = PyList_GetItem(cfs,r);
55 PyObject *total_obj = PyFloat_FromDouble(nt); //(new ref)
56 PyObject_SetAttrString(cf,"_norm_total",total_obj);
57 PyObject_SetAttrString(cf,"_has_norm_total",Py_True);
58 Py_DECREF(cfs);
59 Py_DECREF(total_obj);
60 }
61 }
62
63 }
64 """
65 inline(code, ['projlist','active_units_mask','sheet_mask','num_cfs','length'],
66 local_dict=locals())
67
68 provide_unoptimized_equivalent("compute_joint_norm_totals_opt",
69 "compute_joint_norm_totals",locals())
70
71
73 """
74 Faster but potentially unsafe optimized version of LISSOM.
75
76 Adds a NeighborhoodMask that skips computation for neurons
77 sufficiently distant from all those activated in the first few
78 steps of settling. This is safe only if activity bubbles reliably
79 shrink after the first few steps; otherwise the results will
80 differ from LISSOM.
81
82 Typically useful only for standard LISSOM simulations with
83 localized (e.g. Gaussian) inputs and that shrink the lateral
84 excitatory radius, which results in small patches of activity in
85 an otherwise inactive sheet.
86
87 Also overrides the function
88 JointNormalizingCFSheet.__compute_joint_norm_totals with
89 C-optimized code for LISSOM sheets.
90 """
91
92 joint_norm_fn = param.Callable(default=compute_joint_norm_totals_opt)
93
98
99 provide_unoptimized_equivalent("LISSOM_Opt","LISSOM",locals())
100
101
102
104
106 rows,cols = self.data.shape
107 ignore1,matradius = self.sheet.sheet2matrixidx(self.radius,0)
108 ignore2,x = self.sheet.sheet2matrixidx(0,0)
109 matradius = int(abs(matradius -x))
110 thr = self.threshold
111 activity = self.sheet.activity
112 mask = self.data
113
114 code = c_header + """
115 #define min(x,y) (x<y?x:y)
116 #define max(x,y) (x>y?x:y)
117
118 npfloat *X = mask;
119 npfloat *A = activity;
120 for (int r=0; r<rows; ++r) {
121 for (int l=0; l<cols; ++l) {
122 int lbx = max(0,r-matradius);
123 int lby = max(0,l-matradius);
124 int hbx = min(r+matradius+1,rows);
125 int hby = min(l+matradius+1,cols);
126
127 *X = 0.0;
128 int breakFlag = 0;
129 for(int k=lbx;k<hbx;k++)
130 {
131 for(int l=lby;l<hby;l++)
132 {
133 npfloat *a = A+k*rows + l;
134 if(*a > thr)
135 {
136 *X = 1.0;
137 //JAALERT HACK. Want to jump out both nested loops!!!
138 breakFlag = 1;
139 break;
140 }
141 }
142 if(breakFlag)break;
143 }
144
145 X++;
146 }
147 }
148 """
149 inline(code, ['thr','activity','matradius','mask','rows','cols'], local_dict=locals())
150
151 provide_unoptimized_equivalent("NeighborhoodMask_Opt","NeighborhoodMask",locals())
152