Beispiel #1
0
    def test_get_rbf_matrix(self):
        """Test basic properties of the RBF matrix (e.g. symmetry, size).

        Verify that the RBF matrix is symmetric and it has the correct
        size for all types of RBF.
        """
        settings = RbfoptSettings()
        for i in range(50):
            dim = np.random.randint(1, 20)
            num_points = np.random.randint(10, 50)
            node_pos = np.random.uniform(-100, 100, size=(num_points, dim))
            # Possible shapes of the matrix
            for rbf_type in self.rbf_types:
                settings.rbf = rbf_type
                mat = ru.get_rbf_matrix(settings, dim, num_points, node_pos)
                self.assertIsInstance(mat, np.ndarray)
                self.assertEqual(len(mat.shape), 2)
                self.assertAlmostEqual(np.max(mat - mat.transpose()),
                                       0.0,
                                       msg='RBF matrix is not symmetric')
                size = num_points
                if (ru.get_degree_polynomial(settings) >= 0):
                    size += 1
                if (ru.get_degree_polynomial(settings) > 0):
                    size += dim**ru.get_degree_polynomial(settings)
                self.assertEqual(mat.shape, (size, size))
        # Check that exception is raised for unknown RBF types
        settings.rbf = 'unknown'
        self.assertRaises(ValueError, ru.get_rbf_matrix, settings, dim,
                          num_points, node_pos)
Beispiel #2
0
    def test_get_rbf_matrix(self):
        """Test basic properties of the RBF matrix (e.g. symmetry, size).

        Verify that the RBF matrix is symmetric and it has the correct
        size for all types of RBF.
        """
        settings = RbfoptSettings()
        for i in range(50):
            dim = np.random.randint(1, 20)
            num_points = np.random.randint(10, 50)
            node_pos = np.random.uniform(-100, 100, size=(num_points,dim))
            # Possible shapes of the matrix
            for rbf_type in self.rbf_types:
                settings.rbf = rbf_type
                mat = ru.get_rbf_matrix(settings, dim, num_points, node_pos)
                self.assertIsInstance(mat, np.matrix)
                self.assertAlmostEqual(np.max(mat - mat.transpose()), 0.0,
                                       msg='RBF matrix is not symmetric')
                size = num_points
                if (ru.get_degree_polynomial(settings) >= 0):
                    size += 1
                if (ru.get_degree_polynomial(settings) > 0):
                    size += dim ** ru.get_degree_polynomial(settings)
                self.assertEqual(mat.shape, (size, size))
        # Check that exception is raised for unknown RBF types
        settings.rbf = 'unknown'
        self.assertRaises(ValueError, ru.get_rbf_matrix, settings, 
                          dim, num_points, node_pos)
Beispiel #3
0
 def test_get_degree_polynomial(self):
     """Verify that the degree is always between 0 and 1."""
     settings = RbfoptSettings()
     for rbf_type in self.rbf_types:
         settings.rbf = rbf_type
         degree = ru.get_degree_polynomial(settings)
         self.assertTrue(-1 <= degree <= 1)
Beispiel #4
0
 def test_get_degree_polynomial(self):
     """Verify that the degree is always between 0 and 1."""
     settings = RbfoptSettings()
     for rbf_type in self.rbf_types:
         settings.rbf = rbf_type
         degree = ru.get_degree_polynomial(settings)
         self.assertTrue(-1 <= degree <= 1)
Beispiel #5
0
def create_min_msrsm_model(settings, n, k, var_lower, var_upper, integer_vars,
                           node_pos, rbf_lambda, rbf_h, dist_weight, dist_min,
                           dist_max, fmin, fmax):
    """Create the concrete model to optimize the MSRSM objective.

    Create the concreate model to minimize a weighted combination of
    the value of the RBF interpolant and the (negative of the)
    distance from the closes interpolation node. This is the Global
    Search Step of the MSRSM method.

    Parameters
    ----------

    settings : :class:`rbfopt_settings.RbfoptSettings`
        Global and algorithmic settings.

    n : int
        The dimension of the problem, i.e. size of the space.

    k : int
        Number of nodes, i.e. interpolation points.

    var_lower : 1D numpy.ndarray[float]
        Vector of variable lower bounds.

    var_upper : 1D numpy.ndarray[float]
        Vector of variable upper bounds.

    integer_vars : 1D numpy.ndarray[int]
        List of indices of integer variables.

    node_pos : 2D numpy.ndarray[float]
        List of coordinates of the nodes (one on each row).

    rbf_lambda : 1D numpy.ndarray[float]
        The lambda coefficients of the RBF interpolant, corresponding
        to the radial basis functions. List of dimension k.

    rbf_h : 1D numpy.ndarray[float]
        The h coefficients of the RBF interpolant, corresponding to
        the polynomial. List of dimension n+1.

    dist_weight : float
        The weight paramater for distance and RBF interpolant
        value. Must be between 0 and 1. A weight of 1.0 corresponds to
        using solely distance, 0.0 to objective function.

    dist_min : float
        The minimum distance between two interpolation nodes.

    dist_max : float
        The maximum distance between two interpolation nodes.

    fmin : float
        The minimum value of an interpolation node.

    fmax : float
        The maximum value of an interpolation node.

    Returns
    -------
    pyomo.ConcreteModel
        The concrete model describing the problem.

    """
    assert (isinstance(var_lower, np.ndarray))
    assert (isinstance(var_upper, np.ndarray))
    assert (isinstance(integer_vars, np.ndarray))
    assert (isinstance(node_pos, np.ndarray))
    assert (isinstance(rbf_lambda, np.ndarray))
    assert (isinstance(rbf_h, np.ndarray))
    assert (len(var_lower) == n)
    assert (len(var_upper) == n)
    assert (len(rbf_lambda) == k)
    assert (len(rbf_h) == 1)
    assert (len(node_pos) == k)
    assert (isinstance(settings, RbfoptSettings))
    assert (ru.get_degree_polynomial(settings) == 0)
    assert (0 <= dist_weight <= 1)
    assert (dist_max >= dist_min >= 0)

    model = ConcreteModel()

    # Dimension of the space
    model.n = Param(initialize=n)
    model.N = RangeSet(0, model.n - 1)

    # Number of interpolation nodes
    model.k = Param(initialize=k)
    model.K = RangeSet(0, model.k - 1)

    # Dimension of u_pi
    model.q = Param(initialize=(k + 1))
    model.Q = RangeSet(0, model.q - 1)

    # Coefficients of the RBF
    lambda_h_param = {}
    for i in range(k):
        lambda_h_param[i] = float(rbf_lambda[i])
    for i in range(1):
        lambda_h_param[k + i] = float(rbf_h[i])
    model.lambda_h = Param(model.Q, initialize=lambda_h_param)

    # Coordinates of the nodes
    node_param = {}
    for i in range(k):
        for j in range(n):
            node_param[i, j] = float(node_pos[i][j])
    model.node = Param(model.K, model.N, initialize=node_param)

    # Variable bounds
    var_lower_param = {}
    var_upper_param = {}
    for i in range(n):
        var_lower_param[i] = float(var_lower[i])
        var_upper_param[i] = float(var_upper[i])
    model.var_lower = Param(model.N, initialize=var_lower_param)
    model.var_upper = Param(model.N, initialize=var_upper_param)

    # Adjust parameters to avoid zero denominators in expressions
    if (fmax <= fmin + settings.eps_zero):
        fmax = fmin + 1
    if (dist_max <= dist_min + settings.eps_zero):
        dist_min = dist_max - 1
    # Minimum and maximum distance
    model.dist_min = Param(initialize=dist_min)
    model.dist_max = Param(initialize=dist_max)
    # Minimum and maximum of function values interpolation nodes
    model.fmin = Param(initialize=fmin)
    model.fmax = Param(initialize=fmax)
    # Weight of the distance and objective criteria
    model.dist_weight = Param(initialize=dist_weight)
    model.obj_weight = Param(
        initialize=(1.0 if settings.modified_msrsm_score else 1 - dist_weight))

    # Value of phi at zero, necessary for shift
    if (settings.rbf == 'linear'):
        model.phi_0 = Param(initialize=0.0)
    elif (settings.rbf == 'multiquadric'):
        model.phi_0 = Param(initialize=settings.rbf_shape_parameter)
        model.gamma = Param(initialize=settings.rbf_shape_parameter)

    # Variable: the point in the space
    model.x = Var(model.N, domain=Reals, bounds=_x_bounds)

    # Auxiliary variable: value of the minimum distance to the nodes
    model.mindistsq = Var(domain=NonNegativeReals,
                          bounds=(settings.min_dist, float('inf')))

    # Objective function.
    if (settings.rbf == 'linear'):
        model.OBJ = Objective(rule=_min_msrsm_obj_expression_linear,
                              sense=minimize)
    elif (settings.rbf == 'multiquadric'):
        model.OBJ = Objective(rule=_min_msrsm_obj_expression_mq,
                              sense=minimize)
    model.MdistdefConstraint = Constraint(model.K,
                                          rule=_mdistdef_constraint_rule)

    # Add integer variables if necessary
    if (len(integer_vars)):
        add_integrality_constraints(model, integer_vars)

    return model
