Exemple #1
0
def bincount(x, weights=None, minlength=None, assert_nonneg=False):
    """Count number of occurrences of each value in array of ints.

    The number of bins (of size 1) is one larger than the largest
    value in x. If minlength is specified, there will be at least
    this number of bins in the output array (though it will be longer
    if necessary, depending on the contents of x). Each bin gives the
    number of occurrences of its index value in x. If weights is
    specified the input array is weighted by it, i.e. if a value n
    is found at position i, out[n] += weight[i] instead of out[n] += 1.

    Parameters
    ----------
    x : 1 dimension, nonnegative ints
    weights : array of the same shape as x with corresponding weights.
        Optional.
    minlength : A minimum number of bins for the output array.
        Optional.
    assert_nonneg : A flag that inserts an assert_op to check if
        every input x is nonnegative.
        Optional.

    .. versionadded:: 0.6

    """
    compatible_type = ('int8', 'int16', 'int32', 'int64',
                       'uint8', 'uint16', 'uint32')
    unsupported_dtypes = ('uint64',)

    if x.dtype in unsupported_dtypes:
            raise TypeError(
                ("Input dtype %s is not supported, "
                 % unsupported_dtypes), x.dtype)

    if x.dtype not in compatible_type:
        raise TypeError("Inputs dtype must be an integer.")

    if x.ndim != 1:
        raise TypeError("Inputs must be of dimension 1.")

    if assert_nonneg:
        from theano.tensor.opt import Assert
        assert_op = Assert('Input to bincount has negative values!')
        x = assert_op(x, theano.tensor.all(x >= 0))

    max_value = theano.tensor.cast(x.max() + 1, 'int64')

    if minlength is not None:
        max_value = theano.tensor.maximum(max_value, minlength)

    if weights is None:
        out = theano.tensor.zeros([max_value], dtype=x.dtype)
        out = theano.tensor.inc_subtensor(out[x], 1)
    else:
        out = theano.tensor.zeros([max_value], dtype=weights.dtype)
        out = theano.tensor.inc_subtensor(out[x], weights)
    return out
Exemple #2
0
def bincount(x, weights=None, minlength=None, assert_nonneg=False):
    """Count number of occurrences of each value in array of ints.

    The number of bins (of size 1) is one larger than the largest
    value in x. If minlength is specified, there will be at least
    this number of bins in the output array (though it will be longer
    if necessary, depending on the contents of x). Each bin gives the
    number of occurrences of its index value in x. If weights is
    specified the input array is weighted by it, i.e. if a value n
    is found at position i, out[n] += weight[i] instead of out[n] += 1.

    Parameters
    ----------
    x : 1 dimension, nonnegative ints
    weights : array of the same shape as x with corresponding weights.
        Optional.
    minlength : A minimum number of bins for the output array.
        Optional.
    assert_nonneg : A flag that inserts an assert_op to check if
        every input x is nonnegative.
        Optional.


    .. versionadded:: 0.6

    """
    if x.ndim != 1:
        raise TypeError("Inputs must be of dimension 1.")

    if assert_nonneg:
        from theano.tensor.opt import Assert

        assert_op = Assert("Input to bincount has negative values!")
        x = assert_op(x, theano.tensor.all(x >= 0))

    max_value = theano.tensor.cast(x.max() + 1, "int64")

    if minlength is not None:
        max_value = theano.tensor.maximum(max_value, minlength)

    # Note: we do not use inc_subtensor(out[x], ...) in the following lines,
    # since out[x] raises an exception if the indices (x) are int8.
    if weights is None:
        out = theano.tensor.zeros([max_value], dtype=x.dtype)
        out = theano.tensor.advanced_inc_subtensor1(out, 1, x)
    else:
        out = theano.tensor.zeros([max_value], dtype=weights.dtype)
        out = theano.tensor.advanced_inc_subtensor1(out, weights, x)
    return out
