def _hsv_to_rgb_array_opt(HSV): """Equivalent to hsv_to_rgb_array().""" hue = HSV[:,:,0] sat = HSV[:,:,1] val = HSV[:,:,2] shape = hue.shape dtype = hue.dtype red = numpy.zeros(shape,dtype=dtype) grn = numpy.zeros(shape,dtype=dtype) blu = numpy.zeros(shape,dtype=dtype) code = """ for (int i=0; i<Nhue[0]; ++i) { for (int j=0; j<Nhue[1]; ++j) { // translation of Python's colorsys.hsv_to_rgb() using parts // of code from // http://www.cs.rit.edu/~ncs/color/t_convert.html float h=HUE2(i,j); float s=SAT2(i,j); float v=VAL2(i,j); float r,g,b; if(s==0) r=g=b=v; else { int i=(int)floor(h*6.0); if(i<0) i=0; float f=(h*6.0)-i; float p=v*(1.0-s); float q=v*(1.0-s*f); float t=v*(1.0-s*(1-f)); switch(i) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; case 5: r = v; g = p; b = q; break; } } RED2(i,j)=r; GRN2(i,j)=g; BLU2(i,j)=b; } } """ inline(code, ['red','grn','blu','hue','sat','val'], local_dict=locals()) return numpy.dstack((red,grn,blu))
def __call__(self, iterator, input_activity, activity, strength, **params): temp_act = activity irows,icols = input_activity.shape X = input_activity.ravel() cfs = iterator.flatcfs num_cfs = len(cfs) mask = iterator.mask.data cf_type = iterator.cf_type # Note: no performance hit from array indexing of mask and # temp_act (r11447). code = c_header + """ DECLARE_SLOT_OFFSET(weights,cf_type); DECLARE_SLOT_OFFSET(input_sheet_slice,cf_type); %(cfs_loop_pragma)s for (int r=0; r<num_cfs; ++r) { if(mask[r] == 0.0) temp_act[r] = 0; else { PyObject *cf = PyList_GetItem(cfs,r); CONTIGUOUS_ARRAY_FROM_SLOT_OFFSET(float,weights,cf) LOOKUP_FROM_SLOT_OFFSET(int,input_sheet_slice,cf); UNPACK_FOUR_TUPLE(int,rr1,rr2,cc1,cc2,input_sheet_slice); double tot = 0.0; npfloat *xj = X+icols*rr1+cc1; // computes the dot product for (int i=rr1; i<rr2; ++i) { npfloat *xi = xj; float *wi = weights; for (int j=cc1; j<cc2; ++j) { tot += *wi * *xi; ++wi; ++xi; } xj += icols; weights += cc2-cc1; } temp_act[r] = tot*strength; DECREF_CONTIGUOUS_ARRAY(weights); } } """%c_decorators inline(code, ['mask','X', 'strength', 'icols', 'temp_act','cfs','num_cfs','cf_type'], local_dict=locals(), headers=['<structmember.h>'])
def __call__(self, iterator, **params): cf_type=iterator.cf_type # pyflakes:ignore (passed to weave C code) cfs = iterator.flatcfs # pyflakes:ignore (passed to weave C code) num_cfs = len(iterator.flatcfs) # pyflakes:ignore (passed to weave C code) # CB: for performance, it is better to process the masks in # the C code (rather than combining them before). active_units_mask = iterator.get_active_units_mask() # pyflakes:ignore (passed to weave C code) sheet_mask = iterator.get_sheet_mask() # pyflakes:ignore (passed to weave C code) code = c_header + """ DECLARE_SLOT_OFFSET(weights,cf_type); DECLARE_SLOT_OFFSET(input_sheet_slice,cf_type); DECLARE_SLOT_OFFSET(_norm_total,cf_type); DECLARE_SLOT_OFFSET(_has_norm_total,cf_type); DECLARE_SLOT_OFFSET(mask,cf_type); %(cfs_loop_pragma)s for (int r=0; r<num_cfs; ++r) { if (active_units_mask[r] != 0 && sheet_mask[r] != 0) { PyObject *cf = PyList_GetItem(cfs,r); LOOKUP_FROM_SLOT_OFFSET(float,weights,cf); LOOKUP_FROM_SLOT_OFFSET(int,input_sheet_slice,cf); LOOKUP_FROM_SLOT_OFFSET(double,_norm_total,cf); LOOKUP_FROM_SLOT_OFFSET(int,_has_norm_total,cf); UNPACK_FOUR_TUPLE(int,rr1,rr2,cc1,cc2,input_sheet_slice); // if normalized total is not available, sum the weights if (_has_norm_total[0] == 0) { SUM_NORM_TOTAL(cf,weights,_norm_total,rr1,rr2,cc1,cc2); } // normalize the weights double factor = 1.0/_norm_total[0]; int rc = (rr2-rr1)*(cc2-cc1); for (int i=0; i<rc; ++i) { *(weights++) *= factor; } // Indicate that norm_total is stale _has_norm_total[0]=0; } } """%c_decorators inline(code, ['sheet_mask','active_units_mask','cfs','cf_type','num_cfs'], local_dict=locals(), headers=['<structmember.h>'])
def calculate(self): rows, cols = self.data.shape ignore1, matradius = self.sheet.sheet2matrixidx(self.radius, 0) ignore2, x = self.sheet.sheet2matrixidx(0, 0) matradius = int(abs(matradius - x)) thr = self.threshold # pyflakes:ignore (passed to weave C code) activity = self.sheet.activity # pyflakes:ignore (passed to weave C code) mask = self.data # pyflakes:ignore (passed to weave C code) code = c_header + """ #define min(x,y) (x<y?x:y) #define max(x,y) (x>y?x:y) npfloat *X = mask; npfloat *A = activity; for (int r=0; r<rows; ++r) { for (int l=0; l<cols; ++l) { int lbx = max(0,r-matradius); int lby = max(0,l-matradius); int hbx = min(r+matradius+1,rows); int hby = min(l+matradius+1,cols); *X = 0.0; int breakFlag = 0; for(int k=lbx;k<hbx;k++) { for(int l=lby;l<hby;l++) { npfloat *a = A+k*rows + l; if(*a > thr) { *X = 1.0; //JAALERT HACK. Want to jump out both nested loops!!! breakFlag = 1; break; } } if(breakFlag)break; } X++; } } """ inline(code, ['thr', 'activity', 'matradius', 'mask', 'rows', 'cols'], local_dict=locals())
def calculate(self): rows,cols = self.data.shape ignore1,matradius = self.sheet.sheet2matrixidx(self.radius,0) ignore2,x = self.sheet.sheet2matrixidx(0,0) matradius = int(abs(matradius -x)) thr = self.threshold # pyflakes:ignore (passed to weave C code) activity = self.sheet.activity # pyflakes:ignore (passed to weave C code) mask = self.data # pyflakes:ignore (passed to weave C code) code = c_header + """ #define min(x,y) (x<y?x:y) #define max(x,y) (x>y?x:y) npfloat *X = mask; npfloat *A = activity; for (int r=0; r<rows; ++r) { for (int l=0; l<cols; ++l) { int lbx = max(0,r-matradius); int lby = max(0,l-matradius); int hbx = min(r+matradius+1,rows); int hby = min(l+matradius+1,cols); *X = 0.0; int breakFlag = 0; for(int k=lbx;k<hbx;k++) { for(int l=lby;l<hby;l++) { npfloat *a = A+k*rows + l; if(*a > thr) { *X = 1.0; //JAALERT HACK. Want to jump out both nested loops!!! breakFlag = 1; break; } } if(breakFlag)break; } X++; } } """ inline(code, ['thr','activity','matradius','mask','rows','cols'], local_dict=locals())
def __call__(self, iterator, input_activity, activity, strength, **params): temp_act = activity # pyflakes:ignore (passed to weave C code) irows, icols = input_activity.shape X = input_activity.ravel() # pyflakes:ignore (passed to weave C code) cfs = iterator.flatcfs num_cfs = len(cfs) # pyflakes:ignore (passed to weave C code) mask = iterator.mask.data # pyflakes:ignore (passed to weave C code) cf_type = iterator.cf_type # pyflakes:ignore (passed to weave C code) # Note: no performance hit from array indexing of mask and # temp_act (r11447). code = c_header + """ DECLARE_SLOT_OFFSET(weights,cf_type); DECLARE_SLOT_OFFSET(input_sheet_slice,cf_type); %(cfs_loop_pragma)s for (int r=0; r<num_cfs; ++r) { if(mask[r] == 0.0) { temp_act[r] = 0; } else { PyObject *cf = PyList_GetItem(cfs,r); // CONTIGUOUS_ARRAY_FROM_SLOT_OFFSET(float,weights,cf) <<<<<<<<<<< LOOKUP_FROM_SLOT_OFFSET_UNDECL_DATA(float,weights,cf); char *data = weights_obj->data; int s0 = weights_obj->strides[0]; int s1 = weights_obj->strides[1]; LOOKUP_FROM_SLOT_OFFSET(int,input_sheet_slice,cf); UNPACK_FOUR_TUPLE(int,rr1,rr2,cc1,cc2,input_sheet_slice); double tot = 0.0; npfloat *xj = X+icols*rr1+cc1; // computes the dot product for (int i=rr1; i<rr2; ++i) { npfloat *xi = xj; // float *wi = weights; // for (int j=cc1; j<cc2; ++j) { // tot += *wi * *xi; // ++wi; // ++xi; // } for (int j=cc1; j<cc2; ++j) { tot += *((float *)(data + (i-rr1)*s0 + (j-cc1)*s1)) * *xi; ++xi; } xj += icols; // weights += cc2-cc1; } temp_act[r] = tot*strength; // DECREF_CONTIGUOUS_ARRAY(weights); } } """ % c_decorators inline(code, [ 'mask', 'X', 'strength', 'icols', 'temp_act', 'cfs', 'num_cfs', 'cf_type' ], local_dict=locals(), headers=['<structmember.h>'])
def __call__(self, iterator, input_activity, activity, strength, **params): temp_act = activity # pyflakes:ignore (passed to weave C code) rows, cols = activity.shape irows, icols = input_activity.shape X = input_activity.ravel() # pyflakes:ignore (passed to weave C code) cfs = iterator.flatcfs num_cfs = len(cfs) # pyflakes:ignore (passed to weave C code) code = c_header + """ #include <math.h> npfloat *tact = temp_act; double max_dist=0.0; for (int r=0; r<num_cfs; ++r) { PyObject *cf = PyList_GetItem(cfs,r); PyObject *weights_obj = PyObject_GetAttrString(cf,"weights"); PyObject *slice_obj = PyObject_GetAttrString(cf,"input_sheet_slice"); float *wj = (float *)(((PyArrayObject*)weights_obj)->data); int *slice = (int *)(((PyArrayObject*)slice_obj)->data); int rr1 = *slice++; int rr2 = *slice++; int cc1 = *slice++; int cc2 = *slice; npfloat *xj = X+icols*rr1+cc1; // computes the dot product double tot = 0.0; for (int i=rr1; i<rr2; ++i) { npfloat *xi = xj; float *wi = wj; for (int j=cc1; j<cc2; ++j) { double diff = *wi - *xi; tot += diff*diff; ++wi; ++xi; } xj += icols; wj += cc2-cc1; } double euclidean_distance = sqrt(tot); if (euclidean_distance>max_dist) max_dist = euclidean_distance; *tact = euclidean_distance; ++tact; // Anything obtained with PyObject_GetAttrString must be explicitly freed Py_DECREF(weights_obj); Py_DECREF(slice_obj); } tact = temp_act; for (int r=0; r<num_cfs; ++r) { *tact = strength*(max_dist - *tact); ++tact; } """ inline(code, ['X', 'strength', 'icols', 'temp_act', 'cfs', 'num_cfs'], local_dict=locals())
def __call__(self, iterator, input_activity, output_activity, learning_rate, **params): single_connection_learning_rate = self.constant_sum_connection_rate(iterator.proj_n_units,learning_rate) if single_connection_learning_rate==0: return cfs = iterator.flatcfs num_cfs = len(cfs) # pyflakes:ignore (passed to weave C code) irows,icols = input_activity.shape cf_type = iterator.cf_type # pyflakes:ignore (passed to weave C code) # CEBALERT: this function *always* skips inactive units, # because it uses the output_activity directly rather than # going through the iterator. That's ok since we know this # function can always skip inactive units. But the unoptimized # equivalent should be made to do the same, because right now # it respects the iterator. (Just a case of setting the # iterator's active_units_mask to be True before calling the # iterator in the unoptimized version.) sheet_mask = iterator.get_sheet_mask() # pyflakes:ignore (passed to weave C code) code = c_header + """ DECLARE_SLOT_OFFSET(weights,cf_type); DECLARE_SLOT_OFFSET(input_sheet_slice,cf_type); DECLARE_SLOT_OFFSET(mask,cf_type); DECLARE_SLOT_OFFSET(_norm_total,cf_type); DECLARE_SLOT_OFFSET(_has_norm_total,cf_type); %(cfs_loop_pragma)s for (int r=0; r<num_cfs; ++r) { double load = output_activity[r]; if (load != 0 && sheet_mask[r] != 0) { load *= single_connection_learning_rate; PyObject *cf = PyList_GetItem(cfs,r); LOOKUP_FROM_SLOT_OFFSET(float,weights,cf); LOOKUP_FROM_SLOT_OFFSET(int,input_sheet_slice,cf); LOOKUP_FROM_SLOT_OFFSET(float,mask,cf); UNPACK_FOUR_TUPLE(int,rr1,rr2,cc1,cc2,input_sheet_slice); double total = 0.0; // modify non-masked weights npfloat *inpj = input_activity+icols*rr1+cc1; for (int i=rr1; i<rr2; ++i) { npfloat *inpi = inpj; for (int j=cc1; j<cc2; ++j) { // The mask is floating point, so we have to // use a robust comparison instead of testing // against exactly 0.0. if (*(mask++) >= MASK_THRESHOLD) { *weights += load * *inpi; total += fabs(*weights); } ++weights; ++inpi; } inpj += icols; } // store the sum of the cf's weights LOOKUP_FROM_SLOT_OFFSET(double,_norm_total,cf); _norm_total[0]=total; LOOKUP_FROM_SLOT_OFFSET(int,_has_norm_total,cf); _has_norm_total[0]=1; } } """%c_decorators inline(code, ['input_activity', 'output_activity','sheet_mask','num_cfs', 'icols', 'cfs', 'single_connection_learning_rate','cf_type'], local_dict=locals(), headers=['<structmember.h>'])
def __call__(self, iterator, input_activity, output_activity, learning_rate, **params): cfs = iterator.flatcfs # pyflakes:ignore (passed to weave C code) single_connection_learning_rate = self.constant_sum_connection_rate(iterator.proj_n_units,learning_rate) irows,icols = input_activity.shape if single_connection_learning_rate==0: return cfs = iterator.flatcfs num_cfs = len(cfs) # pyflakes:ignore (passed to weave C code) ##Initialise traces to zero if they don't already exist if not hasattr(self,'traces'): self.traces=zeros(output_activity.shape,activity_type) self.traces = (self.trace_strength*output_activity)+((1-self.trace_strength)*self.traces) traces = self.traces # pyflakes:ignore (passed to weave C code) cf_type = iterator.cf_type # pyflakes:ignore (passed to weave C code) code = c_header + """ DECLARE_SLOT_OFFSET(weights,cf_type); DECLARE_SLOT_OFFSET(input_sheet_slice,cf_type); DECLARE_SLOT_OFFSET(mask,cf_type); DECLARE_SLOT_OFFSET(_norm_total,cf_type); DECLARE_SLOT_OFFSET(_has_norm_total,cf_type); %(cfs_loop_pragma)s for (int r=0; r<num_cfs; ++r) { double load = traces[r]; if (load != 0) { load *= single_connection_learning_rate; PyObject *cf = PyList_GetItem(cfs,r); LOOKUP_FROM_SLOT_OFFSET(float,weights,cf); LOOKUP_FROM_SLOT_OFFSET(int,input_sheet_slice,cf); LOOKUP_FROM_SLOT_OFFSET(float,mask,cf); UNPACK_FOUR_TUPLE(int,rr1,rr2,cc1,cc2,input_sheet_slice); double total = 0.0; // modify non-masked weights npfloat *inpj = input_activity+icols*rr1+cc1; for (int i=rr1; i<rr2; ++i) { npfloat *inpi = inpj; for (int j=cc1; j<cc2; ++j) { // The mask is floating point, so we have to // use a robust comparison instead of testing // against exactly 0.0. if (*(mask++) >= MASK_THRESHOLD) { *weights += load * *inpi; total += fabs(*weight); } ++weights; ++inpi; } inpj += icols; } // store the sum of the cf's weights LOOKUP_FROM_SLOT_OFFSET(double,_norm_total,cf); _norm_total[0]=total; LOOKUP_FROM_SLOT_OFFSET(int,_has_norm_total,cf); _has_norm_total[0]=1; } } """%c_decorators inline(code, ['input_activity', 'traces','num_cfs', 'icols', 'cfs', 'single_connection_learning_rate','cf_type'], local_dict=locals(), headers=['<structmember.h>'])
def compute_joint_norm_totals_opt(projlist, active_units_mask): """ Compute norm_total for each CF in each projections from a group to be normalized jointly. The same assumptions are made as in the original function. """ # Assumes that all Projections in the list have the same r,c size length = len(projlist) assert length >= 1 proj = projlist[0] iterator = CFIter(proj, active_units_mask=active_units_mask) num_cfs = len(proj.flatcfs) # pyflakes:ignore (passed to weave C code) active_units_mask = iterator.get_active_units_mask() sheet_mask = iterator.get_sheet_mask( ) # pyflakes:ignore (passed to weave C code) cf_type = iterator.cf_type # pyflakes:ignore (passed to weave C code) # CEBALERT: Not consistent with other C code. E.g. could be # simplified to use active_units_mask[] and sheet_mask[]? code = c_header + """ DECLARE_SLOT_OFFSET(_norm_total,cf_type); DECLARE_SLOT_OFFSET(_has_norm_total,cf_type); DECLARE_SLOT_OFFSET(weights,cf_type); DECLARE_SLOT_OFFSET(input_sheet_slice,cf_type); DECLARE_SLOT_OFFSET(mask,cf_type); npfloat *x = active_units_mask; npfloat *m = sheet_mask; for (int r=0; r<num_cfs; ++r) { double load = *x++; double msk = *m++; if (msk!=0 && load != 0) { double nt = 0; for(int p=0; p<length; p++) { PyObject *proj = PyList_GetItem(projlist,p); PyObject *cfs = PyObject_GetAttrString(proj,"flatcfs"); PyObject *cf = PyList_GetItem(cfs,r); LOOKUP_FROM_SLOT_OFFSET(int,_has_norm_total,cf); LOOKUP_FROM_SLOT_OFFSET(double,_norm_total,cf); if (_has_norm_total[0] == 0) { LOOKUP_FROM_SLOT_OFFSET(float,weights,cf); LOOKUP_FROM_SLOT_OFFSET(int,input_sheet_slice,cf); UNPACK_FOUR_TUPLE(int,rr1,rr2,cc1,cc2,input_sheet_slice); SUM_NORM_TOTAL(cf,weights,_norm_total,rr1,rr2,cc1,cc2); } nt += _norm_total[0]; Py_DECREF(cfs); } for(int p=0; p<length; p++) { PyObject *proj = PyList_GetItem(projlist,p); PyObject *cfs = PyObject_GetAttrString(proj,"flatcfs"); PyObject *cf = PyList_GetItem(cfs,r); LOOKUP_FROM_SLOT_OFFSET(double,_norm_total,cf); _norm_total[0] = nt; LOOKUP_FROM_SLOT_OFFSET(int,_has_norm_total,cf); _has_norm_total[0] = 1; Py_DECREF(cfs); } } } """ inline(code, [ 'projlist', 'active_units_mask', 'sheet_mask', 'num_cfs', 'length', 'cf_type' ], local_dict=locals(), headers=['<structmember.h>'])
def __call__(self, iterator, input_activity, activity, strength, **params): temp_act = activity # pyflakes:ignore (passed to weave C code) rows,cols = activity.shape irows,icols = input_activity.shape X = input_activity.ravel() # pyflakes:ignore (passed to weave C code) cfs = iterator.flatcfs num_cfs = len(cfs) # pyflakes:ignore (passed to weave C code) code = c_header + """ #include <math.h> npfloat *tact = temp_act; double max_dist=0.0; for (int r=0; r<num_cfs; ++r) { PyObject *cf = PyList_GetItem(cfs,r); PyObject *weights_obj = PyObject_GetAttrString(cf,"weights"); PyObject *slice_obj = PyObject_GetAttrString(cf,"input_sheet_slice"); float *wj = (float *)(((PyArrayObject*)weights_obj)->data); int *slice = (int *)(((PyArrayObject*)slice_obj)->data); int rr1 = *slice++; int rr2 = *slice++; int cc1 = *slice++; int cc2 = *slice; npfloat *xj = X+icols*rr1+cc1; // computes the dot product double tot = 0.0; for (int i=rr1; i<rr2; ++i) { npfloat *xi = xj; float *wi = wj; for (int j=cc1; j<cc2; ++j) { double diff = *wi - *xi; tot += diff*diff; ++wi; ++xi; } xj += icols; wj += cc2-cc1; } double euclidean_distance = sqrt(tot); if (euclidean_distance>max_dist) max_dist = euclidean_distance; *tact = euclidean_distance; ++tact; // Anything obtained with PyObject_GetAttrString must be explicitly freed Py_DECREF(weights_obj); Py_DECREF(slice_obj); } tact = temp_act; for (int r=0; r<num_cfs; ++r) { *tact = strength*(max_dist - *tact); ++tact; } """ inline(code, ['X', 'strength', 'icols', 'temp_act','cfs','num_cfs'], local_dict=locals())
def __call__(self, iterator, input_activity, output_activity, learning_rate, **params): cfs = iterator.flatcfs # pyflakes:ignore (passed to weave C code) single_connection_learning_rate = self.constant_sum_connection_rate( iterator.proj_n_units, learning_rate) irows, icols = input_activity.shape if single_connection_learning_rate == 0: return cfs = iterator.flatcfs num_cfs = len(cfs) # pyflakes:ignore (passed to weave C code) ##Initialise traces to zero if they don't already exist if not hasattr(self, 'traces'): self.traces = zeros(output_activity.shape, activity_type) self.traces = (self.trace_strength * output_activity) + ( (1 - self.trace_strength) * self.traces) traces = self.traces # pyflakes:ignore (passed to weave C code) cf_type = iterator.cf_type # pyflakes:ignore (passed to weave C code) code = c_header + """ DECLARE_SLOT_OFFSET(weights,cf_type); DECLARE_SLOT_OFFSET(input_sheet_slice,cf_type); DECLARE_SLOT_OFFSET(mask,cf_type); DECLARE_SLOT_OFFSET(_norm_total,cf_type); DECLARE_SLOT_OFFSET(_has_norm_total,cf_type); %(cfs_loop_pragma)s for (int r=0; r<num_cfs; ++r) { double load = traces[r]; if (load != 0) { load *= single_connection_learning_rate; PyObject *cf = PyList_GetItem(cfs,r); LOOKUP_FROM_SLOT_OFFSET(float,weights,cf); LOOKUP_FROM_SLOT_OFFSET(int,input_sheet_slice,cf); LOOKUP_FROM_SLOT_OFFSET(float,mask,cf); UNPACK_FOUR_TUPLE(int,rr1,rr2,cc1,cc2,input_sheet_slice); double total = 0.0; // modify non-masked weights npfloat *inpj = input_activity+icols*rr1+cc1; for (int i=rr1; i<rr2; ++i) { npfloat *inpi = inpj; for (int j=cc1; j<cc2; ++j) { // The mask is floating point, so we have to // use a robust comparison instead of testing // against exactly 0.0. if (*(mask++) >= MASK_THRESHOLD) { *weights += load * *inpi; total += fabs(*weight); } ++weights; ++inpi; } inpj += icols; } // store the sum of the cf's weights LOOKUP_FROM_SLOT_OFFSET(double,_norm_total,cf); _norm_total[0]=total; LOOKUP_FROM_SLOT_OFFSET(int,_has_norm_total,cf); _has_norm_total[0]=1; } } """ % c_decorators inline(code, [ 'input_activity', 'traces', 'num_cfs', 'icols', 'cfs', 'single_connection_learning_rate', 'cf_type' ], local_dict=locals(), headers=['<structmember.h>'])
def __call__(self, iterator, input_activity, output_activity, learning_rate, **params): cfs = iterator.flatcfs # pyflakes:ignore (passed to weave C code) single_connection_learning_rate = self.constant_sum_connection_rate(iterator.proj_n_units, learning_rate) irows, icols = input_activity.shape if single_connection_learning_rate == 0: return ##Initialise traces to zero if they don't already exist if not hasattr(self, "traces"): self.traces = zeros(output_activity.shape, activity_type) self.traces = (self.trace_strength * output_activity) + ((1 - self.trace_strength) * self.traces) traces = self.traces # pyflakes:ignore (passed to weave C code) code = ( c_header + """ npfloat *x = traces; for (int r=0; r<num_cfs; ++r) { double load = *x++; if (load != 0) { load *= single_connection_learning_rate; PyObject *cf = PyList_GetItem(cfs,r); PyObject *weights_obj = PyObject_GetAttrString(cf,"weights"); PyObject *slice_obj = PyObject_GetAttrString(cf,"input_sheet_slice"); PyObject *mask_obj = PyObject_GetAttrString(cf,"mask"); float *wi = (float *)(((PyArrayObject*)weights_obj)->data); int *slice = (int *)(((PyArrayObject*)slice_obj)->data); float *m = (float *)(((PyArrayObject*)mask_obj)->data); int rr1 = *slice++; int rr2 = *slice++; int cc1 = *slice++; int cc2 = *slice; double total = 0.0; // modify non-masked weights npfloat *inpj = input_activity+icols*rr1+cc1; for (int i=rr1; i<rr2; ++i) { npfloat *inpi = inpj; for (int j=cc1; j<cc2; ++j) { // The mask is floating point, so we have to // use a robust comparison instead of testing // against exactly 0.0. if (*(m++) >= 0.000001) { *wi += load * *inpi; total += fabs(*wi); } ++wi; ++inpi; } inpj += icols; } // Anything obtained with PyObject_GetAttrString must be explicitly freed Py_DECREF(weights_obj); Py_DECREF(slice_obj); Py_DECREF(mask_obj); // store the sum of the cf's weights PyObject *total_obj = PyFloat_FromDouble(total); //(new ref) PyObject_SetAttrString(cf,"norm_total",total_obj); PyObject_SetAttrString(cf,"_has_norm_total",Py_True); Py_DECREF(total_obj); } } """ ) inline( code, ["input_activity", "traces", "num_cfs", "icols", "cfs", "single_connection_learning_rate"], local_dict=locals(), )
def __call__(self, iterator, input_activity, output_activity, learning_rate, **params): rows, cols = output_activity.shape cfs = iterator.flatcfs num_cfs = len(cfs) # pyflakes:ignore (passed to weave C code) single_connection_learning_rate = self.constant_sum_connection_rate(iterator.proj_n_units, learning_rate) if single_connection_learning_rate == 0: return unit_threshold = self.unit_threshold # pyflakes:ignore (passed to weave C code) irows, icols = input_activity.shape cf_type = iterator.cf_type # pyflakes:ignore (passed to weave C code) code = ( c_header + """ // CEBALERT: should provide a macro for getting offset ///// GET WEIGHTS OFFSET PyMemberDescrObject *weights_descr = (PyMemberDescrObject *)PyObject_GetAttrString(cf_type,"weights"); Py_ssize_t weights_offset = weights_descr->d_member->offset; Py_DECREF(weights_descr); ///// GET SLICE OFFSET PyMemberDescrObject *slice_descr = (PyMemberDescrObject *)PyObject_GetAttrString(cf_type,"input_sheet_slice"); Py_ssize_t slice_offset = slice_descr->d_member->offset; Py_DECREF(slice_descr); ///// GET MASK OFFSET PyMemberDescrObject *mask_descr = (PyMemberDescrObject *)PyObject_GetAttrString(cf_type,"mask"); Py_ssize_t mask_offset = mask_descr->d_member->offset; Py_DECREF(mask_descr); npfloat *x = output_activity; for (int r=0; r<num_cfs; ++r) { double load = *x++; double unit_activity= load; if (load != 0) { load *= single_connection_learning_rate; PyObject *cf = PyList_GetItem(cfs,r); PyArrayObject *weights_obj = *((PyArrayObject **)((char *)cf + weights_offset)); PyArrayObject *slice_obj = *((PyArrayObject **)((char *)cf + slice_offset)); PyArrayObject *mask_obj = *((PyArrayObject **)((char *)cf + mask_offset)); float *wi = (float *)(weights_obj->data); int *slice = (int *)(slice_obj->data); float *m = (float *)(mask_obj->data); int rr1 = *slice++; int rr2 = *slice++; int cc1 = *slice++; int cc2 = *slice; double total = 0.0; // modify non-masked weights npfloat *inpj = input_activity+icols*rr1+cc1; for (int i=rr1; i<rr2; ++i) { npfloat *inpi = inpj; for (int j=cc1; j<cc2; ++j) { // The mask is floating point, so we have to // use a robust comparison instead of testing // against exactly 0.0. if (*(m++) >= 0.000001) { *wi += load * *inpi * (unit_activity - unit_threshold); if (*wi<0) { *wi = 0;} total += fabs(*wi); } ++wi; ++inpi; } inpj += icols; } // store the sum of the cf's weights PyObject *total_obj = PyFloat_FromDouble(total); //(new ref) PyObject_SetAttrString(cf,"_norm_total",total_obj); PyObject_SetAttrString(cf,"_has_norm_total",Py_True); Py_DECREF(total_obj); } } """ ) inline( code, [ "input_activity", "output_activity", "num_cfs", "icols", "cfs", "single_connection_learning_rate", "unit_threshold", "cf_type", ], local_dict=locals(), headers=["<structmember.h>"], )
def __call__(self, iterator, input_activity, output_activity, learning_rate, **params): if self.learning_rate_scaling_factor is None: self.learning_rate_scaling_factor = ones(output_activity.shape)*1.0 learning_rate_scaling_factor = self.learning_rate_scaling_factor cfs = iterator.flatcfs num_cfs = len(cfs) single_connection_learning_rate = self.constant_sum_connection_rate(iterator.proj_n_units,learning_rate) if single_connection_learning_rate==0: return irows,icols = input_activity.shape code = c_header + """ npfloat *x = output_activity; double *sclr = learning_rate_scaling_factor; for (int r=0; r<num_cfs; ++r) { double load = *x++; double a= *sclr++; load = load * a; if (load != 0) { load *= single_connection_learning_rate; PyObject *cf = PyList_GetItem(cfs,r); PyObject *weights_obj = PyObject_GetAttrString(cf,"weights"); PyObject *slice_obj = PyObject_GetAttrString(cf,"input_sheet_slice"); PyObject *mask_obj = PyObject_GetAttrString(cf,"mask"); float *wi = (float *)(((PyArrayObject*)weights_obj)->data); int *slice = (int *)(((PyArrayObject*)slice_obj)->data); float *m = (float *)(((PyArrayObject*)mask_obj)->data); int rr1 = *slice++; int rr2 = *slice++; int cc1 = *slice++; int cc2 = *slice; double total = 0.0; // modify non-masked weights npfloat *inpj = input_activity+icols*rr1+cc1; for (int i=rr1; i<rr2; ++i) { npfloat *inpi = inpj; for (int j=cc1; j<cc2; ++j) { // The mask is floating point, so we have to // use a robust comparison instead of testing // against exactly 0.0. if (*(m++) >= 0.000001) { *wi += load * *inpi; total += fabs(*wi); } ++wi; ++inpi; } inpj += icols; } // Anything obtained with PyObject_GetAttrString must be explicitly freed Py_DECREF(weights_obj); Py_DECREF(slice_obj); Py_DECREF(mask_obj); // store the sum of the cf's weights PyObject *total_obj = PyFloat_FromDouble(total); //(new ref) PyObject_SetAttrString(cf,"_norm_total",total_obj); PyObject_SetAttrString(cf,"_has_norm_total",Py_True); Py_DECREF(total_obj); } } """ inline(code, ['input_activity','learning_rate_scaling_factor', 'output_activity','num_cfs', 'icols', 'cfs', 'single_connection_learning_rate'], local_dict=locals())
def __call__(self, iterator, input_activity, output_activity, learning_rate, **params): single_connection_learning_rate = self.constant_sum_connection_rate( iterator.proj_n_units, learning_rate) if single_connection_learning_rate == 0: return cfs = iterator.flatcfs num_cfs = len(cfs) # pyflakes:ignore (passed to weave C code) irows, icols = input_activity.shape cf_type = iterator.cf_type # pyflakes:ignore (passed to weave C code) # CEBALERT: this function *always* skips inactive units, # because it uses the output_activity directly rather than # going through the iterator. That's ok since we know this # function can always skip inactive units. But the unoptimized # equivalent should be made to do the same, because right now # it respects the iterator. (Just a case of setting the # iterator's active_units_mask to be True before calling the # iterator in the unoptimized version.) sheet_mask = iterator.get_sheet_mask( ) # pyflakes:ignore (passed to weave C code) code = c_header + """ DECLARE_SLOT_OFFSET(weights,cf_type); DECLARE_SLOT_OFFSET(input_sheet_slice,cf_type); DECLARE_SLOT_OFFSET(mask,cf_type); DECLARE_SLOT_OFFSET(_norm_total,cf_type); DECLARE_SLOT_OFFSET(_has_norm_total,cf_type); %(cfs_loop_pragma)s for (int r=0; r<num_cfs; ++r) { double load = output_activity[r]; if (load != 0 && sheet_mask[r] != 0) { load *= single_connection_learning_rate; PyObject *cf = PyList_GetItem(cfs,r); LOOKUP_FROM_SLOT_OFFSET(float,weights,cf); LOOKUP_FROM_SLOT_OFFSET(int,input_sheet_slice,cf); LOOKUP_FROM_SLOT_OFFSET(float,mask,cf); UNPACK_FOUR_TUPLE(int,rr1,rr2,cc1,cc2,input_sheet_slice); double total = 0.0; // modify non-masked weights npfloat *inpj = input_activity+icols*rr1+cc1; for (int i=rr1; i<rr2; ++i) { npfloat *inpi = inpj; for (int j=cc1; j<cc2; ++j) { // The mask is floating point, so we have to // use a robust comparison instead of testing // against exactly 0.0. if (*(mask++) >= MASK_THRESHOLD) { *weights += load * *inpi; total += fabs(*weights); } ++weights; ++inpi; } inpj += icols; } // store the sum of the cf's weights LOOKUP_FROM_SLOT_OFFSET(double,_norm_total,cf); _norm_total[0]=total; LOOKUP_FROM_SLOT_OFFSET(int,_has_norm_total,cf); _has_norm_total[0]=1; } } """ % c_decorators inline(code, [ 'input_activity', 'output_activity', 'sheet_mask', 'num_cfs', 'icols', 'cfs', 'single_connection_learning_rate', 'cf_type' ], local_dict=locals(), headers=['<structmember.h>'])
def _rgb_to_hsv_array_opt(RGB): """Equivalent to rgb_to_hsv_array().""" red = RGB[:,:,0] grn = RGB[:,:,1] blu = RGB[:,:,2] shape = red.shape dtype = red.dtype hue = numpy.zeros(shape,dtype=dtype) sat = numpy.zeros(shape,dtype=dtype) val = numpy.zeros(shape,dtype=dtype) code = """ //// MIN3,MAX3 macros from // http://en.literateprograms.org/RGB_to_HSV_color_space_conversion_(C) #define MIN3(x,y,z) ((y) <= (z) ? ((x) <= (y) ? (x) : (y)) : ((x) <= (z) ? (x) : (z))) #define MAX3(x,y,z) ((y) >= (z) ? ((x) >= (y) ? (x) : (y)) : ((x) >= (z) ? (x) : (z))) //// for (int i=0; i<Nred[0]; ++i) { for (int j=0; j<Nred[1]; ++j) { // translation of Python's colorsys.rgb_to_hsv() float r=RED2(i,j); float g=GRN2(i,j); float b=BLU2(i,j); float minc=MIN3(r,g,b); float maxc=MAX3(r,g,b); VAL2(i,j)=maxc; if(minc==maxc) { HUE2(i,j)=0.0; SAT2(i,j)=0.0; } else { float delta=maxc-minc; SAT2(i,j)=delta/maxc; float rc=(maxc-r)/delta; float gc=(maxc-g)/delta; float bc=(maxc-b)/delta; if(r==maxc) HUE2(i,j)=bc-gc; else if(g==maxc) HUE2(i,j)=2.0+rc-bc; else HUE2(i,j)=4.0+gc-rc; HUE2(i,j)=(HUE2(i,j)/6.0); if(HUE2(i,j)<0) HUE2(i,j)+=1; //else if(HUE2(i,j)>1) // HUE2(i,j)-=1; } } } """ inline(code, ['red','grn','blu','hue','sat','val'], local_dict=locals()) return numpy.dstack((hue,sat,val))
def __call__(self, iterator, input_activity, activity, strength, **params): temp_act = activity # pyflakes:ignore (passed to weave C code) irows,icols = input_activity.shape X = input_activity.ravel() # pyflakes:ignore (passed to weave C code) cfs = iterator.flatcfs num_cfs = len(cfs) # pyflakes:ignore (passed to weave C code) mask = iterator.mask.data # pyflakes:ignore (passed to weave C code) cf_type = iterator.cf_type # pyflakes:ignore (passed to weave C code) # Note: no performance hit from array indexing of mask and # temp_act (r11447). code = c_header + """ DECLARE_SLOT_OFFSET(weights,cf_type); DECLARE_SLOT_OFFSET(input_sheet_slice,cf_type); %(cfs_loop_pragma)s for (int r=0; r<num_cfs; ++r) { if(mask[r] == 0.0) { temp_act[r] = 0; } else { PyObject *cf = PyList_GetItem(cfs,r); // CONTIGUOUS_ARRAY_FROM_SLOT_OFFSET(float,weights,cf) <<<<<<<<<<< LOOKUP_FROM_SLOT_OFFSET_UNDECL_DATA(float,weights,cf); char *data = weights_obj->data; int s0 = weights_obj->strides[0]; int s1 = weights_obj->strides[1]; LOOKUP_FROM_SLOT_OFFSET(int,input_sheet_slice,cf); UNPACK_FOUR_TUPLE(int,rr1,rr2,cc1,cc2,input_sheet_slice); double tot = 0.0; npfloat *xj = X+icols*rr1+cc1; // computes the dot product for (int i=rr1; i<rr2; ++i) { npfloat *xi = xj; // float *wi = weights; // for (int j=cc1; j<cc2; ++j) { // tot += *wi * *xi; // ++wi; // ++xi; // } for (int j=cc1; j<cc2; ++j) { tot += *((float *)(data + (i-rr1)*s0 + (j-cc1)*s1)) * *xi; ++xi; } xj += icols; // weights += cc2-cc1; } temp_act[r] = tot*strength; // DECREF_CONTIGUOUS_ARRAY(weights); } } """%c_decorators inline(code, ['mask','X', 'strength', 'icols', 'temp_act','cfs','num_cfs','cf_type'], local_dict=locals(), headers=['<structmember.h>'])
def compute_joint_norm_totals_opt(projlist,active_units_mask): """ Compute norm_total for each CF in each projections from a group to be normalized jointly. The same assumptions are made as in the original function. """ # Assumes that all Projections in the list have the same r,c size length = len(projlist) assert length>=1 proj = projlist[0] iterator = CFIter(proj,active_units_mask=active_units_mask) num_cfs = len(proj.flatcfs) # pyflakes:ignore (passed to weave C code) active_units_mask = iterator.get_active_units_mask() sheet_mask = iterator.get_sheet_mask() # pyflakes:ignore (passed to weave C code) cf_type = iterator.cf_type # pyflakes:ignore (passed to weave C code) # CEBALERT: Not consistent with other C code. E.g. could be # simplified to use active_units_mask[] and sheet_mask[]? code = c_header + """ DECLARE_SLOT_OFFSET(_norm_total,cf_type); DECLARE_SLOT_OFFSET(_has_norm_total,cf_type); DECLARE_SLOT_OFFSET(weights,cf_type); DECLARE_SLOT_OFFSET(input_sheet_slice,cf_type); DECLARE_SLOT_OFFSET(mask,cf_type); npfloat *x = active_units_mask; npfloat *m = sheet_mask; for (int r=0; r<num_cfs; ++r) { double load = *x++; double msk = *m++; if (msk!=0 && load != 0) { double nt = 0; for(int p=0; p<length; p++) { PyObject *proj = PyList_GetItem(projlist,p); PyObject *cfs = PyObject_GetAttrString(proj,"flatcfs"); PyObject *cf = PyList_GetItem(cfs,r); LOOKUP_FROM_SLOT_OFFSET(int,_has_norm_total,cf); LOOKUP_FROM_SLOT_OFFSET(double,_norm_total,cf); if (_has_norm_total[0] == 0) { LOOKUP_FROM_SLOT_OFFSET(float,weights,cf); LOOKUP_FROM_SLOT_OFFSET(int,input_sheet_slice,cf); UNPACK_FOUR_TUPLE(int,rr1,rr2,cc1,cc2,input_sheet_slice); SUM_NORM_TOTAL(cf,weights,_norm_total,rr1,rr2,cc1,cc2); } nt += _norm_total[0]; Py_DECREF(cfs); } for(int p=0; p<length; p++) { PyObject *proj = PyList_GetItem(projlist,p); PyObject *cfs = PyObject_GetAttrString(proj,"flatcfs"); PyObject *cf = PyList_GetItem(cfs,r); LOOKUP_FROM_SLOT_OFFSET(double,_norm_total,cf); _norm_total[0] = nt; LOOKUP_FROM_SLOT_OFFSET(int,_has_norm_total,cf); _has_norm_total[0] = 1; Py_DECREF(cfs); } } } """ inline(code, ['projlist','active_units_mask','sheet_mask','num_cfs','length','cf_type'], local_dict=locals(), headers=['<structmember.h>'])