Example #1
0
def full_like(a, fill_value, dtype=None, order='K', subok=False, shape=None):
    """Returns a full array with the same shape and type as a given array.

    Parameters
    ----------
    a : array_like
        The shape and dtype of *a* define these same attributes of the returned array.
    fill_value : scalar
        Fill value.
    dtype : dtype, optional
        Overrides the data type of the result.
    order : {'C', 'F', 'A', or 'K'}, optional
        Overrides the memory layout of the result. 'C' means C-order, 'F' means F-order,
        'A' means 'F' if *a* is Fortran contiguous, 'C' otherwise. 'K' means match the
        layout of *a* as closely as possible.
    subok : bool, optional
        Not implemented.
    shape : int or sequence of ints, optional
        Overrides the shape of the result. If order='K' and the number of dimensions is
        unchanged, will try to keep order, otherwise, order='C' is implied.

    Returns
    -------
    out : ndarray
        Array of *fill_value* with the same shape and type as *a*.

    See Also
    --------
    empty_like : Returns a new array with the same shape
        and type as a given array.
    ones_like : Returns an array of ones with the same shape
        and type as a given array.
    zeros_like : Returns an array of zeros with the same shape
        and type as a given array.
    full : Returns a new array of given shape and type,
        filled with fill_value.

    Examples
    --------
    >>> import nlcpy as vp
    >>> x = vp.arange(6, dtype=int)
    >>> vp.full_like(x, 1)
    array([1, 1, 1, 1, 1, 1])
    >>> vp.full_like(x, 0.1)
    array([0, 0, 0, 0, 0, 0])
    >>> vp.full_like(x, 0.1, dtype=vp.double)
    array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1])
    >>> vp.full_like(x, vp.nan, dtype=vp.double)
    array([nan, nan, nan, nan, nan, nan])
    >>> y = vp.arange(6, dtype=vp.double)
    >>> vp.full_like(y, 0.1)
    array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1])

    """
    if subok is not False:
        raise NotImplementedError('subok in full_like is not implemented yet.')

    a = nlcpy.asanyarray(a)
    if shape is None:
        shape = a.shape
    if dtype is None:
        dtype = a.dtype
    else:
        dtype = nlcpy.dtype(dtype)

    if numpy.dtype(dtype).kind == 'V':
        raise NotImplementedError(
            'void dtype in full_like is not implemented yet.')

    if order is None or order in 'kKaA':
        if a._f_contiguous and not a._c_contiguous:
            order = 'F'
        else:
            order = 'C'

    if numpy.isscalar(fill_value):
        if numpy.iscomplex(fill_value):
            if dtype in ('complex64', 'complex128'):
                pass
            else:
                fill_value = numpy.real(fill_value)
                warnings.warn(
                    'Casting complex values to real discards the imaginary part',
                    numpy.ComplexWarning,
                    stacklevel=2)
        out = nlcpy.ndarray(shape=shape, dtype=dtype, order=order)
        out.fill(fill_value)

    elif fill_value is None:
        raise NotImplementedError('fill_value in nlcpy.full_like is None')

    else:
        fill_value = nlcpy.asarray(fill_value)
        out = nlcpy.array(nlcpy.broadcast_to(fill_value, shape=shape),
                          dtype=dtype,
                          order=order)

    return out
