import numpy

import cupy
from cupy import core


def arange(start, stop=None, step=1, dtype=None):
    """Rerurns an array with evenly spaced values within a given interval.

    Values are generated within the half-open interval [start, stop). The first
    three arguments are mapped like the ``range`` built-in function, i.e. start
    and step are optional.

    Args:
        start: Start of the interval.
        stop: End of the interval.
        step: Step width between each pair of consecutive values.
        dtype: Data type specifier. It is inferred from other arguments by
            default.

    Returns:
        cupy.ndarray: The 1-D array of range values.

    .. seealso:: :func:`numpy.arange`

    """
    if dtype is None:
        if any(numpy.dtype(type(val)).kind == 'f'
               for val in (start, stop, step)):
            dtype = float
        else:
            dtype = int

    if stop is None:
        stop = start
        start = 0
    size = int(numpy.ceil((stop - start) / step))
    if size <= 0:
        return cupy.empty((0,), dtype=dtype)

    ret = cupy.empty((size,), dtype=dtype)
    typ = numpy.dtype(dtype).type
    _arange_ufunc(typ(start), typ(step), ret, dtype=dtype)
    return ret


def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None):
    """Returns an array with evenly-spaced values within a given interval.

    Instead of specifying the step width like :func:`cupy.arange`, this
    function requires the total number of elements specified.

    Args:
        start: Start of the interval.
        stop: End of the interval.
        num: Number of elements.
        endpoint (bool): If True, the stop value is included as the last
            element. Otherwise, the stop value is omitted.
        retstep (bool): If True, this function returns (array, step).
            Otherwise, it returns only the array.
        dtype: Data type specifier. It is inferred from the start and stop
            arguments by default.

    Returns:
        cupy.ndarray: The 1-D array of ranged values.

    """
    if num < 0:
        raise ValueError('linspace with num<0 is not supported')

    if dtype is None:
        # In actual implementation, only float is used
        dtype = float

    ret = cupy.empty((num,), dtype=dtype)
    if num == 0:
        step = float('nan')
    elif num == 1:
        ret.fill(start)
        step = float('nan')
    else:
        div = (num - 1) if endpoint else num
        step = float(stop - start) / div
        stop = float(stop)

        if step == 0.0:
            # for underflow
            _linspace_ufunc_underflow(start, stop - start, div, ret)
        else:
            _linspace_ufunc(start, step, ret)

        if endpoint:
            ret[-1] = stop

    if retstep:
        return ret, step
    else:
        return ret


# TODO(okuta): Implement logspace


# TODO(okuta): Implement meshgrid


# mgrid
# ogrid


_arange_ufunc = core.create_ufunc(
    'cupy_arange',
    ('bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L',
     'qq->q', 'QQ->Q', 'ee->e', 'ff->f', 'dd->d'),
    'out0 = in0 + i * in1')


_linspace_ufunc = core.create_ufunc(
    'cupy_linspace',
    ('dd->d',),
    'out0 = in0 + i * in1')

_linspace_ufunc_underflow = core.create_ufunc(
    'cupy_linspace',
    ('ddd->d',),
    'out0 = in0 + i * in1 / in2')

cupy/creation/ranges.py
import numpy

import cupy
from cupy import core


def arange(start, stop=None, step=1, dtype=None):
    """Rerurns an array with evenly spaced values within a given interval.

    Values are generated within the half-open interval [start, stop). The first
    three arguments are mapped like the ``range`` built-in function, i.e. start
    and step are optional.

    Args:
        start: Start of the interval.
        stop: End of the interval.
        step: Step width between each pair of consecutive values.
        dtype: Data type specifier. It is inferred from other arguments by
            default.

    Returns:
        cupy.ndarray: The 1-D array of range values.

    .. seealso:: :func:`numpy.arange`

    """
    if dtype is None:
        if any(numpy.dtype(type(val)).kind == 'f'
               for val in (start, stop, step)):
            dtype = float
        else:
            dtype = int

    if stop is None:
        stop = start
        start = 0
    size = int(numpy.ceil((stop - start) / step))
    if size <= 0:
        return cupy.empty((0,), dtype=dtype)

    ret = cupy.empty((size,), dtype=dtype)
    typ = numpy.dtype(dtype).type
    _arange_ufunc(typ(start), typ(step), ret, dtype=dtype)
    return ret


