3
Md                 @   sL   d Z ddlZddlmZ ddlmZmZmZm	Z	 dgZ
edd
d	dZdS )zFunction for computing Harmonic function algorithm by Zhu et al.

References
----------
Zhu, X., Ghahramani, Z., & Lafferty, J. (2003, August).
Semi-supervised learning using gaussian fields and harmonic functions.
In ICML (Vol. 3, pp. 912-919).
    N)not_implemented_for)_get_label_info_init_label_matrix
_propagate_predictharmonic_functionZdirected   labelc                 s4  yddl  W n, tk
r8 } ztd|W Y dd}~X nX yddlm W n, tk
rv } ztd|W Y dd}~X nX fdd} fdd	}tj| }t| |\}}|jd dkrtjd
| d |jd }	|jd }
t	|	|
}|||}||||
}|}x$|dkr$t
|||}|d8 }qW t||}|S )a+  Node classification by Harmonic function

    Parameters
    ----------
    G : NetworkX Graph
    max_iter : int
        maximum number of iterations allowed
    label_name : string
        name of target labels to predict

    Returns
    ----------
    predicted : array, shape = [n_samples]
        Array of predicted labels

    Raises
    ----------
    NetworkXError
        If no nodes on `G` has `label_name`.

    Examples
    --------
    >>> from networkx.algorithms import node_classification
    >>> G = nx.path_graph(4)
    >>> G.nodes[0]["label"] = "A"
    >>> G.nodes[3]["label"] = "B"
    >>> G.nodes(data=True)
    NodeDataView({0: {'label': 'A'}, 1: {}, 2: {}, 3: {'label': 'B'}})
    >>> G.edges()
    EdgeView([(0, 1), (1, 2), (2, 3)])
    >>> predicted = node_classification.harmonic_function(G)
    >>> predicted
    ['A', 'A', 'B', 'B']

    References
    ----------
    Zhu, X., Ghahramani, Z., & Lafferty, J. (2003, August).
    Semi-supervised learning using gaussian fields and harmonic functions.
    In ICML (Vol. 3, pp. 912-919).
    r   Nz6harmonic_function() requires numpy: http://numpy.org/ )sparsez6harmonic_function() requires scipy: http://scipy.org/ c                sV   | j ddjd }d||dk<  jd| dd}|j| j }d||dddf < |S )a  Build propagation matrix of Harmonic function

        Parameters
        ----------
        X : scipy sparse matrix, shape = [n_samples, n_samples]
            Adjacency matrix
        labels : array, shape = [n_samples, 2]
            Array of pairs of node id and label id

        Returns
        ----------
        P : scipy sparse matrix, shape = [n_samples, n_samples]
            Propagation matrix

        r   )Zaxis   g      ?)offsetsN)sumAZdiagsdotZtolil)XlabelsdegreesDP)r
    ]/var/www/html/virt/lib/python3.6/site-packages/networkx/algorithms/node_classification/hmn.py_build_propagation_matrixM   s    z4harmonic_function.<locals>._build_propagation_matrixc                s@   | j d } j||f}d||dddf |dddf f< |S )a  Build base matrix of Harmonic function

        Parameters
        ----------
        X : scipy sparse matrix, shape = [n_samples, n_samples]
            Adjacency matrix
        labels : array, shape = [n_samples, 2]
            Array of pairs of node id and label id
        n_classes : integer
            The number of classes (distinct labels) on the input graph

        Returns
        ----------
        B : array, shape = [n_samples, n_classes]
            Base matrix
        r   r   N)shapeZzeros)r   r   	n_classes	n_samplesB)npr   r   _build_base_matrixd   s    
$z-harmonic_function.<locals>._build_base_matrixz*No node on the input graph is labeled by 'z'.r   )ZnumpyImportErrorZscipyr
   nxZto_scipy_sparse_matrixr   r   ZNetworkXErrorr   r   r   )GZmax_iterZ
label_nameer   r   r   r   Z
label_dictr   r   Fr   r   Zremaining_iterZ	predictedr   )r   r
   r   r      s<    *





)r   r	   )__doc__Znetworkxr   Znetworkx.utils.decoratorsr   Z-networkx.algorithms.node_classification.utilsr   r   r   r   __all__r   r   r   r   r   <module>   s   