Example #1
0
    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
Example #2
0
    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)
Example #4
0
    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
Example #6
0
    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)
Example #7
0
    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)
Example #8
0
    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
Example #9
0
    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)
Example #10
0
    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)
Example #11
0
    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
Example #12
0
    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
Example #14
0
    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)