Beispiel #6
0
def create_min_bump_model(settings, n, k, Phimat, Pmat, node_val,
                          node_err_bounds):
    """Create a model to find RBF coefficients with min bumpiness.

    Create a quadratic problem to compute the coefficients of the RBF
    interpolant that minimizes bumpiness and lets all points deviate
    by a specified amount from their value.

    Parameters
    ----------
    settings : :class:`rbfopt_settings.RbfoptSettings`
        Global and algorithmic settings.

    n : int
        The dimension of the problem, i.e. size of the space.

    k : int
        Number of nodes, i.e. interpolation points.

    Phimat : numpy.matrix
        Matrix Phi, i.e. top left part of the standard RBF matrix.

    Pmat : numpy.matrix
        Matrix P, i.e. top right part of the standard RBF matrix.

    node_val : 1D numpy.ndarray[float]
        List of values of the function at the nodes.

    node_err_bounds : 2D numpy.ndarray[float]
        Allowed deviation from node values for nodes affected by
        error. This is a matrix with rows (lower_deviation, 
        upper_deviation).

    Returns
    -------
    pyomo.ConcreteModel
        The concrete model describing the problem.
    """
    assert (isinstance(settings, RbfoptSettings))
    assert (isinstance(node_val, np.ndarray))
    assert (isinstance(node_err_bounds, np.ndarray))
    assert (len(node_val) == k)
    assert (isinstance(Phimat, np.matrix))
    assert (isinstance(Pmat, np.matrix))
    assert (Phimat.shape == (k, k))
    assert (Pmat.shape == (k, 1))
    assert (len(node_val) == len(node_err_bounds))
    assert (ru.get_degree_polynomial(settings) == 0)

    model = ConcreteModel()

    # Dimension of the space
    model.n = Param(initialize=n)
    model.N = RangeSet(0, model.n - 1)

    # Dimension of P matrix
    model.p = Param(initialize=1)
    model.P = RangeSet(0, 0)

    # Number of interpolation nodes
    model.k = Param(initialize=k)
    model.K = RangeSet(0, model.k - 1)

    # Node values, i.e. right hand sides of the first set of equations
    # in the constraints
    node_val_param = {}
    for i in range(k):
        node_val_param[i] = node_val[i]
    model.node_val = Param(model.K, initialize=node_val_param)

    # Variable bounds
    slack_lower_param = {}
    slack_upper_param = {}
    for i in np.where(node_err_bounds[:, 1] -
                      node_err_bounds[:, 0] > settings.eps_zero)[0]:
        slack_lower_param[i] = float(node_err_bounds[i, 0])
        slack_upper_param[i] = float(node_err_bounds[i, 1])
    model.slack_lower = Param(model.K,
                              initialize=slack_lower_param,
                              default=0.0)
    model.slack_upper = Param(model.K,
                              initialize=slack_upper_param,
                              default=0.0)

    # Phi matrix.
    Phi_param = {}
    for i in range(k):
        for j in range(k):
            if (abs(Phimat[i, j]) != 0.0):
                Phi_param[i, j] = float(Phimat[i, j])
    model.Phi = Param(model.K, model.K, initialize=Phi_param, default=0.0)

    # P matrix.
    Pm_param = {}
    for i in range(k):
        for j in range(1):
            if (abs(Pmat[i, j]) != 0.0):
                Pm_param[i, j] = float(Pmat[i, j])
    model.Pm = Param(model.K, model.P, initialize=Pm_param, default=0.0)

    # Variable: the lambda coefficients of the RBF
    model.rbf_lambda = Var(model.K, domain=Reals)

    # Variable: the h coefficients of the RBF
    model.rbf_h = Var(model.P, domain=Reals)

    # Variable: the slacks for the equality constraints
    model.slack = Var(model.K, domain=Reals, bounds=_slack_bounds)

    # Objective function.
    model.OBJ = Objective(rule=_min_bump_obj_expression, sense=minimize)

    # Constraints. See definitions below.
    model.IntrConstraint = Constraint(model.K, rule=_intr_constraint_rule)
    model.UnisConstraint = Constraint(model.P, rule=_unis_constraint_rule)

    return model