Example #2
0
def insert(arr, obj, values, axis=None):
    """Inserts values along the given axis before the given indices.

    Parameters
    ----------
    arr : array_like
        Input array.
    obj : int, slice or sequence of ints
        Object that defines the index or indices before which values is inserted.
        Support for multiple insertions when obj is a single scalar or a sequence
        with one element (similar to calling insert multiple times).
    values : array_like
        Values to insert into arr. If the type of values is different from that of
        arr, values is converted to the type of arr. values should be shaped so that
        arr[...,obj,...] = values is legal.
    axis : int, optional
        Axis along which to insert values. If axis is None then arr is flattened
        first.

    Returns
    -------
    out : ndarray
        A copy of arr with values inserted. Note that insert does not occur in-place:
        a new array is returned. If axis is None, out is a flattened array.

    Note:
        Note that for higher dimensional inserts obj=0 behaves very different from
        obj=[0] just like arr[:,0,:] = values is different from arr[:,[0],:] = values.

    See Also
    --------
    append : Appends values to the end of an array.
    concatenate : Joins a sequence of arrays along an existing axis.
    delete : Returns a new array with sub-arrays along an axis deleted.

    Examples
    --------
    >>> import nlcpy as vp
    >>> from nlcpy import testing
    >>> a = vp.array([[1, 1], [2, 2], [3, 3]])
    >>> a
    array([[1, 1],
           [2, 2],
           [3, 3]])
    >>> vp.insert(a, 1, 5)
    array([1, 5, 1, 2, 2, 3, 3])
    >>> vp.insert(a, 1, 5, axis=1)
    array([[1, 5, 1],
           [2, 5, 2],
           [3, 5, 3]])

    Difference between sequence and scalars:

    >>> vp.insert(a, [1], [[1],[2],[3]], axis=1)
    array([[1, 1, 1],
           [2, 2, 2],
           [3, 3, 3]])
    >>> vp.testing.assert_array_equal(
    ...                vp.insert(a, 1, [1, 2, 3], axis=1),
    ...                vp.insert(a, [1], [[1],[2],[3]], axis=1))
    >>> b = a.flatten()
    >>> b
    array([1, 1, 2, 2, 3, 3])
    >>> vp.insert(b, [2, 2], [5, 6])
    array([1, 1, 5, 6, 2, 2, 3, 3])
    >>> vp.insert(b, slice(2, 4), [5, 6])
    array([1, 1, 5, 2, 6, 2, 3, 3])
    >>> vp.insert(b, [2, 2], [7.13, False]) # type casting
    array([1, 1, 7, 0, 2, 2, 3, 3])
    >>> x = vp.arange(8).reshape(2, 4)
    >>> idx = (1, 3)
    >>> vp.insert(x, idx, 999, axis=1)
    array([[  0, 999,   1,   2, 999,   3],
           [  4, 999,   5,   6, 999,   7]])

    """
    a = nlcpy.asarray(arr)
    if axis is None:
        if a.ndim != 1:
            a = a.ravel()
        axis = 0
    elif isinstance(axis, nlcpy.ndarray) or isinstance(axis, numpy.ndarray):
        axis = int(axis)
    elif not isinstance(axis, int):
        raise TypeError("an integer is required "
                        "(got type {0})".format(type(axis).__name__))

    if axis < -a.ndim or axis >= a.ndim:
        raise nlcpy.AxisError(
            "axis {0} is out of bounds for array of dimension {1}".format(axis, a.ndim))

    if axis < 0:
        axis += a.ndim

    if type(obj) is slice:
        start, stop, step = obj.indices(a.shape[axis])
        obj = nlcpy.arange(start, stop, step)
    else:
        obj = nlcpy.array(obj)
        if obj.dtype.char == '?':
            warnings.warn(
                "in the future insert will treat boolean arrays and "
                "array-likes as a boolean index instead of casting it to "
                "integer", FutureWarning, stacklevel=3)
        elif obj.dtype.char in 'fdFD':
            if obj.size == 1:
                raise TypeError(
                    "slice indices must be integers or "
                    "None or have an __index__ method")
            elif obj.size > 0:
                raise IndexError(
                    'arrays used as indices must be of integer (or boolean) type')
        elif obj.dtype.char in 'IL':
            if obj.size == 1:
                objval = obj[()] if obj.ndim == 0 else obj[0]
                if objval > a.shape[axis]:
                    raise IndexError(
                        "index {0} is out of bounds for axis {1} with size {2}".format(
                            objval, axis, a.shape[axis]))
            else:
                tmp = 'float64' if obj.dtype.char == 'L' else 'int64'
                raise UFuncTypeError(
                    "Cannot cast ufunc 'add' output from dtype('{0}') to "
                    "dtype('{1}') with casting rule 'same_kind'".format(tmp, obj.dtype))
        obj = obj.astype('l')
        if obj.ndim > 1:
            raise ValueError(
                "index array argument obj to insert must be one dimensional or scalar")

    if obj.ndim == 0:
        if obj > a.shape[axis] or obj < -a.shape[axis]:
            raise IndexError(
                "index {0} is out of bounds for axis {1} with size {2}".format(
                    obj[()] if obj > 0 else obj[()] + a.shape[axis],
                    axis, a.shape[axis]))

    newshape = list(a.shape)
    if obj.size == 1:
        values = nlcpy.array(values, copy=False, ndmin=a.ndim, dtype=a.dtype)
        if obj.ndim == 0:
            values = nlcpy.moveaxis(values, 0, axis)
        newshape[axis] += values.shape[axis]
        obj = nlcpy.array(nlcpy.broadcast_to(obj, values.shape[axis]))
        val_shape = list(a.shape)
        val_shape[axis] = values.shape[axis]
        values = nlcpy.broadcast_to(values, val_shape)
    else:
        newshape[axis] += obj.size
        values = nlcpy.array(values, copy=False, ndmin=a.ndim, dtype=a.dtype)
        val_shape = list(a.shape)
        val_shape[axis] = obj.size
        values = nlcpy.broadcast_to(values, val_shape)

    out = nlcpy.empty(newshape, dtype=a.dtype)
    work = nlcpy.zeros(obj.size + out.shape[axis] + 2, dtype='l')
    work[-1] = -1
    request._push_request(
        'nlcpy_insert',
        'manipulation_op',
        (a, obj, values, out, axis, work)
    )
    if work[-1] != -1:
        raise IndexError(
            "index {0} is out of bounds for axis {1} with size {2}"
            .format(obj[work[-1]], axis, out.shape[axis]))
    return out
