Пример #1
0
def _components(data, p=1, phi=0.0, axis=None, weights=None):
    # Utility function for computing the generalized rectangular components
    # of the circular data.
    if weights is None:
        weights = np.ones((1,))
    try:
        weights = broadcast_to(weights, data.shape)
    except ValueError:
        raise ValueError("Weights and data have inconsistent shape.")

    C = np.sum(weights * np.cos(p * (data - phi)), axis) / np.sum(weights, axis)
    S = np.sum(weights * np.sin(p * (data - phi)), axis) / np.sum(weights, axis)

    return C, S
Пример #2
0
def _components(data, p=1, phi=0.0, axis=None, weights=None):
    # Utility function for computing the generalized rectangular components
    # of the circular data.
    if weights is None:
        weights = np.ones((1,))
    try:
        weights = broadcast_to(weights, data.shape)
    except ValueError:
        raise ValueError('Weights and data have inconsistent shape.')

    C = np.sum(weights * np.cos(p * (data - phi)), axis)/np.sum(weights, axis)
    S = np.sum(weights * np.sin(p * (data - phi)), axis)/np.sum(weights, axis)

    return C, S
Пример #3
0
def vtest(data, mu=0.0, axis=None, weights=None):
    """ Performs the Rayleigh test of uniformity where the alternative
    hypothesis H1 is assumed to have a known mean angle ``mu``.

    Parameters
    ----------
    data : numpy.ndarray or Quantity
        Array of circular (directional) data, which is assumed to be in
        radians whenever ``data`` is ``numpy.ndarray``.
    mu : float or Quantity, optional
        Mean angle. Assumed to be known.
    axis : int, optional
        Axis along which the V test will be performed.
    weights : numpy.ndarray, optional
        In case of grouped data, the i-th element of ``weights`` represents a
        weighting factor for each group such that ``sum(weights, axis)``
        equals the number of observations. See [1], remark 1.4, page 22, for
        detailed explanation.

    Returns
    -------
    p-value : float or dimensionless Quantity
        p-value.

    Examples
    --------
    >>> import numpy as np
    >>> from astropy.stats import vtest
    >>> from astropy import units as u
    >>> data = np.array([130, 90, 0, 145])*u.deg
    >>> vtest(data) # doctest: +FLOAT_CMP
    <Quantity 0.6223678199713766>

    References
    ----------
    .. [1] S. R. Jammalamadaka, A. SenGupta. "Topics in Circular Statistics".
       Series on Multivariate Analysis, Vol. 5, 2001.
    .. [2] C. Agostinelli, U. Lund. "Circular Statistics from 'Topics in
       Circular Statistics (2001)'". 2015.
       <https://cran.r-project.org/web/packages/CircStats/CircStats.pdf>
    .. [3] M. Chirstman., C. Miller. "Testing a Sample of Directions for
       Uniformity." Lecture Notes, STA 6934/5805. University of Florida, 2007.
    """
    from scipy.stats import norm

    if weights is None:
        weights = np.ones((1, ))
    try:
        weights = broadcast_to(weights, data.shape)
    except ValueError:
        raise ValueError('Weights and data have inconsistent shape.')

    n = np.size(data, axis=axis)
    R0bar = np.sum(weights * np.cos(data - mu), axis) / np.sum(weights, axis)
    z = np.sqrt(2.0 * n) * R0bar
    pz = norm.cdf(z)
    fz = norm.pdf(z)
    # see reference [3]
    p_value = 1 - pz + fz * ((3 * z - z**3) / (16.0 * n) +
                             (15 * z + 305 * z**3 - 125 * z**5 + 9 * z**7) /
                             (4608.0 * n * n))
    return p_value
Пример #4
0
def vtest(data, mu=0.0, axis=None, weights=None):
    """ Performs the Rayleigh test of uniformity where the alternative
    hypothesis H1 is assumed to have a known mean angle ``mu``.

    Parameters
    ----------
    data : numpy.ndarray or Quantity
        Array of circular (directional) data, which is assumed to be in
        radians whenever ``data`` is ``numpy.ndarray``.
    mu : float or Quantity, optional
        Mean angle. Assumed to be known.
    axis : int, optional
        Axis along which the V test will be performed.
    weights : numpy.ndarray, optional
        In case of grouped data, the i-th element of ``weights`` represents a
        weighting factor for each group such that ``sum(weights, axis)``
        equals the number of observations. See [1], remark 1.4, page 22, for
        detailed explanation.

    Returns
    -------
    p-value : float or dimensionless Quantity
        p-value.

    Examples
    --------
    >>> import numpy as np
    >>> from astropy.stats import vtest
    >>> from astropy import units as u
    >>> data = np.array([130, 90, 0, 145])*u.deg
    >>> vtest(data) # doctest: +FLOAT_CMP
    <Quantity 0.6223678199713766>

    References
    ----------
    .. [1] S. R. Jammalamadaka, A. SenGupta. "Topics in Circular Statistics".
       Series on Multivariate Analysis, Vol. 5, 2001.
    .. [2] C. Agostinelli, U. Lund. "Circular Statistics from 'Topics in
       Circular Statistics (2001)'". 2015.
       <https://cran.r-project.org/web/packages/CircStats/CircStats.pdf>
    .. [3] M. Chirstman., C. Miller. "Testing a Sample of Directions for
       Uniformity." Lecture Notes, STA 6934/5805. University of Florida, 2007.
    """
    from scipy.stats import norm

    if weights is None:
        weights = np.ones((1,))
    try:
        weights = broadcast_to(weights, data.shape)
    except ValueError:
        raise ValueError("Weights and data have inconsistent shape.")

    n = np.size(data, axis=axis)
    R0bar = np.sum(weights * np.cos(data - mu), axis) / np.sum(weights, axis)
    z = np.sqrt(2.0 * n) * R0bar
    pz = norm.cdf(z)
    fz = norm.pdf(z)
    # see reference [3]
    p_value = (
        1
        - pz
        + fz * ((3 * z - z ** 3) / (16.0 * n) + (15 * z + 305 * z ** 3 - 125 * z ** 5 + 9 * z ** 7) / (4608.0 * n * n))
    )
    return p_value