def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None):
    """Returns an array with evenly-spaced values within a given interval.

    Instead of specifying the step width like :func:`cupy.arange`, this
    function requires the total number of elements specified.

    Args:
        start: Start of the interval.
        stop: End of the interval.
        num: Number of elements.
        endpoint (bool): If True, the stop value is included as the last
            element. Otherwise, the stop value is omitted.
        retstep (bool): If True, this function returns (array, step).
            Otherwise, it returns only the array.
        dtype: Data type specifier. It is inferred from the start and stop
            arguments by default.

    Returns:
        cupy.ndarray: The 1-D array of ranged values.

    """
    if num < 0:
        raise ValueError('linspace with num<0 is not supported')

    if dtype is None:
        # In actual implementation, only float is used
        dtype = float

    ret = cupy.empty((num,), dtype=dtype)
    if num == 0:
        step = float('nan')
    elif num == 1:
        ret.fill(start)
        step = float('nan')
    else:
        div = (num - 1) if endpoint else num
        step = float(stop - start) / div
        stop = float(stop)

        if step == 0.0:
            # for underflow
            _linspace_ufunc_underflow(start, stop - start, div, ret,
                                      casting='unsafe')
        else:
            _linspace_ufunc(start, step, ret, casting='unsafe')

        if endpoint:
            ret[-1] = stop

    if retstep:
        return ret, step
    else:
        return ret


# TODO(okuta): Implement logspace


# TODO(okuta): Implement meshgrid


# mgrid
# ogrid


_arange_ufunc = core.create_ufunc(
    'cupy_arange',
    ('bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L',
     'qq->q', 'QQ->Q', 'ee->e', 'ff->f', 'dd->d'),
    'out0 = in0 + i * in1')


_linspace_ufunc = core.create_ufunc(
    'cupy_linspace',
    ('dd->d',),
    'out0 = in0 + i * in1')

_linspace_ufunc_underflow = core.create_ufunc(
    'cupy_linspace',
    ('ddd->d',),
    'out0 = in0 + i * in1 / in2')

cupy/creation/ranges.py
diff --git a/README.md b/README.md
index ecddea87c994..d6e5c03604b5 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ Chainer is tested on Ubuntu 14.04 and CentOS 7. We recommend them to use Chainer
 
 Minimum requirements:
 - Python 2.7.6+, 3.4.3+, 3.5.0+
-- NumPy 1.9
+- NumPy 1.9, 1.10
 - Six 1.9
 - h5py 2.5.0
 
diff --git a/cupy/core/core.pyx b/cupy/core/core.pyx
index 885db8f47f85..f9bdb33f81e5 100644
--- a/cupy/core/core.pyx
+++ b/cupy/core/core.pyx
@@ -1245,20 +1245,30 @@ include "reduction.pxi"
 
 cdef _id = 'out0 = in0'
 
