Esempio n. 1
0
def pick_ffd_points(centers, rvec):
    r"""
    Pick Lambda_dim points, for each centers, for a forward finite
    difference gradient approximation.  The points are returned in the order:
    centers, followed by the cluster around the first center, then the cluster
    around the second center and so on.
    :param centers: Points in :math:`\Lambda` the place stencil around
    :type centers: :class:`np.ndarray` of shape (num_centers, Lambda_dim)
    :param rvec: The radius of the stencil, along each axis
    :type rvec: :class:`np.ndarray` of shape (Lambda_dim,)
    :rtype: :class:`np.ndarray` of shape ((Lambda_dim+1)*num_centers,
        Lambda_dim)
    :returns: Samples for centered finite difference stencil for
        each point in centers.
    """
    Lambda_dim = centers.shape[1]
    num_centers = centers.shape[0]
    samples = np.repeat(centers, Lambda_dim, axis=0)
    rvec = util.fix_dimensions_vector(rvec)

    # Construct a [num_centers*(Lambda_dim+1), Lambda_dim] matrix that
    # translates the centers to the FFD points.
    translate = np.tile(np.eye(Lambda_dim) * rvec, (num_centers, 1))
    samples = samples + translate

    return np.concatenate([centers, samples])
Esempio n. 2
0
def pick_cfd_points(centers, rvec):
    r"""
    Pick 2*Lambda_dim points, for each center, for centered finite difference
    gradient approximation.  The center are not needed for the CFD gradient
    approximation, they are returned for consistency with the other methods and
    because of the common need to have not just the gradient but also the QoI
    value at the centers in adaptive sampling algorithms.The points are returned 
    in the order: centers, followed by the cluster around the first center, then 
    the cluster around the second center and so on.
    :param centers: Points in :math:`\Lambda` to cluster points around
    :type centers: :class:`np.ndarray` of shape (num_centers, Lambda_dim)
    :param rvec: The radius of the stencil, along each axis
    :type rvec: :class:`np.ndarray` of shape (Lambda_dim,)
    :rtype: :class:`np.ndarray` of shape ((2*Lambda_dim+1)*num_centers,
        Lambda_dim)
    :returns: Samples for centered finite difference stencil for
        each point in centers.
    """
    Lambda_dim = centers.shape[1]
    num_centers = centers.shape[0]
    samples = np.repeat(centers, 2 * Lambda_dim, axis=0)
    rvec = util.fix_dimensions_vector(rvec)

    # Contstruct a [num_centers*2*Lambda_dim, Lambda_dim] matrix that
    # translates the centers to the CFD points
    ident = np.eye(Lambda_dim) * rvec
    translate = np.tile(np.append(ident, -ident, axis=0), (num_centers, 1))
    samples = samples + translate

    return np.concatenate([centers, samples])
Esempio n. 3
0
def pick_cfd_points(centers, rvec):
    r"""
    Pick 2*Lambda_dim points, for each center, for centered finite difference
    gradient approximation.  The center are not needed for the CFD gradient
    approximation, they are returned for consistency with the other methods and
    because of the common need to have not just the gradient but also the QoI
    value at the centers in adaptive sampling algorithms.The points are returned 
    in the order: centers, followed by the cluster around the first center, then 
    the cluster around the second center and so on.
    :param centers: Points in :math:`\Lambda` to cluster points around
    :type centers: :class:`np.ndarray` of shape (num_centers, Lambda_dim)
    :param rvec: The radius of the stencil, along each axis
    :type rvec: :class:`np.ndarray` of shape (Lambda_dim,)
    :rtype: :class:`np.ndarray` of shape ((2*Lambda_dim+1)*num_centers,
        Lambda_dim)
    :returns: Samples for centered finite difference stencil for
        each point in centers.
    """
    Lambda_dim = centers.shape[1]
    num_centers = centers.shape[0]
    samples = np.repeat(centers, 2 * Lambda_dim, axis=0)
    rvec = util.fix_dimensions_vector(rvec)

    # Contstruct a [num_centers*2*Lambda_dim, Lambda_dim] matrix that
    # translates the centers to the CFD points
    ident = np.eye(Lambda_dim) * rvec
    translate = np.tile(np.append(ident, -ident, axis=0), (num_centers, 1))
    samples = samples + translate

    return np.concatenate([centers, samples])
