def fitness(moveablePts): global nutrient_values, product_values try: xPoints = moveablePts[0::2] #get x points np array view from flat list yPoints = moveablePts[1::2] #get y points np array view from flat list except: xPoints = moveablePts._value[0::2] yPoints = moveablePts._value[1::2] try: xIntPoints = list([int(x) for x in xPoints]) yIntPoints = list([int(y) for y in yPoints]) except: xIntPoints = list([int(x) for x in xPoints._value]) yIntPoints = list([int(y) for y in yPoints._value]) nutrient_values = np.zeros((HowManyCells, HowManyCells)) product_values = np.zeros((HowManyCells, HowManyCells)) nutrient_values = doPDE(nutrient_values, moveablePts, xPoints, yPoints, xIntPoints, yIntPoints) product_values = doPDE(product_values, moveablePts, xPoints, yPoints, xIntPoints, yIntPoints) odeResult = doODE(nutrient_values, product_values, moveablePts, xPoints, yPoints, xIntPoints, yIntPoints) nutrient_values += odeResult[0] product_values += odeResult[1] # nutrient_values.clip(min=0) #put all negative values to 0 # product_values.clip(min=0) return (nutrient_values[10][10])
def generate_edges(self, tri, pts): edges = [] for _, s in enumerate(tri.simplices): tri_pts = [pts[i] for i in list(s)] for i, pt in enumerate(tri_pts): if i == 0: continue elif pt == tri_pts[-1]: # Wrap around self.add_edge_to_graph(pt, tri_pts[0]) self.add_edge_to_graph(tri_pts[i - 1], pt) topl_to_topR = ([self.min_range, self.max_range], [self.max_range, self.max_range]) btml_to_btmR = ([self.min_range, self.min_range], [self.max_range, self.min_range]) for pt_pair in [topl_to_topR, btml_to_btmR]: pt1, pt2 = pt_pair if pt2 in self.graph[tuple(pt1)]: idx = self.graph[tuple(pt1)].index(pt2) del self.graph[tuple(pt1)][idx] elif pt1 in self.graph[tuple(pt2)]: idx = self.graph[tuple(pt2)].index(pt1) del self.graph[tuple(pt1)][idx] for tuple_pt, lst_pt_list in self.graph.items(): for lst_pt in lst_pt_list: # edges.append((np.asarray(tuple_pt), list(np_pt))) edges.append((list(tuple_pt), lst_pt)) return edges
def doPDE(values, movablePts, xPoints, yPoints, xIntPoints, yIntPoints): # Update the values based on diffusion of the proteins to nearby cells D = 0.1 # diffusion parameter valuesT = np.transpose(values) adjustmentPDEX = D * nonLinearAdjustment(xPoints) adjustmentPDEY = D * nonLinearAdjustment(yPoints) #simple diffusion is just a convolution convolveLinear = np.array([1 * D, -2 * D, 1 * D]) # accumulate the changes due to diffusion for rep in range(50): # print(rep) newValuesX = list([]) newValuesY = list([]) for i in range(HowManyCells): row = values[i] + sig.convolve( values[i], convolveLinear)[1:-1] #take off first and last rowY = valuesT[i] + sig.convolve( valuesT[i], convolveLinear)[1:-1] #take off first and last # non-linear diffusion, add the adjustment if i in xIntPoints: row = row + np.multiply(row, adjustmentPDEX) if i in yIntPoints: rowY = rowY + np.multiply(rowY, adjustmentPDEY) newValuesX.append(row) newValuesY.append(rowY) #Merge rows and transposed columns values = np.array(newValuesX) + np.array(newValuesY).T # add source at each iteration values = values + addSources3(xPoints, yPoints) #Update transposed values valuesT = values.T # the total update returned is the difference between the original values and the values after diffusion return values
def plot(self, *args, start=None, end=None, step=500, **kwargs): if start == None or end == None: xs = np.linspace(self.end, self.start, step) ys = list(map(self.function, xs)) else: xs = np.linspace(start, end, step) ys = list(map(self.function, xs)) plt.plot(xs, ys, *args, **kwargs)
def nonLinearAdjustment(movablePts): # adds an adjustment to the material transfer to take into account # the actural position of the cell point in space # adjustment is constant for each simulation, because the points do # not move so compute once allAdjustment = np.zeros(HowManyCells) for x in list(movablePts): #only single numbers in x one D try: pointI = int(x) except: pointI = int(x._value) thisAdj = [] totalAdj = 0 # accumulate the changes around the center point for xI in range(0, HowManyCells): # find the array locations just before or just after the moveable point if ((pointI == xI - 1 and pointI > 0) or (pointI == xI + 1 and pointI < HowManyCells)): deltaConc = distToConc( abs(x - (xI + 0.5))) #distance off from the center thisAdj.append(deltaConc) totalAdj = totalAdj + deltaConc #accun # Otherwise no adjustment else: thisAdj.append(0) #accumulate this movable point into the total adjustment allAdjustment = allAdjustment + np.array(thisAdj) return allAdjustment
def get_hand_seq(Theta, bones_lengths, fingers_angles): hand_seq = list([[]] * 5) for finger_ix in range(5): hand_seq[finger_ix] = get_finger_bone_seq(finger_ix, Theta, bones_lengths, fingers_angles) return hand_seq
def update_hillclimb_pts(self, new_mvable_pts): self.graph = dict() pts_lst = [] prev = None cur = None for i in range(0, len(list(new_mvable_pts))): cur = list(new_mvable_pts)[i] # print('updating points', cur) x = float(cur[0]) y = float(cur[1]) if x < self.min_range + 1: x = float(self.min_range + 1) elif x > self.max_range - 1: x = float(self.max_range - 1) if y < self.min_range + 1: y = float(self.min_range + 1) elif y > self.max_range - 1: y = float(self.max_range - 1) cur = [x, y] pts_lst = pts_lst + [cur] self.moveable_pts = pts_lst self.remove_dup_pts() pts = [] if self.has_side_nodes: pts = self.moveable_pts + self.left_wall + self.right_wall + self.left_wall_startend + self.right_wall_startend else: pts = self.moveable_pts + self.left_wall_startend + self.right_wall_startend self.pts = sorted(pts, key=lambda x: (-x[0], x[1]), reverse=True) self.tri = Delaunay(self.pts) self.edges = self.generate_edges(self.tri, self.pts) self.img = None self.img = self.convert_to_img(self.edges, self.max_range) self.update_count = self.update_count + 1
def add_flows_to_img(self, flow_dict): # print('In add_flows_to_img') img = [] self.pts_on_vessels = defaultdict(lambda: 0.0) for _ in range(int(self.max_range + 1)): img.append([0.0 for i in range(int(self.max_range + 1))]) for pt_key, flow_val in flow_dict.items(): pt1, pt2 = pt_key pt1 = [int(i) for i in list(pt1)] pt2 = [int(i) for i in list(pt2)] pts_on_line = list(bresenham(pt1[0], pt1[1], pt2[0], pt2[1])) for x, y in pts_on_line: img[x][y] = flow_val self.pts_on_vessels[(x, y)] = flow_val self.img = img self.Q = np.array(img) return self.img
def rotate_diff_axis(axis, vec, ix_start, theta, eps=1e-6): if abs(theta) <= eps: return vec if axis == 0: x, y, z = rotate_diff_x(vec, ix_start, theta) elif axis == 1: x, y, z = rotate_diff_y(vec, ix_start, theta) elif axis == 2: x, y, z = rotate_diff_z(vec, ix_start, theta) else: return None return list([x, y, z])
def get_finger_bone_seq_no_rot(finger_ix, bones_lengths): finger_bone_angles_ixs = [0] * 4 for i in range(4): finger_bone_angles_ixs[i] = i + 3 finger_bone_seq = list([[0., 0., 0.]] * 4) curr_seq_len = 0. for i in range(4): finger_bone_seq[i] = [ curr_seq_len + bones_lengths[finger_ix][i], 0., 0. ] curr_seq_len += bones_lengths[finger_ix][0] return finger_bone_seq
def doODE(nutrient_values, product_values, movablePts, xPoints, yPoints, xIntPoints, yIntPoints): k = 0.01 product_result = list([]) nutrient_result = list([]) for iy in range(HowManyCells): product_result_row = list([]) nutrient_result_row = list([]) for ix in range(HowManyCells): isVessel = False if ix == xIntPoints[0] and iy == yIntPoints[0]: isVessel = True x = product_values[ix][iy] n = nutrient_values[ix][iy] dx = deltaProduct(x, n, k, isVessel) dn = deltaNutrient(x, n, k, isVessel) product_result_row.append(dx) nutrient_result_row.append(dn) product_result.append(product_result_row) nutrient_result.append(nutrient_result_row) return (np.array(product_result), np.array(nutrient_result))
def get_bones_lengths(): ''' :return skeleton model fixed bone lengths in mm ''' bone_lengths = list([[]] * 5) # finger bone_lengths[0] = [52., 43., 35., 32.] # index bone_lengths[1] = [86., 42., 34., 29.] # middle bone_lengths[2] = [78., 48., 34., 28.] # ring bone_lengths[3] = [77., 50., 32., 29.] # little1 bone_lengths[4] = [77., 29., 21., 23.] return bone_lengths
def get_fingers_angles_canonical(right_hand=True): ''' :return: bone angles of hand canonical pose ''' finger_angles = list([[0., 0., 0.]] * 5) if right_hand: # finger finger_angles[0] = [0., 0.2, 0.785] # index finger_angles[1] = [0., 0., 0.3925] # middle finger_angles[2] = [0., 0., 0.] # ring finger_angles[3] = [0., 0., 5.8875] # little finger_angles[4] = [0., 0., 5.495] return finger_angles
def get_finger_bone_seq(finger_ix, Theta, bones_lengths, fingers_angles): # get local bone sequence positions, without rotation finger_bone_seq = list([[0., 0., 0.]] * 4) for i in range(4): finger_bone_seq[i] = [bones_lengths[finger_ix][i], 0., 0.] # get finger-dependent indexes of Theta and axes of rotation theta_ixs, axes_rot = get_finger_theta_ixs_and_axes(finger_ix) # rotate each finger bone with Theta for i in range(4): ix_rev = 3 - i angle = Theta[theta_ixs[ix_rev]] ax_rot = axes_rot[ix_rev] finger_bone_seq[ix_rev] = rotate_diff_axis(ax_rot, finger_bone_seq[ix_rev], 0, angle) # update "children" bones j = ix_rev while j < 3: finger_bone_seq[j + 1] = rotate_diff_axis(ax_rot, finger_bone_seq[j + 1], 0, angle) j += 1 # put all finger bones in absolute position to hand root for i in range(3): finger_bone_seq[i + 1] = [ finger_bone_seq[i + 1][0] + finger_bone_seq[i][0], finger_bone_seq[i + 1][1] + finger_bone_seq[i][1], finger_bone_seq[i + 1][2] + finger_bone_seq[i][2] ] # rotate each finger with its finger canonical angle for each axis for i in range(4): for ax in range(3): angle = fingers_angles[finger_ix][ax] finger_bone_seq[i] = rotate_diff_axis(ax, finger_bone_seq[i], 0, angle) # rotate each finger according to the hand root rotation for i in range(4): for j in range(3): finger_bone_seq[i] = rotate_diff_axis(j, finger_bone_seq[i], 0, Theta[j]) return finger_bone_seq
def convert_to_img(self, edges, max_range): img = [] for _ in range(int(max_range + 1.0)): img.append([0.0 for i in range(int(max_range + 1.0))]) for edge in edges: pt1, pt2 = edge pt1 = [int(i) for i in pt1] pt2 = [int(i) for i in pt2] # TODO(zcase): Account for it points go <min or > max for both x and y # print(pt1) # print(pt2) pts_on_line = list(bresenham(pt1[0], pt1[1], pt2[0], pt2[1])) # print(pts_on_line) for x, y in pts_on_line: if (x == pt1[0] and y == pt1[1]) or (x == pt2[0] and y == pt2[1]): img[x][y] = 2 else: img[x][y] = 1 return img
def nonlinearDiffusion(mvble_pts, img, D, linearConv): #http://greg-ashton.physics.monash.edu/applying-python-functions-in-moving-windows.html #https://stackoverflow.com/questions/12816293/vectorize-this-convolution-type-loop-more-efficiently-in-numpy h, w = np.array(img).shape deltaDomain2 = [] for _ in range(w): deltaDomain2.append([0.0 for _ in range(h)]) # maximum distance from moveable point to center of neighboring grid location #maxD = math.sqrt(0.5 * 0.5 + 1.5*1.5) for i in range(len(mvble_pts)): pt = mvble_pts[i] x = pt[0] y = pt[1] int_x = 0 int_y = 0 # print(mvble_pts[i][0], type(mvble_pts[i][0])) # get the int coordinates of this moveable point if type(x) != type(np.array((1, 1))) and type(x) != type(1) and ( type(mvble_pts[i][0]) != float and type(mvble_pts[i][0]) != np.float64): # if type(x) != type(np.array((1,1))) and type(mvble_pts[i][0]) != np.float64: int_x = int(np.array(mvble_pts[i][0]._value)) int_y = int(np.array(mvble_pts[i][1]._value)) else: int_x = int(np.array(mvble_pts[i][0])) int_y = int(np.array(mvble_pts[i][1])) # int_x = int(np.array(mvble_pts[i][0]._value)) # int_y = int(np.array(mvble_pts[i][1]._value)) np_pt = np.array([x, y]) inc = 0.5 # to center of neighbor grid locations # compute all the distances with the neighbors dist_0 = np.linalg.norm(np_pt - np.array([int_x - 1 + inc, int_y - 1 + inc])) dist_1 = np.linalg.norm(np_pt - np.array([int_x + inc, int_y - 1 + inc])) dist_2 = np.linalg.norm(np_pt - np.array([int_x + 1 + inc, int_y - 1 + inc])) dist_3 = np.linalg.norm(np_pt - np.array([int_x - 1 + inc, int_y + inc])) dist_4 = np.linalg.norm(np_pt - np.array([int_x + inc, int_y + inc])) dist_5 = np.linalg.norm(np_pt - np.array([int_x + 1 + inc, int_y + inc])) dist_6 = np.linalg.norm(np_pt - np.array([int_x - 1 + inc, int_y + 1 + inc])) dist_7 = np.linalg.norm(np_pt - np.array([int_x + inc, int_y + 1 + inc])) dist_8 = np.linalg.norm(np_pt - np.array([int_x + 1 + inc, int_y + 1 + inc])) # calculate non-linear concentrations adjustments needed based on the position of the point at that grid location # contribution of concentration to neighbor adjusts the contribution already calculated by linear diffution # let d be the distance from the moveable point to the center of the neighboring grid location # then adjustment in concentration is 1 - d. # if d=1, no adjustment (realdy done this) # if d<1, then closer so positive adjustment # if d>1, then farther away so negative adjustment # let this function be distToConc(d) --> conc # center = sum([distToConc(d) for d in [dist_0, dist_1, dist_2, dist_3, dist_4, dist_5, dist_6, dist_7, dist_8]]) * -1 # convolution = [[distToConc(dist_0), distToConc(dist_1), distToConc(dist_2)], # [distToConc(dist_3), center, distToConc(dist_5)], # [distToConc(dist_6), distToConc(dist_7), distToConc(dist_8)]] center = sum([ d for d in [ dist_0, dist_1, dist_2, dist_3, dist_4, dist_5, dist_6, dist_7, dist_8 ] ]) * -1 convolution = [[dist_0, dist_1, dist_2], [dist_3, center, dist_5], [dist_6, dist_7, dist_8]] convolution = np.array(linearConv) - np.array(convolution) convolution = [val for val in list(convolution)] # center = sum([distToConc(d) for d in [dist_0, dist_1, dist_2, dist_3, dist_4, dist_5, dist_6, dist_7, dist_8]]) * -1 # convolution = [[distToConc(dist_0), distToConc(dist_1), distToConc(dist_2)], # [distToConc(dist_3), center, distToConc(dist_5)], # [distToConc(dist_6), distToConc(dist_7), distToConc(dist_8)]] print('\nNonLinear Conv (After Subtracting from Linear)') print(np.array(convolution)) print('Sqrt(2): ', np.sqrt(2), 1 - np.sqrt(2)) print('D0: ', dist_0) #, distToConc(dist_0)) print('D1: ', dist_1) #, distToConc(dist_1)) print('D2: ', dist_2) #, distToConc(dist_2)) print('D3: ', dist_3) #, distToConc(dist_3)) print( 'D4: ', sum([ d for d in [ dist_0, dist_1, dist_2, dist_3, dist_4, dist_5, dist_6, dist_7, dist_8 ] ]) * -1 ) #, sum([distToConc(d) for d in [dist_0, dist_1, dist_2, dist_3, dist_4, dist_5, dist_6, dist_7, dist_8]]) * -1) print('D5: ', dist_5) #, distToConc(dist_5)) print('D6: ', dist_6) #, distToConc(dist_6)) print('D7: ', dist_7) #, distToConc(dist_7)) print('D8: ', dist_8) #, distToConc(dist_8)) # try: deltaDomain2 = get_submatrix_add(deltaDomain2, (int_x, int_y), convolution) # print(np.array(deltaDomain2)) # print((int_x, int_y)) # os.sys.exit() # except Exception as e: # print(e) # print(np.array(deltaDomain2), np.array(deltaDomain2).shape) # print((int_x, int_y)) # print(np.array(convolution)) # print(np.array(deltaDomain2) * D) # return np.array(deltaDomain2) * D return np.array(deltaDomain2)
def get_hand_seq_canonical(bones_lengths, fingers_angles): hand_seq = list([[]] * 5) for finger_ix in range(5): hand_seq[finger_ix] = get_finger_canonical_bone_seq( finger_ix, bones_lengths, fingers_angles) return hand_seq
ax_values.set_ylabel('value') ax_values.imshow(nutrient_values) ax_product.cla() ax_product.set_title('Product') ax_product.set_xlabel('position') ax_product.set_ylabel('value') ax_product.imshow(product_values) plt.draw() saveFigureImage(iteration) plt.pause(0.001) return 3 gradPDE = grad(fitness) mvable_pts = list([12.4, 14.99, 5.3, 6.8 ]) #flat list for autograd but points are (x,y) (x,y) if useAdam: m = np.zeros(np.array(mvable_pts).shape, dtype=np.float64) v = np.zeros(np.array(mvable_pts).shape, dtype=np.float64) b1 = 0.9 b2 = 0.999 eps = 10**-8 # print(gradPDE((25.99, 3.4))) for i in range(500): grad_pts = gradPDE(mvable_pts) print(grad_pts) if useAdam: m = (1 - b1) * np.array( grad_pts, dtype=np.float64) + b1 * m # First moment estimate. v = (1 - b2) * (np.array(grad_pts, dtype=np.float64)**
def update_moveable_pts(self, new_mvable_pts): # print('In update_moveable_pts') # print('VasGen2 236: ', new_mvable_pts) # print(type(new_mvable_pts)) self.graph = dict() pts_lst = [] prev = None cur = None # print('\n IN UPDATE PTS') # print('new_mv_pts: ', new_mvable_pts) # for i in range(2, len(list(new_mvable_pts)._value)+2, 2): for i in range(2, len(list(new_mvable_pts)) + 2, 2): # cur = list(new_mvable_pts)._value[i-2:i] cur = list(new_mvable_pts)[i - 2:i] x = float(cur[0]) y = float(cur[1]) if x < self.min_range + 1: x = float(self.min_range + 1) elif x > self.max_range - 1: x = float(self.max_range - 1) if y < self.min_range + 1: y = float(self.min_range + 1) elif y > self.max_range - 1: y = float(self.max_range - 1) cur = [x, y] # print('First Cur: ', cur) # if i > 2: # prev = [float(i) for i in prev] # cur = [float(i) for i in cur] # print('prev: ', prev) # print('cur : ', cur) # pts_lst = pts_lst + [prev, cur] # prev = cur pts_lst = pts_lst + [cur] # print('\nhere: ') # print(pts_lst, type(pts_lst), len(pts_lst)) # os.sys.exit() # print('hERE: ', list(new_mvable_pts)._value) self.moveable_pts = pts_lst self.remove_dup_pts() # print('HERE 2: ', self.moveable_pts) pts = [] if self.has_side_nodes: pts = self.moveable_pts + self.left_wall + self.right_wall + self.left_wall_startend + self.right_wall_startend else: pts = self.moveable_pts + self.left_wall_startend + self.right_wall_startend # print('VasGen2: ', np.array(pts), type(pts)) self.pts = sorted(pts, key=lambda x: (-x[0], x[1]), reverse=True) self.tri = Delaunay(self.pts) self.edges = self.generate_edges(self.tri, self.pts) self.img = None self.img = self.convert_to_img(self.edges, self.max_range) self.update_count = self.update_count + 1
def eval_repar(e, thts, env={}): """ Summary: computes the reparameterization term in our estimator. Args: - e : Expr - thts : float array - env : (str -> (func * float)) dict Returns: - ret : func - retvl : float - epss : float array - xs : float array - logpq : func where - env[var_str] = return value of Var(var_str) as (function of \THT, float) - ret(\THT) = return value of e (as a function of \THT) - retvl = ret(thts) - epss = values sampled from N(0,1) - xs = T_thts(epss) - logpq(\THT) = log p(X,Y) - log q_\THT(X) |_{X=T_\THT(epss)} here capital math symbols denote vectors. """ if isinstance(e, Cnst): ret = lambda _thts, c=e.c: c retvl = ret([]) epss = anp.array([]) xs = anp.array([]) logpq = lambda _thts: 0.0 elif isinstance(e, Var): assert (e.v in env) (ret, retvl) = env[e.v] epss = anp.array([]) xs = anp.array([]) logpq = lambda _thts: 0.0 elif isinstance(e, Linear): ret = None # ASSUME: (Linear ...) appear only in the conditional part of If. retvl = e.c0 + sum([ci * env[vi][1] for (ci, vi) in e.cv_l]) epss = anp.array([]) xs = anp.array([]) logpq = lambda _thts: 0.0 elif isinstance(e, App): # recursive calls num_args = len(e.args) (ret_sub, retvl_sub, epss_sub, xs_sub, logpq_sub)\ = zip(*[ eval_repar(e.args[i], thts, env) for i in range(num_args) ]) # compute: all but ret, retvl epss = anp.concatenate(epss_sub) xs = anp.concatenate(xs_sub) logpq = merge_logpqs(logpq_sub) # compute: ret, retvl op = App.OP_DICT[num_args][e.op] ret = lambda _thts, op=op, ret_sub=ret_sub, num_args=num_args:\ op(*[ ret_sub[i](_thts) for i in range(num_args)]) retvl = op(*[retvl_sub[i] for i in range(num_args)]) elif isinstance(e, If): # recursive calls (_, retvl_1, epss_1, xs_1, logpq_1)\ = eval_repar(e.e1, thts, env) (ret_r, retvl_r, epss_r, xs_r, logpq_r)\ = (eval_repar(e.e2, thts, env) if retvl_1 > 0 else\ eval_repar(e.e3, thts, env)) # compute: all ret = ret_r retvl = retvl_r epss = anp.concatenate((epss_1, epss_r)) xs = anp.concatenate((xs_1, xs_r)) logpq = merge_logpqs([logpq_1, logpq_r]) elif isinstance(e, Let): # recursive calls (ret_1, retvl_1, epss_1, xs_1, logpq_1) = eval_repar(e.e1, thts, env) env_new = util.copy_add_dict(env, {e.v1.v: (ret_1, retvl_1)}) (ret_2, retvl_2, epss_2, xs_2, logpq_2) = eval_repar(e.e2, thts, env_new) # compute: all ret = ret_2 retvl = retvl_2 epss = anp.concatenate((epss_1, epss_2)) xs = anp.concatenate((xs_1, xs_2)) logpq = merge_logpqs([logpq_1, logpq_2]) elif isinstance(e, Sample): # recursive calls (ret_1, retvl_1, epss_1, xs_1, logpq_1) = eval_repar(e.e1, thts, env) (ret_2, retvl_2, epss_2, xs_2, logpq_2) = eval_repar(e.e2, thts, env) # compute: all but logpq stind = e.stind['thts'] eps_3 = np.random.normal(0, 1) # do sampling eps2x_cur = lambda _tht, eps=eps_3: _tht[0] + util.softplus_anp(_tht[1] ) * eps eps2x_3 = lambda _thts, eps2x_cur=eps2x_cur, stind=stind: eps2x_cur( _thts[stind:stind + 2]) x_3 = eps2x_3(thts) ret = lambda _thts, eps2x_3=eps2x_3: eps2x_3(_thts) retvl = x_3 # use current thts value to compute return value epss = anp.concatenate((epss_1, epss_2, anp.array([eps_3]))) xs = anp.concatenate((xs_1, xs_2, anp.array([x_3]))) # compute: logpq def logpq_3(_thts, ret=ret, ret_1=ret_1, ret_2=ret_2, stind=stind): # compute: log p(x|p_loc,p_scale) - log q(x|q_loc,q_scale) x = ret(_thts) p_loc = ret_1(_thts) p_scale = ret_2(_thts) q_loc = _thts[stind] q_scale = util.softplus_anp(_thts[stind + 1]) return (ascipy.stats.norm.logpdf(x, p_loc, p_scale) -\ ascipy.stats.norm.logpdf(x, q_loc, q_scale)) logpq = merge_logpqs([logpq_1, logpq_2, logpq_3]) elif isinstance(e, Fsample): # recursive calls (ret_1, retvl_1, epss_1, xs_1, logpq_1) = eval_repar(e.e1, thts, env) (ret_2, retvl_2, epss_2, xs_2, logpq_2) = eval_repar(e.e2, thts, env) # compute: all x_3 = np.random.normal(retvl_1, retvl_2) # do sampling ret = lambda _thts, x_3=x_3: x_3 retvl = x_3 epss = anp.concatenate((epss_1, epss_2)) xs = anp.concatenate((xs_1, xs_2)) logpq = merge_logpqs([logpq_1, logpq_2]) elif isinstance(e, Observe): # recursive calls num_args = len(e.args) (ret_sub, retvl_sub, epss_sub, xs_sub, logpq_sub)\ = zip(*[ eval_repar(e.args[i], thts, env) for i in range(num_args) ]) # compute: all but logpq ret = lambda _thts, c=e.c1.c: c retvl = ret([]) epss = anp.concatenate(epss_sub) xs = anp.concatenate(xs_sub) # compute: logpq dstr_logpdf = Observe.DSTR_DICT[e.dstr] def logpq_cur(_thts, dstr_logpdf=dstr_logpdf, c=e.c1.c, ret_sub=ret_sub, num_args=num_args): # compute: log p(c|p_loc,p_scale) return dstr_logpdf(c, *[ret_sub[i](_thts) for i in range(num_args)]) logpq = merge_logpqs(list(logpq_sub) + [logpq_cur]) else: assert (False) return (ret, retvl, epss, xs, logpq)