text:
from itertools import combinations, chain
from collections import defaultdict
from dataclasses import dataclass
import typing

import numpy as np
import pandas as pd
import networkx as nx
from tqdm.auto import tqdm

from pgmpy.base import DAG
from pgmpy.factors.discrete import TabularCPD
from pgmpy.global_vars import SHOW_PROGRESS

@dataclass(eq=True, frozen=True)
class DynamicNode:
    """
    Class for representing the nodes of Dynamic Bayesian Networks.
    """

    node: str
    time_slice: int

    def __getitem__(self, idx: int) -> typing.Union[str, int]:
        if idx == 0:
            return self.node
        elif idx == 1:
            return self.time_slice
        else:
            raise IndexError(f"Index {idx} out of bounds.")

    def __str__(self) -> str:
        return f"({self.node}, {self.time_slice})"

    def __repr__(self) -> str:
        return f"<DynamicNode({self.node}, {self.time_slice}) at {hex(id(self))}>"

    def __lt__(self, other) -> bool:
        if self.node < other.node:
            return True
        elif self.node > other.node:
            return False
        else:
            return self.time_slice < other.time_slice

    def __le__(self, other) -> bool:
        if self.node <= other.node:
            return True
        elif self.node > other.node:
            return False
        else:
            return self.time_slice <= other.time_slice

    def __eq__(self, other) -> bool:
        if isinstance(other, DynamicNode):
            return (self.node, self.time_slice) == (other.node, other.time_slice)
        elif isinstance(other, (list, tuple)):
            return (self.node, self.time_slice) == tuple(other)
        else:
            return False

    def to_tuple(self) -> tuple:
        """
        Returns a tuple representation as (node, time_slice) for DynamicNode object.
        """
        return (self.node, self.time_slice)