Esempio n. 4
0
def pick_ffd_points(centers, rvec):
    r"""
    Pick Lambda_dim points, for each centers, for a forward finite
    difference gradient approximation.  The points are returned in the order:
    centers, followed by the cluster around the first center, then the cluster
    around the second center and so on.
    :param centers: Points in :math:`\Lambda` the place stencil around
    :type centers: :class:`np.ndarray` of shape (num_centers, Lambda_dim)
    :param rvec: The radius of the stencil, along each axis
    :type rvec: :class:`np.ndarray` of shape (Lambda_dim,)
    :rtype: :class:`np.ndarray` of shape ((Lambda_dim+1)*num_centers,
        Lambda_dim)
    :returns: Samples for centered finite difference stencil for
        each point in centers.
    """
    Lambda_dim = centers.shape[1]
    num_centers = centers.shape[0]
    samples = np.repeat(centers, Lambda_dim, axis=0)
    rvec = util.fix_dimensions_vector(rvec)

    # Construct a [num_centers*(Lambda_dim+1), Lambda_dim] matrix that
    # translates the centers to the FFD points.
    translate = np.tile(np.eye(Lambda_dim) * rvec, (num_centers, 1))
    samples = samples + translate

    return np.concatenate([centers, samples])
Esempio n. 5
0
def test_fix_dimensions_vector():
    """
    Tests :meth:`bet.util.fix_dimensions_vector`
    """
    values = [1, [1], range(5), np.array(range(5)), np.ones((5, 1)), np.ones((5, 5))]
    shapes = [(1,), (1,), (5,), (5,), (5,), (25,)]
    for value, shape in zip(values, shapes):
        vector = util.fix_dimensions_vector(value)
        assert vector.shape == shape
Esempio n. 6
0
def test_fix_dimensions_vector():
    """
    Tests :meth:`bet.util.fix_dimensions_vector`
    """
    values = [
        1, [1],
        range(5),
        np.array(range(5)),
        np.ones((5, 1)),
        np.ones((5, 5))
    ]
    shapes = [(1, ), (1, ), (5, ), (5, ), (5, ), (25, )]
    for value, shape in zip(values, shapes):
        vector = util.fix_dimensions_vector(value)
        assert vector.shape == shape
Esempio n. 7
0
def pick_cfd_points(input_set, radii_vec):
    r"""
    Pick 2*input_dim points, for each center, for centered finite difference
    gradient approximation.  The center are not needed for the CFD gradient
    approximation, they are returned for consistency with the other methods and
    because of the common need to have not just the gradient but also the QoI
    value at the centers in adaptive sampling algorithms.The points are returned 
    in the order: centers, followed by the cluster around the first center, then 
    the cluster around the second center and so on.
    
    :param input_set: The input sample set.  Make sure the attribute _values is
        not None
    :type input_set: :class:`~bet.sample.sample_set`
    :param radii_vec: The radius of the stencil, along each axis
    :type radii_vec: :class:`numpy.ndarray` of shape (input_dim,)
    
    :rtype: :class:`~bet.sample.sample_set`
    :returns: Centers and clusters of samples near each center (values are 
        :class:`numpy.ndarray` of shape ((``num_close+1``)*``num_centers``,
        ``input_dim``))
    
    """
    if input_set._values is None:
        raise ValueError("You must have values to use this method.")
    input_dim = input_set.get_dim()
    centers = input_set.get_values()
    num_centers = centers.shape[0]
    samples = np.repeat(centers, 2 * input_dim, axis=0)
    radii_vec = util.fix_dimensions_vector(radii_vec)

    # Contstruct a [num_centers*2*input_dim, input_dim] array that
    # translates the centers to the CFD points
    ident = np.eye(input_dim) * radii_vec
    translate = np.tile(np.append(ident, -ident, axis=0), (num_centers, 1))
    samples = samples + translate

    cluster_set = sample.sample_set(input_dim)
    if input_set.get_domain() is not None:
        cluster_set.set_domain(input_set.get_domain())
    cluster_set.set_values(centers)
    cluster_set.append_values(samples)
    return cluster_set
