예제 #1
0
        def wrapper(*args, **kwargs) -> Any:
            if len(args) == 1 and is_list_like(args[0]):
                args, = args

            outputs = cal_outpus(func, args, kwargs,
                                 type_check=self.type_check)
            if outputs is not None and is_list_like(outputs) and len(outputs) == 1:
                outputs, = outputs
            return outputs
예제 #2
0
def cal_outpus(func: Callable, args: List, kwargs: Dict,
               type_check: bool = True):

    if is_list_like(args) and not is_scalar_like(args[0]):
        if type_check:
            assert_same_type(*args)
        return tuple(cal_outpus(func, arg, kwargs, type_check=type_check) for arg in args)

    return func(args, **kwargs)
예제 #3
0
def normalize_adj(adj_matrix, rate=-0.5, fill_weight=1.0):
    """Normalize adjacency matrix.

    >>> normalize_adj(adj, rate=-0.5) # return a normalized adjacency matrix

    # return a list of normalized adjacency matrices
    >>> normalize_adj(adj, rate=[-0.5, 1.0]) 

    Parameters
    ----------
        adj_matrix: Scipy matrix or Numpy array or a list of them 
            Single or a list of Scipy sparse matrices or Numpy arrays.
        rate: Single or a list of float scale, optional.
            the normalize rate for `adj_matrix`.
        fill_weight: float scalar, optional.
            weight of self loops for the adjacency matrix.

    Returns
    ----------
        Single or a list of Scipy sparse matrix or Numpy matrices.

    See also
    ----------
        graphgallery.transforms.NormalizeAdj          

    """
    def _normalize_adj(adj, r):

        # here a new copy of adj is created
        if fill_weight:
            adj = adj + fill_weight * sp.eye(adj.shape[0], dtype=adj.dtype)
        else:
            adj = adj.copy()

        if r is None:
            return adj

        degree = adj.sum(1).A1
        degree_power = np.power(degree, r)
        
        if sp.isspmatrix(adj):
            adj = adj.tocoo(copy=False)
            adj.data = degree_power[adj.row] * adj.data * degree_power[adj.col]
            adj = adj.tocsr(copy=False)
        else:
            degree_power_matrix = sp.diags(degree_power)
            adj = degree_power_matrix @ adj @ degree_power_matrix
            adj = adj.A
        return adj

    if is_list_like(rate):
        return tuple(_normalize_adj(adj_matrix, r) for r in rate)
    else:
        return _normalize_adj(adj_matrix, rate)
예제 #4
0
def astensor(x, dtype=None, device=None):
    """Convert input matrices to Tensor or SparseTensor.

    Parameters:
    ----------
    x: tf.Tensor, tf.Variable, Scipy sparse matrix, 
        Numpy array-like, etc.

    dtype: The type of Tensor `x`, if not specified,
        it will automatically using appropriate data type.
        See `graphgallery.infer_type`.

    device (:class:`torch.device`, optional): the desired device of returned tensor.
        Default: if ``None``, uses the current device for the default tensor type
        (see :func:`torch.set_default_tensor_type`). :attr:`device` will be the CPU
        for CPU tensor types and the current CUDA device for CUDA tensor types.

    Returns:
    ----------      
    Tensor or SparseTensor with dtype:       
        1. `graphgallery.floatx()` if `x` is floating
        2. `graphgallery.intx() ` if `x` is integer
        3. `'bool'` if `x` is bool.
    """
    if x is None:
        return x

    if dtype is None:
        dtype = infer_type(x)
    elif isinstance(dtype, str):
        ...
        # TODO
    elif isinstance(dtype, torch.dtype):
        dtype = str(dtype).split('.')[-1]
    else:
        raise TypeError(
            f"argument 'dtype' must be torch.dtype or str, not {type(dtype).__name__}."
        )

    if is_th_tensor(x):
        tensor = x.to(getattr(torch, dtype))
    elif sp.isspmatrix(x):
        tensor = sparse_adj_to_sparse_tensor(x, dtype=dtype)
    elif isinstance(
            x,
        (np.ndarray, np.matrix)) or is_list_like(x) or is_scalar_like(x):
        tensor = torch.tensor(x, dtype=getattr(torch, dtype), device=device)
    else:
        raise TypeError(
            f'Invalid type of inputs data. Allowed data type `(Tensor, SparseTensor, Numpy array, Scipy sparse tensor, None)`, but got {type(x)}.'
        )

    return tensor.to(device)
