Source code for chainer.functions.math.trigonometric

import numpy

from chainer import cuda
from chainer import function
from chainer import utils
from chainer.utils import type_check


class Sin(function.Function):

    @property
    def label(self):
        return 'sin'

    def check_type_forward(self, in_types):
        type_check.expect(in_types.size() == 1)
        type_check.expect(in_types[0].dtype.kind == 'f')

    def forward(self, x):
        xp = cuda.get_array_module(*x)
        return utils.force_array(xp.sin(x[0])),

    def backward_cpu(self, x, gy):
        gx = utils.force_array(numpy.cos(x[0]))
        gx *= gy[0]
        return gx,

    def backward_gpu(self, x, gy):
        gx = cuda.elementwise(
            'T x, T gy', 'T gx', 'gx = cos(x) * gy', 'sin_bwd'
        )(x[0], gy[0])
        return gx,


[docs]def sin(x): """Elementwise sin function.""" return Sin()(x)
class Cos(function.Function): @property def label(self): return 'cos' def check_type_forward(self, in_types): type_check.expect(in_types.size() == 1) type_check.expect(in_types[0].dtype.kind == 'f') def forward(self, x): xp = cuda.get_array_module(*x) return utils.force_array(xp.cos(x[0])), def backward_cpu(self, x, gy): gx = utils.force_array(numpy.sin(x[0])) numpy.negative(gx, out=gx) gx *= gy[0] return gx, def backward_gpu(self, x, gy): gx = cuda.elementwise( 'T x, T gy', 'T gx', 'gx = -sin(x) * gy', 'cos_bwd' )(x[0], gy[0]) return gx,
[docs]def cos(x): """Elementwise cos function.""" return Cos()(x)
class Tan(function.Function): @property def label(self): return 'tan' def check_type_forward(self, in_types): type_check.expect(in_types.size() == 1) type_check.expect(in_types[0].dtype.kind == 'f') def forward(self, x): xp = cuda.get_array_module(*x) return utils.force_array(xp.tan(x[0])), def backward(self, x, gy): xp = cuda.get_array_module(*x) gx = utils.force_array(xp.cos(x[0])) xp.square(gx, out=gx) xp.reciprocal(gx, out=gx) gx *= gy[0] return gx,
[docs]def tan(x): """Elementwise tan function.""" return Tan()(x)
class Arcsin(function.Function): @property def label(self): return 'arcsin' def check_type_forward(self, in_types): type_check.expect(in_types.size() == 1) type_check.expect(in_types[0].dtype.kind == 'f') def forward(self, x): xp = cuda.get_array_module(*x) return utils.force_array(xp.arcsin(x[0])), def backward_cpu(self, x, gy): gx = utils.force_array(numpy.square(x[0])) numpy.negative(gx, out=gx) gx += 1 numpy.sqrt(gx, out=gx) numpy.reciprocal(gx, out=gx) gx *= gy[0] return gx, def backward_gpu(self, x, gy): gx = cuda.elementwise( 'T x, T gy', 'T gx', 'gx = rsqrt((T)1.0 - x * x) * gy', 'arcsin_bwd' )(x[0], gy[0]) return gx,
[docs]def arcsin(x): """Elementwise arcsine function. .. math:: y_i = \\arcsin x_i. Args: x (~chainer.Variable): Input variable. Returns: ~chainer.Variable: Output variable. """ return Arcsin()(x)
class Arccos(function.Function): @property def label(self): return 'arccos' def check_type_forward(self, in_types): type_check.expect(in_types.size() == 1) type_check.expect(in_types[0].dtype.kind == 'f') def forward(self, x): xp = cuda.get_array_module(*x) return utils.force_array(xp.arccos(x[0])), def backward_cpu(self, x, gy): gx = utils.force_array(numpy.square(x[0])) numpy.negative(gx, out=gx) gx += 1 numpy.sqrt(gx, out=gx) numpy.reciprocal(gx, out=gx) numpy.negative(gx, out=gx) gx *= gy[0] return gx, def backward_gpu(self, x, gy): gx = cuda.elementwise( 'T x, T gy', 'T gx', 'gx = -rsqrt((T)1.0 - x * x) * gy', 'arccos_bwd' )(x[0], gy[0]) return gx,
[docs]def arccos(x): """Elementwise arccosine function. .. math:: y_i = \\arccos x_i. Args: x (~chainer.Variable): Input variable. Returns: ~chainer.Variable: Output variable. """ return Arccos()(x)
class Arctan(function.Function): @property def label(self): return 'arctan' def check_type_forward(self, in_types): type_check.expect(in_types.size() == 1) type_check.expect(in_types[0].dtype.kind == 'f') def forward(self, x): xp = cuda.get_array_module(*x) return utils.force_array(xp.arctan(x[0])), def backward_cpu(self, x, gy): gx = utils.force_array(numpy.square(x[0])) gx += 1 numpy.reciprocal(gx, out=gx) gx *= gy[0] return gx, def backward_gpu(self, x, gy): gx = cuda.elementwise( 'T x, T gy', 'T gx', 'gx = (T)1.0 / ((T)1.0 + x * x) * gy', 'arctan_bwd' )(x[0], gy[0]) return gx,
[docs]def arctan(x): """Elementwise arctangent function. .. math:: y_i = \\arctan x_i. Args: x (~chainer.Variable): Input variable. Returns: ~chainer.Variable: Output variable. """ return Arctan()(x)