Esempio n. 8
0
def pick_cfd_points(input_set, radii_vec):
    r"""
    Pick 2*input_dim points, for each center, for centered finite difference
    gradient approximation.  The center are not needed for the CFD gradient
    approximation, they are returned for consistency with the other methods and
    because of the common need to have not just the gradient but also the QoI
    value at the centers in adaptive sampling algorithms.The points are returned 
    in the order: centers, followed by the cluster around the first center, then 
    the cluster around the second center and so on.
    
    :param input_set: The input sample set.  Make sure the attribute _values is
        not None
    :type input_set: :class:`~bet.sample.sample_set`
    :param radii_vec: The radius of the stencil, along each axis
    :type radii_vec: :class:`numpy.ndarray` of shape (input_dim,)
    
    :rtype: :class:`~bet.sample.sample_set`
    :returns: Centers and clusters of samples near each center (values are 
        :class:`numpy.ndarray` of shape ((``num_close+1``)*``num_centers``,
        ``input_dim``))
    
    """
    if input_set._values is None:
        raise ValueError("You must have values to use this method.")
    input_dim = input_set.get_dim()
    centers = input_set.get_values()
    num_centers = centers.shape[0]
    samples = np.repeat(centers, 2 * input_dim, axis=0)
    radii_vec = util.fix_dimensions_vector(radii_vec)

    # Contstruct a [num_centers*2*input_dim, input_dim] array that
    # translates the centers to the CFD points
    ident = np.eye(input_dim) * radii_vec
    translate = np.tile(np.append(ident, -ident, axis=0), (num_centers, 1))
    samples = samples + translate

    cluster_set = sample.sample_set(input_dim)
    if input_set.get_domain() is not None:
        cluster_set.set_domain(input_set.get_domain())
    cluster_set.set_values(centers)
    cluster_set.append_values(samples)
    return cluster_set
Esempio n. 9
0
def sample_linf_ball(centers, num_close, rvec, lam_domain=None):
    r"""
    Pick num_close points in a the l-infinity ball of length 2*rvec around a
    point in :math:`\Lambda`, do this for each point in centers.  If this box
    extends outside of :math:`\Lambda`, we sample the intersection.

    :param centers: Points in :math:`\Lambda` to cluster points around
    :type centers: :class:`np.ndarray` of shape (num_centers, Lambda_dim)
    :param int num_close: Number of points in each cluster
    :param rvec: Each side of the box will have length 2*rvec[i]
    :type rvec: :class:`np.ndarray` of shape (Lambda_dim,)
    :param lam_domain: The domain of the parameter space
    :type lam_domain: :class:`np.ndarray` of shape (Lambda_dim, 2)

    :rtype: :class:`np.ndarray` of shape ((num_close+1)*num_centers, Lambda_dim)
    :returns: Centers and clusters of samples near each center

    """
    Lambda_dim = centers.shape[1]
    num_centers = centers.shape[0]
    rvec = util.fix_dimensions_vector(rvec)

    #If no lam_domain, set domain large
    if lam_domain is None:
        lam_domain = np.zeros([Lambda_dim, 2])
        lam_domain[:, 0] = -sys.float_info[0]
        lam_domain[:, 1] = sys.float_info[0]

    # Define bounds for each box
    left = np.maximum(
        centers - rvec, np.ones([num_centers, Lambda_dim]) * lam_domain[:, 0])
    right = np.minimum(
        centers + rvec, np.ones([num_centers, Lambda_dim]) * lam_domain[:, 1])

    # Samples each box uniformly
    samples = np.repeat(right - left, num_close, axis=0) * np.random.random(
        [num_centers * num_close, Lambda_dim]) + np.repeat(left, num_close, \
        axis=0)

    return np.concatenate([centers, samples])