예제 #5
0
def astensor(x, *, dtype=None, device=None):
    """Convert input matrices to Tensor or SparseTensor.

    Parameters:
    ----------
    x: any python object

    dtype: The type of Tensor `x`, if not specified,
        it will automatically use appropriate data type.
        See `graphgallery.infer_type`.
        
    device (:class:`tf.device`, optional): the desired device of returned tensor.
        Default: if ``None``, uses the current device for the default tensor type.

    Returns:
    ----------      
    Tensor(s) or SparseTensor(s) with dtype, if dtype is `None`:       
        1. `graphgallery.floatx()` if `x` is floating
        2. `graphgallery.intx() ` if `x` is integer
        3. `'bool'` if `x` is bool.
    """

    if x is None:
        return x

    if dtype is None:
        dtype = infer_type(x)
    elif isinstance(dtype, str):
        ...
        # TODO
    elif isinstance(dtype, tf.dtypes.DType):
        dtype = dtype.name
    else:
        raise TypeError(
            f"argument 'dtype' must be tensorflow.dtypes.DType or str, not {type(dtype).__name__}."
        )

    with tf.device(device):
        if is_tensor(x, kind="T"):
            if x.dtype != dtype:
                x = tf.cast(x, dtype=dtype)
            return x
        elif sp.isspmatrix(x):
            return sparse_adj_to_sparse_tensor(x, dtype=dtype)
        elif isinstance(
                x,
            (np.ndarray, np.matrix)) or is_list_like(x) or is_scalar_like(x):
            return tf.convert_to_tensor(x, dtype=dtype)
        else:
            raise TypeError(
                f'Invalid type of inputs data. Allowed data type `(Tensor, SparseTensor, Numpy array, Scipy sparse tensor, None)`, but got {type(x)}.'
            )
예제 #6
0
def get(transform: Union[str, Transform, None, List, Tuple,
                         Compose]) -> Transform:
    if is_list_like(transform):
        return Compose(*transform)

    if isinstance(transform, Transform) or callable(transform):
        return transform
    elif transform is None:
        return NullTransform()
    _transform = str(transform).lower()
    _transform = _TRANSFORMER.get(_transform, None)
    if _transform is None:
        raise ValueError(
            f"Unknown transform: '{transform}', expected one of {_ALLOWED}, None or a callable function."
        )
    return _transform()
예제 #7
0
def add_selfloops(adj_matrix, fill_weight: float = 1.0):
    """Normalize adjacency matrix.

    >>> add_selfloops(adj, fill_weight=1.0) # return a normalized adjacency matrix

    # return a list of normalized adjacency matrices
    >>> add_selfloops(adj, adj, fill_weight=[1.0, 2.0]) 

    Parameters
    ----------
        adj_matrix: Scipy matrix or Numpy array or a list of them 
            Single or a list of Scipy sparse matrices or Numpy arrays.
        fill_weight: float scalar, optional.
            weight of self loops for the adjacency matrix.

    Returns
    ----------
        Single or a list of Scipy sparse matrix or Numpy matrices.

    See also
    ----------
        graphgallery.transforms.AddSelfLoops          

    """
    def _add_selfloops(adj, w):

        # here a new copy of adj is created
        if w:
            return adj + w * sp.eye(adj.shape[0], dtype=adj.dtype)
        else:
            return adj.copy()

    if is_list_like(fill_weight):
        return tuple(_add_selfloops(adj_matrix, w) for w in fill_weight)
    else:
        return _add_selfloops(adj_matrix, fill_weight)