Exemple #3
0
def test_RandomVariable():

    str_res = str(
        RandomVariable(
            "normal",
            0,
            [0, 0],
            "normal",
            inplace=True,
        )
    )

    assert str_res == "normal_rv"

    # `ndims_params` should be a `Sequence` type
    with raises(TypeError, match="^Parameter ndims_params*"):
        RandomVariable(
            "normal",
            0,
            0,
            config.floatX,
            inplace=True,
        )

    # `size` should be a `Sequence` type
    with raises(TypeError, match="^Parameter size*"):
        RandomVariable(
            "normal",
            0,
            [0, 0],
            config.floatX,
            inplace=True,
        )(0, 1, size={1, 2})

    # No dtype
    with raises(TypeError, match="^dtype*"):
        RandomVariable(
            "normal",
            0,
            [0, 0],
            inplace=True,
        )(0, 1)

    # Confirm that `inplace` works
    rv = RandomVariable(
        "normal",
        0,
        [0, 0],
        "normal",
        inplace=True,
    )

    assert rv.inplace
    assert rv.destroy_map == {0: [3]}

    # A no-params `RandomVariable`
    rv = RandomVariable(name="test_rv", ndim_supp=0, ndims_params=())

    with raises(TypeError):
        rv.make_node(rng=1)

    # `RandomVariable._infer_shape` should handle no parameters
    rv_shape = rv._infer_shape(tt.constant([]), (), [])
    assert rv_shape.equals(tt.constant([], dtype="int64"))

    # Integer-specificed `dtype`
    dtype_1 = tt.all_dtypes[1]
    rv_node = rv.make_node(None, None, 1)
    rv_out = rv_node.outputs[1]
    rv_out.tag.test_value = 1

    assert rv_out.dtype == dtype_1

    with raises(NullTypeGradError):
        tt.grad(rv_out, [rv_node.inputs[0]])

    rv = RandomVariable("normal", 0, [0, 0], config.floatX, inplace=True)

    mu = tt.tensor(config.floatX, [True, False, False])
    mu.tag.test_value = np.zeros((1, 2, 3)).astype(config.floatX)
    sd = tt.tensor(config.floatX, [False, False])
    sd.tag.test_value = np.ones((2, 3)).astype(config.floatX)

    s1 = tt.iscalar()
    s1.tag.test_value = 1
    s2 = tt.iscalar()
    s2.tag.test_value = 2
    s3 = tt.iscalar()
    s3.tag.test_value = 3
    s3 = Assert("testing")(s3, tt.eq(s1, 1))

    res = rv.compute_bcast([mu, sd], (s1, s2, s3))
    assert res == [False] * 3
Exemple #4
0
def broadcast_shape_iter(arrays, **kwargs):
    """Compute the shape resulting from broadcasting arrays.

    Parameters
    ----------
    arrays: Iterable[TensorVariable] or Iterable[Tuple[Variable]]
        An iterable of tensors, or a tuple of shapes (as tuples),
        for which the broadcast shape is computed.
        XXX: Do not call this with a generator/iterator; this function will not
        make copies!
    arrays_are_shapes: bool (Optional)
        Indicates whether or not the `arrays` contains shape tuples.
        If you use this approach, make sure that the broadcastable dimensions
        are (scalar) constants with the value `1` or `1` exactly.

    """
    one = theano.scalar.ScalarConstant(theano.scalar.int64, 1)

    arrays_are_shapes = kwargs.pop("arrays_are_shapes", False)
    if arrays_are_shapes:
        max_dims = max(len(a) for a in arrays)

        array_shapes = [(one, ) * (max_dims - len(a)) +
                        tuple(one if getattr(sh, "value", sh) == 1 else sh
                              for sh in a) for a in arrays]
    else:
        max_dims = max(a.ndim for a in arrays)

        array_shapes = [(one, ) * (max_dims - a.ndim) +
                        tuple(one if bcast else sh
                              for sh, bcast in zip(a.shape, a.broadcastable))
                        for a in arrays]

    result_dims = []

    for dim_shapes in zip(*array_shapes):
        non_bcast_shapes = [shape for shape in dim_shapes if shape != one]

        if len(non_bcast_shapes) > 0:
            # Either there's only one non-broadcastable dimensions--and that's
            # what determines the dimension size, or there are multiple
            # non-broadcastable dimensions that must be equal
            i_dim = non_bcast_shapes.pop()

            potentially_unequal_dims = [
                dim for dim in non_bcast_shapes
                # TODO FIXME: This is a largely deficient means of comparing graphs
                # (and especially shapes)
                if not theano.gof.graph.equal_computations([i_dim], [dim])
            ]

            if potentially_unequal_dims:
                from theano.tensor.opt import Assert

                # In this case, we can't tell whether or not the dimensions are
                # equal, so we'll need to assert their equality and move the error
                # handling to evaluation time.
                assert_dim = Assert("Could not broadcast dimensions")
                eq_condition = basic.all([
                    basic.or_(basic.eq(dim, one), basic.eq(i_dim, dim))
                    for dim in potentially_unequal_dims
                ])
                eq_condition = basic.or_(basic.eq(i_dim, one), eq_condition)
                result_dims.append(assert_dim(i_dim, eq_condition))
            else:
                result_dims.append(i_dim)
        else:
            # Every array was broadcastable in this dimension
            result_dims.append(one)

    return tuple(result_dims)