Esempio n. 10
0
def pick_ffd_points(input_set, radii_vec):
    r"""
    Pick input_dim points, for each centers, for a forward finite
    difference gradient approximation.  The points are returned in the order:
    centers, followed by the cluster around the first center, then the cluster
    around the second center and so on.
    
    :param input_set: The input sample set.  Make sure the attribute _values is
        not None
    :type input_set: :class:`~bet.sample.sample_set`
    :param radii_vec: The radius of the stencil, along each axis
    :type radii_vec: :class:`numpy.ndarray` of shape (input_dim,)
    
    :rtype: :class:`~bet.sample.sample_set`
    :returns: Centers and clusters of samples near each center (values are 
        :class:`numpy.ndarray` of shape ((``num_close+1``)*``num_centers``,
        ``input_dim``))
    
    """
    if input_set._values is None:
        raise ValueError("You must have values to use this method.")
    input_dim = input_set.get_dim()
    centers = input_set.get_values()
    num_centers = centers.shape[0]
    samples = np.repeat(centers, input_dim, axis=0)
    radii_vec = util.fix_dimensions_vector(radii_vec)

    # Construct a [num_centers*(input_dim+1), input_dim] matrix that
    # translates the centers to the FFD points.
    translate = np.tile(np.eye(input_dim) * radii_vec, (num_centers, 1))
    samples = samples + translate

    cluster_set = sample.sample_set(input_dim)
    if input_set.get_domain() is not None:
        cluster_set.set_domain(input_set.get_domain())
    cluster_set.set_values(centers)
    cluster_set.append_values(samples)
    return cluster_set
Esempio n. 11
0
def pick_ffd_points(input_set, radii_vec):
    r"""
    Pick input_dim points, for each centers, for a forward finite
    difference gradient approximation.  The points are returned in the order:
    centers, followed by the cluster around the first center, then the cluster
    around the second center and so on.
    
    :param input_set: The input sample set.  Make sure the attribute _values is
        not None
    :type input_set: :class:`~bet.sample.sample_set`
    :param radii_vec: The radius of the stencil, along each axis
    :type radii_vec: :class:`numpy.ndarray` of shape (input_dim,)
    
    :rtype: :class:`~bet.sample.sample_set`
    :returns: Centers and clusters of samples near each center (values are 
        :class:`numpy.ndarray` of shape ((``num_close+1``)*``num_centers``,
        ``input_dim``))
    
    """
    if input_set._values is None:
        raise ValueError("You must have values to use this method.")
    input_dim = input_set.get_dim()
    centers = input_set.get_values()
    num_centers = centers.shape[0]
    samples = np.repeat(centers, input_dim, axis=0)
    radii_vec = util.fix_dimensions_vector(radii_vec)

    # Construct a [num_centers*(input_dim+1), input_dim] matrix that
    # translates the centers to the FFD points.
    translate = np.tile(np.eye(input_dim) * radii_vec, (num_centers, 1))
    samples = samples + translate

    cluster_set = sample.sample_set(input_dim)
    if input_set.get_domain() is not None:
        cluster_set.set_domain(input_set.get_domain())
    cluster_set.set_values(centers)
    cluster_set.append_values(samples)
    return cluster_set
