import unittest

import numpy

import chainer
from chainer import cuda
from chainer import gradient_check
from chainer.testing import attr
from chainer.testing import condition


if cuda.available:
    cuda.init()


class NumeraicalGradientTest(unittest.TestCase):

    def setUp(self):
        self.x = numpy.random.uniform(-1, 1, (2, 1)).astype(numpy.float32)
        self.gy = numpy.random.uniform(-1, 1, (2, 1)).astype(numpy.float32)
        self.f = lambda x: (x**2, )
        self.df = lambda x: (2*x, )

    def check_numerical_grad(self, f, df, x, dy):
        dx_expect, = tuple(d*dy for d in df(x))
        func = lambda: f(x)
        dx_actual, = gradient_check.numerical_grad(func, (x,), (dy,), eps=0.5)
        gradient_check.assert_allclose(dx_expect, dx_actual)

    @condition.retry(3)
    def test_numerical_grad_cpu(self):
        self.check_numerical_grad(self.f, self.df, self.x, self.gy)

    @condition.retry(3)
    @attr.gpu
    def test_numerical_grad_gpu(self):
        self.check_numerical_grad(self.f, self.df, cuda.to_gpu(self.x), cuda.to_gpu(self.gy))


@@ -259,16 +259,100 @@
 Case):%0A%0A
+    def _f(self, x):%0A        return x**2%0A%0A    def _df(self, x):%0A        return 2*x%0A%0A
     def 
@@ -356,32 +356,32 @@
 ef setUp(self):%0A
-
         self.x =
@@ -547,14 +547,19 @@
 x: (
-x**2, 
+self._f(x),
 )%0A  
@@ -589,13 +589,20 @@
 x: (
-2*x, 
+self._df(x),
 )%0A%0A 
@@ -798,17 +798,8 @@
 dy,)
-, eps=0.5
 )%0A  
@@ -1059,32 +1059,32 @@
 grad_gpu(self):%0A
-
         self.che
@@ -1162,8 +1162,346 @@
 f.gy))%0A%0A
+%0Aclass NumericalGradientTest2(NumeraicalGradientTest):%0A%0A    _f = lambda self, x: 1%0A    _df = lambda self, x: 0%0A%0A%0Aclass NumericalGradientTest3(NumeraicalGradientTest):%0A%0A    def _exp(self, x):%0A        if isinstance(x, numpy.ndarray):%0A            return numpy.exp(x)%0A        else:%0A            return cuda.cumath.exp(x)%0A%0A    _f = _df = _exp%0A%0A

Add more unittests for numerical_gradient