Example #3
0
def full(shape, fill_value, dtype=None, order='C'):
    """Returns a new array of given shape and type, filled with *fill_value*.

    Parameters
    ----------
    shape : int or sequence of ints
        Shape of the new array, e.g., ``(2, 3)`` or ``2``.
    fill_value : scalar
        Fill value.
    dtype : dtype, optional
        The desired dtype for the array, e.g, ``nlcpy.int64``.
        Default is ``nlcpy.float64``.
    order : {'C', 'F'}, optional
        Whether to store multidimensional data in C- or Fortran-contiguous (row- or
        column-wise) order in memory.

    Returns
    -------
    out : ndarray
        Array of *fill_value* with the given shape, dtype, and order.

    See Also
    --------
    full_like : Returns a full array with the same shape
        and type as a given array.
    empty : Returns a new array of given shape and type,
        without initializing entries.
    ones : Returns a new array of given shape and type,
        filled with ones.
    zeros : Returns a new array of given shape and type,
        filled with zeros.

    Examples
    --------
    >>> import nlcpy as vp
    >>> vp.full((2, 2), vp.inf)
    array([[inf, inf],
           [inf, inf]])
    >>> vp.full((2, 2), 10)
    array([[10, 10],
           [10, 10]])

    """
    if numpy.dtype(dtype).kind == 'V':
        raise NotImplementedError('void dtype in full is not implemented yet.')

    if dtype is None:
        dtype = numpy.result_type(fill_value)
    else:
        dtype = nlcpy.dtype(dtype)

    if numpy.isscalar(fill_value):
        if numpy.iscomplex(fill_value):
            if dtype in ('complex64', 'complex128'):
                pass
            else:
                fill_value = numpy.real(fill_value)
                warnings.warn(
                    'Casting complex values to real discards the imaginary part',
                    numpy.ComplexWarning,
                    stacklevel=2)
        out = nlcpy.ndarray(shape=shape, dtype=dtype, order=order)
        out.fill(fill_value)

    elif fill_value is None:
        raise NotImplementedError('fill_value in nlcpy.full is None')

    else:
        fill_value = nlcpy.asarray(fill_value)
        out = nlcpy.array(nlcpy.broadcast_to(fill_value, shape=shape),
                          dtype=dtype,
                          order=order)

    return out