Beispiel #7
0
def create_max_h_k_model(settings, n, k, var_lower, var_upper, integer_vars,
                         node_pos, rbf_lambda, rbf_h, mat, target_val):
    """Create the abstract model to maximize h_k.

    Create the abstract model to maximize h_k, also known as the
    Global Search Step of the RBF method.

    Parameters
    ----------

    settings : :class:`rbfopt_settings.RbfoptSettings`
        Global and algorithmic settings.

    n : int
        The dimension of the problem, i.e. size of the space.

    k : int
        Number of nodes, i.e. interpolation points.

    var_lower : 1D numpy.ndarray[float]
        Vector of variable lower bounds.

    var_upper : 1D numpy.ndarray[float]
        Vector of variable upper bounds.

    integer_vars : 1D numpy.ndarray[int]
        List of indices of integer variables.

    node_pos : 2D numpy.ndarray[float]
        List of coordinates of the nodes (one on each row).

    rbf_lambda : 1D numpy.ndarray[float]
        The lambda coefficients of the RBF interpolant, corresponding
        to the radial basis functions. List of dimension k.

    rbf_h : 1D numpy.ndarray[float]
        The h coefficients of the RBF interpolant, corresponding to
        the polynomial. List of dimension n+1.

    mat: numpy.matrix
        The matrix necessary for the computation. This is the inverse
        of the matrix [Phi P; P^T 0], see paper as cited above. Must
        be a numpy.matrix of dimension ((k+1) x (k+1))

    target_val : float
        Value f* that we want to find in the unknown objective
        function.

    Returns
    -------
    pyomo.ConcreteModel
        The concrete model describing the problem.
    """
    assert (isinstance(var_lower, np.ndarray))
    assert (isinstance(var_upper, np.ndarray))
    assert (isinstance(integer_vars, np.ndarray))
    assert (isinstance(node_pos, np.ndarray))
    assert (isinstance(rbf_lambda, np.ndarray))
    assert (isinstance(rbf_h, np.ndarray))
    assert (len(var_lower) == n)
    assert (len(var_upper) == n)
    assert (len(rbf_lambda) == k)
    assert (len(rbf_h) == 1)
    assert (len(node_pos) == k)
    assert (isinstance(mat, np.matrix))
    assert (mat.shape == (k + 1, k + 1))
    assert (isinstance(settings, RbfoptSettings))
    assert (ru.get_degree_polynomial(settings) == 0)

    model = ConcreteModel()

    # Dimension of the space
    model.n = Param(initialize=n)
    model.N = RangeSet(0, model.n - 1)

    # Number of interpolation nodes
    model.k = Param(initialize=k)
    model.K = RangeSet(0, model.k - 1)

    # Dimension of the matrix
    model.q = Param(initialize=(k + 1))
    model.Q = RangeSet(0, model.q - 1)

    # Coefficients of the RBF
    lambda_h_param = {}
    for i in range(k):
        lambda_h_param[i] = float(rbf_lambda[i])
    for i in range(1):
        lambda_h_param[k + i] = float(rbf_h[i])
    model.lambda_h = Param(model.Q, initialize=lambda_h_param)

    # Coordinates of the nodes
    node_param = {}
    for i in range(k):
        for j in range(n):
            node_param[i, j] = float(node_pos[i][j])
    model.node = Param(model.K, model.N, initialize=node_param)

    # Variable bounds
    var_lower_param = {}
    var_upper_param = {}
    for i in range(n):
        var_lower_param[i] = float(var_lower[i])
        var_upper_param[i] = float(var_upper[i])
    model.var_lower = Param(model.N, initialize=var_lower_param)
    model.var_upper = Param(model.N, initialize=var_upper_param)

    # Inverse of the matrix [Phi P; P^T 0]. Because the matrix is
    # symmetric, we only save the upper right part, while doubling the
    # off-diagonal elements.
    Ainv_param = {}
    for i in range(k + 1):
        for j in range(i, k + 1):
            if (abs(mat[i, j]) != 0.0):
                if (i == j):
                    Ainv_param[i, j] = float(mat[i, j])
                else:
                    Ainv_param[i, j] = float(2 * mat[i, j])
    model.Ainv = Param(model.Q, model.Q, initialize=Ainv_param, default=0.0)

    # Target value
    model.fstar = Param(initialize=target_val)

    # Value of phi at zero, necessary for shift
    if (settings.rbf == 'linear'):
        model.phi_0 = Param(initialize=0.0)
    elif (settings.rbf == 'multiquadric'):
        model.phi_0 = Param(initialize=settings.rbf_shape_parameter)
        model.gamma = Param(initialize=settings.rbf_shape_parameter)

    # Variable: the point in the space
    model.x = Var(model.N, domain=Reals, bounds=_x_bounds)

    # Objective function.
    if (settings.rbf == 'linear'):
        model.OBJ = Objective(rule=_max_h_k_obj_expression_linear,
                              sense=maximize)
    elif (settings.rbf == 'multiquadric'):
        model.OBJ = Objective(rule=_max_h_k_obj_expression_mq, sense=maximize)

    # Add integer variables if necessary
    if (len(integer_vars)):
        add_integrality_constraints(model, integer_vars)

    return model