class DynamicBayesianNetwork(DAG):
    def __init__(self, ebunch=None):
        """
        Base class for Dynamic Bayesian Network

        This is a time variant model of the static Bayesian model, where each
        time-slice has some static nodes and is then replicated over a certain
        time period.

        The nodes can be any hashable python objects.

        Parameters
        ----------
        ebunch: Data to initialize graph.  If data=None (default) an empty
              graph is created.  The data can be an edge list, or any NetworkX
              graph object

        Examples
        --------
        Create an empty Dynamic Bayesian Network with no nodes and no edges:
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> dbn = DBN()

        Adding nodes and edges inside the dynamic bayesian network. A single
        node can be added using the method below. For adding edges we need to
        specify the time slice since edges can be across different time slices.

        For example for a network as [image](http://s8.postimg.org/aaybw4x2t/Blank_Flowchart_New_Page_1.png),
        we will need to add all the edges in the 2-TBN as:

        >>> dbn.add_edges_from([(('D', 0), ('G', 0)), (('I', 0), ('G', 0)),
        ...                     (('G', 0), ('L', 0)), (('D', 0), ('D', 1)),
        ...                     (('I', 0), ('I', 1)), (('G', 0), ('G', 1)),
        ...                     (('G', 0), ('L', 1)), (('L', 0), ('L', 1))])

        We can query the edges and nodes in the network as:
        >>> dbn.nodes()
        ['G', 'D', 'I', 'L']
        >>> dbn.edges()
        [(('D', 1), ('G', 1)), (('I', 0), ('G', 0)), (('I', 0), ('I', 1)),
         (('I', 1), ('G', 1)), (('G', 0), ('L', 0)), (('G', 0), ('G', 1)),
         (('G', 0), ('L', 1)), (('D', 0), ('G', 0)), (('D', 0), ('D', 1)),
         (('L', 0), ('L', 1)), (('G', 1), ('L', 1))]

        If any variable is not present in the network while adding an edge,
        pgmpy will automatically add that variable to the network.

        But for adding nodes to the model we don't need to specify the time
        slice as it is common in all the time slices. And therefore pgmpy
        automatically replicated it all the time slices. For example, for
        adding a new variable `S` in the above network we can simply do:
        >>> dbn.add_node('S')
        >>> dbn.nodes()
        ['S', 'G', 'D', 'I', 'L']

        Public Methods
        --------------
        add_node
        add_nodes_from
        add_edges
        add_edges_from
        add_cpds
        initialize_initial_state
        inter_slice
        intra_slice
        copy
        """
        super(DynamicBayesianNetwork, self).__init__()
        if ebunch:
            self.add_edges_from(ebunch)
        self.cpds = []
        self.cardinalities = defaultdict(int)

    def add_node(self, node, **attr):
        """
        Adds a single node to the Network

        Parameters
        ----------
        node: node
            A node can be any hashable Python object.

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> dbn = DBN()
        >>> dbn.add_node('A')
        ['A']
        """
        super(DynamicBayesianNetwork, self).add_node(DynamicNode(node, 0), **attr)

    def add_nodes_from(self, nodes, **attr):
        """
        Add multiple nodes to the Network.

        Parameters
        ----------
        nodes: iterable container
            A container of nodes (list, dict, set, etc.).

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> dbn = DBN()
        >>> dbn.add_nodes_from(['A', 'B', 'C'])
        """
        for node in nodes:
            self.add_node(node)

    def _nodes(self):
        """
        Returns the list of nodes present in the network

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> dbn = DBN()
        >>> dbn.add_nodes_from(['A', 'B', 'C'])
        >>> sorted(dbn._nodes())
        ['B', 'A', 'C']
        """
        return list(
            set(
                [
                    node
                    for node, timeslice in super(DynamicBayesianNetwork, self).nodes()
                ]
            )
        )

    def _timeslices(self):
        return list(
            set(
                [
                    timeslice
                    for node, timeslice in super(DynamicBayesianNetwork, self).nodes()
                ]
            )
        )

    def add_edge(self, start, end, **kwargs):
        """
        Add an edge between two nodes.

        The nodes will be automatically added if they are not present in the network.

        Parameters
        ----------
        start: tuple
               Both the start and end nodes should specify the time slice as
               (node_name, time_slice). Here, node_name can be any hashable
               python object while the time_slice is an integer value,
               which denotes the time slice that the node belongs to.

        end: tuple
               Both the start and end nodes should specify the time slice as
               (node_name, time_slice). Here, node_name can be any hashable
               python object while the time_slice is an integer value,
               which denotes the time slice that the node belongs to.

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> model = DBN()
        >>> model.add_nodes_from(['D', 'I'])
        >>> model.add_edge(('D',0), ('I',0))
        >>> sorted(model.edges())
        [(('D', 0), ('I', 0)), (('D', 1), ('I', 1))]
        """
        try:
            if len(start) != 2 or len(end) != 2:
                raise ValueError("Nodes must be of type (node, time_slice).")
            elif not isinstance(start[1], int) or not isinstance(end[1], int):
                raise ValueError("Nodes must be of type (node, time_slice).")
            elif start[1] == end[1]:
                start = (start[0], 0)
                end = (end[0], 0)
            elif start[1] == end[1] - 1:
                start = (start[0], 0)
                end = (end[0], 1)
            elif start[1] > end[1]:
                raise NotImplementedError(
                    "Edges in backward direction are not allowed."
                )
            elif start[1] != end[1]:
                raise ValueError(
                    "Edges over multiple time slices is not currently supported"
                )
        except TypeError:
            raise ValueError("Nodes must be of type (node, time_slice).")

        start = DynamicNode(*start)
        end = DynamicNode(*end)

        if start == end:
            raise ValueError("Self Loops are not allowed")
        elif (
            start in super(DynamicBayesianNetwork, self).nodes()
            and end in super(DynamicBayesianNetwork, self).nodes()
            and nx.has_path(self, end, start)
        ):
            raise ValueError(
                f"Loops are not allowed. Adding the edge from ({str(start)} --> {str(end)}) forms a loop."
            )

        super(DynamicBayesianNetwork, self).add_edge(start, end, **kwargs)

        if start[1] == end[1]:
            super(DynamicBayesianNetwork, self).add_edge(
                DynamicNode(start[0], 1 - start[1]), DynamicNode(end[0], 1 - end[1])
            )
        else:
            super(DynamicBayesianNetwork, self).add_node(
                DynamicNode(end[0], 1 - end[1])
            )

    def add_edges_from(self, ebunch, **kwargs):
        """
        Add all the edges in ebunch.

        If nodes referred in the ebunch are not already present, they
        will be automatically added. Node names can be any hashable python object.

        Parameters
        ----------
        ebunch : list, array-like
                List of edges to add. Each edge must be of the form of
                ((start, time_slice), (end, time_slice)).

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> dbn = DBN()
        >>> dbn.add_edges_from([(('D', 0), ('G', 0)), (('I', 0), ('G', 0))])
        >>> dbn.nodes()
        ['G', 'I', 'D']
        >>> dbn.edges()
        [(('D', 1), ('G', 1)),
         (('I', 1), ('G', 1)),
         (('D', 0), ('G', 0)),
         (('I', 0), ('G', 0))]
        """
        for edge in ebunch:
            self.add_edge(edge[0], edge[1])

    def get_intra_edges(self, time_slice=0):
        """
        Returns the intra slice edges present in the 2-TBN.

        Parameters
        ----------
        time_slice: int (whole number)
                The time slice for which to get intra edges. The timeslice
                should be a positive value or zero.

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> dbn = DBN()
        >>> dbn.add_nodes_from(['D', 'G', 'I', 'S', 'L'])
        >>> dbn.add_edges_from([(('D', 0), ('G', 0)), (('I', 0), ('G', 0)),
        ...                     (('G', 0), ('L', 0)), (('D', 0), ('D', 1)),
        ...                     (('I', 0), ('I', 1)), (('G', 0), ('G', 1)),
        ...                     (('G', 0), ('L', 1)), (('L', 0), ('L', 1))])
        >>> dbn.get_intra_edges()
        [(('D', 0), ('G', 0)), (('G', 0), ('L', 0)), (('I', 0), ('G', 0))]
        """
        if not isinstance(time_slice, int) or time_slice < 0:
            raise ValueError(
                "The timeslice should be a positive value greater than or equal to zero"
            )

        return [
            tuple(DynamicNode(x[0], time_slice) for x in edge)
            for edge in self.edges()
            if edge[0][1] == edge[1][1] == 0
        ]

    def get_inter_edges(self):
        """
        Returns the inter-slice edges present in the 2-TBN.

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> dbn = DBN()
        >>> dbn.add_edges_from([(('D', 0), ('G', 0)), (('I', 0), ('G', 0)),
        ...                     (('G', 0), ('L', 0)), (('D', 0), ('D', 1)),
        ...                     (('I', 0), ('I', 1)), (('G', 0), ('G', 1)),
        ...                     (('G', 0), ('L', 1)), (('L', 0), ('L', 1))])
        >>> dbn.get_inter_edges()
        [(('D', 0), ('D', 1)),
         (('G', 0), ('G', 1)),
         (('G', 0), ('L', 1)),
         (('I', 0), ('I', 1)),
         (('L', 0), ('L', 1))]
        """
        return [edge for edge in self.edges() if edge[0][1] != edge[1][1]]

    def get_interface_nodes(self, time_slice=0):
        """
        Returns the nodes in the first timeslice whose children are present in the first timeslice.

        Parameters
        ----------
        time_slice:int
                The timeslice should be a positive value greater than or equal to zero

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> dbn = DBN()
        >>> dbn.add_nodes_from(['D', 'G', 'I', 'S', 'L'])
        >>> dbn.add_edges_from([(('D',0),('G',0)),(('I',0),('G',0)),(('G',0),('L',0)),(('D',0),('D',1))])
        >>> dbn.get_interface_nodes()
        [('D', 0)]
        """
        if not isinstance(time_slice, int) or time_slice < 0:
            raise ValueError(
                f"The timeslice should be a positive integer greater than or equal to zero: ({type(time_slice)}, value: {time_slice})"
            )

        return [
            DynamicNode(edge[time_slice][0], edge[time_slice][1])
            for edge in self.get_inter_edges()
        ]

    def get_slice_nodes(self, time_slice=0):
        """
        Returns the nodes present in a particular timeslice

        Parameters
        ----------
        time_slice:int
                The timeslice should be a positive value greater than or equal to zero

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> dbn = DBN()
        >>> dbn.add_nodes_from(['D', 'G', 'I', 'S', 'L'])
        >>> dbn.add_edges_from([(('D', 0),('G', 0)),(('I', 0),('G', 0)),(('G', 0),('L', 0)),(('D', 0),('D', 1))])
        >>> dbn.get_slice_nodes()
        """
        if not isinstance(time_slice, int) or time_slice < 0:
            raise ValueError(
                "The timeslice should be a positive value greater than or equal to zero"
            )

        return [DynamicNode(node, time_slice) for node in self._nodes()]

    def add_cpds(self, *cpds):
        """
        This method adds the cpds to the dynamic bayesian network.
        Note that while adding variables and the evidence in cpd,
        they have to be of the following form
        (node_name, time_slice)
        Here, node_name is the node that is inserted
        while the time_slice is an integer value, which denotes
        the index of the time_slice that the node belongs to.

        Parameters
        ----------
        cpds : list, set, tuple (array-like)
            List of CPDs which are to be associated with the model. Each CPD
            should be an instance of `TabularCPD`.

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> from pgmpy.factors.discrete import TabularCPD
        >>> dbn = DBN()
        >>> dbn.add_edges_from([(('D', 0),('G', 0)),(('I', 0),('G', 0)),(('D', 0),('D', 1)),(('I', 0),('I', 1))])
        >>> grade_cpd = TabularCPD(('G', 0), 3, [[0.3, 0.05, 0.9, 0.5],
        ...                                      [0.4, 0.25, 0.8, 0.03],
        ...                                      [0.3, 0.7, 0.02, 0.2]],
        ...                        evidence=[('I', 0),('D', 0)],
        ...                        evidence_card=[2, 2])
        >>> d_i_cpd = TabularCPD(('D',1), 2, [[0.6, 0.3],
        ...                                   [0.4, 0.7]],
        ...                      evidence=[('D',0)],
        ...                      evidence_card=[2])
        >>> diff_cpd = TabularCPD(('D', 0), 2, [[0.6, 0.4]])
        >>> intel_cpd = TabularCPD(('I', 0), 2, [[0.7, 0.3]])
        >>> i_i_cpd = TabularCPD(('I', 1), 2, [[0.5, 0.4],
        ...                                    [0.5, 0.6]],
        ...                      evidence=[('I', 0)],
        ...                      evidence_card=[2])
        >>> dbn.add_cpds(grade_cpd, d_i_cpd, diff_cpd, intel_cpd, i_i_cpd)
        >>> dbn.get_cpds()
        [<TabularCPD representing P(('G', 0):3 | ('I', 0):2, ('D', 0):2) at 0x7ff7f27b0cf8>,
         <TabularCPD representing P(('D', 1):2 | ('D', 0):2) at 0x7ff810b9c2e8>,
         <TabularCPD representing P(('D', 0):2) at 0x7ff7f27e6f98>,
         <TabularCPD representing P(('I', 0):2) at 0x7ff7f27e6ba8>,
         <TabularCPD representing P(('I', 1):2 | ('I', 0):2) at 0x7ff7f27e6668>]
        """
        for cpd in cpds:
            if not isinstance(cpd, TabularCPD):
                raise ValueError("cpd should be an instance of TabularCPD")

            if set(cpd.variables) - set(cpd.variables).intersection(
                set(super(DynamicBayesianNetwork, self).nodes())
            ):
                raise ValueError("CPD defined on variable not in the model", cpd)

        self.cpds.extend(cpds)

    def get_cpds(self, node=None, time_slice=None):
        """
        Returns the CPDs that have been associated with the network.

        Parameters
        ----------
        node: tuple (node_name, time_slice)
            The node should be in the following form (node_name, time_slice).
            Here, node_name is the node that is inserted while the time_slice is
            an integer value, which denotes the index of the time_slice that the
            node belongs to.

        time_slice: int
            The time_slice should be a positive integer greater than or equal to zero.

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> from pgmpy.factors.discrete import TabularCPD
        >>> dbn = DBN()
        >>> dbn.add_edges_from([(('D',0),('G',0)),(('I',0),('G',0)),(('D',0),('D',1)),(('I',0),('I',1))])
        >>> grade_cpd =  TabularCPD(('G',0), 3, [[0.3,0.05,0.9,0.5],
        ...                                      [0.4,0.25,0.8,0.03],
        ...                                      [0.3,0.7,0.02,0.2]], [('I', 0),('D', 0)],[2,2])
        >>> dbn.add_cpds(grade_cpd)
        >>> dbn.get_cpds()
        """

        if time_slice is None:
            time_slices = self._timeslices()
        elif isinstance(time_slice, int) and time_slice >= 0:
            time_slices = [time_slice]
        elif isinstance(time_slice, typing.Iterable):
            if all(isinstance(n, int) for n in time_slice):
                time_slices = time_slice
            else:
                raise ValueError(
                    "At least one element inside time_slice interable is not positive and/or integer"
                )
        else:
            raise ValueError(
                "Time slice is not a positive integer neither a interable of integers"
            )

        if node:
            if node not in super(DynamicBayesianNetwork, self).nodes():
                raise ValueError("Node not present in the model.")
            else:
                for cpd in self.cpds:
                    if cpd.variable == node:
                        return cpd
        else:
            return_cpds = []
            for time_slice in time_slices:
                for var in self.get_slice_nodes(time_slice=time_slice):
                    cpd = self.get_cpds(node=var)
                    if cpd:
                        return_cpds.append(cpd)
            return return_cpds

    def remove_cpds(self, *cpds):
        """
        Removes the cpds that are provided in the argument.

        Parameters
        ----------
        *cpds : list, set, tuple (array-like)
            List of CPDs which are to be associated with the model. Each CPD
            should be an instance of `TabularCPD`.

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> from pgmpy.factors.discrete import TabularCPD
        >>> dbn = DBN()
        >>> dbn.add_edges_from([(('D',0),('G',0)),(('I',0),('G',0)),(('D',0),('D',1)),(('I',0),('I',1))])
        >>> grade_cpd =  TabularCPD(('G',0), 3, [[0.3,0.05,0.9,0.5],
        ...                                      [0.4,0.25,0.8,0.03],
        ...                                      [0.3,0.7,0.02,0.2]], [('I', 0),('D', 0)],[2,2])
        >>> dbn.add_cpds(grade_cpd)
        >>> dbn.get_cpds()
        [<TabularCPD representing P(('G', 0):3 | ('I', 0):2, ('D', 0):2) at 0x3348ab0>]
        >>> dbn.remove_cpds(grade_cpd)
        >>> dbn.get_cpds()
        []
        """
        for cpd in cpds:
            if isinstance(cpd, (tuple, list)):
                cpd = self.get_cpds(cpd)
            self.cpds.remove(cpd)

    def check_model(self):
        """
        Check the model for various errors. This method checks for the following
        errors.

        * Checks if the sum of the probabilities in each associated CPD for each
            state is equal to 1 (tol=0.01).
        * Checks if the CPDs associated with nodes are consistent with their parents.

        Returns
        -------
        boolean: True if everything seems to be order. Otherwise raises error
            according to the problem.
        """
        for node in super(DynamicBayesianNetwork, self).nodes():
            cpd = self.get_cpds(node=node)
            if isinstance(cpd, TabularCPD):
                evidence = cpd.variables[:0:-1]
                evidence_card = cpd.cardinality[:0:-1]
                parents = self.get_parents(node)
                if set(evidence) != set(parents if parents else []):
                    raise ValueError(
                        f"CPD associated with {node} doesn't have proper parents associated with it."
                    )
                if not np.allclose(
                    cpd.to_factor()
                    .marginalize([node], inplace=False)
                    .values.flatten("C"),
                    np.ones(np.product(evidence_card)),
                    atol=0.01,
                ):
                    raise ValueError(
                        f"Sum of probabilities of states for node {node} is not equal to 1"
                    )
        return True

    def initialize_initial_state(self):
        """
        This method will automatically re-adjust the cpds and the edges added to the bayesian network.
        If an edge that is added as an intra time slice edge in the 0th timeslice, this method will
        automatically add it in the 1st timeslice. It will also add the cpds. However, to call this
        method, one needs to add cpds as well as the edges in the bayesian network of the whole
        skeleton including the 0th and the 1st timeslice,.

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> from pgmpy.factors.discrete import TabularCPD
        >>> student = DBN()
        >>> student.add_nodes_from(['D', 'G', 'I', 'S', 'L'])
        >>> student.add_edges_from([(('D', 0),('G', 0)),(('I', 0),('G', 0)),(('D', 0),('D', 1)),(('I', 0),('I', 1))])
        >>> grade_cpd = TabularCPD(('G', 0), 3, [[0.3, 0.05, 0.9, 0.5],
        ...                                      [0.4, 0.25, 0.08, 0.3],
        ...                                      [0.3, 0.7, 0.02, 0.2]],
        ...                        evidence=[('I', 0),('D', 0)],
        ...                        evidence_card=[2, 2])
        >>> d_i_cpd = TabularCPD(('D', 1), 2, [[0.6, 0.3],
        ...                                    [0.4, 0.7]],
        ...                      evidence=[('D', 0)],
        ...                      evidence_card=[2])
        >>> diff_cpd = TabularCPD(('D', 0), 2, [[0.6, 0.4]])
        >>> intel_cpd = TabularCPD(('I',0), 2, [[0.7, 0.3]])
        >>> i_i_cpd = TabularCPD(('I', 1), 2, [[0.5, 0.4],
        ...                                    [0.5, 0.6]],
        ...                      evidence=[('I', 0)],
        ...                      evidence_card=[2])
        >>> student.add_cpds(grade_cpd, d_i_cpd, diff_cpd, intel_cpd, i_i_cpd)
        >>> student.initialize_initial_state()
        """
        for cpd in self.cpds:
            temp_var = DynamicNode(cpd.variable[0], 1 - cpd.variable[1])
            parents = self.get_parents(temp_var)
            if not any(x.variable == temp_var for x in self.cpds):
                if all(x[1] == parents[0][1] for x in parents):
                    if parents:
                        evidence_card = cpd.cardinality[:0:-1]
                        new_cpd = TabularCPD(
                            temp_var,
                            cpd.variable_card,
                            cpd.values.reshape(
                                cpd.variable_card, np.prod(evidence_card)
                            ),
                            parents,
                            evidence_card,
                        )
                    else:
                        if cpd.get_evidence():
                            initial_cpd = cpd.marginalize(
                                cpd.get_evidence(), inplace=False
                            )
                            new_cpd = TabularCPD(
                                temp_var,
                                cpd.variable_card,
                                np.reshape(initial_cpd.values, (2, -1)),
                            )
                        else:
                            new_cpd = TabularCPD(
                                temp_var,
                                cpd.variable_card,
                                np.reshape(cpd.values, (2, -1)),
                            )
                    self.add_cpds(new_cpd)
            self.check_model()

    def moralize(self):
        """
        Removes all the immoralities in the Network and creates a moral
        graph (UndirectedGraph).

        A v-structure X->Z<-Y is an immorality if there is no directed edge
        between X and Y.

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> dbn = DBN([(('D',0), ('G',0)), (('I',0), ('G',0))])
        >>> moral_graph = dbn.moralize()
        >>> moral_graph.edges()
        EdgeView([(('G', 0), ('I', 0)),
                  (('G', 0), ('D', 0)),
                  (('D', 1), ('I', 1)),
                  (('D', 1), ('G', 1)),
                  (('I', 0), ('D', 0)),
                  (('G', 1), ('I', 1))])
        """
        moral_graph = self.to_undirected()

        for node in super(DynamicBayesianNetwork, self).nodes():
            moral_graph.add_edges_from(combinations(self.get_parents(node), 2))

        return moral_graph

    def copy(self):
        """
        Returns a copy of the dynamic bayesian network.

        Returns
        -------
        DynamicBayesianNetwork: copy of the dynamic bayesian network

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> from pgmpy.factors.discrete import TabularCPD
        >>> dbn = DBN()
        >>> dbn.add_edges_from([(('D',0),('G',0)),(('I',0),('G',0)),(('D',0),('D',1)),(('I',0),('I',1))])
        >>> grade_cpd =  TabularCPD(('G',0), 3, [[0.3, 0.05, 0.9,  0.5 ],
        ...                                      [0.4, 0.25, 0.8,  0.03],
        ...                                      [0.3,  0.7, 0.02, 0.2 ]],
        ...                         [('I', 0), ('D', 0)],[2,2])
        >>> dbn.add_cpds(grade_cpd)
        >>> dbn_copy = dbn.copy()
        >>> dbn_copy.nodes()
        ['Z', 'G', 'I', 'D']
        >>> dbn_copy.edges()
        [(('I', 1), ('G', 1)),
        (('I', 0), ('I', 1)),
        (('I', 0), ('G', 0)),
        (('D', 1), ('G', 1)),
        (('D', 0), ('G', 0)),
        (('D', 0), ('D', 1))]
        >>> dbn_copy.get_cpds()
        [<TabularCPD representing P(('G', 0):3 | ('I', 0):2, ('D', 0):2) at 0x7f13961a3320>]
        """
        dbn = DynamicBayesianNetwork()
        dbn.add_nodes_from(self._nodes())
        edges = [(u.to_tuple(), v.to_tuple()) for (u, v) in self.edges()]
        dbn.add_edges_from(edges)
        cpd_copy = [cpd.copy() for cpd in self.get_cpds()]
        dbn.add_cpds(*cpd_copy)
        return dbn

    def get_markov_blanket(self, node):
        # Wrap node into DynamicNode
        if not isinstance(node, DynamicNode):
            node = DynamicNode(*node)
        # Get standard Markov blanket
        markov_blanket = set(
            super(DynamicBayesianNetwork, self).get_markov_blanket(node)
        )

        # Augment Markov blanket:
        # if node is in the last time slice, unroll and add children nodes from next time slice
        max_ts = max([n.time_slice for n in self.nodes()])
        if node.time_slice == max_ts:
            # Move node to previous time slice and get children
            temp_children = self.get_children(
                DynamicNode(node.node, node.time_slice - 1)
            )
            # Move children to next time slice
            next_children = {
                DynamicNode(child.node, child.time_slice + 1) for child in temp_children
            }
            # Get children parents
            next_parents = set(
                chain(*[self.get_parents(child) for child in temp_children])
            )
            # Get children's parents
            temp_parents = {
                parent for child in temp_children for parent in self.get_parents(child)
            }
            # Move children's parents to next time slice
            next_parents = {
                DynamicNode(parent.node, parent.time_slice + 1)
                for parent in temp_parents
            }
            # Add them to Markov blanket
            markov_blanket = markov_blanket | next_children
            markov_blanket = markov_blanket | next_parents

        return sorted(markov_blanket)

    def get_constant_bn(self, t_slice=0):
        """
        Returns a normal bayesian network object which has nodes from the first two
        time slices and all the edges in the first time slice and edges going from
        first to second time slice. The returned bayesian network bascially represents
        the part of the DBN which remains constant.

        The node names are changed to strings in the form `{var}_{time}`.
        """
        from pgmpy.models import BayesianNetwork

        edges = [
            (
                str(u[0]) + "_" + str(u[1] + t_slice),
                str(v[0]) + "_" + str(v[1] + t_slice),
            )
            for u, v in self.edges()
        ]
        new_cpds = []
        for cpd in self.cpds:
            new_vars = [
                str(var) + "_" + str(time + t_slice) for var, time in cpd.variables
            ]
            new_cpds.append(
                TabularCPD(
                    variable=new_vars[0],
                    variable_card=cpd.cardinality[0],
                    values=cpd.get_values(),
                    evidence=new_vars[1:],
                    evidence_card=cpd.cardinality[1:],
                )
            )

        bn = BayesianNetwork(edges)
        bn.add_cpds(*new_cpds)
        return bn

    def fit(self, data, estimator="MLE"):
        """
        Learns the CPD of the model from data.

        Since the assumption is that the 2-TBN stays constant throughtout the model,
        the algorithm iterates over every 2 consecutive time slices in the data and
        updates the CPDs based on it.

        Parameters
        ----------
        data: pandas.DataFrame instance
            The column names must be of the form (variable, time_slice). The
            time-slices must start from 0.

        estimator: str
            Currently only Maximum Likelihood Estimator is supported.

        Returns
        -------
        None: The CPDs are added to the model instance.

        Examples
        --------
        >>> import numpy as np
        >>> import pandas as pd
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> model = DBN(
        >>>     [
        >>>         (("A", 0), ("B", 0)),
        >>>         (("A", 0), ("C", 0)),
        >>>         (("B", 0), ("D", 0)),
        >>>         (("C", 0), ("D", 0)),
        >>>         (("A", 0), ("A", 1)),
        >>>         (("B", 0), ("B", 1)),
        >>>         (("C", 0), ("C", 1)),
        >>>         (("D", 0), ("D", 1)),
        >>>     ]
        >>> )
        >>> data = np.random.randint(low=0, high=2, size=(1000, 20))
        >>> colnames = []
        >>> for t in range(5):
        ...     colnames.extend([("A", t), ("B", t), ("C", t), ("D", t)])
        >>> df = pd.DataFrame(data, columns=colnames)
        >>> model.fit(df)
        """
        if not isinstance(data, pd.DataFrame):
            raise ValueError(f"data must be a pandas dataframe. Got: {type(data)}")

        if min(data.columns, key=lambda t: t[1])[1] != 0:
            raise ValueError("data column names must start from time slice 0.")

        if estimator not in {"MLE", "mle"}:
            raise ValueError("Only Maximum Likelihood Estimator is supported currently")

        # Make a copy and replace tuple column names with str.
        data_copy = data.copy()
        data_copy.columns = [str(var) + "_" + str(t) for (var, t) in data.columns]

        n_samples = data.shape[0]
        const_bn = self.get_constant_bn()
        n_time_slices = max(data.columns, key=lambda t: t[1])[1]

        for t_slice in range(n_time_slices):
            # Get the columns names for this time slice
            colnames = [str(node) + "_" + str(t_slice) for node in self._nodes()]
            colnames.extend(
                [str(node) + "_" + str(t_slice + 1) for node in self._nodes()]
            )

            # Select the data frame for this time slice
            df_slice = data_copy.loc[:, colnames]

            # Change the column time slice to match the constant bayesian network.
            tuple_colnames = [var.rsplit("_", 1) for var in df_slice.columns]
            new_colnames = [
                str(node) + "_" + str(int(t) - t_slice) for (node, t) in tuple_colnames
            ]
            df_slice.columns = new_colnames

            # Fit or fit_update with df_slice depending on the time slice
            if t_slice == 0:
                const_bn.fit(df_slice)
            else:
                const_bn.fit_update(df_slice, n_prev_samples=t_slice * n_samples)

        cpds = []
        for cpd in const_bn.cpds:
            var_tuples = [var.rsplit("_", 1) for var in cpd.variables]
            new_vars = [DynamicNode(var, int(t)) for var, t in var_tuples]
            cpds.append(
                TabularCPD(
                    variable=new_vars[0],
                    variable_card=cpd.variable_card,
                    values=cpd.get_values(),
                    evidence=new_vars[1:],
                    evidence_card=cpd.cardinality[1:],
                )
            )

        self.add_cpds(*cpds)

    def active_trail_nodes(self, variables, observed=None, include_latents=False):
        if not isinstance(variables, DynamicNode):
            # Wrap variables in DynamicNode objects
            if len(variables) == 2 and isinstance(variables[1], int):
                variables = DynamicNode(*variables)
            else:
                variables = [DynamicNode(*v) for v in variables]
        if (
            observed is not None
            and len(observed) > 0
            and any([not isinstance(o, DynamicNode) for o in observed])
        ):
            # Wrap observed in DynamicNode objects
            if len(observed) == 2 and isinstance(observed[1], int):
                observed = DynamicNode(*observed)
            else:
                observed = [DynamicNode(*o) for o in observed]
        # Call super method
        return super(DynamicBayesianNetwork, self).active_trail_nodes(
            variables, observed, include_latents
        )

    @staticmethod
    def _postprocess(df):
        """
        Postprocess the generated samples before returning.
        1. Remove any of the variables created because of the virtual evidence or intervention. Variables
           starting with `__`
        2. Change the column names from str to tuples.
        """
        # Step 1: Remove virtual evidence columns
        non_virt_cols = [col for col in df.columns if not col.startswith("__")]
        df = df.loc[:, non_virt_cols]

        # Step 2: Change the column names
        tuple_cols = [col.rsplit("_", 1) for col in df.columns]
        new_cols = [(var, int(t)) for var, t in tuple_cols]
        df.columns = new_cols
        return df

    def simulate(
        self,
        n_samples=10,
        n_time_slices=2,
        do=None,
        evidence=None,
        virtual_evidence=None,
        virtual_intervention=None,
        include_latents=False,
        seed=None,
        show_progress=True,
    ):
        """
        Simulates time-series data from the specified model.

        Parameters
        ----------
        n_samples: int
            The number of data samples to simulate from the model.

        n_time_slices: int
            The number of time slices for which to simulate the data.

        do: dict
            The interventions to apply to the model. dict should be of the form
            {(variable_name, time_slice): state}

        evidence: dict
            Observed evidence to apply to the model. dict should be of the form
            {(variable_name, time_slice): state}

        virtual_evidence: list
            Probabilistically apply evidence to the model. `virtual_evidence` should
            be a list of `pgmpy.factors.discrete.TabularCPD` objects specifying the
            virtual probabilities.

        virtual_intervention: list
            Also known as soft intervention. `virtual_intervention` should be a list
            of `pgmpy.factors.discrete.TabularCPD` objects specifying the virtual/soft
            intervention probabilities.

        include_latents: boolean (default: False)
            Whether to include the latent variable values in the generated samples.

        seed: int (default: None)
            If a value is provided, sets the seed for numpy.random.

        show_progress: bool
            If True, shows a progress bar when generating samples.

        Returns
        -------
        pandas.DataFrame: A dataframe with the simulated data.

        Examples
        --------
        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> from pgmpy.factors.discrete import TabularCPD
        >>> dbn = DBN([(("D", 0), ("G", 0)), (("I", 0), ("G", 0)),
        ...            (("D", 0), ("D", 1)), (("I", 0), ("I", 1)),])
        >>> diff_cpd = TabularCPD(("D", 0), 2, [[0.6], [0.4]])
        >>> grade_cpd = TabularCPD(variable=("G", 0), variable_card=3,
        ...                        values=[[0.3, 0.05, 0.9, 0.5],
        ...                                [0.4, 0.25, 0.08, 0.3],
        ...                                [0.3, 0.7, 0.02, 0.2]],
        ...                        evidence=[("I", 0), ("D", 0)],
        ...                        evidence_card=[2, 2])
        >>> d_i_cpd = TabularCPD(variable=("D", 1), variable_card=2,
        ...                      values=[[0.6, 0.3], [0.4, 0.7]],
        ...                      evidence=[("D", 0)],
        ...                      evidence_card=[2])
        >>> intel_cpd = TabularCPD(("I", 0), 2, [[0.7], [0.3]])
        >>> i_i_cpd = TabularCPD(variable=("I", 1), variable_card=2,
        ...                      values=[[0.5, 0.4], [0.5, 0.6]],
        ...                      evidence=[("I", 0)],
        ...                      evidence_card=[2])
        >>> g_i_cpd = TabularCPD(variable=("G", 1), variable_card=3,
        ...                      values=[[0.3, 0.05, 0.9, 0.5],
        ...                              [0.4, 0.25, 0.08, 0.3],
        ...                              [0.3, 0.7, 0.02, 0.2]],
        ...                      evidence=[("I", 1), ("D", 1)],
        ...                      evidence_card=[2, 2])
        >>> dbn.add_cpds(diff_cpd, grade_cpd, d_i_cpd, intel_cpd, i_i_cpd, g_i_cpd)

        Normal simulation from the model.

        >>> dbn.simulate(n_time_slices=4, n_samples=2)
           (D, 0)  (G, 0)  (I, 0)  (D, 1)  (G, 1)  (I, 1)  (D, 2)  (G, 2)  (D, 3)  (G, 3)  (I, 2)  (I, 3)
        0       0       2       0       0       0       1       0       2       0       2       0       0
        1       0       1       0       0       0       1       1       0       1       2       1       0

        Simulation with evidence.

        >>> dbn.simulate(n_time_slices=4, n_samples=2, evidence={('D', 0): 1, ('D', 2): 0})
           (D, 0)  (G, 0)  (I, 0)  (D, 1)  (G, 1)  (I, 1)  (D, 2)  (G, 2)  (D, 3)  (G, 3)  (I, 2)  (I, 3)
        0       1       1       1       1       2       0       0       2       1       1       0       1
        1       1       2       1       1       2       0       0       1       1       0       0       1

        Simulation with virtual/soft evidence.

        >>> dbn.simulate(n_time_slices=4, n_samples=2, virtual_evidence=[TabularCPD(('D', 2), 2, [[0.7], [0.3]])])
           (D, 0)  (G, 0)  (I, 0)  (D, 1)  (G, 1)  (I, 1)  (D, 2)  (G, 2)  (D, 3)  (G, 3)  (I, 2)  (I, 3)
        0       0       1       0       0       1       0       0       0       1       0       1       1
        1       0       1       0       0       0       1       0       0       0       0       1       1

        Simulation with intervention.

        >>> dbn.simulate(n_time_slices=4, n_samples=2, do={('D', 0): 1, ('D', 2): 0})
           (D, 0)  (G, 0)  (I, 0)  (D, 1)  (G, 1)  (I, 1)  (D, 2)  (G, 2)  (D, 3)  (G, 3)  (I, 2)  (I, 3)
        0       1       0       1       1       0       1       0       2       0       0       0       1
        1       1       1       0       1       2       1       0       0       1       1       1       1

        Simulation with virtual/soft intervention.

        >>> dbn.simulate(n_time_slices=4, n_samples=2, virtual_intervention=[TabularCPD(('D', 2), 2, [[0.7], [0.3]])])
           (D, 0)  (G, 0)  (I, 0)  (D, 1)  (G, 1)  (I, 1)  (D, 2)  (G, 2)  (D, 3)  (G, 3)  (I, 2)  (I, 3)
        0       0       0       0       1       2       0       1       2       1       1       0       1
        1       0       1       1       1       2       0       1       2       1       1       0       0
        """
        from pgmpy.sampling import BayesianModelSampling

        if show_progress and SHOW_PROGRESS:
            pbar = tqdm(total=n_time_slices * len(self._nodes()))

        # Step 1: Create some data strucures for easily accessing values
        do = {} if do is None else do
        evidence = {} if evidence is None else evidence
        virtual_intervention = (
            [] if virtual_intervention is None else virtual_intervention
        )
        virtual_evidence = [] if virtual_evidence is None else virtual_evidence

        do_dict = defaultdict(dict)
        evidence_dict = defaultdict(dict)
        virtual_inter_dict = defaultdict(list)
        virtual_evi_dict = defaultdict(list)

        for var, state in do.items():
            do_dict[var[1]][str(var[0]) + "_" + str(var[1])] = state
        for var, state in evidence.items():
            evidence_dict[var[1]][str(var[0]) + "_" + str(var[1])] = state
        for cpd in virtual_intervention:
            new_vars = [str(var[0]) + "_" + str(var[1]) for var in cpd.variables]
            new_cpd = TabularCPD(
                variable=new_vars[0],
                variable_card=cpd.cardinality[0],
                values=cpd.get_values(),
                evidence=new_vars[1:],
                evidence_card=cpd.cardinality[1:],
            )
            virtual_inter_dict[cpd.variables[0][1]].append(new_cpd)
        for cpd in virtual_evidence:
            new_vars = [str(var[0]) + "_" + str(var[1]) for var in cpd.variables]
            new_cpd = TabularCPD(
                variable=new_vars[0],
                variable_card=cpd.cardinality[0],
                values=cpd.get_values(),
                evidence=new_vars[1:],
                evidence_card=cpd.cardinality[1:],
            )
            virtual_evi_dict[cpd.variables[0][1]].append(new_cpd)

        # Step 2: Generate first two time samples
        const_bn = self.get_constant_bn(t_slice=0)
        sampled = const_bn.simulate(
            n_samples=n_samples,
            do={**do_dict[0], **do_dict[1]},
            evidence={**evidence_dict[0], **evidence_dict[1]},
            virtual_evidence=[*virtual_evi_dict[0], *virtual_evi_dict[1]],
            virtual_intervention=[*virtual_inter_dict[0], *virtual_inter_dict[1]],
            include_latents=True,
            seed=seed,
            show_progress=False,
        )
        if n_time_slices == 1:
            sampled = self._postprocess(sampled)
            return sampled.loc[:, [col for col in sampled.columns if col[1] == 0]]
        elif n_time_slices == 2:
            sampled = self._postprocess(sampled)
            return sampled

        # Step 3: If n_time_slices > 2, iterate over the time slices and generate samples
        for t_slice in range(1, n_time_slices - 1):
            const_bn = self.get_constant_bn(t_slice=t_slice)
            partial_colnames = [
                str(node) + "_" + str(t_slice) for node in self._nodes()
            ]
            partial_df = sampled.loc[:, partial_colnames]
            remaining_df = sampled.loc[:, ~sampled.columns.isin(partial_colnames)]
            new_samples = const_bn.simulate(
                n_samples=n_samples,
                do={**do_dict[t_slice], **do_dict[t_slice + 1]},
                evidence={**evidence_dict[t_slice], **evidence_dict[t_slice + 1]},
                virtual_evidence=[
                    *virtual_evi_dict[t_slice],
                    *virtual_evi_dict[t_slice + 1],
                ],
                virtual_intervention=[
                    *virtual_inter_dict[t_slice],
                    *virtual_inter_dict[t_slice + 1],
                ],
                include_latents=True,
                partial_samples=partial_df,
                seed=seed,
                show_progress=False,
            )
            sampled = pd.concat((remaining_df, new_samples), axis=1)
        return self._postprocess(sampled)