Example #4
0
def meshgrid(*xi, **kwargs):
    """Returns coordinate matrices from coordinate vectors.

    Make N-D coordinate arrays for vectorized evaluations of N-D scalar/vector fields
    over N-D grids, given one-dimensional coordinate arrays x1, x2,..., xn.

    Parameters
    ----------
    x1, x2, ..., xn : array_like
        1-D arrays representing the coordinates of a grid.
    indexing : {'xy', 'ij'}, optional
        Cartesian ('xy', default) or matrix ('ij') indexing of output. See Notes for
        more details.
    sparse : bool, optional
        If True a sparse grid is returned in order to conserve memory. Default is
        False.
    copy : bool, optional
        If False, a view into the original arrays are returned in order to conserve
        memory. Default is True. Please note that ``sparse=False, copy=False`` will
        likely return non-contiguous arrays. Furthermore, more than one element of a
        broadcast array may refer to a single memory location. If you need to write
        to the arrays, make copies first.

    Returns
    -------
    X1, X2, ..., XN : ndarray
        For vectors x1, x2, ..., 'xn' with lengths ``Ni=len(xi)``, return
        ``(N1, N2, N3, ..., Nn)`` shaped arrays if indexing='ij' or (N2, N1, N3, ...,
        Nn) shaped arrays if indexing='xy' with the elements of xi repeated to fill the
        matrix along the first dimension for x1, the second for x2 and so on.

    Note
    ----
    This function supports both indexing conventions through the indexing keyword
    argument. Giving the string 'ij' returns a meshgrid with matrix indexing, while
    'xy' returns a meshgrid with Cartesian indexing. In the 2-D case with inputs of
    length M and N, the outputs are of shape (N, M) for 'xy' indexing and (M, N) for
    'ij' indexing. In the 3-D case with inputs of length M, N and P, outputs are of
    shape (N, M, P) for 'xy' indexing and (M, N, P) for 'ij' indexing.
    The difference is illustrated by the following code snippet::

        import nlcpy as vp
        xv, yv = vp.meshgrid(x, y, sparse=False, indexing='ij')
        for i in range(nx):
            for j in range(ny):
                # treat xv[i,j], yv[i,j]
        xv, yv = vp.meshgrid(x, y, sparse=False, indexing='xy')
        for i in range(nx):
            for j in range(ny):
                # treat xv[j,i], yv[j,i]

    In the 1-D and 0-D case, the indexing and sparse keywords have no effect.

    Examples
    --------
    >>> import nlcpy as vp
    >>> nx, ny = (3, 2)
    >>> x = vp.linspace(0, 1, nx)
    >>> y = vp.linspace(0, 1, ny)
    >>> xv, yv = vp.meshgrid(x, y)
    >>> xv
    array([[0. , 0.5, 1. ],
           [0. , 0.5, 1. ]])
    >>> yv
    array([[0., 0., 0.],
           [1., 1., 1.]])
    >>> xv, yv = vp.meshgrid(x, y, sparse=True)  # make sparse output arrays
    >>> xv
    array([[0. , 0.5, 1. ]])
    >>> yv
    array([[0.],
           [1.]])

    meshgrid is very useful to evaluate functions on a grid.

    >>> import matplotlib.pyplot as plt
    >>> x = vp.arange(-5, 5, 0.1)
    >>> y = vp.arange(-5, 5, 0.1)
    >>> xx, yy = vp.meshgrid(x, y, sparse=True)
    >>> z = vp.sin(xx**2 + yy**2) / (xx**2 + yy**2)
    >>> h = plt.contourf(x,y,z)
    >>> plt.show()

    """
    copy_ = kwargs.pop('copy', True)
    sparse = kwargs.pop('sparse', False)
    indexing = kwargs.pop('indexing', 'xy')

    if kwargs:
        raise TypeError("meshgrid() got an unexpected keyword argument '%s'" %
                        (list(kwargs)[0], ))

    if indexing not in ['xy', 'ij']:
        raise ValueError("Valid values for `indexing` are 'xy' and 'ij'.")

    ndim = len(xi)
    s0 = (1, ) * ndim
    output = [
        nlcpy.asanyarray(x).reshape(s0[:i] + (-1, ) + s0[i + 1:])
        for i, x in enumerate(xi)
    ]

    if not sparse:
        shape = [output[i].shape[i] for i in range(len(output))]

    if indexing == 'xy' and ndim > 1:
        output[0].shape = (1, -1) + s0[2:]
        output[1].shape = (-1, 1) + s0[2:]
        if not sparse:
            shape[0], shape[1] = shape[1], shape[0]

    if not sparse:
        output = [nlcpy.broadcast_to(x, shape) for x in output]

    if copy_:
        output = [x.copy() for x in output]

    return output