Beispiel #8
0
def create_min_rbf_model(settings, n, k, var_lower, var_upper, integer_vars,
                         node_pos, rbf_lambda, rbf_h):
    """Create the concrete model to minimize the RBF.

    Create the concrete model to minimize the RBF.

    Parameters
    ----------

    settings : :class:`rbfopt_settings.RbfoptSettings`
        Global and algorithmic settings.

    n : int
        The dimension of the problem, i.e. size of the space.

    k : int
        Number of nodes, i.e. interpolation points.

    var_lower : 1D numpy.ndarray[float]
        Vector of variable lower bounds.

    var_upper : 1D numpy.ndarray[float]
        Vector of variable upper bounds.

    integer_vars : 1D numpy.ndarray[int]
        List of indices of integer variables.

    node_pos : 2D numpy.ndarray[float]
        List of coordinates of the nodes.

    rbf_lambda : 1D numpy.ndarray[float]
        The lambda coefficients of the RBF interpolant, corresponding
        to the radial basis functions. List of dimension k.

    rbf_h : 1D numpy.ndarray[float]
        The h coefficients of the RBF interpolant, corresponding to
        the polynomial. List of dimension n+1.

    Returns
    -------
    pyomo.ConcreteModel
        The concrete model describing the problem.
    """
    assert (isinstance(var_lower, np.ndarray))
    assert (isinstance(var_upper, np.ndarray))
    assert (isinstance(integer_vars, np.ndarray))
    assert (isinstance(node_pos, np.ndarray))
    assert (isinstance(rbf_lambda, np.ndarray))
    assert (isinstance(rbf_h, np.ndarray))
    assert (len(var_lower) == n)
    assert (len(var_upper) == n)
    assert (len(rbf_lambda) == k)
    assert (len(rbf_h) == 1)
    assert (len(node_pos) == k)
    assert (isinstance(settings, RbfoptSettings))
    assert (ru.get_degree_polynomial(settings) == 0)

    model = ConcreteModel()

    # Dimension of the space
    model.n = Param(initialize=n)
    model.N = RangeSet(0, model.n - 1)

    # Number of interpolation nodes
    model.k = Param(initialize=k)
    model.K = RangeSet(0, model.k - 1)

    # Dimension of u_pi
    model.q = Param(initialize=(k + 1))
    model.Q = RangeSet(0, model.q - 1)

    # Coefficients of the RBF
    lambda_h_param = {}
    for i in range(k):
        lambda_h_param[i] = float(rbf_lambda[i])
    for i in range(1):
        lambda_h_param[k + i] = float(rbf_h[i])
    model.lambda_h = Param(model.Q, initialize=lambda_h_param)

    # Coordinates of the nodes
    node_param = {}
    for i in range(k):
        for j in range(n):
            node_param[i, j] = float(node_pos[i][j])
    model.node = Param(model.K, model.N, initialize=node_param)

    # Variable bounds
    var_lower_param = {}
    var_upper_param = {}
    for i in range(n):
        var_lower_param[i] = float(var_lower[i])
        var_upper_param[i] = float(var_upper[i])
    model.var_lower = Param(model.N, initialize=var_lower_param)
    model.var_upper = Param(model.N, initialize=var_upper_param)

    # Variable: the point in the space
    model.x = Var(model.N, domain=Reals, bounds=_x_bounds)

    if (settings.rbf == 'linear'):
        model.OBJ = Objective(rule=_min_rbf_obj_expression_linear,
                              sense=minimize)
    elif (settings.rbf == 'multiquadric'):
        model.gamma = Param(initialize=settings.rbf_shape_parameter)
        model.OBJ = Objective(rule=_min_rbf_obj_expression_mq, sense=minimize)

    # Add integer variables if necessary
    if (len(integer_vars)):
        add_integrality_constraints(model, integer_vars)

    return model
Beispiel #9
0
def create_max_one_over_mu_model(settings, n, k, var_lower, var_upper,
                                 integer_vars, node_pos, mat):
    """Create the concrete model to maximize 1/\mu.

    Create the concrete model to maximize :math: `1/\mu`, also known
    as the InfStep of the RBF method.

    See paper by Costa and Nannicini, equation (7) pag 4, and the
    references therein.

    Parameters
    ----------

    settings : :class:`rbfopt_settings.RbfoptSettings`
        Global and algorithmic settings.

    n : int
        The dimension of the problem, i.e. size of the space.

    k : int
        Number of nodes, i.e. interpolation points.

    var_lower : 1D numpy.ndarray[float]
        Vector of variable lower bounds.

    var_upper : 1D numpy.ndarray[float]
        Vector of variable upper bounds.

    integer_vars : 1D numpy.ndarray[int]
        List of indices of integer variables.

    node_pos : 2D numpy.ndarray[float]
        List of coordinates of the nodes (one on each row).

    mat: numpy.matrix
        The matrix necessary for the computation. This is the inverse
        of the matrix [Phi P; P^T 0], see paper as cited above. Must
        be a numpy.matrix of dimension ((k+1) x (k+1))

    Returns
    -------
    pyomo.ConcreteModel
        The concrete model describing the problem.
    """
    assert (isinstance(var_lower, np.ndarray))
    assert (isinstance(var_upper, np.ndarray))
    assert (isinstance(integer_vars, np.ndarray))
    assert (isinstance(node_pos, np.ndarray))
    assert (len(var_lower) == n)
    assert (len(var_upper) == n)
    assert (len(node_pos) == k)
    assert (isinstance(mat, np.matrix))
    assert (mat.shape == (k, k))
    assert (isinstance(settings, RbfoptSettings))
    assert (ru.get_degree_polynomial(settings) == -1)

    model = ConcreteModel()

    # Dimension of the space
    model.n = Param(initialize=n)
    model.N = RangeSet(0, model.n - 1)

    # Number of interpolation nodes
    model.k = Param(initialize=k)
    model.K = RangeSet(0, model.k - 1)

    # Coordinates of the nodes
    node_param = {}
    for i in range(k):
        for j in range(n):
            node_param[i, j] = float(node_pos[i][j])
    model.node = Param(model.K, model.N, initialize=node_param)

    # Variable bounds
    var_lower_param = {}
    var_upper_param = {}
    for i in range(n):
        var_lower_param[i] = float(var_lower[i])
        var_upper_param[i] = float(var_upper[i])
    model.var_lower = Param(model.N, initialize=var_lower_param)
    model.var_upper = Param(model.N, initialize=var_upper_param)

    # Inverse of the matrix [Phi P; P^T 0]. Because the matrix is
    # symmetric, we only save the upper right part, while doubling the
    # off-diagonal elements.
    Ainv_param = {}
    for i in range(k):
        for j in range(i, k):
            if (abs(mat[i, j]) != 0.0):
                if (i == j):
                    Ainv_param[i, j] = float(mat[i, j])
                else:
                    Ainv_param[i, j] = float(2 * mat[i, j])
    model.Ainv = Param(model.K, model.K, initialize=Ainv_param, default=0.0)

    if (settings.rbf == 'gaussian'):
        model.phi_0 = Param(initialize=1.0)
        model.gamma = Param(initialize=settings.rbf_shape_parameter)

    # Variable: the point in the space
    model.x = Var(model.N, domain=Reals, bounds=_x_bounds)

    # Objective function.
    if (settings.rbf == 'gaussian'):
        model.OBJ = Objective(rule=_max_one_over_mu_obj_expression_gaussian,
                              sense=maximize)

    # Add integer variables if necessary
    if (len(integer_vars)):
        add_integrality_constraints(model, integer_vars)

    return model
