def convert_pot_df_to_pot(is_quantum, pot_df, ord_nodes, normalize=True): """ Returns a Potential pot with ordered nodes ord_nodes. Parameters ---------- is_quantum : bool pot_df : pandas.DataFrame a dataframe returned by learn_pot_df() ord_nodes : list[BayesNode] ordered nodes of Potential pot that is returned normalize : bool True if want pot to be normalized as a cond probability or cond amplitude, P(x|y) or A(x|y), where x is ord_nodes[-1] Returns ------- pandas.DataFrame """ pot = DiscreteCondPot(is_quantum, ord_nodes, bias=0) for row in range(len(pot_df.index)): # print([pot_df.iloc[row, col] # for col in range(len(ord_nodes)) # ]) index = [ ord_nodes[col].st_name_index(str(pot_df.iloc[row, col])) for col in range(len(ord_nodes)) ] pot.pot_arr[tuple(index)] = pot_df.loc[row, 'pot_values'] if normalize: pot.normalize_self() # print(pot) return pot
def build_bnet(): """ Builds QBnet called QuWetGrass with diamond shape Cloudy / \ Rain Sprinkler \ / WetGrass All arrows pointing down """ cl = BayesNode(0, name="Cloudy") sp = BayesNode(1, name="Sprinkler") ra = BayesNode(2, name="Rain") we = BayesNode(3, name="WetGrass") we.add_parent(sp) we.add_parent(ra) sp.add_parent(cl) ra.add_parent(cl) nodes = {cl, ra, sp, we} cl.potential = DiscreteUniPot(True, cl) # P(a) sp.potential = DiscreteCondPot(True, [cl, sp]) # P(b| a) ra.potential = DiscreteCondPot(True, [cl, ra]) we.potential = DiscreteCondPot(True, [sp, ra, we]) # in general # DiscreteCondPot(True, [y1, y2, y3, x]) refers to A(x| y1, y2, y3) # off = 0 # on = 1 cl.potential.pot_arr[:] = [.5 + .1j, .5] ra.potential.pot_arr[1, :] = [.5 - .1j, .5 + .3j] ra.potential.pot_arr[0, :] = [.4, .6 - .7j] sp.potential.pot_arr[1, :] = [.7 + 3.j, .3 - 1.j] sp.potential.pot_arr[0, :] = [.2 + .5j, .8] we.potential.pot_arr[1, 1, :] = [.01 + 1j, .99] we.potential.pot_arr[1, 0, :] = [.01 - 5.j, .99] we.potential.pot_arr[0, 1, :] = [.01, .99 + 2.3j] we.potential.pot_arr[0, 0, :] = [.99, .01 - .01j] cl.potential.normalize_self() ra.potential.normalize_self() sp.potential.normalize_self() we.potential.normalize_self() return BayesNet(nodes)
def build_bnet(): """ Builds CBnet called WetGrass with diamond shape Cloudy / \ Rain Sprinkler \ / WetGrass All arrows pointing down """ cl = BayesNode(0, name="Cloudy") sp = BayesNode(1, name="Sprinkler") ra = BayesNode(2, name="Rain") we = BayesNode(3, name="WetGrass") we.add_parent(sp) we.add_parent(ra) sp.add_parent(cl) ra.add_parent(cl) nodes = {cl, ra, sp, we} cl.potential = DiscreteUniPot(False, cl) # P(a) sp.potential = DiscreteCondPot(False, [cl, sp]) # P(b| a) ra.potential = DiscreteCondPot(False, [cl, ra]) we.potential = DiscreteCondPot(False, [sp, ra, we]) # in general # DiscreteCondPot(False, [y1, y2, y3, x]) refers to P(x| y1, y2, y3) # off = 0 # on = 1 cl.potential.pot_arr[:] = [.5, .5] ra.potential.pot_arr[1, :] = [.5, .5] ra.potential.pot_arr[0, :] = [.4, .6] sp.potential.pot_arr[1, :] = [.7, .3] sp.potential.pot_arr[0, :] = [.2, .8] we.potential.pot_arr[1, 1, :] = [.01, .99] we.potential.pot_arr[1, 0, :] = [.01, .99] we.potential.pot_arr[0, 1, :] = [.01, .99] we.potential.pot_arr[0, 0, :] = [.99, .01] return BayesNet(nodes)
def __init__(self, id_num, name, is_quantum, pa_nd, projected_axis, has_commas=True): """ Constructor Parameters ---------- id_num : int id number of self (focus node) name : str name of self (focus node) is_quantum : bool pa_nd : BayesNode parent node projected_axis : int has_commas : bool Returns ------- """ self.projected_axis = projected_axis self.has_commas = has_commas if has_commas: bad = '() ' # rep = repetitive rep_name_list = [ ut.fix(name, bad, '').split(',')[projected_axis] for name in pa_nd.state_names ] else: rep_name_list = [ name[projected_axis] for name in pa_nd.state_names ] non_rep_name_list = sorted(list(set(rep_name_list))) size = len(non_rep_name_list) BayesNode.__init__(self, id_num, name, size=size) self.add_parent(pa_nd) self.state_names = non_rep_name_list pot = DiscreteCondPot(is_quantum, [pa_nd, self], bias=0) self.potential = pot for k, name in enumerate(self.state_names): for r, pa_name in enumerate(rep_name_list): if name == pa_name: # remember, focus node is last topo_index self.potential[r, k] = 1
def build_bnet(): """ Builds simple 7 node binary tree a0 / \ b0 b1 / \ / \ c0 c1,c2 c3 All arrows pointing down """ a0 = BayesNode(0, name="a0") b0 = BayesNode(1, name="b0") b1 = BayesNode(2, name="b1") c0 = BayesNode(3, name="c0") c1 = BayesNode(4, name="c1") c2 = BayesNode(5, name="c2") c3 = BayesNode(6, name="c3") a0.add_children([b0, b1]) b0.add_children([c0, c1]) b1.add_children([c2, c3]) nodes = {a0, b0, b1, c0, c1, c2, c3} a0.potential = DiscreteUniPot(False, a0) # P(a) b0.potential = DiscreteCondPot(False, [a0, b0]) # P(b| a) b1.potential = DiscreteCondPot(False, [a0, b1]) c0.potential = DiscreteCondPot(False, [b0, c0]) c1.potential = DiscreteCondPot(False, [b0, c1]) c2.potential = DiscreteCondPot(False, [b1, c2]) c3.potential = DiscreteCondPot(False, [b1, c3]) # in general # DiscreteCondPot(False, [y1, y2, y3, x]) refers to P(x| y1, y2, y3) # off = 0 # on = 1 a0.potential.pot_arr = np.array([.7, .3]) b0.potential.pot_arr = np.array([[.5, .5], [.4, .6]]) b1.potential.pot_arr = np.array([[.2, .8], [.4, .6]]) c0.potential.pot_arr = np.array([[.3, .7], [.4, .6]]) c1.potential.pot_arr = np.array([[.5, .5], [.9, .1]]) c2.potential.pot_arr = np.array([[.8, .2], [.4, .6]]) c3.potential.pot_arr = np.array([[.5, .5], [.6, .4]]) return BayesNet(nodes)
def __init__(self, id_num, name, in_nd, theta_degs, max_n_sum=10000): """ Constructor Parameters ---------- id_num : int id number of self (focus node) name : str name of self (focus node) in_nd : BayesNode input node theta_degs : float max_n_sum : float Returns ------- """ self.theta_degs = theta_degs # self.max_n_sum and self.true_max_n_sum defined later m = [ map(int, ut.fix(name, '() ', '').split(',')) for name in in_nd.state_names ] mx, my = zip(*m) self.true_max_n_sum = max([mx[k] + my[k] for k in range(len(mx))]) if max_n_sum > self.true_max_n_sum: max_n_sum = self.true_max_n_sum self.max_n_sum = max_n_sum expected_degen = self.get_expected_degen(mx, my) assert expected_degen > 0, \ "expected degen of polarization rot node is zero" BayesNode.__init__(self, id_num, name, size=expected_degen) self.add_parent(in_nd) pot = DiscreteCondPot(True, [in_nd, self], bias=0) self.potential = pot self.fill_trans_mat_and_st_names_of_nd(mx, my)
def __init__(self, id_num, name, is_quantum, pa1, pa2, pa1_is_control, flipped_by_0): """ Constructor Parameters ---------- id_num : int id number of self (focus node) name : str name of self (focus node) is_quantum : bool pa1 : BayesNode parent 1 pa2 : BayesNode parent 2 pa1_is_control : bool True (False) when parent 1 (parent 2) is control flipped_by_0 : bool True (False) when target flips when state of control is 0 (1) Returns ------- """ self.pa1_is_control = pa1_is_control self.flipped_by_0 = flipped_by_0 assert pa1.size == 2 & pa2.size == 2, \ "The parent nodes of the CNot don't both have size 2" assert pa1.state_names == ['0', '1'], "parent1 states not 0,1" assert pa2.state_names == ['0', '1'], "parent2 states not 0,1" BayesNode.__init__(self, id_num, name, size=4) self.add_parent(pa1) self.add_parent(pa2) self.set_state_names_to_product(['01'], repeat=2, trim=True) pot = DiscreteCondPot(is_quantum, [pa1, pa2, self], bias=0) self.potential = pot for st1 in range(2): for st2 in range(2): self.potential[st1, st2, self.final_st(st1, st2)] = 1
def __init__(self, id_num, name, pa_nd, theta_degs, occ_nums=False): """ Constructor Parameters ---------- id_num : int id number of self (focus node) name : str name of self (focus node) pa_nd : BayesNode parent node theta_degs : float occ_nums : bool True (False) if the states of the parent node are (are not) occupation numbers. Returns ------- """ self.theta_degs = theta_degs self.occ_nums = occ_nums BayesNode.__init__(self, id_num, name, size=pa_nd.size) self.add_parent(pa_nd) self.state_names = pa_nd.state_names pot = DiscreteCondPot(True, [pa_nd, self], bias=0) self.potential = pot theta_rads = theta_degs * math.pi / 180 for k in range(pa_nd.size): if not occ_nums: phase = theta_rads else: num = int(pa_nd.state_names[k]) phase = num * theta_rads self.potential[k, k] = cmath.exp(1j * phase)
def __init__(self, id_num, name, pa_nd, thetas_degs): """ Constructor Parameters ---------- id_num : int id number of self (focus node) name : str name of self (focus node) pa_nd : BayesNode parent node thetas_degs : list[float] Returns ------- """ self.thetas_degs = thetas_degs assert pa_nd.size == 2, "pa_nd of qubit rot does not have size 2" assert pa_nd.state_names == ['0', '1'], \ "parent node state names are not 0,1" BayesNode.__init__(self, id_num, name, size=2) self.add_parent(pa_nd) self.state_names = ['0', "1"] pot = DiscreteCondPot(True, [pa_nd, self], bias=0) self.potential = pot for n in range(2): for m in range(2): self.potential[m, n] = self.qbit_rot_amp(n, m)
def convert_pot_df_to_pot(is_quantum, pot_df, ord_nodes, s_d_pair, use_int_sts=None, normalize=True): """ Returns a DiscreteCondPot pot with ordered nodes ord_nodes. Parameters ---------- is_quantum : bool pot_df : pandas.DataFrame a dataframe returned by learn_pot_df(). pot_df must have one column for each node in ord_nodes plus additioanl final column with pot values ord_nodes : list[BayesNode] ordered nodes of Potential pot that is returned. Nodes must be ordered so that pot_df[:-1].columns = [nd.name for nd in ord_nodes] s_d_pair : tuple[int|str, float] a pair consisting of a state and a degs. The state is taken directly from states_df, so it might be a digit or an actual state name, depending on whether use_int_sts was True or False when states_df was generated. The state is a state of the focus node (the last column of states_cols corresponds to the focus node). The degs is an angle in degrees. For an s_d_pair equal to (x0,ang), whenever pot(C=x| pa(C)=y) = 0 for all x, we will set pot(C=x|pa(C)=y) = exp( 1j*ang*pi/180)*delta(x, x0) in the quantum case and pot( C=x| pa(C)=y) = delta(x, x0) in the classical case. use_int_sts : bool True if states in states_df are integers, False if they are the actual state names. If the parameter use_int_sts is set to None, this function will attempt to find its bool value using the function NetStrucLner:int_sts_detector() normalize : bool True if want pot to be normalized as a cond probability or cond amplitude, P(x|y) or A(x|y), where x is ord_nodes[-1] Returns ------- DiscreteCondPot """ for k, vtx in enumerate(pot_df.columns[:-1]): assert ord_nodes[k].name == vtx focus_vtx = pot_df.columns[-2] focus_nd = ord_nodes[-1] if use_int_sts is None: use_int_sts = NetParamsLner.int_sts_detector(pot_df[:-1]) def int_state(st): if use_int_sts: return int(st) else: return focus_nd.pos_of_st_name(str(st)) pot = DiscreteCondPot(is_quantum, ord_nodes, bias=0) for row in range(len(pot_df.index)): # print([pot_df.iloc[row, col] # for col in range(len(ord_nodes)) # ]) if not use_int_sts: arr_index = [ ord_nodes[col].pos_of_st_name(str(pot_df.iloc[row, col])) for col in range(len(ord_nodes)) ] else: arr_index = [ int(pot_df.iloc[row, col]) for col in range(len(ord_nodes)) ] pot.pot_arr[tuple(arr_index)] = \ pot_df.loc[row, 'last_col_with_vals'] if normalize: try: pot.normalize_self() except UnNormalizablePot as xce: # print('caught exception') focus_index = int_state(s_d_pair[0]) arr_index = tuple(list(xce.pa_indices) + [focus_index]) # print('********************arr_index', arr_index) if is_quantum: pot.pot_arr[arr_index] = \ np.exp(1j * s_d_pair[1] * np.pi / 180) else: pot.pot_arr[arr_index] = 1.0 print('mended pot:\n', pot) # try normalizing pot again now that it is mended pot.normalize_self() return pot
def __init__(self, id_num, name, in_nd1, in_nd2, tau_mag, tau_degs, rho_degs, num_of_comps, max_n_sum=10000): """ Constructor Parameters ---------- id_num : int id number of self (focus node) name : str name of self (focus node) in_nd1 : BayesNode input node (parent) 1 in_nd2 : BayesNode input node (parent) 2 tau_mag : float tau_degs : float rho_degs : float num_of_comps : int number of components, 1 for scalar fields and 2 for vector ones max_n_sum : int Returns ------- """ self.tau_mag = tau_mag self.tau_degs = tau_degs self.rho_degs = rho_degs self.num_of_comps = num_of_comps # self.max_n_sum and self.true_max_n_sum defined later assert 0 <= tau_mag <= 1, "tau_mag must be between 0 and 1" assert num_of_comps == 1 or num_of_comps == 2, \ "number of components must be 1 or 2" if self.num_of_comps == 1: m1 = [int(name) for name in in_nd1.state_names] m2 = [int(name) for name in in_nd2.state_names] m1x = m1 m2x = m2 m1y = None m2y = None self.true_max_n_sum = max(m1x) + max(m2x) else: m1 = [map(int, ut.fix(name, '() ', '').split(',')) for name in in_nd1.state_names] m2 = [map(int, ut.fix(name, '() ', '').split(',')) for name in in_nd2.state_names] # x = [(1,2), (3,4), (8,9)] # y = zip(*x) # y # [(1, 3, 8), (2, 4, 9)] m1x, m1y = zip(*m1) m2x, m2y = zip(*m2) self.true_max_n_sum = max(m1x) + max(m2x) + max(m1y) + max(m2y) if max_n_sum > self.true_max_n_sum: max_n_sum = self.true_max_n_sum self.max_n_sum = max_n_sum expected_degen = self.get_expected_degen(m1x, m2x, m1y, m2y) assert expected_degen > 0, \ "expected degen of beam splitter node is zero" BayesNode.__init__(self, id_num, name, size=expected_degen) self.add_parent(in_nd1) self.add_parent(in_nd2) pot = DiscreteCondPot(True, [in_nd1, in_nd2, self], bias=0) self.potential = pot self.fill_trans_mat_and_st_names_of_nd(m1x, m2x, m1y, m2y)
def convert_pot_df_to_pot(is_quantum, pot_df, ord_nodes, s_d_pair, use_int_sts=None, normalize=True): """ Returns a DiscreteCondPot pot with ordered nodes ord_nodes. Parameters ---------- is_quantum : bool pot_df : pandas.DataFrame a dataframe returned by learn_pot_df(). pot_df must have one column for each node in ord_nodes plus additioanl final column with pot values ord_nodes : list[BayesNode] ordered nodes of Potential pot that is returned. Nodes must be ordered so that pot_df[:-1].columns = [nd.name for nd in ord_nodes] s_d_pair : tuple[int|str, float] a pair consisting of a state and a degs. The state is taken directly from states_df, so it might be a digit or an actual state name, depending on whether use_int_sts was True or False when states_df was generated. The state is a state of the focus node (the last column of states_cols corresponds to the focus node). The degs is an angle in degrees. For an s_d_pair equal to (x0,ang), whenever pot(C=x| pa(C)=y) = 0 for all x, we will set pot(C=x|pa(C)=y) = exp( 1j*ang*pi/180)*delta(x, x0) in the quantum case and pot( C=x| pa(C)=y) = delta(x, x0) in the classical case. use_int_sts : bool True if states in states_df are integers, False if they are the actual state names. If the parameter use_int_sts is set to None, this function will attempt to find its bool value using the function NetStrucLner:int_sts_detector() normalize : bool True if want pot to be normalized as a cond probability or cond amplitude, P(x|y) or A(x|y), where x is ord_nodes[-1] Returns ------- DiscreteCondPot """ for k, vtx in enumerate(pot_df.columns[:-1]): assert ord_nodes[k].name == vtx focus_vtx = pot_df.columns[-2] focus_nd = ord_nodes[-1] if use_int_sts is None: use_int_sts = NetStrucLner.int_sts_detector(pot_df[:-1]) def int_state(st): if use_int_sts: return int(st) else: return focus_nd.st_name_index(str(st)) pot = DiscreteCondPot(is_quantum, ord_nodes, bias=0) for row in range(len(pot_df.index)): # print([pot_df.iloc[row, col] # for col in range(len(ord_nodes)) # ]) if not use_int_sts: arr_index = [ ord_nodes[col].st_name_index(str(pot_df.iloc[row, col])) for col in range(len(ord_nodes))] else: arr_index = [int(pot_df.iloc[row, col]) for col in range(len(ord_nodes))] pot.pot_arr[tuple(arr_index)] = \ pot_df.loc[row, 'last_col_with_vals'] if normalize: try: pot.normalize_self() except UnNormalizablePot as xce: # print('caught exception') focus_index = int_state(s_d_pair[0]) arr_index = tuple(list(xce.pa_indices) + [focus_index]) # print('********************arr_index', arr_index) if is_quantum: pot.pot_arr[arr_index] = \ np.exp(1j * s_d_pair[1] * np.pi / 180) else: pot.pot_arr[arr_index] = 1.0 print('mended pot:\n', pot) # try normalizing pot again now that it is mended pot.normalize_self() return pot
def build_bnet(): """ Builds CBnet in accompanying gif : bnet_HuangDarwiche.gif From "Inference Belief Networks: A Procedural Guide", by C.Huang and A. Darwiche """ a_node = BayesNode(0, name="A") b_node = BayesNode(1, name="B") c_node = BayesNode(2, name="C") d_node = BayesNode(3, name="D") e_node = BayesNode(4, name="E") f_node = BayesNode(5, name="F") g_node = BayesNode(6, name="G") h_node = BayesNode(7, name="H") b_node.add_parent(a_node) c_node.add_parent(a_node) d_node.add_parent(b_node) e_node.add_parent(c_node) f_node.add_parent(d_node) f_node.add_parent(e_node) g_node.add_parent(c_node) h_node.add_parent(e_node) h_node.add_parent(g_node) nodes = { a_node, b_node, c_node, d_node, e_node, f_node, g_node, h_node } a_node.potential = DiscreteUniPot(False, a_node) # P(a) b_node.potential = DiscreteCondPot(False, [a_node, b_node]) # P(b| a) c_node.potential = DiscreteCondPot(False, [a_node, c_node]) d_node.potential = DiscreteCondPot(False, [b_node, d_node]) e_node.potential = DiscreteCondPot(False, [c_node, e_node]) # P(f|d, e) f_node.potential = DiscreteCondPot(False, [d_node, e_node, f_node]) g_node.potential = DiscreteCondPot(False, [c_node, g_node]) h_node.potential = DiscreteCondPot(False, [e_node, g_node, h_node]) # in general # DiscreteCondPot(False, [y1, y2, y3, x]) refers to P(x| y1, y2, y3) # off = 0 # on = 1 a_node.potential.pot_arr[:] = [.5, .5] b_node.potential.pot_arr[1, :] = [.5, .5] b_node.potential.pot_arr[0, :] = [.4, .6] c_node.potential.pot_arr[1, :] = [.7, .3] c_node.potential.pot_arr[0, :] = [.2, .8] d_node.potential.pot_arr[1, :] = [.9, .1] d_node.potential.pot_arr[0, :] = [.5, .5] e_node.potential.pot_arr[1, :] = [.3, .7] e_node.potential.pot_arr[0, :] = [.6, .4] f_node.potential.pot_arr[1, 1, :] = [.01, .99] f_node.potential.pot_arr[1, 0, :] = [.01, .99] f_node.potential.pot_arr[0, 1, :] = [.01, .99] f_node.potential.pot_arr[0, 0, :] = [.99, .01] g_node.potential.pot_arr[1, :] = [.8, .2] g_node.potential.pot_arr[0, :] = [.1, .9] h_node.potential.pot_arr[1, 1, :] = [.05, .95] h_node.potential.pot_arr[1, 0, :] = [.95, .05] h_node.potential.pot_arr[0, 1, :] = [.95, .05] h_node.potential.pot_arr[0, 0, :] = [.95, .05] return BayesNet(nodes)