def maximum(self, s): '''Return a sparse space that contains the maximum value of self and the space s at each index ''' sd = self.data od = s.data if sd[0]=='full': if not od[0]=='full': od = ['full', s.full()] v=maximum(sd[1], od[1]) return self._new(['full', v]) elif od[0]=='full': v=maximum(self.full()+od[1]) return self._new(['full', v]) ind = union1d(sd[0], od[0]) nti=ind.shape[0] if nti > self.MAX_SPARSE * self.size: v = maximum(self.full(), s.full()) return self._new(['full', v]) v = zeros(nti, sd[1].dtype) v2 = zeros(nti, sd[1].dtype) oi=oe.findindex(od[0], ind) si=oe.findindex(sd[0], ind) v[si]=sd[1] v2[oi]=od[1] v=maximum(v,v2) return self._new([ind, v])
def add(self, s): '''Return a Sparse instance that is the sum of self+s, where s is another sparse instance''' if self.data[0]=='full' and s.data[0]=='full': v=self.data[1]+s.data[1] return self._new(['full', v]) sd = self.data od= s.data if sd[0]=='full': v=sd[1].copy() v[od[0]]+=od[1] return self._new(['full', v]) elif od[0]=='full': v=od[1].copy() v[sd[0]]+=sd[1] return self._new(['full', v]) ind = union1d(sd[0], od[0]) msize=max(self.size, s.size) if ind.shape[0] > self.MAX_SPARSE * msize: v=zeros(msize, sd[1].dtype) v[sd[0]]=sd[1] v[od[0]]+=od[1] return self._new(['full', v]) v = zeros(ind.shape[0], sd[1].dtype) oi=oe.findindex(od[0], ind) si=oe.findindex(sd[0], ind) v[si]=sd[1] v[oi]+=od[1] return self._new([ind, v], msize)
def get(self, ind): '''return a 1D array of values at the indexes given in the 1D array ind (ind must be sorted)''' if self.data[0]=='full': return self.data[1][ind] val=zeros(ind.shape[0]) has=union1d(ind, self.data[0]) myind=oe.findindex(has, self.data[0]) ind=oe.findindex(has, ind) val[ind]=self.data[1][myind] return val
def mul(self, space): '''weight the "add" values in self by the values in space''' sp=self.flatindex() op=space.flatindex() both=intersect1d(sp, op) si=oe.findindex(both, sp) oi=oe.findindex(both, op) nv=zeros((both.shape[0], len(self.rules))) for i, t in enumerate(self.rules): if t=='add': nv[:,i]=self.val[si,i]*space.val[oi,i] else: nv[:,i]=self.val[si,i] self.set((both, nv), True, False)
def mul(self, s): '''Return a Sparse instance that is the product of self*s, where s is another sparse instance''' if self.data[0]=='full' and s.data[0]=='full': v=self.data[1]*s.data[1] return self._new(['full', v]) sd = self.data od= s.data if sd[0]=='full': sd = [od[0], sd[1][od[0]]] elif od[0]=='full': od = [sd[0], od[1][sd[0]]] ind=intersect1d(sd[0], od[0]) si=oe.findindex(ind, sd[0]) oi=oe.findindex(ind, od[0]) v=[ind, sd[1][si]*od[1][oi]] return self._new(v)
def set(self, dat): '''sets values in self.data according to the list dat, which should be either a 1D full array, or [indexes, values]. The indexes must be sorted. No size checking is done by this method. Use self.condition if you need it. Note that setting with a full array will entirely overwrite existing data, and may change self.size.''' if type(dat)==ndarray: if len(dat.shape)>1: dat=ravel(dat) self.data=['full', dat] self.size = self.data.shape[0] return myind=setdiff1d(self.data[0], dat[0]) if not myind.shape[0]: self.data=deepcopy(dat) return ind = union1d(dat[0], self.data[0]) vals=zeros(ind.shape[0], self.data[1].dtype) mynewindex=oe.findindex(myind, ind) vals[mynewindex]=self.data[1][myind] newind = oe.findindex(dat[0], ind) vals[newind]=dat[1][dat[0]] self.data=[ind, vals]
def _combineValues(self, t1, t2): if t1[0].shape[0]==0: return t2 elif t2[0].shape[0]==0: return t1 both=intersect1d(t1[0], t2[0]) if both.shape[0]==0: ind=concatenate([t1[0], t2[0]]) val=vstack([t1[1], t2[1]]) return (ind, val) t1u=setdiff1d(t1[0], both) t2u=setdiff1d(t2[0], both) ind=concatenate([t1u, t2u, both]) valr=zeros((ind.shape[0], t1[1].shape[1]), t1[1].dtype) t2u=oe.findindex(t2u, t2[0]) t1u=oe.findindex(t1u, t1[0]) valr[:t1u.shape[0]]=t1[1][t1u] valr[t1u.shape[0]:-both.shape[0]]=t2[1][t2u] cv1=delete(t1[1], t1u, 0) cv2=delete(t2[1], t2u, 0) for i, t in enumerate(self.rules): if t=='ignore': continue c1=cv1[:,i] c2=cv2[:,i] if t=='add': v=c1+c2 elif t=='max': v=maximum(c1, c2) elif t=='min': v=minimum(c1, c2) elif t=='mul': v=c1*c2 elif t=='replace': v=c2 elif t=='av': lc1=cv1[:, i-1] lc2=cv2[:, i-1] v=(c1*lc1+c2*lc2)/(lc1+lc2) valr[-both.shape[0]:,i]=v return (ind, valr)
def sparsedot_int(v1, v2): '''v1 and v2 are tuples of (indexes, values) arrays. Return a float that is the sparse dot product''' ci=intersect1d(v1[0], v2[0]) v1=take(v1[1], oe.findindex(ci, v1[0])) v2=take(v2[1], oe.findindex(ci, v2[0])) return dot(v1, v2)