Esempio n. 12
0
def sample_linf_ball(centers, num_close, rvec, lam_domain=None):
    r"""
    Pick num_close points in a the l-infinity ball of length 2*rvec around a
    point in :math:`\Lambda`, do this for each point in centers.  If this box
    extends outside of :math:`\Lambda`, we sample the intersection.
    :param centers: Points in :math:`\Lambda` to cluster points around
    :type centers: :class:`np.ndarray` of shape (num_centers, Lambda_dim)
    :param int num_close: Number of points in each cluster
    :param rvec: Each side of the box will have length 2*rvec[i]
    :type rvec: :class:`np.ndarray` of shape (Lambda_dim,)
    :param lam_domain: The domain of the parameter space
    :type lam_domain: :class:`np.ndarray` of shape (Lambda_dim, 2)
    :rtype: :class:`np.ndarray` of shape ((num_close+1)*num_centers, Lambda_dim)
    :returns: Centers and clusters of samples near each center
    """
    Lambda_dim = centers.shape[1]
    num_centers = centers.shape[0]
    rvec = util.fix_dimensions_vector(rvec)

    #If no lam_domain, set domain large
    if lam_domain is None:
        lam_domain = np.zeros([Lambda_dim, 2])
        lam_domain[:, 0] = -sys.float_info[0]
        lam_domain[:, 1] = sys.float_info[0]

    # Define bounds for each box
    left = np.maximum(
        centers - rvec, np.ones([num_centers, Lambda_dim]) * lam_domain[:, 0])
    right = np.minimum(
        centers + rvec, np.ones([num_centers, Lambda_dim]) * lam_domain[:, 1])

    # Samples each box uniformly
    samples = np.repeat(right - left, num_close, axis=0) * np.random.random(
        [num_centers * num_close, Lambda_dim]) + np.repeat(left, num_close, \
        axis=0)

    return np.concatenate([centers, samples])
Esempio n. 13
0
def sample_l1_ball(centers, num_close, rvec):
    r"""
    Uniformly sample the l1-ball (defined by 2^dim simplices).  Then scale
    each dimension according to rvec and translate the center to centers.
    Do this for each point in centers.  *This method currently allows
    samples to be placed outside of lam_domain.  Please place your
    centers accordingly.*
    :param centers: Points in :math:`\Lambda` to cluster samples around
    :type centers: :class:`np.ndarray` of shape (num_centers, Ldim)
    :param int num_close: Number of samples in each l1 ball
    :param rvec: The radius of the l1 ball, along each axis
    :type rvec: :class:`np.ndarray` of shape (Lambda_dim)
    :rtype: :class:`np.ndarray` of shape ((num_close+1)*num_centers, Lambda_dim)
    :returns: Uniform random samples from an l1 ball around each center
    """
    Lambda_dim = centers.shape[1]
    rvec = util.fix_dimensions_vector(rvec)

    samples = np.zeros([(num_close + 1) * centers.shape[0], centers.shape[1]])
    samples[0:centers.shape[0], :] = centers

    # We choose weighted random distance from the center for each new sample
    random_dist = np.random.random([num_close, 1])
    weight_vec = random_dist**(1. / Lambda_dim)

    # For each center, randomly sample the l1_ball
    for cen in range(centers.shape[0]):
        # Begin by uniformly sampling the unit simplex in the first quadrant
        # Choose Lambda_dim-1 reals uniformly between 0 and weight_vec for each
        # new sample
        random_mat = np.random.random([num_close, Lambda_dim - 1]) * \
            np.tile(weight_vec, (1, Lambda_dim - 1))

        # Sort the random_mat
        random_mat = np.sort(random_mat, 1)

        # Contrust weight_mat so that the first column is zeros, the next
        # Lambda_dim-1 columns are the sorted reals between 0 and weight_vec,
        # and the last column is weight_vec.
        weight_mat = np.zeros([num_close, Lambda_dim + 1])
        weight_mat[:, 1:Lambda_dim] = random_mat
        weight_mat[:, Lambda_dim] = np.array(weight_vec).transpose()

        # The differences between the Lambda_dim+1 columns will give us
        # random points in the unit simplex of dimension Lambda_dim.
        samples_cen = np.zeros([num_close, Lambda_dim])
        for Ldim in range(Lambda_dim):
            samples_cen[:, Ldim] = weight_mat[:, Ldim + 1] - weight_mat[:, Ldim]

        # Assign a random sign to each element of each new sample
        # This give us samples in the l1_ball, not just the unit simplex in
        # the first quadrant
        rand_sign = 2 * np.round(np.random.random([num_close, Lambda_dim])) - 1
        samples_cen = samples_cen * rand_sign

        # Scale each dimension according to rvec and translate to center
        samples_cen = samples_cen * rvec + centers[cen, :]

        # Append newsamples to samples
        samples[centers.shape[0] + cen * num_close:centers.shape[0] + \
            (cen + 1) * num_close, :] = samples_cen

    return samples
