# Source code for tensorplay.special._elementwise Source: https://www.tensorplay.cn/docs/_modules/tensorplay/special/_elementwise.html ``` """Pointwise transforms and the normalized-exponential reductions.""" import operator import tensorplay as tp from tensorplay import exp, exp2, expm1, log, log1p, sinc __all__ = [ "exp2", "expm1", "log1p", "log_softmax", "logsumexp", "round", "sinc", "softmax", ] def _normalize_dims(dim, ndim): if dim is None: return list(range(ndim)) if isinstance(dim, bool): raise TypeError("dim must be an integer or a sequence of integers") try: dims = [operator.index(dim)] except TypeError: try: dims = [] for value in dim: if isinstance(value, bool): raise TypeError("dim must contain integers") dims.append(operator.index(value)) except TypeError as error: raise TypeError("dim must be an integer or a sequence of integers") from error result = [] for value in dims: if ndim <= 0: raise ValueError("a reduction dimension requires a non-empty input") value = value + ndim if value < 0 else value if value < 0 or value >= ndim: raise ValueError(f"dimension {value} out of range for {ndim}-D input") if value in result: raise ValueError("reduction dimensions must be unique") result.append(value) return result def _copy_to_out(result, out): if out is None: return result if out.dtype != result.dtype: raise TypeError( f"out has dtype {out.dtype}, but the result has dtype {result.dtype}" ) if out.device != result.device: raise RuntimeError( f"out is on {out.device}, but the result is on {result.device}" ) if tuple(out.shape) != tuple(result.shape): out.resize_(result.shape) out.copy_(result) return out [docs] def round(input): """Rounds to nearest even integer (native ``Tensor.round``).""" return input.round() [docs] def softmax(input, dim=None, *, dtype=None): """Normalized exponential along :attr:`dim` (default: the last dim).""" from tensorplay.nn.functional import softmax as _sm return _sm(input, dim=dim if dim is not None else -1, dtype=dtype) [docs] def log_softmax(input, dim=None, *, dtype=None): """``log(softmax(input, dim))``, evaluated without the intermediate exp.""" from tensorplay.nn.functional import log_softmax as _ls return _ls(input, dim=dim if dim is not None else -1, dtype=dtype) [docs] def logsumexp(input, dim=None, keepdim=False, *, out=None): """Log-sum-exp along :attr:`dim`, computed with the max-shift trick.""" dims = _normalize_dims(dim, input.dim()) if not dims: return _copy_to_out(input, out) reduce_all = dim is None work = input.reshape([-1]) if reduce_all else input reduce_dims = [0] if reduce_all else dims m = tp.amax(work, dim=reduce_dims, keepdim=True) safe_m = tp.where(tp.isinf(m), tp.zeros_like(m), m) s = (exp(work - safe_m)).sum(dim=reduce_dims, keepdim=True) lse = log(s) + m lse = tp.where(tp.isposinf(m), m, lse) if reduce_all: lse = lse.reshape([1] * input.dim() if keepdim else []) elif not keepdim: lse = lse.reshape( [size for i, size in enumerate(lse.shape) if i not in dims] ) return _copy_to_out(lse, out) ```