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
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)
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)
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)
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)}.' )
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()
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)