Example #5
0
def linspace(start,
             stop,
             num=50,
             endpoint=True,
             retstep=False,
             dtype=None,
             axis=0):
    """Returns evenly spaced numbers over a specified interval.

    Returns *num* evenly spaced samples, calculated over the interval ``[start, stop]``.
    The endpoint of the interval can optionally be excluded.

    Parameters
    ----------
    start : array_like
        The starting value of the sequence.
    stop : array_like
        The end value of the sequence, unless *endpoint* is set to False. In that case,
        the sequence consists of all but the last of ``num + 1`` evenly spaced samples,
        so that *stop* is excluded. Note that the step size changes when *endpoint* is
        False.
    num : int, optional
        Number of samples to generate. Default is 50. Must be non-negative.
    endpoint : bool, optional
        If True, *stop* is the last sample. Otherwise, it is not included. Default is
        True.
    retstep : bool, optional
        If True, return (*samples*, *step*) where *step* is the spacing between samples.
    dtype : dtype, optional
        The type of the output array. If *dtype* is not given, infer the data type from
        the other input arguments.
    axis : int, optional
        The axis in the result to store the samples. Relevant only if start or stop are
        array-like. By default (0), the samples will be along a new axis inserted at the
        beginning. Use -1 to get an axis at the end.

    Returns
    -------
    samples : ndarray
        There are *num* equally spaced samples in the closed interval ``[start, stop]``
        or the half-open interval ``[start, stop)`` (depending on whether *endpoint* is
        True or False).
    step : float, optional
        Only returned if *retstep* is True
        Size of spacing between samples.

    See Also
    --------
    arange : Returns evenly spaced values within a given interval.

    Examples
    --------
    >>> import nlcpy as vp
    >>> vp.linspace(2.0, 3.0, num=5)
    array([2.  , 2.25, 2.5 , 2.75, 3.  ])
    >>> vp.linspace(2.0, 3.0, num=5, endpoint=False)
    array([2. , 2.2, 2.4, 2.6, 2.8])
    >>> vp.linspace(2.0, 3.0, num=5, retstep=True)
    (array([2.  , 2.25, 2.5 , 2.75, 3.  ]), array([0.25]))

    """
    num = operator.index(num)
    if num < 0:
        raise ValueError("Number of samples, %s, must be non-negative." % num)

    dtype_kind = numpy.dtype(dtype).kind
    if dtype_kind == 'V':
        raise NotImplementedError(
            'void dtype in linspace is not implemented yet.')

    start = nlcpy.asarray(start)
    stop = nlcpy.asarray(stop)
    dt = numpy.result_type(start, stop, float(num))
    if start.dtype.char in '?iIlL' or stop.dtype.char in '?iIlL':
        dt = 'D' if dt.char in 'FD' else 'd'

    if dtype is None:
        dtype = dt

    start = nlcpy.asarray(start, dtype=dt)
    stop = nlcpy.asarray(stop, dtype=dt)
    delta = stop - start
    div = (num - 1) if endpoint else num
    if num == 0:
        ret = nlcpy.empty((num, ) + delta.shape, dtype=dtype)
        if retstep:
            ret = (ret, nlcpy.NaN)
        return ret
    elif div == 0 or num == 1:
        ret = nlcpy.resize(start, (1, ) + delta.shape).astype(dtype)
        if retstep:
            ret = (ret, stop)
        return ret
    else:
        ret = nlcpy.empty((num, ) + delta.shape, dtype=dtype)
    retdata = ret

    delta = delta[nlcpy.newaxis]
    start = nlcpy.array(nlcpy.broadcast_to(start, delta.shape))
    stop = nlcpy.array(nlcpy.broadcast_to(stop, delta.shape))
    step = delta / div if div > 1 else delta
    if retdata._memloc in {on_VE, on_VE_VH}:
        denormal = nlcpy.zeros(1, dtype='l')
        request._push_request(
            "nlcpy_linspace", "creation_op",
            (ret, start, stop, delta, step, int(endpoint), denormal))
        if axis != 0:
            ret = nlcpy.moveaxis(ret, 0, axis)
        if retstep:
            ret = (ret, step)

    if retdata._memloc in {on_VH, on_VE_VH}:
        del retdata.vh_data
        del step.vh_data
        typ = numpy.dtype(dtype).type
        if retstep:
            (retdata.vh_data,
             step.vh_data) = numpy.linspace(typ(start),
                                            typ(stop), num, endpoint,
                                            typ(retstep), dtype, axis)
        else:
            retdata.vh_data = numpy.linspace(typ(start),
                                             typ(stop), num, endpoint,
                                             typ(retstep), dtype, axis)
    return ret