def create_min_rbf_model(settings, n, k, var_lower, var_upper, integer_vars,
                         categorical_info, node_pos, rbf_lambda, rbf_h):
    """Create the concrete model to minimize the RBF.

    Create the concrete model to minimize the RBF.

    Parameters
    ----------

    settings : :class:`rbfopt_settings.RbfoptSettings`
        Global and algorithmic settings.

    n : int
        The dimension of the problem, i.e. size of the space.

    k : int
        Number of nodes, i.e. interpolation points.

    var_lower : 1D numpy.ndarray[float]
        Vector of variable lower bounds.

    var_upper : 1D numpy.ndarray[float]
        Vector of variable upper bounds.

    integer_vars : 1D numpy.ndarray[int]
        List of indices of integer variables.

    categorical_info : (1D numpy.ndarray[int], 1D numpy.ndarray[int],
                        List[(int, 1D numpy.ndarray[int])]) or None
        Information on categorical variables: array of indices of
        categorical variables in original space, array of indices of
        noncategorical variables in original space, and expansion of
        each categorical variable, given as a tuple (original index,
        indices of expanded variables).

    node_pos : 2D numpy.ndarray[float]
        List of coordinates of the nodes (one on each row).

    rbf_lambda : 1D numpy.ndarray[float]
        The lambda coefficients of the RBF interpolant, corresponding
        to the radial basis functions. List of dimension k.

    rbf_h : 1D numpy.ndarray[float]
        The h coefficients of the RBF interpolant, corresponding to
        the polynomial. List of dimension n+1.

    Returns
    -------
    pyomo.ConcreteModel
        The concrete model describing the problem.
    """
    assert (isinstance(var_lower, np.ndarray))
    assert (isinstance(var_upper, np.ndarray))
    assert (isinstance(integer_vars, np.ndarray))
    assert (isinstance(node_pos, np.ndarray))
    assert (isinstance(rbf_lambda, np.ndarray))
    assert (isinstance(rbf_h, np.ndarray))
    assert (len(var_lower) == n)
    assert (len(var_upper) == n)
    assert (len(rbf_lambda) == k)
    assert (len(rbf_h) == (n + 1))
    assert (len(node_pos) == k)
    assert (isinstance(settings, RbfoptSettings))
    assert (ru.get_degree_polynomial(settings) == 1)

    model = ConcreteModel()

    # Dimension of the space
    model.n = Param(initialize=n)
    model.N = RangeSet(0, model.n - 1)

    # Number of interpolation nodes
    model.k = Param(initialize=k)
    model.K = RangeSet(0, model.k - 1)

    # Dimension of u_pi
    model.q = Param(initialize=(n + k + 1))
    model.Q = RangeSet(0, model.q - 1)

    # Coefficients of the RBF
    lambda_h_param = {}
    for i in range(k):
        lambda_h_param[i] = float(rbf_lambda[i])
    for i in range(n + 1):
        lambda_h_param[k + i] = float(rbf_h[i])
    model.lambda_h = Param(model.Q, initialize=lambda_h_param)

    # Coordinates of the nodes
    node_param = {}
    for i in range(k):
        for j in range(n):
            node_param[i, j] = float(node_pos[i][j])
    model.node = Param(model.K, model.N, initialize=node_param)

    # Variable bounds
    var_lower_param = {}
    var_upper_param = {}
    for i in range(n):
        var_lower_param[i] = float(var_lower[i])
        var_upper_param[i] = float(var_upper[i])
    model.var_lower = Param(model.N, initialize=var_lower_param)
    model.var_upper = Param(model.N, initialize=var_upper_param)

    # Variable: the point in the space
    model.x = Var(model.N, domain=Reals, bounds=_x_bounds)

    # Objective function
    if (settings.rbf == 'cubic'):
        model.OBJ = Objective(rule=_min_rbf_obj_expression_cubic,
                              sense=minimize)
    elif (settings.rbf == 'thin_plate_spline'):
        model.OBJ = Objective(rule=_min_rbf_obj_expression_tps, sense=minimize)

    # Add integer variables if necessary
    if (len(integer_vars)):
        add_integrality_constraints(model, integer_vars)

    # Add categorical variables if necessary
    if (categorical_info is not None and categorical_info[2]):
        add_categorical_constraints(model, *categorical_info)

    return model