-elementwise_copy = create_ufunc(
+_elementwise_copy = create_ufunc(
     'cupy_copy',
     ('?->?', 'b->b', 'B->B', 'h->h', 'H->H', 'i->i', 'I->I', 'l->l', 'L->L',
      'q->q', 'Q->Q', 'e->e', 'f->f', 'd->d'),
     _id)
 
 
-elementwise_copy_where = create_ufunc(
+def elementwise_copy(*args, **kwargs):
+    kwargs['casting'] = 'unsafe'
+    return _elementwise_copy(*args, **kwargs)
+
+
+_elementwise_copy_where = create_ufunc(
     'cupy_copy_where',
     ('??->?', 'b?->b', 'B?->B', 'h?->h', 'H?->H', 'i?->i', 'I?->I', 'l?->l',
      'L?->L', 'q?->q', 'Q?->Q', 'e?->e', 'f?->f', 'd?->d'),
     'if (in1) out0 = in0')
 
 
+def elementwise_copy_where(*args, **kwargs):
+    kwargs['casting'] = 'unsafe'
+    return _elementwise_copy_where(*args, **kwargs)
+
+
 cdef _divmod_float = '''
     out0_type a = _floor_divide(in0, in1);
     out0 = a;
diff --git a/cupy/core/elementwise.pxi b/cupy/core/elementwise.pxi
index 7f5609151ba1..878f6c5985de 100644
--- a/cupy/core/elementwise.pxi
+++ b/cupy/core/elementwise.pxi
@@ -341,16 +341,26 @@ cdef tuple _broadcast(list args, tuple params, bint use_size):
     return value, brod.shape
 
 
-cdef list _get_out_args(list out_args, tuple out_types, tuple out_shape):
+cdef list _get_out_args(list out_args, tuple out_types, tuple out_shape,
+                        str casting):
     if not out_args:
         return [ndarray(out_shape, t) for t in out_types]
 
-    for a in out_args:
+    for i, a in enumerate(out_args):
         if not isinstance(a, ndarray):
             raise TypeError(
                 'Output arguments type must be cupy.ndarray')
         if a.shape != out_shape:
             raise ValueError('Out shape is mismatched')
+        out_type = out_types[i]
+        if not numpy.can_cast(out_type, a.dtype, casting=casting):
+            msg = 'output (typecode \'{}\') could not be coerced to ' \
+                  'provided output parameter (typecode \'{}\') according to ' \
+                  'the casting rule "{}"'.format(
+                      numpy.dtype(out_type).char,
+                      a.dtype.char,
+                      casting)
+            raise TypeError(msg)
     return out_args
 
 
@@ -704,6 +714,8 @@ class ufunc(object):
 
         out = kwargs.pop('out', None)
         dtype = kwargs.pop('dtype', None)
+        # Note default behavie of casting is 'same_kind' on numpy>=1.10
+        casting = kwargs.pop('casting', 'same_kind')
         if dtype is not None:
             dtype = numpy.dtype(dtype).type
         if kwargs:
@@ -734,7 +746,7 @@ class ufunc(object):
         in_types, out_types, routine = _guess_routine(
             self.name, self._routine_cache, self._ops, in_args, dtype)
 
-        out_args = _get_out_args(out_args, out_types, shape)
+        out_args = _get_out_args(out_args, out_types, shape, casting)
         if self.nout == 1:
             ret = out_args[0]
         else:
diff --git a/cupy/core/reduction.pxi b/cupy/core/reduction.pxi
index 54262249a622..f23172739392 100644
--- a/cupy/core/reduction.pxi
+++ b/cupy/core/reduction.pxi
@@ -226,7 +226,7 @@ class simple_reduction_function(object):
 
         axis, raxis = _get_axis(axis, a.ndim)
         out_shape = _get_out_shape(a.shape, axis, raxis, keepdims)
-        out_args = _get_out_args(out_args, out_types, out_shape)
+        out_args = _get_out_args(out_args, out_types, out_shape, 'unsafe')
         if 0 in out_shape:
             if len(out_args) == 1:
                 return out_args[0]
diff --git a/cupy/creation/ranges.py b/cupy/creation/ranges.py
index 1575269e59c6..9c810d240b3e 100644
--- a/cupy/creation/ranges.py
+++ b/cupy/creation/ranges.py
@@ -85,9 +85,10 @@ def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None):
 
         if step == 0.0:
             # for underflow
-            _linspace_ufunc_underflow(start, stop - start, div, ret)
+            _linspace_ufunc_underflow(start, stop - start, div, ret,
+                                      casting='unsafe')
         else:
-            _linspace_ufunc(start, step, ret)
+            _linspace_ufunc(start, step, ret, casting='unsafe')
 
         if endpoint:
             ret[-1] = stop
diff --git a/tests/cupy_tests/core_tests/test_ndarray_elementwise_op.py b/tests/cupy_tests/core_tests/test_ndarray_elementwise_op.py
index afa9de70d4a9..98f33a7458cc 100644
--- a/tests/cupy_tests/core_tests/test_ndarray_elementwise_op.py
+++ b/tests/cupy_tests/core_tests/test_ndarray_elementwise_op.py
@@ -28,6 +28,7 @@ def test_add_scalar(self):
     def test_radd_scalar(self):
         self.check_array_scalar_op(operator.add, swap=True)
 
+    @testing.with_requires('numpy>=1.10')
     def test_iadd_scalar(self):
         self.check_array_scalar_op(operator.iadd)
 
@@ -37,6 +38,7 @@ def test_sub_scalar(self):
     def test_rsub_scalar(self):
         self.check_array_scalar_op(operator.sub, swap=True)
 
+    @testing.with_requires('numpy>=1.10')
     def test_isub_scalar(self):
         self.check_array_scalar_op(operator.isub)
 
@@ -46,6 +48,7 @@ def test_mul_scalar(self):
     def test_rmul_scalar(self):
         self.check_array_scalar_op(operator.mul, swap=True)
 
+    @testing.with_requires('numpy>=1.10')
     def test_imul_scalar(self):
         self.check_array_scalar_op(operator.imul)
 
@@ -57,6 +60,7 @@ def test_rtruediv_scalar(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_scalar_op(operator.truediv, swap=True)
 
+    @testing.with_requires('numpy>=1.10')
     def test_itruediv_scalar(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_scalar_op(operator.itruediv)
@@ -73,6 +77,7 @@ def test_rdiv_scalar(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_scalar_op(operator.div, swap=True)
 
+    @testing.with_requires('numpy>=1.10')
     def test_idiv_scalar(self):
         if six.PY3:
             return
@@ -87,6 +92,7 @@ def test_rfloordiv_scalar(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_scalar_op(operator.floordiv, swap=True)
 
+    @testing.with_requires('numpy>=1.10')
     def test_ifloordiv_scalar(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_scalar_op(operator.ifloordiv)
@@ -103,6 +109,7 @@ def check_ipow_scalar(self, xp, x_type, y_type):
         a = xp.array([[1, 2, 3], [4, 5, 6]], x_type)
         return operator.ipow(a, y_type(3))
 
+    @testing.with_requires('numpy>=1.10')
     def test_ipow_scalar(self):
         self.check_ipow_scalar()
 
@@ -150,18 +157,21 @@ def check_array_array_op(self, op, xp, x_type, y_type):
     def test_add_array(self):
         self.check_array_array_op(operator.add)
 
+    @testing.with_requires('numpy>=1.10')
     def test_iadd_array(self):
         self.check_array_array_op(operator.iadd)
 
     def test_sub_array(self):
         self.check_array_array_op(operator.sub)
 
+    @testing.with_requires('numpy>=1.10')
     def test_isub_array(self):
         self.check_array_array_op(operator.isub)
 
     def test_mul_array(self):
         self.check_array_array_op(operator.mul)
 
+    @testing.with_requires('numpy>=1.10')
     def test_imul_array(self):
         self.check_array_array_op(operator.imul)
 
@@ -169,6 +179,7 @@ def test_truediv_array(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_array_op(operator.truediv)
 
+    @testing.with_requires('numpy>=1.10')
     def test_itruediv_array(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_array_op(operator.itruediv)
@@ -179,6 +190,7 @@ def test_div_array(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_array_op(operator.div)
 
+    @testing.with_requires('numpy>=1.10')
     def test_idiv_array(self):
         if six.PY3:
             return
@@ -189,6 +201,7 @@ def test_floordiv_array(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_array_op(operator.floordiv)
 
+    @testing.with_requires('numpy>=1.10')
     def test_ifloordiv_array(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_array_op(operator.ifloordiv)
@@ -203,6 +216,7 @@ def check_ipow_array(self, xp, x_type, y_type):
         b = xp.array([[6, 5, 4], [3, 2, 1]], y_type)
         return operator.ipow(a, b)
 
+    @testing.with_requires('numpy>=1.10')
     def test_ipow_array(self):
         self.check_ipow_array()
 
@@ -242,18 +256,21 @@ def check_array_broadcasted_op(self, op, xp, x_type, y_type):
     def test_broadcasted_add(self):
         self.check_array_broadcasted_op(operator.add)
 
+    @testing.with_requires('numpy>=1.10')
     def test_broadcasted_iadd(self):
         self.check_array_broadcasted_op(operator.iadd)
 
     def test_broadcasted_sub(self):
         self.check_array_broadcasted_op(operator.sub)
 
+    @testing.with_requires('numpy>=1.10')
     def test_broadcasted_isub(self):
         self.check_array_broadcasted_op(operator.isub)
 
     def test_broadcasted_mul(self):
         self.check_array_broadcasted_op(operator.mul)
 
+    @testing.with_requires('numpy>=1.10')
     def test_broadcasted_imul(self):
         self.check_array_broadcasted_op(operator.imul)
 
@@ -261,6 +278,7 @@ def test_broadcasted_truediv(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_broadcasted_op(operator.truediv)
 
+    @testing.with_requires('numpy>=1.10')
     def test_broadcasted_itruediv(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_broadcasted_op(operator.itruediv)
@@ -271,6 +289,7 @@ def test_broadcasted_div(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_broadcasted_op(operator.div)
 
+    @testing.with_requires('numpy>=1.10')
     def test_broadcasted_idiv(self):
         if six.PY3:
             return
@@ -281,6 +300,7 @@ def test_broadcasted_floordiv(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_broadcasted_op(operator.floordiv)
 
+    @testing.with_requires('numpy>=1.10')
     def test_broadcasted_ifloordiv(self):
         with testing.NumpyError(divide='ignore'):
             self.check_array_broadcasted_op(operator.ifloordiv)
@@ -288,6 +308,7 @@ def test_broadcasted_ifloordiv(self):
     def test_broadcasted_pow(self):
         self.check_array_broadcasted_op(operator.pow)
 
+    @testing.with_requires('numpy>=1.10')
     @testing.for_all_dtypes_combination(names=['x_type', 'y_type'])
     @testing.numpy_cupy_allclose(atol=1.0)
     def check_broadcasted_ipow(self, xp, x_type, y_type):
@@ -295,6 +316,7 @@ def check_broadcasted_ipow(self, xp, x_type, y_type):
         b = xp.array([[1], [2]], y_type)
         return operator.ipow(a, b)
 
+    @testing.with_requires('numpy>=1.10')
     def test_broadcasted_ipow(self):
         self.check_broadcasted_ipow()
 
@@ -558,30 +580,35 @@ def check_array_array_op(self, op, xp, x_type, y_type):
     def test_lshift_array(self):
         self.check_array_array_op(operator.lshift)
 
+    @testing.with_requires('numpy>=1.10')
     def test_ilshift_array(self):
         self.check_array_array_op(operator.ilshift)
 
     def test_rshift_array(self):
         self.check_array_array_op(operator.rshift)
 
+    @testing.with_requires('numpy>=1.10')
     def test_irshift_array(self):
         self.check_array_array_op(operator.irshift)
 
     def test_and_array(self):
         self.check_array_array_op(operator.and_)
 
+    @testing.with_requires('numpy>=1.10')
     def test_iand_array(self):
         self.check_array_array_op(operator.iand)
 
     def test_or_array(self):
         self.check_array_array_op(operator.or_)
 
+    @testing.with_requires('numpy>=1.10')
     def test_ior_array(self):
         self.check_array_array_op(operator.ior)
 
     def test_xor_array(self):
         self.check_array_array_op(operator.xor)
 
+    @testing.with_requires('numpy>=1.10')
     def test_ixor_array(self):
         self.check_array_array_op(operator.ixor)
 
@@ -589,6 +616,7 @@ def test_mod_array(self):
         with testing.NumpyError(divide='ignore', invalid='ignore'):
             self.check_array_array_op(operator.mod)
 
+    @testing.with_requires('numpy>=1.10')
     def test_imod_array(self):
         with testing.NumpyError(divide='ignore', invalid='ignore'):
             self.check_array_array_op(operator.imod)
@@ -603,30 +631,35 @@ def check_array_broadcasted_op(self, op, xp, x_type, y_type):
     def test_broadcasted_lshift(self):
         self.check_array_broadcasted_op(operator.lshift)
 
+    @testing.with_requires('numpy>=1.10')
     def test_broadcasted_ilshift(self):
         self.check_array_broadcasted_op(operator.ilshift)
 
     def test_broadcasted_rshift(self):
         self.check_array_broadcasted_op(operator.rshift)
 
+    @testing.with_requires('numpy>=1.10')
     def test_broadcasted_irshift(self):
         self.check_array_broadcasted_op(operator.irshift)
 
     def test_broadcasted_and(self):
         self.check_array_broadcasted_op(operator.and_)
 
+    @testing.with_requires('numpy>=1.10')
     def test_broadcasted_iand(self):
         self.check_array_broadcasted_op(operator.iand)
 
     def test_broadcasted_or(self):
         self.check_array_broadcasted_op(operator.or_)
 
+    @testing.with_requires('numpy>=1.10')
     def test_broadcasted_ior(self):
         self.check_array_broadcasted_op(operator.ior)
 
     def test_broadcasted_xor(self):
         self.check_array_broadcasted_op(operator.xor)
 
+    @testing.with_requires('numpy>=1.10')
     def test_broadcasted_ixor(self):
         self.check_array_broadcasted_op(operator.ixor)
 
@@ -634,6 +667,7 @@ def test_broadcasted_mod(self):
         with testing.NumpyError(divide='ignore', invalid='ignore'):
             self.check_array_broadcasted_op(operator.mod)
 
+    @testing.with_requires('numpy>=1.10')
     def test_broadcasted_imod(self):
         with testing.NumpyError(divide='ignore', invalid='ignore'):
             self.check_array_broadcasted_op(operator.imod)

Support numpy 1.10
numpy 1.10.0 is released on 2015/10/07

https://pypi.python.org/pypi/numpy/1.10.0

