# Path: py/dynesty/utils.py
# def unitcheck(u, nonbounded=None):
#     """Check whether `u` is inside the unit cube. Given a masked array
#     `nonbounded`, also allows periodic boundaries conditions to exceed
#     the unit cube."""
# 
#     if nonbounded is None:
#         # No periodic boundary conditions provided.
#         return np.min(u) > 0 and np.max(u) < 1
#     else:
#         # Alternating periodic and non-periodic boundary conditions.
#         unb = u[nonbounded]
#         # pylint: disable=invalid-unary-operand-type
#         ub = u[~nonbounded]
#         return (unb.min() > 0 and unb.max() < 1 and ub.min() > -0.5
#                 and ub.max() < 1.5)
# 
# def apply_reflect(u):
#     """
#     Iteratively reflect a number until it is contained in [0, 1].
# 
#     This is for priors with a reflective boundary condition, all numbers in the
#     set `u = 2n +/- x` should be mapped to x.
# 
#     For the `+` case we just take `u % 1`.
#     For the `-` case we take `1 - (u % 1)`.
# 
#     E.g., -0.9, 1.1, and 2.9 should all map to 0.9.
# 
#     Parameters
#     ----------
#     u: array-like
#         The array of points to map to the unit cube
# 
#     Returns
#     -------
#     u: array-like
#        The input array, modified in place.
#     """
#     idxs_even = np.mod(u, 2) < 1
#     u[idxs_even] = np.mod(u[idxs_even], 1)
#     u[~idxs_even] = 1 - np.mod(u[~idxs_even], 1)
#     return u
# 
# def get_random_generator(seed=None):
#     """
#     Return a random generator (using the seed provided if available)
#     """
#     return np.random.Generator(np.random.PCG64(seed))
# 
# Path: py/dynesty/bounding.py
# def randsphere(n, rstate=None):
#     """Draw a point uniformly within an `n`-dimensional unit sphere."""
# 
#     z = rstate.standard_normal(size=n)  # initial n-dim vector
#     xhat = z * (rstate.uniform()**(1. / n) / lalg.norm(z))  # scale
#     return xhat


import warnings
import math
import numpy as np
from numpy import linalg
from .utils import unitcheck, apply_reflect, get_random_generator
from .bounding import randsphere
    Here we are proposing points uniformly within an n-d ellipsoid.
    We are only trying once.
    We return the tuple with
    1) proposed point or None
    2) failure flag (if True, the generated point was outside bounds)
    """

    # starting point for clustered dimensions
    u_cluster = u[:n_cluster]

    # draw random point for non clustering parameters
    # we only need to generate them once
    u_non_cluster = rstate.uniform(0, 1, n - n_cluster)
    u_prop = np.zeros(n)
    u_prop[n_cluster:] = u_non_cluster

    # Propose a direction on the unit n-sphere.
    dr = randsphere(n_cluster, rstate=rstate)
    # This generates uniform distribution within n-d ball

    # Transform to proposal distribution.
    du = np.dot(axes, dr)
    u_prop[:n_cluster] = u_cluster + scale * du

    # Wrap periodic parameters
    if periodic is not None:
        u_prop[periodic] = np.mod(u_prop[periodic], 1)

    # Reflect
    if reflective is not None:

# Path: py/dynesty/utils.py
# def unitcheck(u, nonbounded=None):
#     """Check whether `u` is inside the unit cube. Given a masked array
#     `nonbounded`, also allows periodic boundaries conditions to exceed
#     the unit cube."""
# 
#     if nonbounded is None:
#         # No periodic boundary conditions provided.
#         return np.min(u) > 0 and np.max(u) < 1
#     else:
#         # Alternating periodic and non-periodic boundary conditions.
#         unb = u[nonbounded]
#         # pylint: disable=invalid-unary-operand-type
#         ub = u[~nonbounded]
#         return (unb.min() > 0 and unb.max() < 1 and ub.min() > -0.5
#                 and ub.max() < 1.5)
# 
# def apply_reflect(u):
#     """
#     Iteratively reflect a number until it is contained in [0, 1].
# 
#     This is for priors with a reflective boundary condition, all numbers in the
#     set `u = 2n +/- x` should be mapped to x.
# 
#     For the `+` case we just take `u % 1`.
#     For the `-` case we take `1 - (u % 1)`.
# 
#     E.g., -0.9, 1.1, and 2.9 should all map to 0.9.
# 
#     Parameters
#     ----------
#     u: array-like
#         The array of points to map to the unit cube
# 
#     Returns
#     -------
#     u: array-like
#        The input array, modified in place.
#     """
#     idxs_even = np.mod(u, 2) < 1
#     u[idxs_even] = np.mod(u[idxs_even], 1)
#     u[~idxs_even] = 1 - np.mod(u[~idxs_even], 1)
#     return u
# 
# def get_random_generator(seed=None):
#     """
#     Return a random generator (using the seed provided if available)
#     """
#     return np.random.Generator(np.random.PCG64(seed))
# 
# Path: py/dynesty/bounding.py
# def randsphere(n, rstate=None):
#     """Draw a point uniformly within an `n`-dimensional unit sphere."""
# 
#     z = rstate.standard_normal(size=n)  # initial n-dim vector
#     xhat = z * (rstate.uniform()**(1. / n) / lalg.norm(z))  # scale
#     return xhat


# Path: py/dynesty/sampling.py
import warnings
import math
import numpy as np
from numpy import linalg
from .utils import unitcheck, apply_reflect, get_random_generator
from .bounding import randsphere

    Here we are proposing points uniformly within an n-d ellipsoid.
    We are only trying once.
    We return the tuple with
    1) proposed point or None
    2) failure flag (if True, the generated point was outside bounds)
    """

    # starting point for clustered dimensions
    u_cluster = u[:n_cluster]

    # draw random point for non clustering parameters
    # we only need to generate them once
    u_non_cluster = rstate.uniform(0, 1, n - n_cluster)
    u_prop = np.zeros(n)
    u_prop[n_cluster:] = u_non_cluster

    # Propose a direction on the unit n-sphere.
    dr = randsphere(n_cluster, rstate=rstate)
    # This generates uniform distribution within n-d ball

    # Transform to proposal distribution.
    du = np.dot(axes, dr)
    u_prop[:n_cluster] = u_cluster + scale * du

    # Wrap periodic parameters
    if periodic is not None:
        u_prop[periodic] = np.mod(u_prop[periodic], 1)

    # Reflect
    if reflective is not None:

        u_prop[reflective] = apply_reflect(u_prop[reflective])