Beispiel #11
0
def create_min_msrsm_model(settings, n, k, var_lower, var_upper,
                           integer_vars, node_pos, rbf_lambda, rbf_h, 
                           dist_weight, dist_min, dist_max, fmin, fmax):
    """Create the concrete model to optimize the MSRSM objective.

    Create the concreate model to minimize a weighted combination of
    the value of the RBF interpolant and the (negative of the)
    distance from the closes interpolation node. This is the Global
    Search Step of the MSRSM method.

    Parameters
    ----------

    settings : :class:`rbfopt_settings.RbfoptSettings`
        Global and algorithmic settings.

    n : int
        The dimension of the problem, i.e. size of the space.

    k : int
        Number of nodes, i.e. interpolation points.

    var_lower : 1D numpy.ndarray[float]
        Vector of variable lower bounds.

    var_upper : 1D numpy.ndarray[float]
        Vector of variable upper bounds.

    integer_vars : 1D numpy.ndarray[int]
        List of indices of integer variables.

    node_pos : 2D numpy.ndarray[float]
        List of coordinates of the nodes (one on each row).

    rbf_lambda : 1D numpy.ndarray[float]
        The lambda coefficients of the RBF interpolant, corresponding
        to the radial basis functions. List of dimension k.

    rbf_h : 1D numpy.ndarray[float]
        The h coefficients of the RBF interpolant, corresponding to
        the polynomial. List of dimension n+1.

    dist_weight : float
        The weight paramater for distance and RBF interpolant
        value. Must be between 0 and 1. A weight of 1.0 corresponds to
        using solely distance, 0.0 to objective function.

    dist_min : float
        The minimum distance between two interpolation nodes.

    dist_max : float
        The maximum distance between two interpolation nodes.

    fmin : float
        The minimum value of an interpolation node.

    fmax : float
        The maximum value of an interpolation node.

    Returns
    -------
    pyomo.ConcreteModel
        The concrete model describing the problem.

    """
    assert(isinstance(var_lower, np.ndarray))
    assert(isinstance(var_upper, np.ndarray))
    assert(isinstance(integer_vars, np.ndarray))
    assert(isinstance(node_pos, np.ndarray))
    assert(isinstance(rbf_lambda, np.ndarray))
    assert(isinstance(rbf_h, np.ndarray))
    assert(len(var_lower) == n)
    assert(len(var_upper) == n)
    assert(len(rbf_lambda) == k)
    assert(len(rbf_h) == 1)
    assert(len(node_pos) == k)
    assert(isinstance(settings, RbfoptSettings))
    assert(ru.get_degree_polynomial(settings) == 0)
    assert(0 <= dist_weight <= 1)
    assert(dist_max >= dist_min >= 0)

    model = ConcreteModel()

    # Dimension of the space
    model.n = Param(initialize=n)
    model.N = RangeSet(0, model.n - 1)
        
    # Number of interpolation nodes
    model.k = Param(initialize=k)
    model.K = RangeSet(0, model.k - 1)

    # Dimension of u_pi
    model.q = Param(initialize=(k+1))
    model.Q = RangeSet(0, model.q - 1)

    # Coefficients of the RBF
    lambda_h_param = {}
    for i in range(k):
        lambda_h_param[i] = float(rbf_lambda[i])
    for i in range(1):
        lambda_h_param[k+i] = float(rbf_h[i])
    model.lambda_h = Param(model.Q, initialize=lambda_h_param)

    # Coordinates of the nodes
    node_param = {}
    for i in range(k):
        for j in range(n):
            node_param[i, j] = float(node_pos[i][j])
    model.node = Param(model.K, model.N, initialize=node_param)

    # Variable bounds
    var_lower_param = {}
    var_upper_param = {}
    for i in range(n):
        var_lower_param[i] = float(var_lower[i])
        var_upper_param[i] = float(var_upper[i])
    model.var_lower = Param(model.N, initialize=var_lower_param)
    model.var_upper = Param(model.N, initialize=var_upper_param)

    # Adjust parameters to avoid zero denominators in expressions
    if (fmax <= fmin + settings.eps_zero):
        fmax = fmin + 1
    if (dist_max <= dist_min + settings.eps_zero):
        dist_min = dist_max - 1
    # Minimum and maximum distance
    model.dist_min = Param(initialize=dist_min)
    model.dist_max = Param(initialize=dist_max)
    # Minimum and maximum of function values interpolation nodes
    model.fmin = Param(initialize=fmin)
    model.fmax = Param(initialize=fmax)
    # Weight of the distance and objective criteria
    model.dist_weight = Param(initialize=dist_weight)
    model.obj_weight = Param(initialize=(1.0 if settings.modified_msrsm_score
                                         else 1 - dist_weight))

    # Value of phi at zero, necessary for shift
    if (settings.rbf == 'linear'):
        model.phi_0 = Param(initialize=0.0)
    elif (settings.rbf == 'multiquadric'):
        model.phi_0 = Param(initialize=settings.rbf_shape_parameter)
        model.gamma = Param(initialize=settings.rbf_shape_parameter)

    # Variable: the point in the space
    model.x = Var(model.N, domain=Reals, bounds=_x_bounds)

    # Auxiliary variable: value of the minimum distance to the nodes
    model.mindistsq = Var(domain=NonNegativeReals,
                          bounds=(settings.min_dist,float('inf')))

    # Objective function.
    if (settings.rbf == 'linear'):
        model.OBJ = Objective(rule=_min_msrsm_obj_expression_linear,
                              sense=minimize)
    elif (settings.rbf == 'multiquadric'):
        model.OBJ = Objective(rule=_min_msrsm_obj_expression_mq,
                              sense=minimize)
    model.MdistdefConstraint = Constraint(model.K,
                                          rule=_mdistdef_constraint_rule)

    # Add integer variables if necessary
    if (len(integer_vars)):
        add_integrality_constraints(model, integer_vars)

    return model
Beispiel #12
0
def create_min_bump_model(settings, n, k, Phimat, Pmat, node_val, 
                          node_err_bounds):
    """Create a model to find RBF coefficients with min bumpiness.

    Create a quadratic problem to compute the coefficients of the RBF
    interpolant that minimizes bumpiness and lets all points deviate
    by a specified amount from their value.

    Parameters
    ----------
    settings : :class:`rbfopt_settings.RbfoptSettings`
        Global and algorithmic settings.

    n : int
        The dimension of the problem, i.e. size of the space.

    k : int
        Number of nodes, i.e. interpolation points.

    Phimat : numpy.matrix
        Matrix Phi, i.e. top left part of the standard RBF matrix.

    Pmat : numpy.matrix
        Matrix P, i.e. top right part of the standard RBF matrix.

    node_val : 1D numpy.ndarray[float]
        List of values of the function at the nodes.

    node_err_bounds : 2D numpy.ndarray[float]
        Allowed deviation from node values for nodes affected by
        error. This is a matrix with rows (lower_deviation, 
        upper_deviation).

    Returns
    -------
    pyomo.ConcreteModel
        The concrete model describing the problem.
    """
    assert(isinstance(settings, RbfoptSettings))
    assert(isinstance(node_val, np.ndarray))
    assert(isinstance(node_err_bounds, np.ndarray))
    assert(len(node_val) == k)
    assert(isinstance(Phimat, np.matrix))
    assert(isinstance(Pmat, np.matrix))
    assert(Phimat.shape == (k, k))
    assert(Pmat.shape == (k, 1))
    assert(len(node_val) == len(node_err_bounds))
    assert(ru.get_degree_polynomial(settings) == 0)

    model = ConcreteModel()

    # Dimension of the space
    model.n = Param(initialize=n)
    model.N = RangeSet(0, model.n - 1)

    # Dimension of P matrix
    model.p = Param(initialize=1)
    model.P = RangeSet(0, 0)
        
    # Number of interpolation nodes
    model.k = Param(initialize=k)
    model.K = RangeSet(0, model.k - 1)

    # Lower and upper bounds on node values, i.e. bounds for the first
    # set of equations in the constraints
    node_val_lower_param = {}
    node_val_upper_param = {}
    for i in range(k):
        node_val_lower_param[i] = float(node_val[i] + node_err_bounds[i, 0])
        node_val_upper_param[i] = float(node_val[i] + node_err_bounds[i, 1])
    model.node_val_lower = Param(model.K, initialize=node_val_lower_param)
    model.node_val_upper = Param(model.K, initialize=node_val_upper_param)

    # Phi matrix.
    Phi_param = {}
    for i in range(k):
        for j in range(k):
            if (abs(Phimat[i, j]) != 0.0):
                Phi_param[i, j] = float(Phimat[i, j])
    model.Phi = Param(model.K, model.K, initialize=Phi_param,
                      default=0.0)

    # P matrix.
    Pm_param = {}
    for i in range(k):
        for j in range(1):
            if (abs(Pmat[i, j]) != 0.0):
                Pm_param[i, j] = float(Pmat[i, j])
    model.Pm = Param(model.K, model.P, initialize=Pm_param,
                     default=0.0)

    # Variable: the lambda coefficients of the RBF
    model.rbf_lambda = Var(model.K, domain=Reals)

    # Variable: the h coefficients of the RBF
    model.rbf_h = Var(model.P, domain=Reals)

    # Objective function.
    model.OBJ = Objective(rule=_min_bump_obj_expression, sense=minimize)

    # Constraints. See definitions below.
    model.IntrConstraint = Constraint(model.K, rule=_intr_constraint_rule)
    model.UnisConstraint = Constraint(model.P, rule=_unis_constraint_rule)    

    return model