Esempio n. 14
0
def sample_l1_ball(centers, num_close, rvec):
    r"""
    Uniformly sample the l1-ball (defined by 2^dim simplices).  Then scale
    each dimension according to rvec and translate the center to centers.
    Do this for each point in centers.  *This method currently allows
    samples to be placed outside of lam_domain.  Please place your
    centers accordingly.*
    :param centers: Points in :math:`\Lambda` to cluster samples around
    :type centers: :class:`np.ndarray` of shape (num_centers, Ldim)
    :param int num_close: Number of samples in each l1 ball
    :param rvec: The radius of the l1 ball, along each axis
    :type rvec: :class:`np.ndarray` of shape (Lambda_dim)
    :rtype: :class:`np.ndarray` of shape ((num_close+1)*num_centers, Lambda_dim)
    :returns: Uniform random samples from an l1 ball around each center
    """
    Lambda_dim = centers.shape[1]
    rvec = util.fix_dimensions_vector(rvec)

    samples = np.zeros([(num_close + 1) * centers.shape[0], centers.shape[1]])
    samples[0:centers.shape[0], :] = centers

    # We choose weighted random distance from the center for each new sample
    random_dist = np.random.random([num_close, 1])
    weight_vec = random_dist**(1. / Lambda_dim)

    # For each center, randomly sample the l1_ball
    for cen in range(centers.shape[0]):
        # Begin by uniformly sampling the unit simplex in the first quadrant
        # Choose Lambda_dim-1 reals uniformly between 0 and weight_vec for each
        # new sample
        random_mat = np.random.random([num_close, Lambda_dim - 1]) * \
            np.tile(weight_vec, (1, Lambda_dim - 1))

        # Sort the random_mat
        random_mat = np.sort(random_mat, 1)

        # Contrust weight_mat so that the first column is zeros, the next
        # Lambda_dim-1 columns are the sorted reals between 0 and weight_vec,
        # and the last column is weight_vec.
        weight_mat = np.zeros([num_close, Lambda_dim + 1])
        weight_mat[:, 1:Lambda_dim] = random_mat
        weight_mat[:, Lambda_dim] = np.array(weight_vec).transpose()

        # The differences between the Lambda_dim+1 columns will give us
        # random points in the unit simplex of dimension Lambda_dim.
        samples_cen = np.zeros([num_close, Lambda_dim])
        for Ldim in range(Lambda_dim):
            samples_cen[:, Ldim] = weight_mat[:, Ldim + 1] - weight_mat[:, Ldim]

        # Assign a random sign to each element of each new sample
        # This give us samples in the l1_ball, not just the unit simplex in
        # the first quadrant
        rand_sign = 2 * np.round(np.random.random([num_close, Lambda_dim])) - 1
        samples_cen = samples_cen * rand_sign

        # Scale each dimension according to rvec and translate to center
        samples_cen = samples_cen * rvec + centers[cen, :]

        # Append newsamples to samples
        samples[centers.shape[0] + cen * num_close:centers.shape[0] + \
            (cen + 1) * num_close, :] = samples_cen

    return samples