Example #6
0
def solve(a, b):
    """Solves a linear matrix equation, or system of linear scalar equations.

    Computes the "exact" solution, *x*, of the well-determined, i.e., full rank, linear
    matrix equation :math:`ax = b`.

    Parameters
    ----------
    a : (..., M, M) array_like
        Coefficient matrix.
    b : {(..., M,), (..., M, K)} array_like
        Ordinate or "dependent variable" values.

    Returns
    -------
    x : {(..., M,), (..., M, K)} ndarray
        Solution to the system a x = b. Returned shape is identical to *b*.

    Note
    ----
    The solutions are computed using LAPACK routine ``_gesv``.

    `a` must be square and of full-rank, i.e., all rows (or, equivalently, columns) must
    be linearly independent; if either is not true, use :func:`lstsq` for the
    least-squares best "solution" of the system/equation.

    Examples
    --------
    Solve the system of equations ``3 * x0 + x1 = 9`` and ``x0 + 2 * x1 = 8``:

    >>> import nlcpy as vp
    >>> a = vp.array([[3,1], [1,2]])
    >>> b = vp.array([9,8])
    >>> x = vp.linalg.solve(a, b)
    >>> x
    array([2., 3.])

    """
    a = nlcpy.asarray(a)
    b = nlcpy.asarray(b)
    c_order = (a.flags.c_contiguous or a.ndim < 4 or
               a.ndim - b.ndim < 2 and b.flags.c_contiguous) and \
        not (a.ndim < b.ndim and not b.flags.c_contiguous)
    util._assertRankAtLeast2(a)
    util._assertNdSquareness(a)

    if a.ndim - 1 == b.ndim:
        if a.shape[-1] != b.shape[-1]:
            raise ValueError(
                'solve1: Input operand 1 has a mismatch in '
                'its core dimension 0, with gufunc signature (m,m),(m)->(m) '
                '(size {0} is different from {1})'.format(
                    b.shape[-1], a.shape[-1]))
    elif b.ndim == 1:
        raise ValueError(
            'solve: Input operand 1 does not have enough dimensions '
            '(has 1, gufunc core with signature (m,m),(m,n)->(m,n) requires 2)'
        )
    else:
        if a.shape[-1] != b.shape[-2]:
            raise ValueError(
                'solve: Input operand 1 has a mismatch in '
                'its core dimension 0, with gufunc signature (m,m),(m,n)->(m,n) '
                '(size {0} is different from {1})'.format(
                    b.shape[-2], a.shape[-1]))

    if b.ndim == 1 or a.ndim - 1 == b.ndim and a.shape[-1] == b.shape[-1]:
        tmp = 1
        _newaxis = (None, )
    else:
        tmp = 2
        _newaxis = (None, None)
    for i in range(1, min(a.ndim - 2, b.ndim - tmp) + 1):
        if a.shape[-2 - i] != b.shape[-tmp - i] and \
           1 not in (a.shape[-2 - i], b.shape[-tmp - i]):
            raise ValueError(
                'operands could not be broadcast together with '
                'remapped shapes [original->remapped]: {0}->({1}) '
                '{2}->({3}) and requested shape ({4})'.format(
                    str(a.shape).replace(' ', ''),
                    str(a.shape[:-2] + _newaxis).replace(' ', '').replace(
                        'None', 'newaxis').strip('(,)'),
                    str(b.shape).replace(' ', ''),
                    str(b.shape[:-tmp] + _newaxis).replace(' ', '').replace(
                        'None', 'newaxis').replace('None',
                                                   'newaxis').strip('(,)'),
                    str(b.shape[-tmp:]).replace(' ', '').strip('(,)')))

    if a.dtype.char in 'FD' or b.dtype.char in 'FD':
        dtype = 'complex128'
        if a.dtype.char in 'fF' and b.dtype.char in 'fF':
            x_dtype = 'complex64'
        else:
            x_dtype = 'complex128'
    else:
        dtype = 'float64'
        if a.dtype.char == 'f' and b.dtype.char == 'f':
            x_dtype = 'float32'
        else:
            x_dtype = 'float64'

    x_shape = b.shape
    if b.ndim == a.ndim - 1:
        b = b[..., nlcpy.newaxis]
    diff = abs(a.ndim - b.ndim)
    if a.ndim < b.ndim:
        bcast_shape = [
            b.shape[i] if b.shape[i] != 1 or i < diff else a.shape[i - diff]
            for i in range(b.ndim - 2)
        ]
    else:
        bcast_shape = [
            a.shape[i] if a.shape[i] != 1 or i < diff else b.shape[i - diff]
            for i in range(a.ndim - 2)
        ]
    bcast_shape_a = bcast_shape + list(a.shape[-2:])
    bcast_shape_b = bcast_shape + list(b.shape[-2:])
    a = nlcpy.broadcast_to(a, bcast_shape_a)
    if bcast_shape_b != list(b.shape):
        b = nlcpy.broadcast_to(b, bcast_shape_b)
        x_shape = b.shape
    if b.size == 0:
        return nlcpy.empty(x_shape, dtype=x_dtype)

    a = nlcpy.array(nlcpy.moveaxis(a, (-1, -2), (1, 0)),
                    dtype=dtype,
                    order='F')
    b = nlcpy.array(nlcpy.moveaxis(b, (-1, -2), (1, 0)),
                    dtype=dtype,
                    order='F')

    info = numpy.empty(1, dtype='l')
    fpe = request._get_fpe_flag()
    args = (
        a._ve_array,
        b._ve_array,
        veo.OnStack(info, inout=veo.INTENT_OUT),
        veo.OnStack(fpe, inout=veo.INTENT_OUT),
    )

    request._push_and_flush_request('nlcpy_solve',
                                    args,
                                    callback=util._assertNotSingular(info))

    if c_order:
        x = nlcpy.moveaxis(b, (1, 0), (-1, -2)).reshape(x_shape)
        return nlcpy.asarray(x, x_dtype, 'C')
    else:
        x = nlcpy.asarray(b, x_dtype)
        return nlcpy.moveaxis(x, (1, 0), (-1, -2)).reshape(x_shape)