Beispiel #13
0
def create_max_h_k_model(settings, n, k, var_lower, var_upper, integer_vars,
                         node_pos, rbf_lambda, rbf_h, mat, target_val):
    """Create the abstract model to maximize h_k.

    Create the abstract model to maximize h_k, also known as the
    Global Search Step of the RBF method.

    Parameters
    ----------

    settings : :class:`rbfopt_settings.RbfoptSettings`
        Global and algorithmic settings.

    n : int
        The dimension of the problem, i.e. size of the space.

    k : int
        Number of nodes, i.e. interpolation points.

    var_lower : 1D numpy.ndarray[float]
        Vector of variable lower bounds.

    var_upper : 1D numpy.ndarray[float]
        Vector of variable upper bounds.

    integer_vars : 1D numpy.ndarray[int]
        List of indices of integer variables.

    node_pos : 2D numpy.ndarray[float]
        List of coordinates of the nodes (one on each row).

    rbf_lambda : 1D numpy.ndarray[float]
        The lambda coefficients of the RBF interpolant, corresponding
        to the radial basis functions. List of dimension k.

    rbf_h : 1D numpy.ndarray[float]
        The h coefficients of the RBF interpolant, corresponding to
        the polynomial. List of dimension n+1.

    mat: numpy.matrix
        The matrix necessary for the computation. This is the inverse
        of the matrix [Phi P; P^T 0], see paper as cited above. Must
        be a numpy.matrix of dimension ((k+1) x (k+1))

    target_val : float
        Value f* that we want to find in the unknown objective
        function.

    Returns
    -------
    pyomo.ConcreteModel
        The concrete model describing the problem.
    """
    assert(isinstance(var_lower, np.ndarray))
    assert(isinstance(var_upper, np.ndarray))
    assert(isinstance(integer_vars, np.ndarray))
    assert(isinstance(node_pos, np.ndarray))
    assert(isinstance(rbf_lambda, np.ndarray))
    assert(isinstance(rbf_h, np.ndarray))
    assert(len(var_lower) == n)
    assert(len(var_upper) == n)
    assert(len(rbf_lambda) == k)
    assert(len(rbf_h) == 1)
    assert(len(node_pos) == k)
    assert(isinstance(mat, np.matrix))
    assert(mat.shape == (k+1, k+1))
    assert(isinstance(settings, RbfoptSettings))
    assert(ru.get_degree_polynomial(settings) == 0)

    model = ConcreteModel()

    # Dimension of the space
    model.n = Param(initialize=n)
    model.N = RangeSet(0, model.n - 1)
        
    # Number of interpolation nodes
    model.k = Param(initialize=k)
    model.K = RangeSet(0, model.k - 1)

    # Dimension of the matrix
    model.q = Param(initialize=(k+1))
    model.Q = RangeSet(0, model.q - 1)

    # Coefficients of the RBF
    lambda_h_param = {}
    for i in range(k):
        lambda_h_param[i] = float(rbf_lambda[i])
    for i in range(1):
        lambda_h_param[k+i] = float(rbf_h[i])
    model.lambda_h = Param(model.Q, initialize=lambda_h_param)

    # Coordinates of the nodes
    node_param = {}
    for i in range(k):
        for j in range(n):
            node_param[i, j] = float(node_pos[i][j])
    model.node = Param(model.K, model.N, initialize=node_param)

    # Variable bounds
    var_lower_param = {}
    var_upper_param = {}
    for i in range(n):
        var_lower_param[i] = float(var_lower[i])
        var_upper_param[i] = float(var_upper[i])
    model.var_lower = Param(model.N, initialize=var_lower_param)
    model.var_upper = Param(model.N, initialize=var_upper_param)

    # Inverse of the matrix [Phi P; P^T 0]. Because the matrix is
    # symmetric, we only save the upper right part, while doubling the
    # off-diagonal elements.
    Ainv_param = {}
    for i in range(k+1):
        for j in range(i, k+1):
            if (abs(mat[i, j]) != 0.0):
                if (i == j):
                    Ainv_param[i, j] = float(mat[i, j])
                else:
                    Ainv_param[i, j] = float(2*mat[i, j])
    model.Ainv = Param(model.Q, model.Q, initialize=Ainv_param,
                       default=0.0)

    # Target value
    model.fstar = Param(initialize=target_val)

    # Value of phi at zero, necessary for shift
    if (settings.rbf == 'linear'):
        model.phi_0 = Param(initialize=0.0)
    elif (settings.rbf == 'multiquadric'):
        model.phi_0 = Param(initialize=settings.rbf_shape_parameter)
        model.gamma = Param(initialize=settings.rbf_shape_parameter)

    # Variable: the point in the space
    model.x = Var(model.N, domain=Reals, bounds=_x_bounds)

    # Objective function. 
    if (settings.rbf == 'linear'):
        model.OBJ = Objective(rule=_max_h_k_obj_expression_linear,
                              sense=maximize)
    elif (settings.rbf == 'multiquadric'):
        model.OBJ = Objective(rule=_max_h_k_obj_expression_mq,
                              sense=maximize)

    # Add integer variables if necessary
    if (len(integer_vars)):
        add_integrality_constraints(model, integer_vars)

    return model
