def gradient(t, dim='all', bounds=None): """ Compute the gradient of a tensor. :param t: a :class:`Tensor` :param dim: an integer (or list of integers). Default is all :param bounds: a pair (or list of pairs) of reals, or None. The bounds for each variable :return: a :class:`Tensor` (or a list thereof) """ if t.batch: raise ValueError('Batched tensors are not supproted.') if dim == 'all': dim = range(t.dim()) if bounds is None: bounds = [[0, t.shape[d]] for d in dim] if not hasattr(bounds, '__len__'): bounds = [bounds]*len(dim) if not hasattr(dim, '__len__'): return tn.partial(t, dim, bounds) else: return [tn.partial(t, d, order=1, bounds=b) for d, b in zip(dim, bounds)]
def curl(ts, bounds=None): """ Compute the curl of a 3D vector field. :param ts: three 3D tensors encoding the :math:`x, y, z` vector coordinates respectively :param bounds: :return: three tensors of the same shape """ assert [t.dim() == 3 for t in ts] assert len(ts) == 3 if bounds is None: bounds = [None for n in range(3)] elif not hasattr(bounds[0], '__len__'): bounds = [bounds for n in range(3)] assert len(bounds) == 3 return [ tn.partial(ts[2], 1, bounds=bounds[1]) - tn.partial(ts[1], 2, bounds=bounds[2]), tn.partial(ts[0], 2, bounds=bounds[2]) - tn.partial(ts[2], 0, bounds=bounds[0]), tn.partial(ts[1], 0, bounds=bounds[0]) - tn.partial(ts[0], 1, bounds=bounds[1]) ]
def laplacian(t, bounds=None): """ Computes the Laplacian of a scalar field. :param t: a :class:`Tensor` :param bounds: :return: a :class:`Tensor` """ if bounds is None: bounds = [None]*t.dim() elif not hasattr(bounds[0], '__len__'): bounds = [bounds for n in range(t.dim())] assert len(bounds) == t.dim() return sum([tn.partial(t, n, order=2, bounds=bounds[n]) for n in range(t.dim())])
def divergence(ts, bounds=None): """ Computes the divergence (scalar field) out of a vector field encoded in a tensor. :param ts: an ND vector field, encoded as a list of N ND tensors :param bounds: :return: a scalar field """ assert ts[0].dim() == len(ts) assert all([t.shape == ts[0].shape for t in ts[1:]]) if bounds is None: bounds = [None]*len(ts) elif not hasattr(bounds[0], '__len__'): bounds = [bounds for n in range(len(ts))] assert len(bounds) == len(ts) return sum([tn.partial(ts[n], n, order=1, bounds=bounds[n]) for n in range(len(ts))])