# Path: hamaa/utils/np_utils.py
# def eval_numerical_gradient_array(f, x, df=None, verbose=False, h=1e-4):
#     it = np.nditer(x, flags=['multi_index'])
#     grad = np.zeros_like(x)
#     while not it.finished:
#         xi = it.multi_index
#         old_val = x[xi]
# 
#         x[xi] = old_val + h
#         y_top = f(x)
# 
#         x[xi] = old_val - h
#         y_bottom = f(x)
# 
#         if df is not None:
#             grad[xi] = np.sum((y_top - y_bottom) * df) / (2 * h)
#         else:
#             grad[xi] = np.sum(y_top - y_bottom) / (2 * h)
# 
#         if verbose:
#             print it.multi_index, grad[xi]
#         x[xi] = old_val
#         it.iternext()
# 
#     return grad
# 
# def sum_abs_err(u, v):
#     return np.sum(np.abs(u - v))


from hamaa.gates import *
from hamaa.layers import *
from hamaa.utils.np_utils import eval_numerical_gradient_array, sum_abs_err
    z = conv_layer.forward(x)
    d_z = z
    conv_layer.backward(d_z)
    d_w = conv_layer.grads[0]

    def w_forword(layer, xx, ww):
        layer.w = ww
        return layer.forward(xx)

    grad_w = eval_numerical_gradient_array(lambda t: w_forword(conv_layer, x, t), w, d_z)

    # print d_w
    # print grad_w
    print sum_abs_err(d_w, grad_w)


def check_MeanPooling2D():
    layer = MeanPooling2D(pooling_size=[2, 2], input_shape=(1, 6, 6))
    layer.build()

    x = np.arange(36).reshape(1, 1, 6, 6).astype(np.double)
    # print x

    z = layer.forward(x)
    d_z = z
    d_x = layer.backward(d_z)
    grad_x = eval_numerical_gradient_array(layer.forward, x, d_z)
    # print d_x
    # print grad_x


# Path: hamaa/utils/np_utils.py
# def eval_numerical_gradient_array(f, x, df=None, verbose=False, h=1e-4):
#     it = np.nditer(x, flags=['multi_index'])
#     grad = np.zeros_like(x)
#     while not it.finished:
#         xi = it.multi_index
#         old_val = x[xi]
# 
#         x[xi] = old_val + h
#         y_top = f(x)
# 
#         x[xi] = old_val - h
#         y_bottom = f(x)
# 
#         if df is not None:
#             grad[xi] = np.sum((y_top - y_bottom) * df) / (2 * h)
#         else:
#             grad[xi] = np.sum(y_top - y_bottom) / (2 * h)
# 
#         if verbose:
#             print it.multi_index, grad[xi]
#         x[xi] = old_val
#         it.iternext()
# 
#     return grad
# 
# def sum_abs_err(u, v):
#     return np.sum(np.abs(u - v))


# Path: hamaa/tests/check_gradient.py
from hamaa.gates import *
from hamaa.layers import *
from hamaa.utils.np_utils import eval_numerical_gradient_array, sum_abs_err

    z = conv_layer.forward(x)
    d_z = z
    conv_layer.backward(d_z)
    d_w = conv_layer.grads[0]

    def w_forword(layer, xx, ww):
        layer.w = ww
        return layer.forward(xx)

    grad_w = eval_numerical_gradient_array(lambda t: w_forword(conv_layer, x, t), w, d_z)

    # print d_w
    # print grad_w
    print sum_abs_err(d_w, grad_w)


def check_MeanPooling2D():
    layer = MeanPooling2D(pooling_size=[2, 2], input_shape=(1, 6, 6))
    layer.build()

    x = np.arange(36).reshape(1, 1, 6, 6).astype(np.double)
    # print x

    z = layer.forward(x)
    d_z = z
    d_x = layer.backward(d_z)
    grad_x = eval_numerical_gradient_array(layer.forward, x, d_z)
    # print d_x
    # print grad_x


    print sum_abs_err(d_x, grad_x)