提交 0c03f47d authored 作者: Frederic's avatar Frederic

Add ceil_int_div with associated tests.

上级 4c3aa369
...@@ -2822,6 +2822,14 @@ def int_div(a, b): ...@@ -2822,6 +2822,14 @@ def int_div(a, b):
"""elementwise integer-division""" """elementwise integer-division"""
# see decorator for function body # see decorator for function body
def ceil_intdiv(a, b):
""" return ceil(a/b) when a and b are int """
# Is it faster to cast to float when this don't loose precission?
# return cast(cast(a, scalar.upcast(a, 'float32')) / b, scal.upcast(a, b))
return int_div(a, b) + neq(a % b, 0)
def mod_check(x, y): def mod_check(x, y):
"""Make sure we do not try to use complex numbers.""" """Make sure we do not try to use complex numbers."""
if (as_tensor_variable(x).dtype in complex_dtypes or if (as_tensor_variable(x).dtype in complex_dtypes or
......
...@@ -541,31 +541,37 @@ MulInplaceTester = makeBroadcastTester(op = inplace.mul_inplace, ...@@ -541,31 +541,37 @@ MulInplaceTester = makeBroadcastTester(op = inplace.mul_inplace,
grad = _grad_broadcast_binary_normal, grad = _grad_broadcast_binary_normal,
inplace = True) inplace = True)
_good_broadcast_div_mod_normal_float_inplace = dict(same_shapes = (rand(2, 3), rand(2, 3)), # We can't have both input as interger as we need the output
scalar = (rand(2, 3), rand(1, 1)), # to have the same dtype to work inplace.
row = (rand(2, 3), rand(1, 3)), _good_broadcast_div_mod_normal_float_no_complex = dict(
column = (rand(2, 3), rand(2, 1)), same_shapes=(rand(2, 3), rand(2, 3)),
dtype_mixup_1 = (rand(2, 3), randint_nonzero(2, 3)), scalar=(rand(2, 3), rand(1, 1)),
dtype_mixup_2 = (randint_nonzero(2, 3), rand(2, 3)), row=(rand(2, 3), rand(1, 3)),
#integers_positive = (randint_ranged(4, 10, (2, 3)), randint_ranged(1, 6, (2, 3))), column=(rand(2, 3), rand(2, 1)),
#integers_known_to_fail = (numpy.array(-1), numpy.array(5)) dtype_mixup_1=(rand(2, 3), randint_nonzero(2, 3)),
complex1 = (randcomplex(2,3),randcomplex(2,3)), dtype_mixup_2=(randint_nonzero(2, 3), rand(2, 3)),
complex2 = (randcomplex(2,3),rand(2,3)), #empty2=(numpy.asarray([0]), numpy.asarray([])),
#complex3 = (rand(2,3),randcomplex(2,3)),# Inplace on the first element. Must have the same type. )
empty1 = (numpy.asarray([]), numpy.asarray([1])), _good_broadcast_div_mod_normal_float_inplace = dict(
#empty2 = (numpy.asarray([0]), numpy.asarray([])), empty1=(numpy.asarray([]), numpy.asarray([1])),
complex1=(randcomplex(2, 3), randcomplex(2, 3)),
complex2=(randcomplex(2, 3), rand(2, 3)),
# Inplace on the first element. Must have the same type.
#complex3=(rand(2, 3) ,randcomplex(2, 3)),
**_good_broadcast_div_mod_normal_float_no_complex
) )
_good_broadcast_div_mod_normal_float = dict(empty2 = (numpy.asarray([0]), numpy.asarray([])), _good_broadcast_div_mod_normal_float = dict(empty2 = (numpy.asarray([0]), numpy.asarray([])),
**_good_broadcast_div_mod_normal_float_inplace **_good_broadcast_div_mod_normal_float_inplace
) )
def no_complex(d): def no_complex(d):
"""Remove pairs from dictionary d when the value contains complex data.""" """Remove pairs from dictionary d when the value contains complex data."""
return dict((k, v) for k, v in d.iteritems() return dict((k, v) for k, v in d.iteritems()
if all(str(x.dtype) not in tensor.complex_dtypes for x in v)) if all(str(x.dtype) not in tensor.complex_dtypes for x in v))
# 'No-complex' versions. # 'No-complex' versions, with empty2
_good_broadcast_div_mod_normal_float_no_complex = no_complex( _good_broadcast_div_mod_normal_float_no_complex2 = no_complex(
_good_broadcast_div_mod_normal_float) _good_broadcast_div_mod_normal_float)
_good_broadcast_div_mod_normal_float_inplace_no_complex = no_complex( _good_broadcast_div_mod_normal_float_inplace_no_complex = no_complex(
_good_broadcast_div_mod_normal_float_inplace) _good_broadcast_div_mod_normal_float_inplace)
...@@ -605,9 +611,20 @@ TrueDivInplaceTester = makeBroadcastTester(op = inplace.true_div_inplace, ...@@ -605,9 +611,20 @@ TrueDivInplaceTester = makeBroadcastTester(op = inplace.true_div_inplace,
grad_rtol=div_grad_rtol, grad_rtol=div_grad_rtol,
inplace = True) inplace = True)
CeilIntDivTester = makeBroadcastTester(
op=tensor.ceil_intdiv,
expected=lambda x, y: check_floatX((x, y), (x // y) + ((x % y) != 0)),
good=_good_broadcast_div_mod_normal_float_no_complex,
# As we implement this function with neq, the gradient returned is always 0.
# grad=_grad_broadcast_div_mod_normal,
# grad_rtol=div_grad_rtol,
)
ModTester = makeBroadcastTester(op = tensor.mod, ModTester = makeBroadcastTester(op = tensor.mod,
expected = lambda x, y: numpy.asarray(x % y, dtype=theano.scalar.basic.upcast(x.dtype, y.dtype)), expected = lambda x, y: numpy.asarray(x % y, dtype=theano.scalar.basic.upcast(x.dtype, y.dtype)),
good = _good_broadcast_div_mod_normal_float_no_complex, good = _good_broadcast_div_mod_normal_float_no_complex2,
# integers = (randint(2, 3), randint_nonzero(2, 3)), # integers = (randint(2, 3), randint_nonzero(2, 3)),
# dtype_mixup_1 = (rand(2, 3), randint_nonzero(2, 3)), # dtype_mixup_1 = (rand(2, 3), randint_nonzero(2, 3)),
# dtype_mixup_2 = (randint_nonzero(2, 3), rand(2, 3))), # dtype_mixup_2 = (randint_nonzero(2, 3), rand(2, 3))),
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论