max_issues_repo_name: vishalbelsare/pgmpy

max_forks_repo_name: vishalbelsare/pgmpy

reason: import numpy,import networkx


text:
#!/usr/bin/env python3
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

import enum
from typing import (
    Callable,
    Any,
    DefaultDict,
    Dict,
    Hashable,
    List,
    Optional,
    Tuple,
    Union,
)

import numpy as np
from botorch.acquisition import AcquisitionFunction

TNumeric = Union[float, int]
TParamCounter = DefaultDict[int, int]
TParamValue = Optional[Union[str, bool, float, int]]
TParameterization = Dict[str, TParamValue]
TParamValueList = List[TParamValue]  # a parameterization without the keys
TContextStratum = Optional[Dict[str, Union[str, float, int]]]

TBounds = Optional[Tuple[np.ndarray, np.ndarray]]
TModelMean = Dict[str, List[float]]
TModelCov = Dict[str, Dict[str, List[float]]]
TModelPredict = Tuple[TModelMean, TModelCov]
# Model predictions for a single arm:
# ( { metric -> mean }, { metric -> { other_metric -> covariance } } ).
TModelPredictArm = Tuple[Dict[str, float], Optional[Dict[str, Dict[str, float]]]]

FloatLike = Union[float, np.floating, np.integer]
SingleMetricDataTuple = Tuple[FloatLike, Optional[FloatLike]]
SingleMetricData = Union[FloatLike, Tuple[FloatLike, Optional[FloatLike]]]
# 1-arm `Trial` evaluation data: {metric_name -> (mean, standard error)}}.
TTrialEvaluation = Dict[str, SingleMetricData]

