1from chainer import backend
2from chainer import function_node
3from chainer import utils
4from chainer.utils import type_check
5
6
7class Cosh(function_node.FunctionNode):
8
9    @property
10    def label(self):
11        return 'cosh'
12
13    def check_type_forward(self, in_types):
14        type_check._argname(in_types, ('x',))
15        type_check.expect(in_types[0].dtype.kind == 'f')
16
17    def forward(self, x):
18        self.retain_inputs((0,))
19        xp = backend.get_array_module(*x)
20        return utils.force_array(xp.cosh(x[0])),
21
22    def backward(self, indexes, gy):
23        x = self.get_retained_inputs()
24        gx = sinh(x[0])
25        gx *= gy[0]
26        return gx,
27
28
29def cosh(x):
30    """Elementwise hyperbolic cosine function.
31
32    .. math::
33       y_i = \\cosh x_i.
34
35    Args:
36        x (:class:`~chainer.Variable` or :ref:`ndarray`): Input variable.
37
38    Returns:
39        ~chainer.Variable: Output variable.
40    """
41    return Cosh().apply((x,))[0]
42
43
44class Sinh(function_node.FunctionNode):
45
46    @property
47    def label(self):
48        return 'sinh'
49
50    def check_type_forward(self, in_types):
51        type_check._argname(in_types, ('x',))
52        type_check.expect(in_types[0].dtype.kind == 'f')
53
54    def forward(self, x):
55        self.retain_inputs((0,))
56        xp = backend.get_array_module(*x)
57        return utils.force_array(xp.sinh(x[0])),
58
59    def backward(self, x, gy):
60        x = self.get_retained_inputs()
61        gx = cosh(x[0])
62        gx *= gy[0]
63        return gx,
64
65
66def sinh(x):
67    """Elementwise hyperbolic sine function.
68
69    .. math::
70       y_i = \\sinh x_i.
71
72    Args:
73        x (:class:`~chainer.Variable` or :ref:`ndarray`): Input variable.
74
75    Returns:
76        ~chainer.Variable: Output variable.
77    """
78    return Sinh().apply((x,))[0]
79