def vData( self, U, V, node, edges=None, ndim=None ): # THESE MUST NOT MODIFY U OR V!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # VERY IMPORTANT!!!!!! PROBABLY ENFORCE THIS SOMEHOW IN THE FURURE V_row, V_col, V_data = V if( ~np.any( np.in1d( V_row, node ) ) ): # If the node isn't in the V object (node is a leaf) ans = [ np.array( [] ) ] elif( edges is None ): # Return the data over all down edges ans = self.vDataFromMask( V, np.in1d( V_row, node ) ) elif( isinstance( edges, Iterable ) and len( edges ) > 0 ): # Return over only certain edges mask = np.in1d( V_row, node ) for e in edges: mask &= np.in1d( V_col, e ) ans = self.vDataFromMask( V, mask ) elif( isinstance( edges, Iterable ) and len( edges ) == 0 ): # This happens when we're not passed a down edge. In this # case, we should return an empty v value, not a leaf v value return [ np.array( [] ) ] else: # Only looking at one edge ans = self.vDataFromMask( V, np.in1d( V_col, edges ) ) if( len( ans ) == 0 ): # If we're looking at a leaf, return all 0s nVals = 1 if edges is None else len( edges ) ans = [] for _ in range( nVals ): ans.append( np.array( [] ) ) assert sum( [ 0 if ~np.any( np.isnan( v ) ) else 1 for v in ans ] ) == 0, ans return ans
def updateV(self, nodes, edges, new_v, V): V_row, V_col, V_data = V for node, edge, v in zip(nodes, edges, new_v): if (edge is None): continue dataIndices = np.in1d(V_row, node) & np.in1d(V_col, edge) for i in np.where(dataIndices)[0]: V_data[i] = v
def vData( self, U, V, node, edges=None ): # THESE MUST NOT MODIFY U OR V!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # VERY IMPORTANT!!!!!! PROBABLY ENFORCE THIS SOMEHOW IN THE FURURE V_row, V_col, _ = V if( self.inFeedbackSet( node, is_partial_graph_index=True ) ): # This is going to be empty because by construction, # if a node is in the fbs, all the information from # going down the down edges can be gained by going # up an up edge. if( edges is None ): return [] elif( isinstance( edges, Iterable ) ): return [] else: return fbsData( np.array( [] ), -1 ) if( ~np.any( np.in1d( V_row, node ) ) ): # If the node isn't in the V object (node is a leaf) ans = [ fbsData( np.array( [] ), -1 ) ] elif( edges is None ): # Return the data over all down edges ans = self.vDataFromMask( V, np.in1d( V_row, node ) ) elif( isinstance( edges, Iterable ) and len( edges ) > 0 ): # Return over only certain edges mask = np.in1d( V_row, node ) for e in edges: mask &= np.in1d( V_col, e ) ans = self.vDataFromMask( V, mask ) elif( isinstance( edges, Iterable ) and len( edges ) == 0 ): # This happens when we're not passed a down edge. In this # case, we should return an empty v value, not a leaf v value return [ fbsData( np.array( [] ), -1 ) ] else: # Only looking at one edge ans = self.vDataFromMask( V, np.in1d( V_col, edges ) ) if( len( ans ) == 0 ): # If we're looking at a leaf, return all 0s nVals = 1 if edges is None else len( edges ) ans = [] for _ in range( nVals ): ans.append( fbsData( np.array( [] ), -1 ) ) for v in ans: data = v.data assert np.any( np.isnan( data ) ) == False, data return ans
def get_g(self,x): atoms3 = self.atoms3 atoms4 = self.atoms4 p = self.p output = np.zeros(p) combos = np.asarray([[0, 1, 2], [1, 2, 3], [0, 2, 3], [0, 1, 3]]) for k in range(p): atom4 = atoms4[k, :] angles4 = [] # get identities of triangles on boundary of tetrahedron actived = np.zeros(4) for i in range(4): actived[i] = np.where([set(item).issubset(atom4[combos[i, :]]) for item in atoms3])[0][0] actived = np.asarray(actived, dtype=int) naive = np.reshape(x, (int(x.shape[0] / 3), 3))[actived, :] for i in range(4): a = atoms3[actived[i]] b = atom4[np.in1d(atom4, atoms3[actived[i]])] for j in range(3): angles4.append(naive[i, np.where(a == b[j])[0]]) # the jth position in the ith row contains the gradient corresponding to the jth position in the truncated atom4 a4 = np.reshape(angles4, (4, 3)) fitin = self.g4(a4) # plus the lowest index first output[k] = fitin return (output)
def assignV(self, V, node, val, keep_shape=False): V_row, V_col, V_data = V N = V_row.shape[0] VIndices = np.where(np.in1d(V_row, node))[0] for i in VIndices: if (keep_shape is False): V_data[i].data = val else: V_data[i].data[:] = val
def class_posterior(self, y, x, exclude_ac=[]): ''' Note: self._class_posterior is not a rank-1 matrix :return: p_a, p_mix ''' include_idx = ~np.in1d(range(len(self.tr)), exclude_ac) ln_p_am = self._class_posterior(y, x, exclude_ac) mat = np.exp(ln_p_am.reshape(self.n_classes, -1)) return np.sum(mat, axis=0), np.sum(mat, axis=1)
def _class_posterior(self, y, x, exclude_ac): ln_p_a, ln_p_mix = self.class_prior() include_idx = ~np.in1d(range(len(self.tr)), exclude_ac) ln_p_a = ln_p_a[include_idx] tr_fns = [tr for b, tr in zip(include_idx, self.tr) if b] mixture = log_likelihood(self.params, y, x, self.mean, self.cov, tr_fns, ln_p_a, ln_p_mix) return mixture - logsumexp(mixture)
def get_dx_g(self, x): atoms4 = self.atoms4 atoms3 = self.atoms3 p = self.p d = self.d combos = np.asarray([[0, 1, 2], [1, 2, 3], [0, 2, 3], [0, 1, 3]]) output = np.zeros((d, p)) for k in range(p): atom4 = atoms4[k, :] angles4 = [] # get identities of triangles on boundary of tetrahedron # which atoms3 are in the atoms4... actived = [ np.where([ set(item).issubset(atom4[combos[i, :]]) for item in atoms3 ])[0][0] for i in range(4) ] actived = np.asarray(actived, dtype=int) naive = np.reshape(x, (int(x.shape[0] / 3), 3))[actived, :] for i in range(4): a = atoms3[actived[i]] b = atom4[np.in1d(atom4, atoms3[actived[i]])] for j in range(3): angles4.append(naive[i, np.where(a == b[j])[0]]) # the jth positEion in the ith row contains the gradient corresponding to the jth position in the truncated atom4 a4 = np.reshape(angles4, (4, 3)) # fitin = g4(a4)[1] fitin = self.gradg4(a4) faceindex = np.zeros(4) for j in range(4): face = atom4[combos[j]] for i in range(4): if collections.Counter( atoms3[actived][i]) == collections.Counter(face): faceindex[j] = i faceindex = np.asarray(faceindex, dtype=int) anglerowtooutput = actived[faceindex] #print(anglerowtooutput) for i in range(4): face = atom4[combos[i]] buffer = np.asarray(scipy.stats.rankdata(face) - 1, dtype=int) for j in range(3): output[3 * anglerowtooutput[i] + buffer[j], k] = fitin[i, j] return (output)
def predict(self, x_star, y, x, exclude_ac=[]): l = len(x_star[0]) c = np.zeros([l, l]) # exclude actions include_idx = ~np.in1d(range(len(self.tr)), exclude_ac) tr_fns = [tr for b, tr in zip(include_idx, self.tr) if b] ln_p_am = self._class_posterior(y, x, exclude_ac).ravel() ms = [] for mn in self.mean: for tr in tr_fns: _m, _c = self._predict(x_star, y, x, mean_fn=mn, treatment=tr) ms.append(_m) c = _c # all covariance matrix are the same ms = [p * _m for p, _m in zip(np.exp(ln_p_am), ms)] return np.sum(ms, axis=0), c
def compute_W_lsq(EtaXi, XXhat, YYhat, nP=2, nQ=4, freeze_vals=None, lam=0): # EtaXi the input currents # XXhat the input layer activity # YYhat the recurrent layer activity providing synaptic inputs Ymatrix = np.zeros(EtaXi.shape) Ymatrix_pred = np.zeros(EtaXi.shape) Wx = np.zeros((nP, nQ)) Wy = np.zeros((nQ, nQ)) if freeze_vals is None: resEtaXi = EtaXi - 0 else: zeroed = [np.isnan(fv) for fv in freeze_vals] #print(zeroed) freeze_vals[0][zeroed[0]] = 0 freeze_vals[1][zeroed[1]] = 0 resEtaXi = EtaXi - XXhat @ freeze_vals[0] - YYhat @ freeze_vals[1] Wx[~zeroed[0]] = freeze_vals[0][~zeroed[0]] Wy[~zeroed[1]] = freeze_vals[1][~zeroed[1]] for itype in range(nQ): Ymatrix[:, itype] = resEtaXi[:, itype] #others = np.setdiff1d(np.arange(nQ),itype) xothers = np.ones((nP, ), dtype='bool') others = ~np.in1d(np.arange(nQ), itype) if not freeze_vals is None: xothers = xothers & (freeze_vals[0][:, itype] == 0) & ~zeroed[0][:, itype] others = others & (freeze_vals[1][:, itype] == 0) & ~zeroed[1][:, itype] Xmatrix = np.concatenate((XXhat[:, xothers], YYhat[:, others]), axis=1) #print('X shape: '+str(Xmatrix.shape)) #print('Y shape: '+str(Ymatrix.shape)) if not np.all(Xmatrix == 0): #Bmatrix = np.linalg.pinv(Xmatrix) @ Ymatrix[:,itype] Bmatrix = pinv_tik(Xmatrix, lam=lam) @ Ymatrix[:, itype] this_nP = int(xothers.sum()) Wx[xothers, itype] = Bmatrix[:this_nP] Wy[others, itype] = Bmatrix[this_nP:] Ymatrix_pred[:, itype] = Xmatrix @ Bmatrix #print((Wx,Wy)) resEtaXi = resEtaXi - Ymatrix_pred return Wx, Wy, resEtaXi