# 1-arm evaluation data with trace fidelities
TFidelityTrialEvaluation = List[Tuple[TParameterization, TTrialEvaluation]]

# 1-arm evaluation data with arbitrary partial results
TMapDict = Dict[str, Hashable]
TMapTrialEvaluation = List[Tuple[TMapDict, TTrialEvaluation]]

# Format for trasmitting evaluation data to Ax is either:
# 1) {metric_name -> (mean, standard error)} (TTrialEvaluation)
# 2) (mean, standard error) and we assume metric name == objective name
# 3) only the mean, and we assume metric name == objective name and standard error == 0
# 4) [({fidelity_param -> value}, {metric_name} -> (mean, standard error))]

TEvaluationOutcome = Union[
    TTrialEvaluation,
    SingleMetricData,
    TFidelityTrialEvaluation,
    TMapTrialEvaluation,
]
TEvaluationFunction = Callable[[TParameterization, Optional[float]], TEvaluationOutcome]

TConfig = Dict[str, Union[int, float, str, AcquisitionFunction, Dict[str, Any], None]]
TBucket = List[Dict[str, List[str]]]

TGenMetadata = Dict[str, Any]

# Model's metadata about a given candidate (or X).
TCandidateMetadata = Optional[Dict[str, Any]]

class ComparisonOp(enum.Enum):
    """Class for enumerating comparison operations."""

    GEQ: int = 0
    LEQ: int = 1

def merge_model_predict(
    predict: TModelPredict, predict_append: TModelPredict
) -> TModelPredict:
    """Append model predictions to an existing set of model predictions.

    TModelPredict is of the form:
        {metric_name: [mean1, mean2, ...],
        {metric_name: {metric_name: [var1, var2, ...]}})

    This will append the predictions

    Args:
        predict: Initial set of predictions.
        other_predict: Predictions to be appended.

    Returns:
        TModelPredict with the new predictions appended.
    """
    mu, cov = predict
    mu_append, cov_append = predict_append
    if len(mu) != len(mu_append) or len(cov) != len(cov_append):
        raise ValueError("Both sets of model predictions must have the same metrics")

    # Iterate down to the list level and simply add.
    for metric_name, metric_values in mu.items():
        mu[metric_name] = metric_values + mu_append[metric_name]

    for metric_name, co_cov in cov.items():
        for co_metric_name, cov_values in co_cov.items():
            cov[metric_name][co_metric_name] = (
                cov_values + cov_append[metric_name][co_metric_name]
            )
    return mu, cov

ext: py

max_stars_repo_name: j-wilson/Ax

max_issues_repo_name: j-wilson/Ax

max_forks_repo_name: j-wilson/Ax

reason: import numpy


text:
from Cython.Build import cythonize
from distutils.core import setup, Extension
import numpy as np
import os
import sys

exts = cythonize(
    Extension('pywrapfst',
        sources=['src/pywrapfst.pyx'],
        language='c++',
        extra_compile_args=['-std=c++11'],
        libraries=['fst', 'fstscript', 'fstfar', 'fstfarscript'],
        include_dirs=[os.path.join(sys.prefix, 'include'), np.get_include()]
    ),
    include_path=['src'],
)

setup(
    name='pywrapfst',
    version='1.0',
    description='python OpenFst wrapper',
    ext_modules=exts
)

max_stars_repo_name: beer-asr/pywrapfst

max_issues_repo_name: beer-asr/pywrapfst

max_forks_repo_name: beer-asr/pywrapfst


text:
from pathlib import Path
import os

import numpy as np
import pandas as pd
import torch
from matplotlib import pyplot as plt
from tqdm import tqdm

