def lp_min_max_dnf(x, minmax, direction, region, dnf): "min/max direction s.t. region and dnf" regions = dnf.get_regions() l = max([len(region1.get_atoms()) for region1 in regions]) ind = glpk.intArray(l) prob = lp_optimize(x, direction, region, regions[0]) lb, ub = [], [] glpk.glp_set_obj_dir(prob, glpk.GLP_MIN) lb.append(lp_solve(prob)) if 'min' in minmax else None glpk.glp_set_obj_dir(prob, glpk.GLP_MAX) # maximize or minimize ub.append(lp_solve(prob)) if 'max' in minmax else None base_index = len(region.get_atoms()) + 1 for i in range(1, len(regions)): for j in range(0, len(regions[i - 1].get_atoms())): ind[j] = base_index + j glpk.glp_del_rows(prob, len(regions[i - 1]), ind) prob = lp_set_rows_from_region(prob, x, regions[i], base_index) glpk.glp_set_obj_dir(prob, glpk.GLP_MIN) # maximize or minimize lb.append(lp_solve(prob)) glpk.glp_set_obj_dir(prob, glpk.GLP_MAX) # maximize or minimize ub.append(lp_solve(prob)) final_ub = max(ub) if ub != [] else INFTY final_lb = min(lb) if lb != [] else -INFTY glpk.glp_delete_prob(prob) return (final_lb, final_ub)
def lp_optimize_dnf(x, minmax, direction, region, dnf): "min/max direction s.t. region and dnf" regions = dnf.get_regions() l = max([len(region1.get_atoms()) for region1 in regions]) ind = glpk.intArray(l) prob = lp_optimize(x, direction, region, regions[0]) glpk.glp_set_obj_dir(prob, minmax) # maximize or minimize ans = [] ans.append(lp_solve(prob)) base_index = len(region.get_atoms()) + 1 for i in range(1, len(regions)): for j in range(0, len(regions[i - 1].get_atoms())): ind[j] = base_index + j glpk.glp_del_rows(prob, len(regions[i - 1]), ind) prob = lp_set_rows_from_region(prob, x, regions[i], base_index) ans.append(lp_solve(prob)) if minmax == glpk.GLP_MAX: value = max(ans) else: value = min(ans) glpk.glp_delete_prob(prob) return value
glpk.glp_add_cols(lp, 2) # two unknowns: x and y glpk.glp_set_col_bnds(lp, 1, glpk.GLP_DB, 0., 1.) # 0 <= x <= 1 glpk.glp_set_col_bnds(lp, 2, glpk.GLP_DB, 0., 1.) # 0 <= y <= 1 glpk.glp_add_rows(lp, 2) # 2 constraints matrix_row_index = glpk.intArray(5) matrix_column_index = glpk.intArray(5) matrix_content = glpk.doubleArray(5) # First constraint: x + y >= 1. matrix_row_index[1] = 1; matrix_column_index[1] = 1; matrix_content[1] = 1.; matrix_row_index[2] = 1; matrix_column_index[2] = 2; matrix_content[2] = 1.; glpk.glp_set_row_bnds(lp, 1, glpk.GLP_LO, 1., 0.) # Second constraint: - x + y >= -0.5. matrix_row_index[3] = 2; matrix_column_index[3] = 1; matrix_content[3] = -1.; matrix_row_index[4] = 2; matrix_column_index[4] = 2; matrix_content[4] = 1.; glpk.glp_set_row_bnds(lp, 2, glpk.GLP_LO, -0.5, 0.) # Load them glpk.glp_load_matrix(lp, 4, matrix_row_index, matrix_column_index, matrix_content) # Cost function: 0.5 x + y glpk.glp_set_obj_coef(lp, 1, 0.5) glpk.glp_set_obj_coef(lp, 2, 1.) # Solve the linear programming problem options = glpk.glp_smcp() glpk.glp_init_smcp(options) options.msg_lev = glpk.GLP_MSG_ERR options.meth = glpk.GLP_DUAL glpk.glp_simplex(lp, options) print "Computed optimum: x = ", glpk.glp_get_col_prim(lp, 1), ", y = ", glpk.glp_get_col_prim(lp, 2) ,", obj = ", glpk.glp_get_obj_val(lp) print "Expected optimum: x = 0.75, y = 0.25, obj = 0.625" glpk.glp_delete_prob(lp)
matrix_content[1] = 1. matrix_row_index[2] = 1 matrix_column_index[2] = 2 matrix_content[2] = 1. glpk.glp_set_row_bnds(lp, 1, glpk.GLP_LO, 1., 0.) # Second constraint: - x + y >= -0.5. matrix_row_index[3] = 2 matrix_column_index[3] = 1 matrix_content[3] = -1. matrix_row_index[4] = 2 matrix_column_index[4] = 2 matrix_content[4] = 1. glpk.glp_set_row_bnds(lp, 2, glpk.GLP_LO, -0.5, 0.) # Load them glpk.glp_load_matrix(lp, 4, matrix_row_index, matrix_column_index, matrix_content) # Cost function: 0.5 x + y glpk.glp_set_obj_coef(lp, 1, 0.5) glpk.glp_set_obj_coef(lp, 2, 1.) # Solve the linear programming problem options = glpk.glp_smcp() glpk.glp_init_smcp(options) options.msg_lev = glpk.GLP_MSG_ERR options.meth = glpk.GLP_DUAL glpk.glp_simplex(lp, options) print "Computed optimum: x = ", glpk.glp_get_col_prim( lp, 1), ", y = ", glpk.glp_get_col_prim( lp, 2), ", obj = ", glpk.glp_get_obj_val(lp) print "Expected optimum: x = 0.75, y = 0.25, obj = 0.625" glpk.glp_delete_prob(lp)
def get_alpha_LB(self, mu, safeguard=True): self.load_reduced_data_structures() lp = glpk.glp_create_prob() glpk.glp_set_obj_dir(lp, glpk.GLP_MIN) Qa = self.parametrized_problem.Qa N = self.N M_e = self.M_e if M_e < 0: M_e = N if M_e > len(self.C_J): M_e = len(self.C_J) # = N M_p = self.M_p if M_p < 0: M_p = N if M_p > len(self.complement_C_J): M_p = len(self.complement_C_J) # 1. Linear program unknowns: Qa variables, y_1, ..., y_{Q_a} glpk.glp_add_cols(lp, Qa) # 2. Range: constrain the variables to be in the bounding box (note: GLPK indexing starts from 1) for qa in range(Qa): if self.B_min[qa] < self.B_max[qa]: # the usual case glpk.glp_set_col_bnds(lp, qa + 1, glpk.GLP_DB, self.B_min[qa], self.B_max[qa]) elif self.B_min[qa] == self.B_max[qa]: # unlikely, but possible glpk.glp_set_col_bnds(lp, qa + 1, glpk.GLP_FX, self.B_min[qa], self.B_max[qa]) else: # there is something wrong in the bounding box: set as unconstrained variable print "Warning: wrong bounding box for affine expansion element #", qa glpk.glp_set_col_bnds(lp, qa + 1, glpk.GLP_FR, 0., 0.) # 3. Add two different sets of constraints glpk.glp_add_rows(lp, M_e + M_p) array_size = (M_e + M_p)*Qa matrix_row_index = glpk.intArray(array_size + 1) # + 1 since GLPK indexing starts from 1 matrix_column_index = glpk.intArray(array_size + 1) matrix_content = glpk.doubleArray(array_size + 1) glpk_container_size = 0 # 3a. Add constraints: a constraint is added for the closest samples to mu in C_J closest_C_J_indices = self.closest_parameters(M_e, self.C_J, mu) for j in range(M_e): # Overwrite parameter values omega = self.xi_train[ self.C_J[ closest_C_J_indices[j] ] ] self.parametrized_problem.setmu(omega) current_theta_a = self.parametrized_problem.compute_theta_a() # Assemble the LHS of the constraint for qa in range(Qa): matrix_row_index[glpk_container_size + 1] = int(j + 1) matrix_column_index[glpk_container_size + 1] = int(qa + 1) matrix_content[glpk_container_size + 1] = current_theta_a[qa] glpk_container_size += 1 # Assemble the RHS of the constraint glpk.glp_set_row_bnds(lp, j + 1, glpk.GLP_LO, self.alpha_J[ closest_C_J_indices[j] ], 0.) closest_C_J_indices = None # 3b. Add constraints: also constrain the closest point in the complement of C_J, # with RHS depending on previously computed lower bounds closest_complement_C_J_indices = self.closest_parameters(M_p, self.complement_C_J, mu) for j in range(M_p): nu = self.xi_train[ self.complement_C_J[ closest_complement_C_J_indices[j] ] ] self.parametrized_problem.setmu(nu) current_theta_a = self.parametrized_problem.compute_theta_a() # Assemble first the LHS for qa in range(Qa): matrix_row_index[glpk_container_size + 1] = int(M_e + j + 1) matrix_column_index[glpk_container_size + 1] = int(qa + 1) matrix_content[glpk_container_size + 1] = current_theta_a[qa] glpk_container_size += 1 # ... and then the RHS glpk.glp_set_row_bnds(lp, M_e + j + 1, glpk.GLP_LO, self.alpha_LB_on_xi_train[ self.complement_C_J[ closest_complement_C_J_indices[j] ] ], 0.) closest_complement_C_J_indices = None # Load the assembled LHS glpk.glp_load_matrix(lp, array_size, matrix_row_index, matrix_column_index, matrix_content) # 4. Add cost function coefficients self.parametrized_problem.setmu(mu) current_theta_a = self.parametrized_problem.compute_theta_a() for qa in range(Qa): glpk.glp_set_obj_coef(lp, qa + 1, current_theta_a[qa]) # 5. Solve the linear programming problem options = glpk.glp_smcp() glpk.glp_init_smcp(options) options.msg_lev = glpk.GLP_MSG_ERR options.meth = glpk.GLP_DUAL glpk.glp_simplex(lp, options) alpha_LB = glpk.glp_get_obj_val(lp) glpk.glp_delete_prob(lp) # 6. If a safeguard is requested (when called in the online stage of the RB method), # we check the resulting value of alpha_LB. In order to avoid divisions by zero # or taking the square root of a negative number, we allow an inefficient evaluation. if safeguard == True: tol = 1e-10 alpha_UB = self.get_alpha_UB(mu) if alpha_LB/alpha_UB < tol: print "SCM warning: alpha_LB is <= 0 at mu = " + str(mu) + ".", print "Please consider a larger Nmax for SCM. Meanwhile, a truth", print "eigensolve is performed." (alpha_LB, discarded1, discarded2) = self.truth_coercivity_constant() if alpha_LB/alpha_UB > 1 + tol: print "SCM warning: alpha_LB is > alpha_UB at mu = " + str(mu) + ".", print "This should never happen!" return alpha_LB
def get_alpha_LB(self, mu, safeguard=True): self.load_red_data_structures() lp = glpk.glp_create_prob() glpk.glp_set_obj_dir(lp, glpk.GLP_MIN) Qa = self.parametrized_problem.Qa N = self.N M_e = self.M_e if M_e < 0: M_e = N if M_e > len(self.C_J): M_e = len(self.C_J) # = N M_p = self.M_p if M_p < 0: M_p = N if M_p > len(self.complement_C_J): M_p = len(self.complement_C_J) # 1. Linear program unknowns: Qa variables, y_1, ..., y_{Q_a} glpk.glp_add_cols(lp, Qa) # 2. Range: constrain the variables to be in the bounding box (note: GLPK indexing starts from 1) for qa in range(Qa): if self.B_min[qa] < self.B_max[qa]: # the usual case glpk.glp_set_col_bnds(lp, qa + 1, glpk.GLP_DB, self.B_min[qa], self.B_max[qa]) elif self.B_min[qa] == self.B_max[qa]: # unlikely, but possible glpk.glp_set_col_bnds(lp, qa + 1, glpk.GLP_FX, self.B_min[qa], self.B_max[qa]) else: # there is something wrong in the bounding box: set as unconstrained variable print "Warning: wrong bounding box for affine expansion element #", qa glpk.glp_set_col_bnds(lp, qa + 1, glpk.GLP_FR, 0., 0.) # 3. Add two different sets of constraints glpk.glp_add_rows(lp, M_e + M_p) array_size = (M_e + M_p)*Qa matrix_row_index = glpk.intArray(array_size + 1) # + 1 since GLPK indexing starts from 1 matrix_column_index = glpk.intArray(array_size + 1) matrix_content = glpk.doubleArray(array_size + 1) glpk_container_size = 0 # 3a. Add constraints: a constraint is added for the closest samples to mu in C_J closest_C_J_indices = self.closest_parameters(M_e, self.C_J, mu) for j in range(M_e): # Overwrite parameter values omega = self.xi_train[ self.C_J[ closest_C_J_indices[j] ] ] self.parametrized_problem.setmu(omega) current_theta_a = self.parametrized_problem.compute_theta_a() # Assemble the LHS of the constraint for qa in range(Qa): matrix_row_index[glpk_container_size + 1] = int(j + 1) matrix_column_index[glpk_container_size + 1] = int(qa + 1) matrix_content[glpk_container_size + 1] = current_theta_a[qa] glpk_container_size += 1 # Assemble the RHS of the constraint glpk.glp_set_row_bnds(lp, j + 1, glpk.GLP_LO, self.alpha_J[ closest_C_J_indices[j] ], 0.) closest_C_J_indices = None # 3b. Add constraints: also constrain the closest point in the complement of C_J, # with RHS depending on previously computed lower bounds closest_complement_C_J_indices = self.closest_parameters(M_p, self.complement_C_J, mu) for j in range(M_p): nu = self.xi_train[ self.complement_C_J[ closest_complement_C_J_indices[j] ] ] self.parametrized_problem.setmu(nu) current_theta_a = self.parametrized_problem.compute_theta_a() # Assemble first the LHS for qa in range(Qa): matrix_row_index[glpk_container_size + 1] = int(M_e + j + 1) matrix_column_index[glpk_container_size + 1] = int(qa + 1) matrix_content[glpk_container_size + 1] = current_theta_a[qa] glpk_container_size += 1 # ... and then the RHS glpk.glp_set_row_bnds(lp, M_e + j + 1, glpk.GLP_LO, self.alpha_LB_on_xi_train[ self.complement_C_J[ closest_complement_C_J_indices[j] ] ], 0.) closest_complement_C_J_indices = None # Load the assembled LHS glpk.glp_load_matrix(lp, array_size, matrix_row_index, matrix_column_index, matrix_content) # 4. Add cost function coefficients self.parametrized_problem.setmu(mu) current_theta_a = self.parametrized_problem.compute_theta_a() for qa in range(Qa): glpk.glp_set_obj_coef(lp, qa + 1, current_theta_a[qa]) # 5. Solve the linear programming problem options = glpk.glp_smcp() glpk.glp_init_smcp(options) options.msg_lev = glpk.GLP_MSG_ERR options.meth = glpk.GLP_DUAL glpk.glp_simplex(lp, options) alpha_LB = glpk.glp_get_obj_val(lp) glpk.glp_delete_prob(lp) # 6. If a safeguard is requested (when called in the online stage of the RB method), # we check the resulting value of alpha_LB. In order to avoid divisions by zero # or taking the square root of a negative number, we allow an inefficient evaluation. if safeguard == True: tol = 1e-10 alpha_UB = self.get_alpha_UB(mu) if alpha_LB/alpha_UB < tol: print "SCM warning: alpha_LB is <= 0 at mu = " + str(mu) + ".", print "Please consider a larger Nmax for SCM. Meanwhile, a truth", print "eigensolve is performed." (alpha_LB, discarded1, discarded2) = self.truth_coercivity_constant() if alpha_LB/alpha_UB > 1 + tol: print "SCM warning: alpha_LB is > alpha_UB at mu = " + str(mu) + ".", print "This should never happen!" return alpha_LB