def compute_weights(self): if self.w == []: self.w = utilities.list_to_vec( [1 for i in range(len(self.domain))]) #print(self.domain) #print(self.w) eta = 1.0 / len(self.examples[0]) #print(self.domain) for i in range(self.iterations): #eta = eta/(i+1) #print("Iteration " + str(i)) p = print_prob(self.A, self.w, 10, max_prod=False) #print(p) grad = utilities.list_to_vec([0 for i in range(self.w.shape[0])]) for vertex in range(self.A.shape[0]): p_vec = self.get_prob_vec(vertex, p) for sample_color in self.examples[vertex]: s_vec = self.get_feature_vec(sample_color) grad = grad + (s_vec - p_vec) self.w = self.w + eta * grad print("w") print(self.w)
def compute_weights(self): unobserved_list = [i for i, val in enumerate(self.L) if val ==1] if self.w == []: self.w = utilities.list_to_vec([1 for i in range(len(self.domain))]) #print("unobs") #print(unobserved_list) eta = 1.0/self.num_examples for i in range(self.iterations): p = print_prob(self.A,self.w,10, max_prod=False) #print(p) grad = utilities.list_to_vec([0 for i in range(self.w.shape[0])]) #First, we compute grad updates over observed variables for vertex in range(self.num_variables): if self.L[vertex] == 0: p_vec = self.get_prob_vec(vertex,p) for sample_color in self.examples[vertex]: s_vec = self.get_feature_vec(sample_color) grad = grad + (s_vec - p_vec) #The grad update for unobserved samples #for vertex, indicator in enumerate(self.L): if len(unobserved_list)==0: break for vertex in unobserved_list: p_vec = self.get_prob_vec(vertex,p) #print("p_vec") #print(p_vec) for i in range(self.num_examples): example = self.make_example(i) phi_dict = self.compute_phi_dict(example) beliefs = sample_get_beliefs(self.A,self.wts_to_list(),phi_dict,20) #print(beliefs) if len(unobserved_list) == 1: s_vec = beliefs[vertex] grad = grad + (s_vec - p_vec) else: s_vec = beliefs[vertex] p_probs, belief_probs = self.get_product_lists( p, beliefs, unobserved_list) for i in range(len(p_probs)): grad = grad + (s_vec*belief_probs[i] - p_vec*p_probs[i]) self.w = self.w + eta*grad #print(beliefs) print ("my w") print(self.w)
def get_prob_vec(self,vertex,p): prob_vec = [0 for i in range(len(self.domain))] for key in p[vertex].keys(): prob_vec[key] = p[vertex][key][0] #print(prob_vec) #print() return utilities.list_to_vec(prob_vec)
def get_feature_vec(self, color): """ Returns a vector of size of domain, with 1 indicating the color and 0's elsewhere. :param color: :return: """ return utilities.list_to_vec([0 if color != item else 1 for item in self.domain])
def initiaize_message_dict(messageKeys, k): """ Initialize the messages to a vertical vector of 1s, in the length of the range of possible values, as an np array. For example, for a cycle of 3 completely connected vertices: {'12': array([[1], [1], [1]]), '13': array([[1], [1], [1]]), '21': array([[1], [1], [1]]), '23': array([[1], [1], [1]]), '31': array([[1], [1], [1]]), '32': array([[1], [1], [1]])} The key is the message name. :param messageKeys: :param k: :return: """ message_dict = { key: utilities.list_to_vec([1 for i in range(len(k))]) for key in messageKeys } return message_dict
def compute_new_beliefs(vertex_list, message_dict, w, phi_dict): """ New beliefs are computed for each vertex as a product of phi[vertex] ,w, and the incoming messages :param vertex_list: :param message_dict: :param phi: :return: """ new_belief_dict = {} #print("phidict in compute new beliefs") #print(phi_dict) wts = utilities.list_to_vec([float(item) for item in w]) #print("wts in compute new beliefs") #print(wts) for vertex in vertex_list: incoming_message_keys = [ key for key in message_dict if key[1] == str(vertex) ] mult = wts * phi_dict[vertex] if len(incoming_message_keys) > 0: for key in incoming_message_keys: mult = mult * message_dict[key] if np.sum(mult) != 0: belief = mult / np.sum(mult) else: belief = mult new_belief_dict[vertex] = belief #print("beleif dict") #print(new_belief_dict) return new_belief_dict
def sample_get_beliefs(adj_array, w, phi_dict, iter_num=20): """ adjArray = [[0,1,0],[1,0,1],[0,1,0]] wts = [1,1] Tests for convergence on a simple tree: v1--v2--v3 :param adj_array: :param wts: :param iter_num: :return: """ adjArray = np.array(adj_array) vert_list = get_vertex_list(adjArray) #print("vertex list") # print(vert_list) message_keys = get_message_keys(adjArray) message_dict = initiaize_message_dict(message_keys, w) message_dict = normalize_messages(message_dict) #print("Initial message dict") #print(message_dict) psi = np.zeros((len(w), len(w))) #print("psi in test sum product") for i in range(len(w)): for j in range(len(w)): if i != j: psi[i][j] = 1 else: psi[i][j] = 0 bel_old = create_beliefs_dict(vert_list, len(w)) #print("initial belief dict") #print(bel_old) #psi = [[1,.2],[.2, .5]] psi = np.array(psi) wts = utilities.list_to_vec(w) for i in range(iter_num): message_dict = update_messages(vert_list, message_dict, wts, phi_dict, psi) vertex_beliefs = compute_new_beliefs(vert_list, message_dict, w, phi_dict) #print("Iteration number " + str(i)) converge = beliefs_converge(vertex_beliefs, bel_old) #print ("Belief convergence: "+ str(converge)) bel_old = vertex_beliefs #print("vertex beliefs") #print(vertex_beliefs) return vertex_beliefs """
def compute_phi_dict(self, sample): """ Creates a dictionary, whose keys are the vertices (0-k), and whose values are np arrays of 1s for hidden variables and a feature vec for the variables having a value from the sample. The aim is to multiply the vector * w as the messages are being computed, to clamp the probability at the vertices having a value to 1 for the variable taking that value. :param sample: :return: """ phi_dict = {} for i, color in enumerate(sample): if color == None: phi_dict[i] = utilities.list_to_vec([1 for i in range(len(self.domain))]) else: phi_dict[i] = self.get_feature_vec(color) return phi_dict
def sum_product(adj_array, w, iter_num): """ NEEDS TO BE REFACTORED LIKE 'SAMPLE_GET_BELIEFS' TO INCLUDE A PHI-DICT, WHICH WILL FOR EACH VARIABLE BE A VECTOR OF 1'S, DENOTING THAT NO VARIABLES HAVE ASSIGNED VALUES. :param adj_array: :param w: :param iter_num: :return: """ adjArray = np.array(adj_array) vert_list = get_vertex_list(adjArray) message_keys = get_message_keys(adjArray) message_dict = initiaize_message_dict(message_keys, w) message_dict = normalize_messages(message_dict) psi = np.zeros((len(w), len(w))) bel_old = create_beliefs_dict(vert_list, len(w)) phi = np.exp(utilities.list_to_vec(w)) #print("shape phi") #print(phi.shape) #print(phi[0]) for i in range(len(w)): for j in range(len(w)): if i != j: psi[i][j] = 1 else: psi[i][j] = 0 for i in range(iter_num): message_dict = update_messages(vert_list, message_dict, phi, psi) vertex_beliefs = compute_new_beliefs(vert_list, message_dict, w) #print("vert belief") #print(vertex_beliefs) print("Iteration number " + str(i)) converge = beliefs_converge(vertex_beliefs, bel_old) print("Belief convergence: " + str(converge)) bel_old = vertex_beliefs #print(bel) #print(vertex_beliefs) edge_beliefs = compute_edge_beliefs(message_dict, w, psi) #print("edge bel") #print(edge_beliefs) log_Z = compute_bethe_energy(vertex_beliefs, edge_beliefs, psi, phi) print() print("And the partition coefficent, Z is: " + str(math.exp(log_Z)))
def compute_edge_beliefs(message_dict, w, psi, phi_dict): """ psi = np.zeros((len(w), len(w))) for i in range(len(w)): for j in range(len(w)): if i != j: psi[i][j] = 1 else: psi[i][j] = 0 """ edge_belief_dict = {} w_f = [float(item) for item in w] phi = np.exp(utilities.list_to_vec(w_f)) for key in message_dict.keys(): i, j = key[0], key[1] mult_i = phi mult_j = phi incoming_keys_to_i = [ key_in for key_in in message_dict.keys() if key_in[1] == i and key_in[0] != j ] incoming_keys_to_j = [ key_in for key_in in message_dict.keys() if key_in[1] == j and key_in[0] != i ] diag_i = np.zeros((len(w), len(w))) if len(incoming_keys_to_i) > 0: for key_in in incoming_keys_to_i: mult_i = mult_i * message_dict[key_in] diag_i = np.diagflat(mult_i) else: diag_i = np.diagflat(mult_i) if len(incoming_keys_to_j) > 0: for key in incoming_keys_to_j: mult_j = mult_j * message_dict[key] diag_j = np.diagflat(mult_j) else: diag_j = np.diagflat(mult_j) belief_matrix = diag_i @ (psi @ diag_j) edge_belief_dict[key] = belief_matrix / np.sum(belief_matrix) return edge_belief_dict
def get_fdbk_controller( x,t): k = np.where(param.get('T') == t)[0][0] my_1 = util.get_my_1() eta = dynamics.get_eta( x,t) dvdota_dvb = dynamics.get_dvdota_dvb(x,t) xtilde_dot = dynamics.get_xtildedot( x,t) dvdota_dxtilde = dynamics.get_dvdota_dxtilde( x,t) A = np.matmul( np.transpose( my_1), \ np.matmul( dvdota_dxtilde, xtilde_dot)) - \ util.list_to_vec( param.get('ad')[k,:]) B = np.matmul( np.transpose( my_1), dvdota_dvb) K = param.get('k_fdbk')*np.kron( np.eye(param.get('nd')), \ np.ones((1,param.get('gamma')))) u = np.matmul(np.linalg.pinv(B), - A - np.matmul(K,eta)) u = np.clip( u, -param.get('control_max'), param.get('control_max')) return u
def fn3(): pdf_path = os.path.join(os.getcwd(), param.get('fn_plots')) # remove if exists if os.path.exists(pdf_path): os.remove(pdf_path) np.random.seed(88) util.get_x0() util.get_xd() # baseline trajectory bX = [] bU = np.zeros((len(param.get('T')), param.get('m'))) # true perturbed trajectory X = [] Xdot = [] V = [] Vdot = [] # linearized perturbed trajectory tX = [] tXdot = [] tV = [] tVdot = [] # collect baseline x_curr = param.get('x0') for k, t in enumerate(param.get('T')): u_curr = util.list_to_vec(bU[k, :]) x_next = x_curr + param.get('dt') * dynamics.get_dxdt( x_curr, u_curr, t) bX.append(x_curr) x_curr = x_next bX = np.squeeze(np.asarray(bX)) # now run two trajectories and look at divergence eps_x0 = 0.0 * np.random.uniform(size=(param.get('n'), 1)) eps_u = 0.0 * np.random.uniform(size=(param.get('nt'), param.get('m'))) x_curr = param.get('x0') + eps_x0 tx_curr = param.get('x0') + eps_x0 scpU = bU + eps_u for k, t in enumerate(param.get('T')): # current control u_curr = np.reshape(np.transpose(scpU[k, :]), (param.get('m'), 1)) # base ub = util.list_to_vec(bU[k, :]) xb = util.list_to_vec(bX[k, :]) # true dxdt = dynamics.get_dxdt(x_curr, u_curr, t) x_next = x_curr + dxdt * param.get('dt') v = dynamics.get_V(x_curr, t) vdot = dynamics.get_LfV(x_curr, t) + np.matmul( dynamics.get_LgV(x_curr, t), u_curr) # approximate F_k, B_k, d_k = dynamics.get_linear_dynamics( xb, \ ub, t) R_k, w_k = dynamics.get_linear_lyapunov(xb, ub, t) tx_next = np.matmul( F_k, tx_curr) + \ np.matmul( B_k, u_curr) + d_k tv = np.matmul(R_k, tx_curr) + w_k X.append(x_curr) Xdot.append(dxdt) V.append(v) Vdot.append(vdot) tX.append(tx_curr) tV.append(tv) x_curr = x_next tx_curr = tx_next print('Timestep:' + str(k) + '/' + str(len(param.get('T')))) X = np.squeeze(np.asarray(X)) V = np.reshape(np.asarray(V), (len(V), 1)) Xdot = np.squeeze(np.asarray(Xdot)) tX = np.squeeze(np.asarray(tX)) tV = np.reshape(np.asarray(tV), (len(tV), 1)) tXdot = np.gradient(tX, param.get('dt'), axis=0) tVdot = np.gradient(tV, param.get('dt'), axis=0) print(np.shape(X)) print(np.shape(V)) print(np.shape(Xdot)) print(np.shape(tX)) print(np.shape(tV)) print(np.shape(tXdot)) print(np.shape(tVdot)) epa1 = np.linalg.norm(X[:, 0:2] - tX[:, 0:2], axis=1) eva1 = np.linalg.norm(X[:, 2:4] - tX[:, 2:4], axis=1) epa2 = np.linalg.norm(X[:, 4:6] - tX[:, 4:6], axis=1) eva2 = np.linalg.norm(X[:, 6:8] - tX[:, 6:8], axis=1) epb = np.linalg.norm(X[:, 8:10] - tX[:, 8:10], axis=1) evb = np.linalg.norm(X[:, 10:12] - tX[:, 10:12], axis=1) eXdot = np.linalg.norm(Xdot - tXdot, axis=1) eV = np.linalg.norm(V - tV, axis=1) eVdot = np.linalg.norm(Vdot - tVdot, axis=1) import matplotlib.pyplot as plt fig, ax = plt.subplots() plt.plot(epa1, eXdot, label='eXdot') plt.plot(epa1, eV, label='eV') ax.set_xscale('log') ax.set_yscale('log') ax.set_xlabel('epa') plt.legend() fig, ax = plt.subplots() plt.plot(eva1, eXdot, label='eXdot') plt.plot(eva1, eV, label='eV') ax.set_xscale('log') ax.set_yscale('log') ax.set_xlabel('eva') plt.legend() fig, ax = plt.subplots() plt.plot(epb, eXdot, label='eXdot') plt.plot(epb, eV, label='eV') # ax.set_xscale('log') ax.set_yscale('log') ax.set_xlabel('epb') plt.legend() fig, ax = plt.subplots() plt.plot(evb, eXdot, label='eXdot') plt.plot(evb, eV, label='eV') # ax.set_xscale('log') ax.set_yscale('log') ax.set_xlabel('evb') plt.legend() # plt.plot( eX, eVdot, label = 'eVdot') plotter.save_figs() subprocess.call(["xdg-open", pdf_path])
def fn2(): pdf_path = os.path.join(os.getcwd(), param.get('fn_plots')) # remove if exists if os.path.exists(pdf_path): os.remove(pdf_path) np.random.seed(88) util.get_x0() util.get_xd() # trjaectory to linearize about fX = [] fU = [] fV = [] # scp trajectory tX = [] tU = [] tV = [] # integrated trajectory with scp control scpV = [] # linearize about trajectory bV = [] # feedback linearizing baseline x_curr = param.get('x0') for k, t in enumerate(param.get('T')): u_curr = controller.get_fdbk_controller(x_curr, t) x_next = x_curr + param.get('dt') * dynamics.get_dxdt( x_curr, u_curr, t) v = dynamics.get_V(x_curr, t) fX.append(x_curr) fU.append(u_curr) fV.append(v) x_curr = x_next fX = np.squeeze(np.asarray(fX)) fU = np.asarray(fU) # scp scpX, scpU, bX, bU = controller.get_scp_clf_controller() # integrate tx_curr = param.get('x0') x_curr = param.get('x0') for k, t in enumerate(param.get('T')): ub = util.list_to_vec(bU[k, :]) xb = util.list_to_vec(bX[k, :]) u_curr = np.transpose(util.list_to_vec(scpU[k, :])) F_k, B_k, d_k = dynamics.get_linear_dynamics(xb, ub, t) R_k, w_k = dynamics.get_linear_lyapunov(xb, ub, t) tx_next = np.matmul(F_k, tx_curr) + np.matmul(B_k, u_curr) + d_k x_next = x_curr + param.get('dt') * dynamics.get_dxdt( x_curr, u_curr, t) tv = np.matmul(R_k, tx_curr) + w_k scpv = dynamics.get_V(x_curr, t) tX.append(tx_curr) tV.append(tv) scpV.append(scpv) bV.append(dynamics.get_V(xb, t)) tx_curr = tx_next x_curr = x_next tX = np.squeeze(np.asarray(tX)) bV = np.asarray(bV) plotter.plot_SS(fX, param.get('T'), title='Fdbk Linearize SS') plotter.plot_V(fV, param.get('T'), title='Fdbk Linearize V') plotter.plot_U(fU, param.get('T'), title='Fdbk Linearize U') plotter.plot_SS(bX, param.get('T'), title='What SCP is linearizing about: SS') plotter.plot_V(bV, param.get('T'), title='What SCP is linearizing about: V') # plotter.plot_U(bU, param.get('T'), title = 'What SCP is linearizing about: U') plotter.plot_SS(tX, param.get('T'), title='What SCP thinks its doing: SS') plotter.plot_V(tV, param.get('T'), title='What SCP thinks its doing: V') # plotter.plot_U(tU, param.get('T'), title = 'What SCP thinks its doing: U') plotter.plot_SS(scpX, param.get('T'), title='What SCP is actually doing: SS') plotter.plot_V(scpV, param.get('T'), title='What SCP is actually doing: V') # plotter.plot_U(scpU, param.get('T'), title = 'What SCP is actually doing: U') plotter.save_figs() subprocess.call(["xdg-open", pdf_path])
""" edge_beliefs = compute_edge_beliefs(message_dict,w, psi) log_Z = compute_bethe_energy(vertex_beliefs,edge_beliefs, psi) print() print("And the partition coefficent, Z is: " + str(math.exp(log_Z))) """ #def compute_partition_function(belief_dict): if __name__ == '__main__': #parse arguments: """ TO start from commmand line: python3 sumProduct.py [[0,1,1],[1,0,1],[1,1,0]] [1,2,3] 20 """ args = sys.argv array = args[1] wts = args[2] iterations = int(float(args[3])) adjM = ast.literal_eval(array) w = ast.literal_eval(wts) values = 1 #sum_product(adjM, w, iterations) phi_dict = { 0: utilities.list_to_vec([1, 1, 1]), 1: utilities.list_to_vec([1, 0, 0]), 2: utilities.list_to_vec([0, 0, 1]) } a = sample_get_beliefs(adjM, w, phi_dict, iterations) print(a)