from utils.eval_utils import (roc_auc_threshold, calculate_acc,
                              calculate_cosin_sim)

from datasets.eval.lfw import LFWMasked

WEIGHT_SAVE_DIR = "weights/"
GRAPHS_SAVE_DIR = "viz/"

class FRTrainerPlateau():

    def __init__(self, param_config, net_config, dataset_config,
                 optim_params_func=None, scheduler_params=None,
                 eval_transform=None):

        self.params = param_config
        self.net_config = net_config
        self.datasets = dataset_config
        self.eval_transform = eval_transform

        self.device = torch.device(self.params['device'])

        print('preparing dataloader . . .')
        self.train_loader = torch.utils.data.DataLoader(
            self.datasets['train_dataset'],
            batch_size=self.params['batch_size'],
            num_workers=self.params['workers'],
            shuffle=True,
            pin_memory=True,
            drop_last=True
        )
        print('dataloader ready.')

        self.net = net_config['net']
        self.head = net_config['head']
        self.criterion = net_config['criterion']

        if optim_params_func is None:
            optim_params = self.net.params + self.head.params
        else:
            optim_params = optim_params_func(self.net, self.head, self.params)

        self.optimizer = torch.optim.SGD(
            optim_params,
            lr=self.params['lr'],
            momentum=self.params['momentum']
        )

        self.scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(
            self.optimizer, mode='max', **scheduler_params)

        if self.params['multi_gpu']:
            print('initializing data parallel . . .')
            self.net = torch.nn.DataParallel(self.net)
            self.head = torch.nn.DataParallel(self.head)

        self.net.to(self.device)
        self.head.to(self.device)

        self.total_iter = 0

    def train(self):
        print('training started.')
        training_losses = np.array([])
        eval_accs = np.array([])

        for epoch in range(1, self.params['epochs']+1):
            epoch_loss = self._train_iter(epoch)
            training_losses = np.append(training_losses, epoch_loss)

            with torch.no_grad():
                eval_acc = self._evaluate()
                eval_accs = np.append(eval_accs, eval_acc)
                print(f"Epoch {epoch} LFW eval acc: {eval_acc:.4f}")
                self.scheduler.step(eval_acc)

            self._save_weights(epoch)
            self._save_plots(training_losses, eval_accs)
            self._log_csv(training_losses, eval_accs)

    def _get_lr(self):
        lr = [f"{group['lr']:.2e}" for group in self.optimizer.param_groups]
        return lr

    def _train_iter(self, curr_epoch):
        self.net.train()
        self.head.train()

        pbar = tqdm(self.train_loader,
                    mininterval=2.0,
                    position=0,
                    leave=True,
                    dynamic_ncols=True)
        losses = np.array([])
        for it, data in enumerate(pbar, 1):
            self.optimizer.zero_grad()

            # FORWARD PASS
            inputs, labels = data
            inputs = inputs.to(self.device)
            labels = labels.to(self.device)

            feature = self.net(inputs)
            output = self.head(feature, labels)

            loss = self.criterion(output, labels)

            # BACKWARD PASS
            loss.backward()
            self.optimizer.step()

            losses = np.append(losses, loss.item())

            curr_lr = self._get_lr()
            avg_loss = np.mean(losses)

            desc = (f"[Ep {curr_epoch}][Iter {it}][lr {curr_lr}]" +
                    f"[AvgLoss: {avg_loss:.2f}]")

            pbar.set_description(desc, refresh=False)

        pbar.close()

        epoch_loss = np.mean(losses)
        return epoch_loss

    def _evaluate(self):
        self.net.eval()
        self.head.eval()

        lfw_dataset = LFWMasked('datasets/eval/data/lfw',
                                transform=self.eval_transform)

        evalloader = torch.utils.data.DataLoader(
            lfw_dataset,
            batch_size=self.params['batch_size'],
            num_workers=self.params['workers'],
            shuffle=False,
            pin_memory=False
        )

        features = {}
        pbar = tqdm(evalloader,
                    mininterval=2.0, position=0, leave=True,
                    dynamic_ncols=True)
        for imgs, keys in pbar:
            imgs = imgs.to(self.device)
            output = self.net(imgs)
            output = output.cpu().numpy()
            for i, key in enumerate(keys):
                features[str(key)] = output[i]

            pbar.set_description("lfw eval", refresh=False)
        pbar.close()

        preds = np.array([])
        trues = np.array([])

        pairs_file = list(lfw_dataset.pairs_file)
        for pair in pairs_file:
            feat1 = features[str(pair[0])]
            feat2 = features[str(pair[1])]
            ground_truth = int(pair[2])

            pred = calculate_cosin_sim(feat1, feat2)
            preds = np.append(preds, pred)
            trues = np.append(trues, ground_truth)

        _, _, _, threshold = roc_auc_threshold(preds, trues)
        acc = calculate_acc(preds, trues, threshold)

        return acc

    def _save_weights(self, epoch):
        save_loc = Path(WEIGHT_SAVE_DIR) / self.params['name'] / f"epoch_{epoch}"
        save_loc.mkdir(parents=True, exist_ok=True)

        save_net_name = f"{self.params['name']}_ep{epoch}.pth"
        save_net_name = str(save_loc / save_net_name)

        save_head_name = f"{self.params['name']}_head_ep{epoch}.pth"
        save_head_name = str(save_loc / save_head_name)

        if self.params['multi_gpu']:
            torch.save(self.net.module.state_dict(), save_net_name)
            torch.save(self.head.module.state_dict(), save_head_name)
        else:
            torch.save(self.net.state_dict(), save_net_name)
            torch.save(self.head.state_dict(), save_head_name)

    def _save_plots(self, training_losses, eval_accs):
        save_loc = Path(GRAPHS_SAVE_DIR) / self.params['name']
        save_loc.mkdir(parents=True, exist_ok=True)

        epochs = list(range(1, len(training_losses)+1))
        best_loss = np.argmin(training_losses)
        best_eval = np.argmax(eval_accs)

        plt.style.use('classic')

        plt.figure()
        plt.plot(epochs, training_losses, color='darkorange', lw=2)
        plt.plot([best_loss+1], [training_losses[best_loss]], marker="X", lw=5)
        plt.grid(b=True, which='major', axis='x',
                 color='#666666', linestyle='-', alpha=0.6)
        plt.xticks(epochs, fontsize=9)
        plt.xlabel(f'Epoch\nBest: {best_loss+1}')
        plt.ylabel('Train Loss')
        plt.title('Training statistics')
        plt.savefig(f"{str(save_loc)}/{self.params['name']}_training_loss.png")

        plt.figure()
        plt.plot(epochs, eval_accs, color='darkorange', lw=2)
        plt.plot([best_eval+1], [eval_accs[best_eval]], marker="X", lw=5)
        plt.grid(b=True, which='major', axis='x',
                 color='#666666', linestyle='-', alpha=0.6)
        plt.xticks(epochs, fontsize=9)
        plt.xlabel(f'Epoch\nBest: {eval_accs[best_eval]}@{best_eval+1}')
        plt.ylabel('Eval LFW Acc')
        plt.title('LFW eval statistics')
        plt.savefig(f"{str(save_loc)}/{self.params['name']}_eval_accs.png")
        plt.close('all')

    def _log_csv(self, training_losses, eval_accs):
        save_loc = Path(GRAPHS_SAVE_DIR) / self.params['name']
        save_loc.mkdir(parents=True, exist_ok=True)

        epochs = list(range(1, len(training_losses)+1))

        data = {
            'epoch': epochs,
            'loss': training_losses,
            'acc': eval_accs
        }

        log_df = pd.DataFrame(data=data)
        log_df.to_csv(f"{str(save_loc)}/{self.params['name']}_log.csv",
                      index=False)


text:
import tqdm, sys
import numpy as np
import pandas as pd
from scipy import ndimage as ndi
import scipy as sp
import pickle
import trimesh
from concurrent.futures import ProcessPoolExecutor
import bardensr.misc
import tqdm.notebook
from .. import misc
import numpy.random as npr
import scipy.spatial

def calc_circum(V):
    '''
    input
    * V -- (batch x (d+1) x d) -- a simplex

    Output
    * circumcenters -- (batch,d)
    * circumradii -- (batch)
    '''

    '''
    Let

        diff = V[i,j1] - V[i,j2]
        diff = diff/np.linalg.norm(diff)

    Then circumcenter[i] must satisfy

        np.sum(circumcenter[i]*diff) == .5*np.sum(diff*(V[i,j1]+V[i,j2]))

    This forms a system we can work with to compute circumcenters
    and circumradii.
    '''

    directions = V[:,[0]] - V[:,1:]  # batch x d x d
    avgs = .5*(V[:,[0]] + V[:,1:]) # batch x d x d
    directions = directions / np.linalg.norm(directions,keepdims=True,axis=-1) # batch x d x d

    beta = np.sum(avgs*directions,axis=-1)

    circumcenters = np.linalg.solve(directions,beta) # batch x d
    circumradii = np.linalg.norm(circumcenters - V[:,0],axis=-1)

    return circumcenters,circumradii

def alpha_3d_shape(pointcloud,circumradius,perturbfactor=1e-10):
    perturb=np.ptp(pointcloud)*perturbfactor
    pointcloud=pointcloud+(npr.rand(*pointcloud.shape)-.5)*perturb

    dl = sp.spatial.Delaunay(pointcloud)
    s=dl.simplices
    s=pointcloud[s]
    circumcenters,sizes=calc_circum(s)

    # find out which simplices are good
    good = sizes < circumradius

    # get the good simplices
    good_simplices=dl.simplices[good]

    # turn them into faces
    faces = np.stack([
        good_simplices[:,[0,1,2]],
        good_simplices[:,[0,3,1]],
        good_simplices[:,[0,2,3]],
        good_simplices[:,[1,3,2]],
    ],axis=1)

    # figure out signs of faces
    simplex_centers = np.mean(pointcloud[good_simplices], axis=1)  # get centers

    # normals according to winding
    simplex_centers = np.mean(pointcloud[good_simplices], axis=1)
    face_centers = np.mean(pointcloud[faces], axis=-2)
    s2f = simplex_centers[:, None, :] - face_centers
    A = pointcloud[faces[:, :, 0]]-pointcloud[faces[:, :, 1]]
    B = pointcloud[faces[:, :, 0]]-pointcloud[faces[:, :, 2]]
    normals = np.cross(A, B)
    signs = np.sum(normals*s2f, axis=-1)

    # fix as necessary
    faces_reversed = faces[:, :, ::-1]
    faces[signs > 0] = faces_reversed[signs > 0]

    # concatenate
    faces=np.concatenate(faces,axis=0)

    # remove doublefaces
    unq,cts=np.unique(faces,axis=0,return_counts=True)
    faces=unq[cts==1]

    mesh=trimesh.Trimesh(pointcloud,faces)
    return mesh

def dilate_fill(a):
    b = a.copy()
    for m in range(a.shape[0]):
        b[m] = sp.ndimage.binary_fill_holes(b[m])
    for m in range(a.shape[1]):
        b[:,m] = sp.ndimage.binary_fill_holes(b[:,m])
    for m in range(a.shape[-1]):
        b[...,m] = sp.ndimage.binary_fill_holes(b[...,m])
    return b

# def dilate_fill(a):
#     b = np.zeros_like(a)
#     for m in range(a.shape[0]):
#         b[m] = sp.ndimage.binary_fill_holes(a[m])
#     return b

def voxelize(mesh, pitch, mins,maxs):
    '''
    input:
        mash: watertight mesh
        pitch: downsample level
        maxs/mins: boundaries of voxelation; must divide evenly by pitch
    output:
        out: voxelized interior of mesh

    Specifically, out[i,j,k] is True if the voxel spanning the cube

        mins[0]+pitch*i -- mins[0]*pitch+(i+1)
        mins[1]+pitch*j -- mins[1]*pitch+(j+1)
        mins[2]+pitch*k -- mins[2]*pitch+(k+1)

    is belived to intersect with the interior of the mesh.

    '''
    vox=get_boundary_voxels(mesh,pitch,mins,maxs)
    return dilate_fill(vox)