Example #7
0
 def test_broadcast_to_fail_numpy19(self, dtype):
     # Note that broadcast_to is only supported on numpy>=1.10
     a = testing.shaped_arange((3, 1, 4), nlcpy, dtype)
     with self.assertRaises(ValueError):
         nlcpy.broadcast_to(a, (1, 3, 4))
Example #8
0
def roll(a, shift, axis=None):
    """Rolls array elements along a given axis.

    Elements that roll beyond the last position are re-introduced at the first.

    Parameters
    ----------
    a : array_like
        Input array.
    shift : int or tuple of ints
        The number of places by which elements are shifted. If a tuple, then *axis* must
        be a tuple of the same size, and each of the given axes is shifted by the
        corresponding number. If an int while *axis* is a tuple of ints, then the
        same value is used for all given axes.
    axis : int or tuple of ints, optional
        Axis or axes along which elements are shifted. By default, the array is
        flattened before shifting, after which the original shape is restored.

    Returns
    -------
    res : ndarray
        Output array, with the same shape as *a*.

    See Also
    --------
    rollaxis : Rolls the specified axis backwards, until it lies in a given position.

    Examples
    --------
    >>> import nlcpy as vp
    >>> x = vp.arange(10)
    >>> vp.roll(x, 2)
    array([8, 9, 0, 1, 2, 3, 4, 5, 6, 7])
    >>> vp.roll(x, -2)
    array([2, 3, 4, 5, 6, 7, 8, 9, 0, 1])

    >>> x2 = vp.reshape(x, (2,5))
    >>> x2
    array([[0, 1, 2, 3, 4],
           [5, 6, 7, 8, 9]])
    >>> vp.roll(x2, 1)
    array([[9, 0, 1, 2, 3],
           [4, 5, 6, 7, 8]])
    >>> vp.roll(x2, -1)
    array([[1, 2, 3, 4, 5],
           [6, 7, 8, 9, 0]])
    >>> vp.roll(x2, 1, axis=0)
    array([[5, 6, 7, 8, 9],
           [0, 1, 2, 3, 4]])
    >>> vp.roll(x2, -1, axis=0)
    array([[5, 6, 7, 8, 9],
           [0, 1, 2, 3, 4]])
    >>> vp.roll(x2, 1, axis=1)
    array([[4, 0, 1, 2, 3],
           [9, 5, 6, 7, 8]])
    >>> vp.roll(x2, -1, axis=1)
    array([[1, 2, 3, 4, 0],
           [6, 7, 8, 9, 5]])
    """
    a = nlcpy.asanyarray(a)
    if axis is None:
        return roll(a.ravel(), shift, 0).reshape(a.shape)

    if type(axis) not in (tuple, list):
        try:
            axis = [operator.index(axis)]
        except TypeError:
            pass

    _axis = axis.get() if isinstance(axis, nlcpy.ndarray) else axis
    axis = [ax + a.ndim if ax < 0 else ax for ax in _axis]
    for ax in axis:
        if ax < 0 or ax >= a.ndim:
            raise AxisError(
                'axis {} is out of bounds for array of dimension {}'.format(
                    ax, a.ndim))

    shift = nlcpy.asanyarray(shift)
    axis = nlcpy.asanyarray(axis)
    if shift.ndim > 1 or axis.ndim > 1:
        raise ValueError(
            "'shift' and 'axis' should be scalars or 1D sequences")

    if shift.size > axis.size:
        axis = nlcpy.broadcast_to(axis, shift.shape)
    else:
        shift = nlcpy.broadcast_to(shift, axis.shape)

    shift = nlcpy.array(shift, dtype='l')
    axis = nlcpy.array(axis, dtype='l')
    result = nlcpy.empty(a.shape, dtype=a.dtype)
    work = nlcpy.zeros(a.ndim, dtype='l')
    request._push_request('nlcpy_roll', 'manipulation_op',
                          (a, shift, axis, work, result))

    return result