Beispiel #14
0
def create_min_rbf_model(settings, n, k, var_lower, var_upper, 
                         integer_vars, node_pos, rbf_lambda, rbf_h):
    """Create the concrete model to minimize the RBF.

    Create the concrete model to minimize the RBF.

    Parameters
    ----------

    settings : :class:`rbfopt_settings.RbfoptSettings`
        Global and algorithmic settings.

    n : int
        The dimension of the problem, i.e. size of the space.

    k : int
        Number of nodes, i.e. interpolation points.

    var_lower : 1D numpy.ndarray[float]
        Vector of variable lower bounds.

    var_upper : 1D numpy.ndarray[float]
        Vector of variable upper bounds.

    integer_vars : 1D numpy.ndarray[int]
        List of indices of integer variables.

    node_pos : 2D numpy.ndarray[float]
        List of coordinates of the nodes.

    rbf_lambda : 1D numpy.ndarray[float]
        The lambda coefficients of the RBF interpolant, corresponding
        to the radial basis functions. List of dimension k.

    rbf_h : 1D numpy.ndarray[float]
        The h coefficients of the RBF interpolant, corresponding to
        the polynomial. List of dimension n+1.

    Returns
    -------
    pyomo.ConcreteModel
        The concrete model describing the problem.
    """
    assert(isinstance(var_lower, np.ndarray))
    assert(isinstance(var_upper, np.ndarray))
    assert(isinstance(integer_vars, np.ndarray))
    assert(isinstance(node_pos, np.ndarray))
    assert(isinstance(rbf_lambda, np.ndarray))
    assert(isinstance(rbf_h, np.ndarray))
    assert(len(var_lower) == n)
    assert(len(var_upper) == n)
    assert(len(rbf_lambda) == k)
    assert(len(rbf_h) == 1)
    assert(len(node_pos) == k)
    assert(isinstance(settings, RbfoptSettings))
    assert(ru.get_degree_polynomial(settings) == 0)

    model = ConcreteModel()
    
    # Dimension of the space
    model.n = Param(initialize=n)
    model.N = RangeSet(0, model.n - 1)
        
    # Number of interpolation nodes
    model.k = Param(initialize=k)
    model.K = RangeSet(0, model.k - 1)

    # Dimension of u_pi
    model.q = Param(initialize=(k+1))
    model.Q = RangeSet(0, model.q - 1)

    # Coefficients of the RBF
    lambda_h_param = {}
    for i in range(k):
        lambda_h_param[i] = float(rbf_lambda[i])
    for i in range(1):
        lambda_h_param[k+i] = float(rbf_h[i])
    model.lambda_h = Param(model.Q, initialize=lambda_h_param)

    # Coordinates of the nodes
    node_param = {}
    for i in range(k):
        for j in range(n):
            node_param[i, j] = float(node_pos[i][j])
    model.node = Param(model.K, model.N, initialize=node_param)

    # Variable bounds
    var_lower_param = {}
    var_upper_param = {}
    for i in range(n):
        var_lower_param[i] = float(var_lower[i])
        var_upper_param[i] = float(var_upper[i])
    model.var_lower = Param(model.N, initialize=var_lower_param)
    model.var_upper = Param(model.N, initialize=var_upper_param)

    # Variable: the point in the space
    model.x = Var(model.N, domain=Reals, bounds=_x_bounds)

    if (settings.rbf == 'linear'):
        model.OBJ = Objective(rule=_min_rbf_obj_expression_linear,
                              sense=minimize)
    elif (settings.rbf == 'multiquadric'):
        model.gamma = Param(initialize=settings.rbf_shape_parameter)
        model.OBJ = Objective(rule=_min_rbf_obj_expression_mq,
                              sense=minimize)

    # Add integer variables if necessary
    if (len(integer_vars)):
        add_integrality_constraints(model, integer_vars)

    return model
def create_max_one_over_mu_model(settings, n, k, var_lower, var_upper, 
                                 integer_vars, node_pos, mat):

    """Create the concrete model to maximize 1/\mu.

    Create the concrete model to maximize :math: `1/\mu`, also known
    as the InfStep of the RBF method.

    See paper by Costa and Nannicini, equation (7) pag 4, and the
    references therein.

    Parameters
    ----------

    settings : :class:`rbfopt_settings.RbfoptSettings`
        Global and algorithmic settings.

    n : int
        The dimension of the problem, i.e. size of the space.

    k : int
        Number of nodes, i.e. interpolation points.

    var_lower : 1D numpy.ndarray[float]
        Vector of variable lower bounds.

    var_upper : 1D numpy.ndarray[float]
        Vector of variable upper bounds.

    integer_vars : 1D numpy.ndarray[int]
        List of indices of integer variables.

    node_pos : 2D numpy.ndarray[float]
        List of coordinates of the nodes (one on each row).

    mat: numpy.matrix
        The matrix necessary for the computation. This is the inverse
        of the matrix [Phi P; P^T 0], see paper as cited above. Must
        be a numpy.matrix of dimension ((k+1) x (k+1))

    Returns
    -------
    pyomo.ConcreteModel
        The concrete model describing the problem.
    """
    assert(isinstance(var_lower, np.ndarray))
    assert(isinstance(var_upper, np.ndarray))
    assert(isinstance(integer_vars, np.ndarray))
    assert(isinstance(node_pos, np.ndarray))
    assert(len(var_lower) == n)
    assert(len(var_upper) == n)
    assert(len(node_pos) == k)
    assert(isinstance(mat, np.matrix))
    assert(mat.shape == (k, k))
    assert(isinstance(settings, RbfoptSettings))
    assert(ru.get_degree_polynomial(settings) == -1)

    model = ConcreteModel()

    # Dimension of the space
    model.n = Param(initialize=n)
    model.N = RangeSet(0, model.n - 1)
        
    # Number of interpolation nodes
    model.k = Param(initialize=k)
    model.K = RangeSet(0, model.k - 1)

    # Coordinates of the nodes
    node_param = {}
    for i in range(k):
        for j in range(n):
            node_param[i, j] = float(node_pos[i][j])
    model.node = Param(model.K, model.N, initialize=node_param)

    # Variable bounds
    var_lower_param = {}
    var_upper_param = {}
    for i in range(n):
        var_lower_param[i] = float(var_lower[i])
        var_upper_param[i] = float(var_upper[i])
    model.var_lower = Param(model.N, initialize=var_lower_param)
    model.var_upper = Param(model.N, initialize=var_upper_param)

    # Inverse of the matrix [Phi P; P^T 0]. Because the matrix is
    # symmetric, we only save the upper right part, while doubling the
    # off-diagonal elements.
    Ainv_param = {}
    for i in range(k):
        for j in range(i, k):
            if (abs(mat[i, j]) != 0.0):
                if (i == j):
                    Ainv_param[i, j] = float(mat[i, j])
                else:
                    Ainv_param[i, j] = float(2*mat[i, j])
    model.Ainv = Param(model.K, model.K, initialize=Ainv_param,
                       default=0.0)

    if (settings.rbf == 'gaussian'):
        model.phi_0 = Param(initialize=1.0)
        model.gamma = Param(initialize=settings.rbf_shape_parameter)

    # Variable: the point in the space
    model.x = Var(model.N, domain=Reals, bounds=_x_bounds)

    # Objective function. 
    if (settings.rbf == 'gaussian'):
        model.OBJ = Objective(rule=_max_one_over_mu_obj_expression_gaussian,
                              sense=maximize)

    # Add integer variables if necessary
    if (len(integer_vars)):
        add_integrality_constraints(model, integer_vars)

    return model