def get_boundary_voxels(mesh:trimesh.Trimesh, pitch,mins,maxs):
    '''
    input:
        mash: original mesh
        pitch: downsample level
        maxs/mins: boundaries of voxelation; must divide evenly by pitch
    output:
        vox: voxelized version of exterior of mesh

    Specifically, out[i,j,k] is True if the voxel spanning the cube

        mins[0]+pitch*i -- mins[0]*pitch+(i+1)
        mins[1]+pitch*j -- mins[1]*pitch+(j+1)
        mins[2]+pitch*k -- mins[2]*pitch+(k+1)

    is belived to intersect with the mesh surface.
    '''

    assert (maxs>mins).all()
    assert np.allclose(mins%pitch,0)
    assert np.allclose(mins%pitch,0)

    maxs=np.array(maxs)
    mins=np.array(mins)
    pitch=float(pitch)

    # out will be this size
    out= np.zeros(np.require((maxs-mins)//pitch,dtype=np.int),dtype=np.bool)

    # get hits, at pitch-level resolution
    max_edge = pitch / 2.0
    v,f = trimesh.remesh.subdivide_to_size(mesh.vertices, mesh.faces, max_edge)

    # convert hit so that one unit=one pitch
    hit = (v / pitch)

    # integerify and uniquify
    hit = hit.astype(np.int)
    hit = np.unique(hit,axis=0)

    # convert mins,maxs so that one unit = one pitch
    mins=np.require(np.floor(mins/pitch),dtype=np.int)
    maxs=np.require(np.ceil(maxs/pitch),dtype=np.int)

    # figure out how big the output array ought to be
    size=maxs-mins

    # kill those we don't care about
    for i in range(3):
        hit=hit[hit[:,i]>=mins[i]]
    for i in range(3):
        hit=hit[hit[:,i]<maxs[i]]

    # translate so 0=mins
    hit=hit-mins

    # make it!
    out=np.zeros(size,dtype=np.bool)
    out[hit[:,0],hit[:,1],hit[:,2]]=True

    return out

def exhaustively_sample_mesh_interior(mesh,pitch):
    '''
    for one mesh, vozelize and return the rolony based on the poisson rate.
    input:
        mesh: watertight trimesh.Trimesh object
        pitch: approximation level to use in sampling (lengthscale used for voxelation)
    output:
        locations: all voxel locations insite the mesh
    '''
    MX=pitch*(1+np.max(mesh.vertices,axis=0)//pitch)
    MN=pitch*(np.min(mesh.vertices,axis=0)//pitch)
    vv =voxelize(mesh,pitch,maxs=MX,mins=MN)
    opts=np.array(np.where(vv)).T
    opts=opts*pitch+np.array(MN)
    return opts

def voxelize_meshlist_interiors(submeshes,pitch = 100, num_workers=1,
                            use_tqdm_notebook=True):
    '''
    sample interiors of many meshes

    input:
        meshes: a list of trimesh.Trimesh object
        MX,MN : region to voxelize in
        pitch : size of a voxel in resulting dataset
    output:
        rolonies: a list of locations, one for each mesh
    '''
    rolonies=[]
    with ProcessPoolExecutor(max_workers=num_workers) as ex:
        t=range(len(submeshes))
        if use_tqdm_notebook:
            t=tqdm.notebook.tqdm(t)
        jobs=[ex.submit(exhaustively_sample_mesh_interior,mesh, pitch) for mesh in submeshes]
        for idx in t:
            rolonies.append(jobs[idx].result())
    return rolonies

max_stars_repo_name: jacksonloper/bardensr

max_issues_repo_name: jacksonloper/bardensr

max_forks_repo_name: jacksonloper/bardensr

reason: import numpy,import scipy,from scipy


text:
r"""Solve Poisson's equation using a mixed formulation

The Poisson equation is

.. math::

    \nabla^2 u &= f \\
    u(x, y=\pm 1) &= 0 \\
    u(x=2\pi, y) &= u(x=0, y)

We solve using the mixed formulation

.. math::

    g - \nabla(u) &= 0 \\
    \nabla \cdot g &= f \\
    u(x, y=\pm 1) &= 0 \\
    u(x=2\pi, y) &= u(x=0, y) \\
    g(x=2\pi, y) &= g(x=0, y)

We use a Tensorproductspace with Fourier expansions in the x-direction and
a composite Chebyshev basis in the y-direction. The equations are solved
coupled and implicit.

"""

import os
import sys
import numpy as np
from sympy import symbols, sin, cos
from shenfun import *

x, y = symbols("x,y", real=True)

family = sys.argv[-1].lower()
assert len(sys.argv) == 4, "Call with three command-line arguments: N[0], N[1] and family (Chebyshev/Legendre)"
assert family in ('legendre', 'chebyshev')
assert isinstance(int(sys.argv[-2]), int)
assert isinstance(int(sys.argv[-3]), int)

# Create a manufactured solution for verification
#ue = (sin(2*x)*cos(3*y))*(1-x**2)
ue = (sin(4*x)*cos(5*y))*(1-y**2)
dux = ue.diff(x, 1)
duy = ue.diff(y, 1)
fe = ue.diff(x, 2) + ue.diff(y, 2)

N = (int(sys.argv[-3]), int(sys.argv[-2]))

K0 = FunctionSpace(N[0], 'Fourier', dtype='d')
SD = FunctionSpace(N[1], family, bc=(0, 0))
ST = FunctionSpace(N[1], family)

TD = TensorProductSpace(comm, (K0, SD), axes=(1, 0))
TT = TensorProductSpace(comm, (K0, ST), axes=(1, 0))
VT = VectorSpace(TT)
Q = CompositeSpace([VT, TD])

gu = TrialFunction(Q)
pq = TestFunction(Q)

g, u = gu
p, q = pq

A00 = inner(p, g)
if family == 'legendre':
    A01 = inner(div(p), u)
else:
    A01 = inner(p, -grad(u))
A10 = inner(q, div(g))

# Get f and g on quad points
vfj = Array(Q, buffer=(0, 0, fe))
vj, fj = vfj

vf_hat = Function(Q)
v_hat, f_hat = vf_hat
f_hat = inner(q, fj, output_array=f_hat)

M = BlockMatrix(A00+A01+A10)

gu_hat = M.solve(vf_hat)
gu = gu_hat.backward()

g_, u_ = gu

uj = Array(TD, buffer=ue)
duxj = Array(TT, buffer=dux)
duyj = Array(TT, buffer=duy)

error = [comm.reduce(np.linalg.norm(uj-u_)),
         comm.reduce(np.linalg.norm(duxj-g_[0])),
         comm.reduce(np.linalg.norm(duyj-g_[1]))]

if comm.Get_rank() == 0:
    print('Error    u         dudx        dudy')
    print('     %2.4e %2.4e %2.4e' %(error[0], error[1], error[2]))
    assert np.all(abs(np.array(error)) < 1e-8), error

if 'pytest' not in os.environ:
    import matplotlib.pyplot as plt
    plt.figure()
    X = TD.local_mesh(True)
    plt.contourf(X[0], X[1], u_)
    plt.figure()
    plt.quiver(X[1], X[0], g_[1], g_[0])
    plt.figure()
    plt.spy(M.diags((0, 0)).toarray()) # The matrix for given Fourier wavenumber
    plt.show()

reason: import numpy,from sympy


text:
import numpy as np
from skimage import measure

def compare_ssim(phase_a, phase_b):
    ssim = 0.0
    for y_index in range(len(phase_a)):
        ssim += measure.compare_ssim(phase_a[:, y_index, :], phase_b[:, y_index, :])
    return ssim / len(phase_a)

def get_ordered_area_list(phase_mat):
    label_stack, label_num = measure.label(phase_mat, background=0, return_num=True)
    props = measure.regionprops(label_stack, cache=True)
    area_dict = {}
    for region_index in range(len(props)):
        area_dict[props[region_index].label] = props[region_index].area
    return sorted(area_dict.items(), key=lambda d: d[1], reverse=True)

def remove_phase_noise_(phase_mat):
    label_stack, label_num = measure.label(phase_mat, background=0, return_num=True)
    props = measure.regionprops(label_stack, cache=True)
    area_dict = {}
    for region_index in range(len(props)):
        area_dict[props[region_index].label] = props[region_index].area
    max_area_label = int(sorted(area_dict.items(), key=lambda d: d[1], reverse=True)[0][0])
    phase_mat[label_stack != max_area_label] = 0
    return phase_mat

def get_surface_area(phase_mat):
    return calculateSurfaceArea(phase_mat)

def get_volume(phase_mat):
    """

    :param phase_mat:
    :return:
    """
    return np.count_nonzero(phase_mat == 255)

def getSurfaceStack(labelStack,surfaceValue=200):
    """
    功能：将LabelStack中的边缘点标记成surfaceValue，判断边缘点的方法是判断每个前景点，若其26邻域内有一个背景点，则该前景点位边缘点
    :param labelStack: 三维label矩阵
    :param surfaceValue: 需要赋给表面的值，默认200
    :return: 返回边缘标记矩阵
    """
    row = labelStack.shape[0]
    col = labelStack.shape[1]
    depth = labelStack.shape[2]
    expand = np.zeros((row + 1, col + 1, depth + 1), dtype=np.int16)
    surfaceStack = expand.copy()
    expand[1: row + 1, 1: col + 1, 1: depth + 1] = labelStack
    for x in range(1, row):
        for y in range(1, col):
            for z in range(1, depth):
                if expand[x, y, z] != 255:
                    continue
                sumValue = expand[x, y, z - 1] + expand[x, y - 1, z - 1] + expand[x, y + 1, z - 1] + \
                           expand[x - 1, y, z - 1] + expand[x - 1, y - 1, z - 1] + expand[x - 1, y + 1, z - 1] + \
                           expand[x + 1, y, z - 1] + expand[x + 1, y - 1, z - 1] + expand[x + 1, y + 1, z - 1] + \
                           expand[x, y - 1, z] + expand[x, y + 1, z] + \
                           expand[x - 1, y, z] + expand[x - 1, y - 1, z] + expand[x - 1, y + 1, z] + \
                           expand[x + 1, y, z] + expand[x + 1, y - 1, z] + expand[x + 1, y + 1, z] + \
                           expand[x, y, z + 1] + expand[x, y - 1, z + 1] + expand[x, y + 1, z + 1] + \
                           expand[x - 1, y, z + 1] + expand[x - 1, y - 1, z + 1] + expand[x - 1, y + 1, z + 1] + \
                           expand[x + 1, y, z + 1] + expand[x + 1, y - 1, z + 1] + expand[x + 1, y + 1, z + 1]
                if sumValue < 255 * 26:
                    surfaceStack[x, y, z] = surfaceValue
    return surfaceStack[1: row + 1, 1: col + 1, 1: depth + 1]

def calculateSurfaceArea(labelStack, method=0):
    """
    功能：计算表面积
    :param labelStack: 三维label矩阵，背景为0,前景为255
    :param method: 计算方法，0：仅统计边缘点数目
    :return: 表面积
    """
    area = 0
    if method == 0:
        # 仅统计边缘点数目,由于未找到三维卷积代码，自己实现统计，判断每个体素，若其26领域内有一个背景点，则本体素就是边缘点
        surfaceValue = 200
        surfaceStack = getSurfaceStack(labelStack, surfaceValue=surfaceValue)
        area = np.count_nonzero(surfaceStack == surfaceValue)
    else:
        print(" The method isn't implemented")
    return area


text:
# -*- coding: utf-8 -*-

import numpy as np

class Population:
    """
    A Population is a measure over the the cells at given timepoint.

    Parameters
    ----------
    time : int or float
        The time at which the cells where measured.
    p : 1-D array-like
        Measure over the cells at the given timepoint.
    """

    def __init__(self, time, p):
        self.time = time
        self.p = np.asarray(p, dtype=np.float64)

    def normalize(self):
        """
        Make the measure sum to 1, i.e. be a probability distribution over cells.
        """
        self.p = self.p / np.sum(self.p)

max_stars_repo_name: gamazeps/wot

max_issues_repo_name: gamazeps/wot

max_forks_repo_name: gamazeps/wot


text:
from pylab import *
from numpy import *

def moving_average(interval, window_size):
   ''' Compute convoluted window for given size
   '''
   window = ones(int(window_size)) / float (window_size)
   return convolve(interval, window, 'same')

t = linspace(-4, 4, 100)
y = sin(t) + randn(len(t))* 0.1

plot(t, y, "k.")

# compute moving average
y_av = moving_average(y, 10)
plot(t, y_av, "r")
#xlim(0, 1000)

xlabel("Time")
ylabel("Value")
grid(True)
show()

reason: from numpy


text:
# -*- coding: utf-8 -*-
# Author: XuMing <xuming624@qq.com>
# Brief:
import matplotlib.pyplot as plt
import numpy as np
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score, train_test_split, learning_curve
from sklearn.svm import SVC
import sys

def search_cv(x_train, y_train, x_test, y_test, model=GradientBoostingClassifier(n_estimators=30)):
    # grid search找到最好的参数
    parameters = {'kernel': ('linear', 'rbf'), 'C': [1, 2, 4], 'gamma': [0.125, 0.25, 0.5, 1, 2, 4]}
    clf = GridSearchCV(model, param_grid=parameters)
    grid_search = clf.fit(x_train, y_train)
    # 对结果打分
    print("Best score: %0.3f" % grid_search.best_score_)
    print(grid_search.best_estimator_)

    # best prarams
    print('best prarams:', clf.best_params_)

    print('-----grid search end------------')
    print('on all train set')
    scores = cross_val_score(grid_search.best_estimator_, x_train, y_train, cv=3, scoring='accuracy')
    print(scores.mean(), scores)
    print('on test set')
    scores = cross_val_score(grid_search.best_estimator_, x_test, y_test, cv=3, scoring='accuracy')
    print(scores.mean(), scores)

def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None,
                        train_sizes=np.linspace(.1, 1.0, 5), n_jobs=1, figure_path=None):
    plt.figure()
    plt.title(title)
    if ylim is not None:
        plt.ylim(*ylim)
    plt.xlabel("Training examples")
    plt.ylabel("Score")
    train_sizes, train_scores, test_scores = learning_curve(
        estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)
    train_scores_mean = np.mean(train_scores, axis=1)
    train_scores_std = np.std(train_scores, axis=1)
    test_scores_mean = np.mean(test_scores, axis=1)
    test_scores_std = np.std(test_scores, axis=1)
    plt.grid()

    plt.fill_between(train_sizes, train_scores_mean - train_scores_std,
                     train_scores_mean + train_scores_std, alpha=0.1,
                     color="r")
    plt.fill_between(train_sizes, test_scores_mean - test_scores_std,
                     test_scores_mean + test_scores_std, alpha=0.1, color="g")
    plt.plot(train_sizes, train_scores_mean, 'o-', color="r",
             label="Training score")
    plt.plot(train_sizes, test_scores_mean, 'o-', color="g",
             label="Cross-validation score")

    plt.legend(loc="best")
    plt.savefig(figure_path)
    return plt

if __name__ == "__main__":
    sys.path.append("../")
    from models.feature import Feature
    from models.reader import data_reader

    data_content, data_lbl = data_reader('../data/train_words.txt', '\t')
    # init feature
    feature = Feature(feature_type='tfidf_word', feature_vec_path='../output/temp')
    # get data feature
    data_feature = feature.get_feature(data_content)
    # label
    data_label = feature.label_encoder(data_lbl)
    X_train, X_val, y_train, y_val = train_test_split(
        data_feature, data_label, test_size=0.2)
    search_cv(X_train, y_train, X_val, y_val, model=SVC())

    # test plot_learning_curve
    title = "Learning Curves (Random Forest, n_estimators = 30)"
    estimator = SVC()
    plot_learning_curve(estimator, title, X_train, y_train, cv=5, n_jobs=4,
                        figure_path='../output/curve.png')
    plt.show()


text:
# coding=utf-8
# Copyright 2022 The TensorFlow Datasets Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""SpeechCommands dataset."""

import os
import numpy as np

from tensorflow_datasets.core import lazy_imports_lib
import tensorflow_datasets.public_api as tfds

_CITATION = """
@article{speechcommandsv2,
   author = {{Warden}, P.},
    title = "{Speech Commands: A Dataset for Limited-Vocabulary Speech Recognition}",
  journal = {ArXiv e-prints},
  archivePrefix = "arXiv",
  eprint = {1804.03209},
  primaryClass = "cs.CL",
  keywords = {Computer Science - Computation and Language, Computer Science - Human-Computer Interaction},
    year = 2018,
    month = apr,
    url = {https://arxiv.org/abs/1804.03209},
}
"""

_DESCRIPTION = """
An audio dataset of spoken words designed to help train and evaluate keyword
spotting systems. Its primary goal is to provide a way to build and test small
models that detect when a single word is spoken, from a set of ten target words,
with as few false positives as possible from background noise or unrelated
speech. Note that in the train and validation set, the label "unknown" is much
more prevalent than the labels of the target words or background noise.
One difference from the release version is the handling of silent segments.
While in the test set the silence segments are regular 1 second files, in the
training they are provided as long segments under "background_noise" folder.
Here we split these background noise into 1 second clips, and also keep one of
the files for the validation set.
"""

_DOWNLOAD_PATH = 'http://download.tensorflow.org/data/speech_commands_v0.02.tar.gz'
_TEST_DOWNLOAD_PATH_ = 'http://download.tensorflow.org/data/speech_commands_test_set_v0.02.tar.gz'

_SPLITS = ['train', 'valid', 'test']

WORDS = ['down', 'go', 'left', 'no', 'off', 'on', 'right', 'stop', 'up', 'yes']
SILENCE = '_silence_'
UNKNOWN = '_unknown_'
BACKGROUND_NOISE = '_background_noise_'
SAMPLE_RATE = 16000

class SpeechCommands(tfds.core.GeneratorBasedBuilder):
  """The Speech Commands dataset for keyword detection."""

  VERSION = tfds.core.Version('0.0.2')

  def _info(self):
    return tfds.core.DatasetInfo(
        builder=self,
        description=_DESCRIPTION,
        # tfds.features.FeatureConnectors
        features=tfds.features.FeaturesDict({
            'audio':
                tfds.features.Audio(file_format='wav', sample_rate=SAMPLE_RATE),
            'label':
                tfds.features.ClassLabel(names=WORDS + [SILENCE, UNKNOWN])
        }),
        supervised_keys=('audio', 'label'),
        # Homepage of the dataset for documentation
        homepage='https://arxiv.org/abs/1804.03209',
        citation=_CITATION,
    )

  def _split_generators(self, dl_manager):
    """Returns SplitGenerators."""

    dl_path, dl_test_path = dl_manager.download(
        [_DOWNLOAD_PATH, _TEST_DOWNLOAD_PATH_])

    train_paths, validation_paths = self._split_archive(
        dl_manager.iter_archive(dl_path))

    return [
        tfds.core.SplitGenerator(
            name=tfds.Split.TRAIN,
            gen_kwargs={
                'archive': dl_manager.iter_archive(dl_path),
                'file_list': train_paths
            },
        ),
        tfds.core.SplitGenerator(
            name=tfds.Split.VALIDATION,
            gen_kwargs={
                'archive': dl_manager.iter_archive(dl_path),
                'file_list': validation_paths
            },
        ),
        tfds.core.SplitGenerator(
            name=tfds.Split.TEST,
            gen_kwargs={
                'archive': dl_manager.iter_archive(dl_test_path),
                'file_list': None
            },
        ),
    ]

  def _generate_examples(self, archive, file_list):
    """Yields examples."""
    for path, file_obj in archive:
      if file_list is not None and path not in file_list:
        continue
      relpath, wavname = os.path.split(path)
      _, word = os.path.split(relpath)
      example_id = '{}_{}'.format(word, wavname)
      if word in WORDS:
        label = word
      elif word == SILENCE or word == BACKGROUND_NOISE:
        # The main tar file already contains all of the test files, except for
        # the silence ones. In fact it does not contain silence files at all.
        # So for the test set we take the silence files from the test tar file,
        # while for train and validation we build them from the
        # _background_noise_ folder.
        label = SILENCE
      else:
        # Note that in the train and validation there are a lot more _unknown_
        # labels than any of the other ones.
        label = UNKNOWN

      if word == BACKGROUND_NOISE:
        # Special handling of background noise. We need to cut these files to
        # many small files with 1 seconds length, and transform it to silence.
        audio_samples = np.array(
            lazy_imports_lib.lazy_imports.pydub.AudioSegment.from_file(
                file_obj, format='wav').get_array_of_samples())

        for start in range(0,
                           len(audio_samples) - SAMPLE_RATE, SAMPLE_RATE // 2):
          audio_segment = audio_samples[start:start + SAMPLE_RATE]
          cur_id = '{}_{}'.format(example_id, start)
          example = {'audio': audio_segment, 'label': label}
          yield cur_id, example
      else:
        try:
          example = {
              'audio':
                  np.array(
                      lazy_imports_lib.lazy_imports.pydub.AudioSegment
                      .from_file(file_obj,
                                 format='wav').get_array_of_samples()),
              'label':
                  label,
          }
          yield example_id, example
        except lazy_imports_lib.lazy_imports.pydub.exceptions.CouldntDecodeError:
          pass

  def _split_archive(self, train_archive):
    train_paths = []
    for path, file_obj in train_archive:
      if 'testing_list.txt' in path:
        train_test_paths = file_obj.read().strip().splitlines()
        train_test_paths = [p.decode('ascii') for p in train_test_paths]
      elif 'validation_list.txt' in path:
        validation_paths = file_obj.read().strip().splitlines()
        validation_paths = [p.decode('ascii') for p in validation_paths]
      elif path.endswith('.wav'):
        train_paths.append(path)

    # Original validation files did include silence - we add them manually here
    validation_paths.append(os.path.join(BACKGROUND_NOISE, 'running_tap.wav'))

    # The paths for the train set is just whichever paths that do not exist in
    # either the test or validation splits.
    train_paths = (
        set(train_paths) - set(validation_paths) - set(train_test_paths))

    return train_paths, validation_paths


text:
# -*- coding: iso-8859-1 -*-

"""
Colour-blind proof distinct colours module, based on work by Paul Tol
Pieter van der Meer, 2011
SRON - Netherlands Institute for Space Research
"""

# colour table in HTML hex format
hexcols = ['#332288', '#88CCEE', '#44AA99', '#117733', '#999933', '#DDCC77',
           '#CC6677', '#882255', '#AA4499', '#661100', '#6699CC', '#AA4466',
           '#4477AA']

greysafecols = ['#809BC8', '#FF6666', '#FFCC66', '#64C204']

xarr = [[12],
        [12, 6],
        [12, 6, 5],
        [12, 6, 5, 3],
        [0, 1, 3, 5, 6],
        [0, 1, 3, 5, 6, 8],
        [0, 1, 2, 3, 5, 6, 8],
        [0, 1, 2, 3, 4, 5, 6, 8],
        [0, 1, 2, 3, 4, 5, 6, 7, 8],
        [0, 1, 2, 3, 4, 5, 9, 6, 7, 8],
        [0, 10, 1, 2, 3, 4, 5, 9, 6, 7, 8],
        [0, 10, 1, 2, 3, 4, 5, 9, 6, 11, 7, 8]]

# get specified nr of distinct colours in HTML hex format.
# in: nr - number of colours [1..12]
# returns: list of distinct colours in HTML hex

def get_distinct(nr):

    # check if nr is in correct range

    if nr < 1 or nr > 12:
        print("wrong nr of distinct colours!")
        return

    # get list of indices

    lst = xarr[nr-1]

    # generate colour list by stepping through indices and looking them up
    # in the colour table

    i_col = 0
    col = [0] * nr
    for idx in lst:
        col[i_col] = hexcols[idx]
        i_col+=1
    return col

# gets 4 colours, which also look distinct in black&white
# returns: list of 4 colours in
#def get_distinct_grey():

import sys

# display usage information and produce example plot.
if __name__ == '__main__':
    import numpy as np
    import matplotlib.mlab as mlab
    import matplotlib.pyplot as plt

    print(__doc__)
    print("usage examples: ")
    print("print distinct_colours.get_distinct(2)")
    print(get_distinct(2))
    print("print distinct_colours.greysafecols")
    print(greysafecols)

    print("generating example plot: distinct_colours_example.png")
    plt.close()
    t = np.arange(0.0, 2.0, 0.01)
    n = 12
    if len(sys.argv) > 1: n = int(sys.argv[1])
    cols = get_distinct(n)
    d = 2./n
    for i in range(n):
        s = np.sin(i*d*np.pi*t)
        plt.plot(t, s, linewidth=2.0, c=cols[i], label=str(i))

    plt.xlabel('time (s)')
    plt.ylabel('voltage (mV)')
    plt.title('Distinct colours example (n = '+str(n)+')')
    plt.grid(True)
    plt.legend(loc=3, ncol=2)

    plt.savefig("distinct_colours_example.png")
    plt.show()

max_stars_repo_name: rknop/amuse

max_issues_repo_name: rknop/amuse

max_forks_repo_name: rieder/amuse


text:
from torch.utils.data import Subset
from PIL import Image
from torchvision.datasets import EMNIST
from base.torchvision_dataset import TorchvisionDataset
from PIL.ImageFilter import GaussianBlur

import numpy as np
import torch
import torchvision.transforms as transforms
import random

class EMNIST_Dataset(TorchvisionDataset):

    def __init__(self, root: str, split: str = 'letters', normal_class: int = 1, outlier_exposure: bool = False,
                 oe_n_classes: int = 26, blur_oe: bool = False, blur_std: float = 1.0, seed: int = 0):
        super().__init__(root)

        self.image_size = (1, 28, 28)

        self.n_classes = 2  # 0: normal, 1: outlier
        self.shuffle = True
        self.split = split
        random.seed(seed)  # set seed

        if outlier_exposure:
            self.normal_classes = None
            self.outlier_classes = list(range(1, 27))
            self.known_outlier_classes = tuple(random.sample(self.outlier_classes, oe_n_classes))
        else:
            # Define normal and outlier classes
            self.normal_classes = tuple([normal_class])
            self.outlier_classes = list(range(1, 27))
            self.outlier_classes.remove(normal_class)
            self.outlier_classes = tuple(self.outlier_classes)

        # EMNIST preprocessing: feature scaling to [0, 1]
        transform = []
        if blur_oe:
            transform += [transforms.Lambda(lambda x: x.filter(GaussianBlur(radius=blur_std)))]
        transform += [transforms.ToTensor()]
        transform = transforms.Compose(transform)
        target_transform = transforms.Lambda(lambda x: int(x in self.outlier_classes))

        # Get train set
        train_set = MyEMNIST(root=self.root, split=self.split, train=True, transform=transform,
                             target_transform=target_transform, download=True)

        if outlier_exposure:
            idx = np.argwhere(np.isin(train_set.targets.cpu().data.numpy(), self.known_outlier_classes))
            idx = idx.flatten().tolist()
            train_set.semi_targets[idx] = -1 * torch.ones(len(idx)).long()  # set outlier exposure labels

            # Subset train_set to selected classes
            self.train_set = Subset(train_set, idx)
            self.train_set.shuffle_idxs = False
            self.test_set = None
        else:
            # Subset train_set to normal_classes
            idx = np.argwhere(np.isin(train_set.targets.cpu().data.numpy(), self.normal_classes))
            idx = idx.flatten().tolist()
            train_set.semi_targets[idx] = torch.zeros(len(idx)).long()
            self.train_set = Subset(train_set, idx)

            # Get test set
            self.test_set = MyEMNIST(root=self.root, split=self.split, train=False, transform=transform,
                                     target_transform=target_transform, download=True)

class MyEMNIST(EMNIST):
    """
    Torchvision EMNIST class with additional targets for the outlier exposure setting and patch of __getitem__ method
    to also return the outlier exposure target as well as the index of a data sample.
    """

    def __init__(self, *args, **kwargs):
        super(MyEMNIST, self).__init__(*args, **kwargs)

        self.semi_targets = torch.zeros_like(self.targets)
        self.shuffle_idxs = False

    def __getitem__(self, index):
        """Override the original method of the EMNIST class.
        Args:
            index (int): Index

        Returns:
            tuple: (image, target, semi_target, index)
        """
        img, target, semi_target = self.data[index], int(self.targets[index]), int(self.semi_targets[index])

        # doing this so that it is consistent with all other datasets
        # to return a PIL Image
        img = Image.fromarray(img.numpy(), mode='L')

        if self.transform is not None:
            img = self.transform(img)

        if self.target_transform is not None:
            target = self.target_transform(target)

        return img, target, semi_target, index

max_stars_repo_name: bjfranks/Classification-AD

max_issues_repo_name: bjfranks/Classification-AD

max_forks_repo_name: bjfranks/Classification-AD


text:
from torch.utils import data
import torch
import cv2
from contourlet_dec import ContourletDec
import os
import numpy as np
from PIL import Image
from tools.shownsct import shownsct, save_nsct
from tqdm import tqdm

class CityscapesImages(data.Dataset):
    def __init__(self, root, list_path):
        self.root = root
        self.list_path = list_path

        self.img_list = [line.strip().split()[0] for line in open(os.path.join(root, list_path))]

    def __len__(self):
        return len(self.img_list)

    def __getitem__(self, index):
        img = Image.open(os.path.join(self.root, self.img_list[index])).convert('L')
        img = img.resize((512, 256))
        img = np.array(img)
        return img.copy()

def get_index():
    level_012_nsdfb_level2_stage2_zconv1 = np.load('/data/level_012_nsdfb_level{}_stage{}_zconv{}.npy'.format(2, 2, 1))
    level_012_nsdfb_level2_stage2_zconv2 = np.load('/data/level_012_nsdfb_level{}_stage{}_zconv{}.npy'.format(2, 2, 2))
    level_012_nsdfb_level2_stage3_zconv1 = np.load('/data/level_012_nsdfb_level{}_stage{}_zconv{}.npy'.format(2, 3, 1))
    level_012_nsdfb_level2_stage3_zconv2 = np.load('/data/level_012_nsdfb_level{}_stage{}_zconv{}.npy'.format(2, 3, 2))

    level_012_nsfb_level0_atrous1 = np.load('/data/level_012_nsfb_level{}_atrous{}.npy'.format(0, 1))
    level_012_nsfb_level0_atrous2 = np.load('/data/level_012_nsfb_level{}_atrous{}.npy'.format(0, 2))
    level_012_nsfb_level1_atrous1 = np.load('/data/level_012_nsfb_level{}_atrous{}.npy'.format(1, 1))
    level_012_nsfb_level1_atrous2 = np.load('/data/level_012_nsfb_level{}_atrous{}.npy'.format(1, 2))

    index_dict = {'level_012_nsfb_level0_atrous1': level_012_nsfb_level0_atrous1,
                  'level_012_nsfb_level0_atrous2': level_012_nsfb_level0_atrous2,
                  'level_012_nsfb_level1_atrous1': level_012_nsfb_level1_atrous1,
                  'level_012_nsfb_level1_atrous2': level_012_nsfb_level1_atrous2,
                  'level_012_nsdfb_level2_stage2_zconv1': level_012_nsdfb_level2_stage2_zconv1,
                  'level_012_nsdfb_level2_stage2_zconv2': level_012_nsdfb_level2_stage2_zconv2,
                  'level_012_nsdfb_level2_stage3_zconv1': level_012_nsdfb_level2_stage3_zconv1,
                  'level_012_nsdfb_level2_stage3_zconv2': level_012_nsdfb_level2_stage3_zconv2}
    return index_dict

def main():
    # get filters
    levels = [0, 1, 2]
    pfilter = 'maxflat'
    dfilter = 'dmaxflat7'
    nsct = ContourletDec(levels, dfilter, pfilter)
    h1, h2, filters = nsct.get_filters()

    # get index
    index_dict = get_index()

    # get dataloader
    dec_dataset = CityscapesImages('../../data/cityscapes', 'train.lst')
    dec_loader = torch.utils.data.DataLoader(
        dec_dataset,
        batch_size=1,
        num_workers=8,
        pin_memory=True
    )

    for i, batch in tqdm(enumerate(dec_loader), total=dec_dataset.__len__()):
        img = batch
        img = img.squeeze(0).numpy()

        clevels = len(levels)
        nIndex = clevels + 1
        y = nsct.dec_iter(img, h1, h2, filters, index_dict, clevels, nIndex)

        save_dir = '/data/nsct_image/'
        os.makedirs(save_dir, exist_ok=True)
        # shownsct(y)
        save_nsct(y, save_dir, img_name=str(i))

if __name__ == '__main__':
    main()

max_stars_repo_name: yilinshao/CoT-Contourlet-Transformer

max_issues_repo_name: yilinshao/CoT-Contourlet-Transformer

max_forks_repo_name: yilinshao/CoT-Contourlet-Transformer


text:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.colors as mcolors
from Models.backend import baseball

def make_colormap(seq):
    """Return a LinearSegmentedColormap
    seq: a sequence of floats and RGB-tuples. The floats should be increasing
    and in the interval (0,1).
    """
    seq = [(None,) * 3, 0.0] + list(seq) + [1.0, (None,) * 3]
    cdict = {'red': [], 'green': [], 'blue': []}
    for i, item in enumerate(seq):
        if isinstance(item, float):
            r1, g1, b1 = seq[i - 1]
            r2, g2, b2 = seq[i + 1]
            cdict['red'].append([item, r1, r2])
            cdict['green'].append([item, g1, g2])
            cdict['blue'].append([item, b1, b2])
    return mcolors.LinearSegmentedColormap('CustomMap', cdict)

class strikeZone(object):
    def __init__(self,name):
        self.name = name
        self.strikezone = dict.fromkeys([1,2,3,4,5,6,7,8,9])
        self.zoneData = {}
    def updateStrikeZone(self,Zone, Zonedata):
        d = dict(zip(Zone,Zonedata))
        self.strikezone.update(d)
    def strikezoneData(self):
        return self.zoneData
    def visualize(self):

        c = mcolors.ColorConverter().to_rgb
        rvb = make_colormap([c('blue'), c('lightskyblue'), .20, c('lightsalmon'),c('salmon'), .30, c('salmon'),c('red')])

        StrikeZonex = [1,2,3]
        StrikeZoney = [-1.5,0,1.5]
        row1 = []
        row2 = []
        row3 = []
        for i in range(1,4):
            row1.append(self.strikezone.get(i))
        for i in range(4,7):
            row2.append(self.strikezone.get(i))
        for i in range(7,10):
            row3.append(self.strikezone.get(i))

        z = np.array([row1, row2, row3])
        fig, ax = plt.subplots()
        for i in range(len(StrikeZoney)):
            for j in range(len(StrikeZonex)):
                text = ax.text(j, i, z[i, j],
                               ha="center", va="center", color="black")

        im = ax.imshow(z,cmap = rvb)
        fig.tight_layout()

        plt.show()

max_stars_repo_name: Thexumaker/PyBaseball

max_issues_repo_name: Thexumaker/PyBaseball

max_forks_repo_name: Thexumaker/PyBaseball