Пример #5
0
    def __call__(self, observer, targets, times=None,
                 time_range=None, time_grid_resolution=0.5*u.hour,
                 grid_times_targets=False):
        """
        Compute the constraint for this class

        Parameters
        ----------
        observer : `~astroplan.Observer`
            the observation location from which to apply the constraints
        targets : sequence of `~astroplan.Target`
            The targets on which to apply the constraints.
        times : `~astropy.time.Time`
            The times to compute the constraint.
            WHAT HAPPENS WHEN BOTH TIMES AND TIME_RANGE ARE SET?
        time_range : `~astropy.time.Time` (length = 2)
            Lower and upper bounds on time sequence.
        time_grid_resolution : `~astropy.units.quantity`
            Time-grid spacing
        grid_times_targets : bool
            if True, grids the constraint result with targets along the first
            index and times along the second. Otherwise, we rely on broadcasting
            the shapes together using standard numpy rules.
        Returns
        -------
        constraint_result : 1D or 2D array of float or bool
            The constraints. If 2D with targets along the first index and times along
            the second.
        """

        if times is None and time_range is not None:
            times = time_grid_from_range(time_range,
                                         time_resolution=time_grid_resolution)

        if grid_times_targets:
            targets = get_skycoord(targets)
            # TODO: these broadcasting operations are relatively slow
            # but there is potential for huge speedup if the end user
            # disables gridding and re-shapes the coords themselves
            # prior to evaluating multiple constraints.
            if targets.isscalar:
                # ensure we have a (1, 1) shape coord
                targets = SkyCoord(np.tile(targets, 1))[:, np.newaxis]
            else:
                targets = targets[..., np.newaxis]
        times, targets = observer._preprocess_inputs(times, targets, grid_times_targets=False)
        result = self.compute_constraint(times, observer, targets)

        # make sure the output has the same shape as would result from
        # broadcasting times and targets against each other
        if targets is not None:
            # broadcasting times v targets is slow due to
            # complex nature of these objects. We make
            # to simple numpy arrays of the same shape and
            # broadcast these to find the correct shape
            shp1, shp2 = times.shape, targets.shape
            x = np.array([1])
            a = as_strided(x, shape=shp1, strides=[0] * len(shp1))
            b = as_strided(x, shape=shp2, strides=[0] * len(shp2))
            output_shape = np.broadcast(a, b).shape
            if output_shape != result.shape:
                result = broadcast_to(result, output_shape)

        return result
Пример #6
0
    def __call__(self,
                 observer,
                 targets,
                 times=None,
                 time_range=None,
                 time_grid_resolution=0.5 * u.hour,
                 grid_times_targets=False):
        """
        Compute the constraint for this class

        Parameters
        ----------
        observer : `~astroplan.Observer`
            the observation location from which to apply the constraints
        targets : sequence of `~astroplan.Target`
            The targets on which to apply the constraints.
        times : `~astropy.time.Time`
            The times to compute the constraint.
            WHAT HAPPENS WHEN BOTH TIMES AND TIME_RANGE ARE SET?
        time_range : `~astropy.time.Time` (length = 2)
            Lower and upper bounds on time sequence.
        time_grid_resolution : `~astropy.units.quantity`
            Time-grid spacing
        grid_times_targets : bool
            if True, grids the constraint result with targets along the first
            index and times along the second. Otherwise, we rely on broadcasting
            the shapes together using standard numpy rules.
        Returns
        -------
        constraint_result : 1D or 2D array of float or bool
            The constraints. If 2D with targets along the first index and times along
            the second.
        """

        if times is None and time_range is not None:
            times = time_grid_from_range(time_range,
                                         time_resolution=time_grid_resolution)

        if grid_times_targets:
            targets = get_skycoord(targets)
            # TODO: these broadcasting operations are relatively slow
            # but there is potential for huge speedup if the end user
            # disables gridding and re-shapes the coords themselves
            # prior to evaluating multiple constraints.
            if targets.isscalar:
                # ensure we have a (1, 1) shape coord
                targets = SkyCoord(np.tile(targets, 1))[:, np.newaxis]
            else:
                targets = targets[..., np.newaxis]
        times, targets = observer._preprocess_inputs(times,
                                                     targets,
                                                     grid_times_targets=False)
        result = self.compute_constraint(times, observer, targets)

        # make sure the output has the same shape as would result from
        # broadcasting times and targets against each other
        if targets is not None:
            # broadcasting times v targets is slow due to
            # complex nature of these objects. We make
            # to simple numpy arrays of the same shape and
            # broadcast these to find the correct shape
            shp1, shp2 = times.shape, targets.shape
            x = np.array([1])
            a = as_strided(x, shape=shp1, strides=[0] * len(shp1))
            b = as_strided(x, shape=shp2, strides=[0] * len(shp2))
            output_shape = np.broadcast(a, b).shape
            if output_shape != np.array(result).shape:
                result = broadcast_to(result, output_shape)

        return result