def test_model_composition_units(self): class Above(Model): "A simple upper bound on x" def __init__(self): x = Variable("x", "ft") x_max = Variable("x_{max}", 1, "yard") Model.__init__(self, 1/x, [x <= x_max]) class Below(Model): "A simple lower bound on x" def __init__(self): x = Variable("x", "m") x_min = Variable("x_{min}", 1, "cm") Model.__init__(self, x, [x >= x_min]) a, b = Above(), Below() concatm = Model(a.cost*b.cost, [a, b]) concat_cost = concatm.solve(verbosity=0)["cost"] if not isinstance(a["x"].key.units, str): self.assertAlmostEqual(a.solve(verbosity=0)["cost"], 0.3333333) self.assertAlmostEqual(b.solve(verbosity=0)["cost"], 0.01) self.assertAlmostEqual(concat_cost, 0.0109361) # 1 cm/1 yd a1, b1 = Above(), Below() m = a1.link(b1) m.cost = m["x"] sol = m.solve(verbosity=0) if not isinstance(m["x"].key.units, str): expected = (1*gpkit.units.cm/(1*m.cost.units)).to("dimensionless") self.assertAlmostEqual(sol["cost"], expected) # 1 cm/(1 ft or 1 m) self.assertIn(m["x"], sol["variables"]) self.assertIn(a1["x"], sol["variables"]) self.assertIn(b1["x"], sol["variables"]) self.assertNotIn(a["x"], sol["variables"]) self.assertNotIn(b["x"], sol["variables"])
def test_evalfn(self): x = Variable("x") x2 = Variable("x^2", evalfn=lambda solv: solv[x]**2) m = Model(x, [x >= 2]) m.unique_varkeys = set([x2.key]) sol = m.solve(verbosity=0) self.assertAlmostEqual(sol(x2), sol(x)**2)
def test_substitution_issue905(self): x = Variable("x") y = Variable("y") m = Model(x, [x >= y], {"y": 1}) bm = Model(m.cost, Bounded(m)) sol = bm.solve(verbosity=0) self.assertAlmostEqual(sol["cost"], 1.0)
def test_constants_in_objective_1(self): '''Issue 296''' x1 = Variable('x1') x2 = Variable('x2') m = Model(1. + x1 + x2, [x1 >= 1., x2 >= 1.]) sol = m.solve(solver=self.solver, verbosity=0) self.assertAlmostEqual(sol["cost"], 3, self.ndig)
def __init__(self, N=4, **kwargs): EI = Variable("EI", 1e4, "N*m^2") dx = Variable("dx", "m", "Length of an element") L = Variable("L", 5, "m", "Overall beam length") q = VectorVariable(N, "q", 100*np.ones(N), "N/m", "Distributed load at each point") V = VectorVariable(N, "V", "N", "Internal shear") V_tip = Variable("V_{tip}", 0, "N", "Tip loading") M = VectorVariable(N, "M", "N*m", "Internal moment") M_tip = Variable("M_{tip}", 0, "N*m", "Tip moment") th = VectorVariable(N, "\\theta", "-", "Slope") th_base = Variable("\\theta_{base}", 0, "-", "Base angle") w = VectorVariable(N, "w", "m", "Displacement") w_base = Variable("w_{base}", 0, "m", "Base deflection") # below: trapezoidal integration to form a piecewise-linear # approximation of loading, shear, and so on # shear and moment increase from tip to base (left > right) shear_eq = (V >= V.right + 0.5*dx*(q + q.right)) shear_eq[-1] = (V[-1] >= V_tip) # tip boundary condition moment_eq = (M >= M.right + 0.5*dx*(V + V.right)) moment_eq[-1] = (M[-1] >= M_tip) # slope and displacement increase from base to tip (right > left) theta_eq = (th >= th.left + 0.5*dx*(M + M.left)/EI) theta_eq[0] = (th[0] >= th_base) # base boundary condition displ_eq = (w >= w.left + 0.5*dx*(th + th.left)) displ_eq[0] = (w[0] >= w_base) # minimize tip displacement (the last w) Model.__init__(self, w[-1], [shear_eq, moment_eq, theta_eq, displ_eq, L == (N-1)*dx], **kwargs)
def test_constants_in_objective_2(self): '''Issue 296''' x1 = Variable('x1') x2 = Variable('x2') m = Model(x1**2 + 100 + 3*x2, [x1 >= 10., x2 >= 15.]) sol = m.solve(solver=self.solver, verbosity=0) self.assertAlmostEqual(sol["cost"]/245., 1, self.ndig)
def test_additive_constants(self): x = Variable('x') m = Model(1/x, [1 >= 5*x + 0.5, 1 >= 10*x]) m.solve(verbosity=0) gp = m.program self.assertEqual(gp.cs[1], gp.cs[2]) self.assertEqual(gp.A.data[1], gp.A.data[2])
def test_sp_initial_guess_sub(self): x = Variable("x") y = Variable("y") x0 = 2 y0 = 2 with SignomialsEnabled(): constraints = [y + x >= 4, y <= x] objective = x m = Model(objective, constraints) try: sol = m.localsolve(x0={x: x0, y: y0}, verbosity=0, solver=self.solver) except TypeError: self.fail("Call to local solve with only variables failed") self.assertAlmostEqual(sol(x), 2, self.ndig) self.assertAlmostEqual(sol["cost"], 2, self.ndig) try: sol = m.localsolve(x0={"x": x0, "y": y0}, verbosity=0, solver=self.solver) except TypeError: self.fail("Call to local solve with only variable strings failed") self.assertAlmostEqual(sol("x"), 2, self.ndig) self.assertAlmostEqual(sol["cost"], 2, self.ndig) try: sol = m.localsolve(x0={"x": x0, y: y0}, verbosity=0, solver=self.solver) except TypeError: self.fail("Call to local solve with a mix of variable strings " "and variables failed") self.assertAlmostEqual(sol["cost"], 2, self.ndig)
def __init__(self, min_rho=True, **kwargs): self.min_rho = min_rho Lval = 0.0065 # [K/m] th = GRAVITATIONAL_ACCEL/(GAS_CONSTANT*Lval) # [-] L = Variable('L', Lval, 'K/m', 'Temperature lapse rate') p_0 = Variable('p_0', 101325, 'Pa', 'Pressure at sea level') T_0 = Variable('T_0', 288.15, 'K', 'Temperature at sea level') if min_rho: objective = rho # minimize density else: objective = 1/rho # maximize density # Temperature lapse rate constraint if min_rho: with SignomialsEnabled(): constraints = TCS([T_0 <= T + L*h]) else: constraints = TCS([T_0 >= T + L*h]) constraints += [h <= 11000*units.m, h >= 1E-6*units.m, # Pressure-altitude relation (p/p_0)**(1/th) == T/T_0, # Ideal gas law rho == p/(R*T), ] su = Sutherland() lc = su.link(constraints) Model.__init__(self, objective, lc, **kwargs)
def test_trivial_sp2(self): x = Variable("x") y = Variable("y") # converging from above with SignomialsEnabled(): constraints = [y + x >= 2, y >= x] objective = y x0 = 1 y0 = 2 m = Model(objective, constraints) sol1 = m.localsolve(x0={x: x0, y: y0}, verbosity=0, solver=self.solver) # converging from right with SignomialsEnabled(): constraints = [y + x >= 2, y <= x] objective = x x0 = 2 y0 = 1 m = Model(objective, constraints) sol2 = m.localsolve(x0={x: x0, y: y0}, verbosity=0, solver=self.solver) self.assertAlmostEqual(sol1["variables"]["x"], sol2["variables"]["x"], self.ndig) self.assertAlmostEqual(sol1["variables"]["y"], sol2["variables"]["x"], self.ndig)
def test_partial_sub_signomial(self): """Test SP partial x0 initialization""" x = Variable('x') y = Variable('y') with SignomialsEnabled(): m = Model(x, [x + y >= 1, y <= 0.5]) m.localsolve(x0={x: 0.5}, verbosity=0) self.assertEqual(m.program.gps[0].constraints[0].exp[x], -1./3)
def test_cvxopt_kwargs(self): if "cvxopt" not in settings["installed_solvers"]: return x = Variable("x") m = Model(x, [x >= 12]) # make sure it's possible to pass the kktsolver option to cvxopt sol = m.solve(solver="cvxopt", verbosity=0, kktsolver="ldl") self.assertAlmostEqual(sol["cost"], 12., NDIGS["cvxopt"])
def test_no_naming_on_var_access(self): # make sure that analysis models don't add their names to # variables looked up from other models box = Box() area_bounds = BoxAreaBounds(box) M = Model(box["V"], [box, area_bounds]) for var in ("h", "w", "d"): self.assertEqual(len(M.variables_byname(var)), 1)
def test_call_units(self): # test from issue541 x = Variable("x", 10, "ft") y = Variable("y", "m") m = Model(y, [y >= x]) sol = m.solve(verbosity=0) self.assertAlmostEqual(sol("y")/sol("x"), 1.0, 6) self.assertAlmostEqual(sol(x)/sol(y), 1.0, 6)
def test_additive_constants(self): x = Variable('x') m = Model(1/x, [1 >= 5*x + 0.5, 1 >= 10*x]) m.solve(verbosity=0) # pylint: disable=no-member gp = m.program # created by solve() self.assertEqual(gp.cs[1], gp.cs[2]) self.assertEqual(gp.A.data[1], gp.A.data[2])
def test_sigs_not_allowed_in_cost(self): with SignomialsEnabled(): x = Variable('x') y = Variable('y') J = 0.01*((x - 1)**2 + (y - 1)**2) + (x*y - 1)**2 m = Model(J) with self.assertRaises(TypeError): m.localsolve(verbosity=0)
def test_601(self): # tautological monomials should solve but not pass to the solver x = Variable("x") y = Variable("y", 2) m = Model(x, [x >= 1, y == 2]) m.solve(verbosity=0) self.assertEqual(len(m.program.constraints), 2)
def test_partial_sub_signomial(self): "Test SP partial x0 initialization" x = Variable('x') y = Variable('y') with SignomialsEnabled(): m = Model(x, [x + y >= 1, y <= 0.5]) gp = m.sp().gp(x0={x: 0.5}) # pylint: disable=no-member first_gp_constr_posy = gp[0][0].as_posyslt1()[0] self.assertEqual(first_gp_constr_posy.exp[x.key], -1./3)
def simpleflight(verbosity=0): """Simple flight model""" # Constants k = Variable("k", 1.2, "-", "form factor") e = Variable("e", 0.95, "-", "Oswald efficiency factor") mu = Variable("\\mu", 1.78e-5, "kg/m/s", "viscosity of air") pi = Variable("\\pi", np.pi, "-", "half of the circle constant") rho = Variable("\\rho", 1.23, "kg/m^3", "density of air") tau = Variable("\\tau", 0.12, "-", "airfoil thickness to chord ratio") N_ult = Variable("N_{ult}", 3.8, "-", "ultimate load factor") V_min = Variable("V_{min}", 22, "m/s", "takeoff speed") C_Lmax = Variable("C_{L,max}", 1.5, "-", "max CL with flaps down") S_wetratio = Variable("(\\frac{S}{S_{wet}})", 2.05, "-", "wetted area ratio") W_W_coeff1 = Variable("W_{W_{coeff1}}", 8.71e-5, "1/m", "Wing Weight Coefficent 1") W_W_coeff2 = Variable("W_{W_{coeff2}}", 45.24, "Pa", "Wing Weight Coefficent 2") CDA0 = Variable("(CDA0)", 0.031, "m^2", "fuselage drag area") W_0 = Variable("W_0", 4940.0, "N", "aircraft weight excluding wing") # Free Variables D = Variable("D", "N", "total drag force") A = Variable("A", "-", "aspect ratio") S = Variable("S", "m^2", "total wing area") V = Variable("V", "m/s", "cruising speed") W = Variable("W", "N", "total aircraft weight") Re = Variable("Re", "-", "Reynold's number") C_D = Variable("C_D", "-", "Drag coefficient of wing") C_L = Variable("C_L", "-", "Lift coefficent of wing") C_f = Variable("C_f", "-", "skin friction coefficient") W_w = Variable("W_w", "N", "wing weight") constraints = [] # Drag model C_D_fuse = CDA0/S C_D_wpar = k*C_f*S_wetratio C_D_ind = C_L**2/(pi*A*e) constraints += [C_D >= C_D_fuse + C_D_wpar + C_D_ind] # Wing weight model W_w_strc = W_W_coeff1*(N_ult*A**1.5*(W_0*W*S)**0.5)/tau W_w_surf = W_W_coeff2 * S constraints += [W_w >= W_w_surf + W_w_strc] # and the rest of the models constraints += [D == 0.5*rho*S*C_D*V**2, Re <= (rho/mu)*V*(S/A)**0.5, C_f >= 0.074/Re**0.2, W <= 0.5*rho*S*C_L*V**2, W <= 0.5*rho*S*C_Lmax*V_min**2, W >= W_0 + W_w] m = Model(D, constraints) m.solve(verbosity=verbosity) return m
def test_call_vector(self): n = 5 x = VectorVariable(n, 'x') prob = Model(sum(x), [x >= 2.5]) sol = prob.solve(verbosity=0) solx = sol(x) self.assertEqual(type(solx), np.ndarray) self.assertEqual(solx.shape, (n,)) self.assertTrue((abs(solx - 2.5*np.ones(n)) < 1e-7).all())
def test_zeroing(self): L = Variable("L") k = Variable("k", 0) with SignomialsEnabled(): constr = [L-5*k <= 10] sol = Model(1/L, constr).solve(self.solver, verbosity=0) self.assertAlmostEqual(sol(L), 10, self.ndig) self.assertAlmostEqual(sol["cost"], 0.1, self.ndig) self.assertTrue(sol.almost_equal(sol))
def test_posyconstr_in_gp(self): """Tests tight constraint set with solve()""" x = Variable("x") x_min = Variable("x_{min}", 2) m = Model(x, [Tight([x >= 1], raiseerror=True), x >= x_min]) with self.assertRaises(ValueError): m.solve(verbosity=0) m.substitutions[x_min] = 0.5 self.assertAlmostEqual(m.solve(verbosity=0)["cost"], 1)
def test_601(self): # tautological monomials should solve but not pass to the solver x = Variable("x") y = Variable("y", 2) m = Model(x, [x >= 1, y == 2]) m.solve(solver=self.solver, verbosity=0) self.assertEqual(len(m.program[0]), 2) # pylint:disable=unsubscriptable-object self.assertEqual(len(m.program.posynomials), 2)
def test_tautological_spconstraint(self): x = Variable('x') y = Variable('y') z = Variable('z', 0) with SignomialsEnabled(): m = Model(x, [x >= 1-y, y <= 0.1, y >= z]) with self.assertRaises(InvalidGPConstraint): m.solve(verbosity=0) sol = m.localsolve(self.solver, verbosity=0) self.assertAlmostEqual(sol["variables"]["x"], 0.9, self.ndig)
def test_sub_tol(self): """ Test PosyIneq feasibility tolerance under substitutions""" x = Variable('x') y = Variable('y') z = Variable('z') PosynomialInequality.feastol = 1e-5 m = Model(z, [x == z, x >= y], {x: 1., y: 1.0001}) self.assertRaises(ValueError, m.solve, verbosity=0) PosynomialInequality.feastol = 1e-3 self.assertEqual(m.substitutions('x'), m.solve(verbosity=0)('x'))
def test_cost_freeing(self): "Test freeing a variable that's in the cost." x = Variable("x", 1) x_min = Variable("x_{min}", 2) m = Model(x, [x >= x_min]) self.assertRaises((RuntimeWarning, ValueError), m.solve, verbosity=0) del m.substitutions["x"] self.assertAlmostEqual(m.solve(verbosity=0)["cost"], 2) del m.substitutions["x_{min}"] self.assertRaises((RuntimeWarning, ValueError), m.solve, verbosity=0)
def test_composite_objective(self): L = Variable("L") W = Variable("W") eqns = [L >= 1, W >= 1, L*W == 10] obj = composite_objective(L+W, W**-1 * L**-3, sub={L: 1, W: 1}) m = Model(obj, eqns) sol = m.solve(verbosity=0) a = sol["cost"] b = np.array([1.58856898, 2.6410391, 3.69348122, 4.74591386]) self.assertTrue((abs(a-b)/(a+b+1e-7) < 1e-7).all())
def test_result_access(self): x = Variable("x") y = Variable("y") with SignomialsEnabled(): sig = (y + 6*x >= 13 + x**2) m = Model(y, [sig]) sol = m.localsolve(verbosity=0) self.assertTrue(all([isinstance(gp.result.table(), Strings) for gp in m.program.gps])) self.assertAlmostEqual(sol["cost"]/4.0, 1.0, 5) self.assertAlmostEqual(sol("x")/3.0, 1.0, 3)
def test_reassigned_constant_cost(self): # for issue 1131 x = Variable('x') x_min = Variable('x_min', 1) y = Variable('y') with SignomialsEnabled(): m = Model(y, [y + 0.5 >= x, x >= x_min, 6 >= y]) m.localsolve(verbosity=0, solver=self.solver) del m.substitutions[x_min] m.cost = 1/x_min self.assertNotIn(x_min, m.sp().substitutions)
def test_sigeq(self): x = Variable("x") y = VectorVariable(1, "y") # test vector input to sigeq c = Variable("c") with SignomialsEnabled(): m = Model(c, [c >= (x + 0.25)**2 + (y - 0.5)**2, SignomialEquality(x**2 + x, y)]) sol = m.localsolve(solver=self.solver, verbosity=0) self.assertAlmostEqual(sol("x"), 0.1639472, self.ndig) self.assertAlmostEqual(sol("y"), 0.1908254, self.ndig) self.assertAlmostEqual(sol("c"), 0.2669448, self.ndig)
def test_issue180(self): L = Variable("L") Lmax = Variable("L_{max}", 10) W = Variable("W") Wmax = Variable("W_{max}", 10) A = Variable("A", 10) Obj = Variable("Obj") a_val = 0.01 a = Variable("a", a_val) with SignomialsEnabled(): eqns = [ L <= Lmax, W <= Wmax, L * W >= A, Obj >= a * (2 * L + 2 * W) + (1 - a) * (12 * W**-1 * L**-3) ] m = Model(Obj, eqns) spsol = m.solve(self.solver, verbosity=0) # now solve as GP m[-1] = (Obj >= a_val * (2 * L + 2 * W) + (1 - a_val) * (12 * W**-1 * L**-3)) del m.substitutions[m["a"]] gpsol = m.solve(self.solver, verbosity=0) self.assertAlmostEqual(spsol["cost"], gpsol["cost"])
def test_trivial_gp(self): """ Create and solve a trivial GP: minimize x + 2y subject to xy >= 1 The global optimum is (x, y) = (sqrt(2), 1/sqrt(2)). """ x = Variable('x') y = Variable('y') prob = Model(cost=(x + 2*y), constraints=[x*y >= 1]) sol = prob.solve(solver=self.solver, verbosity=0) self.assertEqual(type(prob.latex()), unicode) # pylint: disable=protected-access self.assertEqual(type(prob._repr_latex_()), unicode) self.assertAlmostEqual(sol("x"), np.sqrt(2.), self.ndig) self.assertAlmostEqual(sol("y"), 1/np.sqrt(2.), self.ndig) self.assertAlmostEqual(sol("x") + 2*sol("y"), 2*np.sqrt(2), self.ndig) self.assertAlmostEqual(sol["cost"], 2*np.sqrt(2), self.ndig)
def test_posyconstr_in_sp(self): x = Variable('x') y = Variable('y') with SignomialsEnabled(): sig_constraint = (x + y >= 0.1) m = Model(x*y, [Tight([x >= y], raiseerror=True), x >= 2, y >= 1, sig_constraint]) with self.assertRaises(ValueError): m.localsolve(verbosity=0) m.pop(1) self.assertAlmostEqual(m.localsolve(verbosity=0)["cost"], 1, 5)
def rotors_analysis_function(T=2000 * ureg("lbf"), VT="unconstrained", h=0 * ureg.ft, N=12, R=1.804 * ureg("ft"), s=0.1, Cl_mean_max=1.4, print_summary="No"): #Function uses GPKit models as the backend to analyze a rotor. testRotor = Rotors() testRotor.substitutions.update({ "R": R, "N": N, "s": s, "Cl_{mean_{max}}": Cl_mean_max }) testState = FlightState(h=h) testRotor_AeroAnalysis = testRotor.performance(testState) testRotor_AeroAnalysis.substitutions.update( {"T": T.to(ureg.lbf).magnitude}) if VT != "unconstrained": testRotor_AeroAnalysis.substitutions.update({"VT": VT}) testModel = Model(testRotor_AeroAnalysis["P"], [testRotor, testRotor_AeroAnalysis]) testSolution = testModel.solve(verbosity=0) if print_summary == "Yes": print testSolution.summary() VT = testSolution["variables"]["VT_RotorsAero"] P = testSolution["variables"]["P_RotorsAero"] FOM = testSolution["variables"]["FOM_RotorsAero"] Cl_mean = testSolution["variables"]["Cl_mean_RotorsAero"] SPL = 20 * np.log10(testSolution["variables"]["p_{ratio}_RotorsAero"]) return [VT, P, FOM, Cl_mean, SPL]
def test_simple_united_gp(self): R = Variable("R", "nautical_miles") if not R.units: return a0 = Variable("a0", 340.29, "m/s") theta = Variable("\\theta", 0.7598) t = Variable("t", 10, "hr") T_loiter = Variable("T_{loiter}", 1, "hr") T_reserve = Variable("T_{reserve}", 45, "min") M = VectorVariable(2, "M") prob = Model(1 / R, [ t >= sum(R / a0 / M / theta**0.5) + T_loiter + T_reserve, M <= 0.76 ]) sol = prob.solve(solver=self.solver, verbosity=0) almostequal = self.assertAlmostEqual almostequal(0.000553226 / R.units / sol["cost"], 1, self.ndig) almostequal(340.29 / sol["constants"]["a0"], 1, self.ndig) almostequal(340.29 / sol["variables"]["a0"], 1, self.ndig) almostequal(340.29 * a0.units / sol("a0"), 1, self.ndig) almostequal(1807.58 / sol["freevariables"]["R"], 1, self.ndig) almostequal(1807.58 * R.units / sol("R"), 1, self.ndig)
def test_becomes_posy_sensitivities(self): # pylint: disable=invalid-name # model from #1165 ujet = Variable("ujet") PK = Variable("PK") # Constants Dp = Variable("Dp", 0.662) fBLI = Variable("fBLI", 0.4) fsurf = Variable("fsurf", 0.836) mdot = Variable("mdot", 1 / 0.7376) with SignomialsEnabled(): m = Model(PK, [ mdot * ujet + fBLI * Dp >= 1, PK >= 0.5 * mdot * ujet * (2 + ujet) + fBLI * fsurf * Dp ]) var_senss = m.solve(verbosity=0)["sensitivities"]["constants"] self.assertAlmostEqual(var_senss[Dp], -0.16, 2) self.assertAlmostEqual(var_senss[fBLI], -0.16, 2) self.assertAlmostEqual(var_senss[fsurf], 0.19, 2) self.assertAlmostEqual(var_senss[mdot], -0.17, 2)
def test_sp_bounded(self): x = Variable("x") y = Variable("y") with SignomialsEnabled(): m = Model(x, [x + y >= 1, y <= 0.1]) # solves cost = m.localsolve(verbosity=0)["cost"] self.assertAlmostEqual(cost, 0.9, self.ndig) with SignomialsEnabled(): m = Model(x, [x + y >= 1]) # dual infeasible with self.assertRaises((RuntimeWarning, ValueError)): m.localsolve(verbosity=0) with SignomialsEnabled(): m = Model(x, Bounded([x + y >= 1], verbosity=0)) sol = m.localsolve(verbosity=0) boundedness = sol["boundedness"] if "value near lower bound" in boundedness: self.assertIn(x.key, boundedness["value near lower bound"]) if "value near upper bound" in boundedness: self.assertIn(y.key, boundedness["value near upper bound"])
def infeasibility_check(delta, params_dict, feature_names, target_name, patterns=None, result_dict=None): is_fair = (patterns is not None) is_initialize = (result_dict is not None) s = Variable(str("s")) objective = s s_constraint = [s >= 1] constraints = get_feasibility_parity_constraints(params_dict, s, feature_names) constraints += s_constraint if is_fair: fair_constraints = get_fairness_constraints(delta, patterns, params_dict, target_name) #print(fair_constraints) constraints += fair_constraints m = Model(objective, constraints) if is_fair: if is_initialize: #print("Local solver with initialization") sol = m.localsolve(solver='mosek_cli', x0=result_dict) else: sol = m.localsolve(solver='mosek_cli') else: sol = m.solve(solver='mosek_cli') #print("Optimal cost: %.4g" % sol["cost"]) #print(sol.summary()) result_dict_2 = {} for key, value in params_dict.items(): result_dict_2[key] = sol["variables"][value[0]] return result_dict_2
def test_trivial_sp(self): x = Variable('x') y = Variable('y') with SignomialsEnabled(): m = Model(x, [x >= 1 - y, y <= 0.1]) with self.assertRaises(ValueError): # solve should catch the TypeError raised by an SP constraints # and raise its own ValueError instead m.solve(verbosity=0) sol = m.localsolve(self.solver, verbosity=0) self.assertAlmostEqual(sol["variables"]["x"], 0.9, self.ndig) with SignomialsEnabled(): m = Model(x, [x + y >= 1, y <= 0.1]) sol = m.localsolve(self.solver, verbosity=0) self.assertAlmostEqual(sol["variables"]["x"], 0.9, self.ndig)
def optimize_aircraft(m, substitutions, fixedBPR=False, pRatOpt=True, x0 = None): """ Optimizes an aircraft of a given configuration :param m: aircraft model with objective and configuration :param fixedBPR: boolean specifying whether or not BPR is fixed (depends on config) :param pRatOpt: boolean specifying whether or not pressure ratio is optimized (depends on config) :return: solution of aircraft model """ if fixedBPR: substitutions.update({ '\\alpha_{max}': 6.97, #8.62, }) if pRatOpt: del substitutions['\pi_{f_D}'] del substitutions['\pi_{lc_D}'] del substitutions['\pi_{hc_D}'] m.substitutions.update(substitutions) m = Model(m.cost, Bounded(m), m.substitutions) sol = m.localsolve(verbosity=2, iteration_limit=200, reltol=0.01) return sol
def test_fmincon_generator(self): """Test fmincon comparison tool""" x = Variable('x') y = Variable('y') m = Model(x, [x**3.2 >= 17*y + y**-0.2, x >= 2, y == 4]) obj, c, ceq, DC, DCeq = generate_mfiles(m, writefiles=False) self.assertEqual(obj, 'x(2)') self.assertEqual(c, ['-x(2)**3.2 + 17*x(1) + x(1)**-0.2', '-x(2) + 2']) self.assertEqual(ceq, ['-x(1) + 4']) self.assertEqual(DC, ['-0.2*x(1).^-1.2 + 17,...\n ' + '-3.2*x(2).^2.2', '0,...\n -1']) self.assertEqual(DCeq, ['-1,...\n 0'])
def run_M072_737(objective, fixedBPR, pRatOpt, mutategparg): # User definitions Nclimb = 3 Ncruise = 2 Nmission = 1 aircraft = 'M072_737' m = Mission(Nclimb, Ncruise, objective, aircraft, Nmission) substitutions = get_M072_737_subs() if Nmission > 1: substitutions.update({ 'R_{req}': [3000. * units('nmi'), 2500. * units('nmi')], 'n_{pass}': [180., 180.], }) else: substitutions.update({ 'R_{req}': 3000. * units('nmi'), 'n_{pass}': 180., }) if fixedBPR: substitutions.update({ '\\alpha_{max}': 6.97, }) if pRatOpt: del substitutions['\pi_{f_D}'] ## del substitutions['\pi_{lc_D}'] ## del substitutions['\pi_{hc_D}'] m.substitutions.update(substitutions) m = Model(m.cost, BCS(m)) m_relax = relaxed_constants(m, None, ['M_{takeoff}', '\\theta_{db}']) sol = m_relax.localsolve(verbosity=4, iteration_limit=200, reltol=0.01, mutategp=mutategparg) post_process(sol) percent_diff(sol, aircraft, Nclimb) post_compute(sol, Nclimb) return sol
def test_emp(): Sw = Variable("S_w", 50, "ft**2", "wing area") bw = Variable("b_w", 20, "ft", "wing span") cmac = Variable("cmac", 15, "in", "wing MAC") emp = Empennage() fs = FlightState() emp.substitutions.update({emp.W: 10, emp.tailboom.l: 5, emp.htail.planform.AR: 4, emp.vtail.planform.AR: 4, emp.vtail.Vv: 0.04, emp.htail.Vh: 0.4, emp.htail.mh: 0.01}) htperf = emp.htail.flight_model(emp.htail, fs) vtperf = emp.vtail.flight_model(emp.vtail, fs) tbperf = emp.tailboom.flight_model(emp.tailboom, fs) m = Model(htperf.Cd + vtperf.Cd + tbperf.Cf, [emp.vtail.lv == emp.tailboom.l, emp.htail.lh == emp.tailboom.l, emp.htail.Vh <= emp.htail.planform.S*emp.htail.lh/Sw/cmac, emp.vtail.Vv <= emp.vtail.planform.S*emp.vtail.lv/Sw/bw, emp, fs, htperf, vtperf, tbperf]) m.solve(verbosity=0)
def relaxed_constants(model, include_only=None, exclude=None): """ Method to precondition an SP so it solves with a relaxed constants algorithm ARGUMENTS --------- model: the model to solve with relaxed constants RETURNS ------- feas: the input model but with relaxed constants and a new objective """ if model.substitutions: constsrelaxed = ConstantsRelaxed(model, include_only, exclude) feas = Model(constsrelaxed.relaxvars.prod()**20 * model.cost, constsrelaxed) # NOTE: It hasn't yet been seen but might be possible that # the model.cost component above could cause infeasibility else: feas = Model(model.cost, model) return feas
def test_posyconstr_in_gp(self): """Tests tight constraint set with solve()""" x = Variable('x') x_min = Variable('x_{min}', 2) m = Model(x, [Tight([x >= 1], raiseerror=True), x >= x_min]) with self.assertRaises(ValueError): m.solve(verbosity=0) m.substitutions[x_min] = 0.5 self.assertAlmostEqual(m.solve(verbosity=0)["cost"], 1)
def test_model_composition_units(self): class Above(Model): "A simple upper bound on x" def __init__(self): x = Variable("x", "ft") x_max = Variable("x_{max}", 1, "yard") Model.__init__(self, 1 / x, [x <= x_max]) class Below(Model): "A simple lower bound on x" def __init__(self): x = Variable("x", "m") x_min = Variable("x_{min}", 1, "cm") Model.__init__(self, x, [x >= x_min]) a, b = Above(), Below() concatm = Model(a.cost * b.cost, [a, b]) concat_cost = concatm.solve(verbosity=0)["cost"] if not isinstance(a["x"].key.units, str): self.assertAlmostEqual(a.solve(verbosity=0)["cost"], 0.3333333) self.assertAlmostEqual(b.solve(verbosity=0)["cost"], 0.01) self.assertAlmostEqual(concat_cost, 0.0109361) # 1 cm/1 yd a1, b1 = Above(), Below() m = a1.link(b1) m.cost = m["x"] sol = m.solve(verbosity=0) if not isinstance(m["x"].key.units, str): expected = (1 * gpkit.units.cm / (1 * m.cost.units)).to("dimensionless") self.assertAlmostEqual(sol["cost"], expected) # 1 cm/(1 ft or 1 m) self.assertIn(m["x"], sol["variables"]) self.assertIn(a1["x"], sol["variables"]) self.assertIn(b1["x"], sol["variables"]) self.assertNotIn(a["x"], sol["variables"]) self.assertNotIn(b["x"], sol["variables"])
def test_sp_initial_guess_sub(self): x = Variable("x") y = Variable("y") x0 = 3 y0 = 2 with SignomialsEnabled(): constraints = [y + x >= 4, y <= x] objective = x m = Model(objective, constraints) # Call to local solve with only variables sol = m.localsolve(x0={ "x": x0, y: y0 }, verbosity=0, solver=self.solver) self.assertAlmostEqual(sol(x), 2, self.ndig) self.assertAlmostEqual(sol["cost"], 2, self.ndig) # Call to local solve with only variable strings sol = m.localsolve(x0={ "x": x0, "y": y0 }, verbosity=0, solver=self.solver) self.assertAlmostEqual(sol("x"), 2, self.ndig) self.assertAlmostEqual(sol["cost"], 2, self.ndig) # Call to local solve with a mix of variable strings and variables sol = m.localsolve(x0={ "x": x0, y: y0 }, verbosity=0, solver=self.solver) self.assertAlmostEqual(sol["cost"], 2, self.ndig)
def test_sp_substitutions(self): x = Variable('x') y = Variable('y', 1) z = Variable('z', 4) with self.assertRaises(ValueError): with SignomialsEnabled(): m = Model(x, [x + z >= y]) m.localsolve() with SignomialsEnabled(): m = Model(x, [x + y >= z]) self.assertAlmostEqual(m.solve(self.solver, verbosity=0)["cost"], 3)
def synthetic_model(number_of_constraints): constraints = [] obj = 1 number_of_gp_variables = number_of_constraints / 2 + int( number_of_constraints * np.random.rand()) + 1 gp_variables = [] s = [] # Variable('s_relax_sm') for i in xrange(number_of_gp_variables): x = Variable('x_sm_%s' % i) gp_variables.append(x) constraints.append(x >= 0.01) number_of_uncertain_variables = int(50 * np.random.rand()) + 1 uncertain_variables = [] for i in xrange(number_of_uncertain_variables): uncertain_variables.append( Variable('u_sm_%s' % i, 2 * np.random.random(), pr=50 * np.random.random())) for counter in xrange(number_of_constraints): number_of_monomials = int(15 * np.random.random()) + 1 vector_to_choose_from = [0, 0, 0, 1, -1] # , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, m = number_of_monomials * [1] for j in xrange(number_of_monomials): for _ in xrange( int(number_of_gp_variables * np.random.rand() / 2) + 1): m[j] *= (np.random.choice(gp_variables))**( 10 * np.random.random()) # -5) for i in xrange(number_of_uncertain_variables): neg_pos_neutral_powers = [ vector_to_choose_from[int( len(vector_to_choose_from) * np.random.rand())] for _ in xrange(number_of_monomials) ] for j in xrange(number_of_monomials): m[j] *= uncertain_variables[i]**(np.random.rand() * 2 * (neg_pos_neutral_powers[j])) s.append(Variable('s_relax_sm_%s' % counter)) constraints.append(sum(m) <= s[counter]) for x in gp_variables: obj += 1000 * np.random.rand() * x**(-np.random.rand() * 10) # - 5) obj += sum([i**0.2 for i in s]) m = Model(obj, constraints) return m
def test_unbounded_debugging(self): "Test nearly-dual-feasible problems" from gpkit.constraints.bounded import Bounded x = Variable("x") y = Variable("y") m = Model(x*y, [x*y**1.000001 >= 100]) with self.assertRaises((RuntimeWarning, ValueError)): m.solve(self.solver, verbosity=0) m = Model(x*y, Bounded(m, verbosity=0)) sol = m.solve(self.solver, verbosity=0) bounds = sol["boundedness"] self.assertEqual(bounds["sensitive to upper bound"], [y.key]) self.assertEqual(bounds["sensitive to lower bound"], [x.key])
def p1(Fs, Lmax) -> float: """ minimize E subject to: L <= L_{max} T_w >= T_w^{min} |I^0|*E_{tx}^1 <= 1/4 var. Tw """ Tw = Variable('Tw') objective = computeEnergy(Fs)(Tw) constraints = [ computeDelay(Tw, Fs) <= Lmax, Tw >= Tw_min, bottleneckConstraint(Fs, Tw) ] m = Model(objective, constraints) # m.debug() # Some problems are not feasible try: sol = m.solve(verbosity=0) return round(sol['variables'][Tw], 1) except Exception: return None
def relaxed_constraints(model): """ Method to precondition an SP so it solves with a relaxed constants algorithm ARGUMENTS --------- model: the model to solve with relaxed constants RETURNS ------- feas: the input model but with relaxed constants and a new objective """ constsrelaxed = ConstraintsRelaxedEqually(model) return Model(constsrelaxed.relaxvar**20 * model.cost, constsrelaxed)
def test_mdd_example(self): Cl = Variable("Cl", 0.5, "-", "Lift Coefficient") Mdd = Variable("Mdd", "-", "Drag Divergence Mach Number") m1 = Model(1 / Mdd, [1 >= 5 * Mdd + 0.5, Mdd >= 0.00001]) m2 = Model(1 / Mdd, [1 >= 5 * Mdd + 0.5]) m3 = Model(1 / Mdd, [1 >= 5 * Mdd + Cl, Mdd >= 0.00001]) sol1 = m1.solve(solver=self.solver, verbosity=0) sol2 = m2.solve(solver=self.solver, verbosity=0) sol3 = m3.solve(solver=self.solver, verbosity=0) # pylint: disable=no-member gp1, gp2, gp3 = [m.program for m in [m1, m2, m3]] self.assertEqual( gp1.A, CootMatrix(row=[0, 1, 2], col=[0, 0, 0], data=[-1, 1, -1])) self.assertEqual(gp2.A, CootMatrix(row=[0, 1], col=[0, 0], data=[-1, 1])) self.assertEqual( gp3.A, CootMatrix(row=[0, 1, 2], col=[0, 0, 0], data=[-1, 1, -1])) self.assertAlmostEqual(sol1(Mdd), sol2(Mdd)) self.assertAlmostEqual(sol1(Mdd), sol3(Mdd)) self.assertAlmostEqual(sol2(Mdd), sol3(Mdd))
def test_posyconstr_in_sp(self): x = Variable('x') y = Variable('y') x_min = Variable('x_min', 1) y_min = Variable('y_min', 2) with SignomialsEnabled(): sig_constraint = (x + y >= 3.5) m = Model(x*y, [Loose([x >= y], raiseerror=True), x >= x_min, y >= y_min, sig_constraint]) with self.assertRaises(ValueError): m.localsolve(verbosity=0) m.substitutions[x_min] = 2 m.substitutions[y_min] = 1 self.assertAlmostEqual(m.localsolve(verbosity=0)["cost"], 2.5, 5)
def test_vector_sweep(self): """Test sweep involving VectorVariables""" x = Variable("x") y = VectorVariable(2, "y") m = Model(x, [x >= y.prod()]) m.substitutions.update({y: ('sweep', [[2, 3], [5, 7], [9, 11]])}) a = m.solve(verbosity=0)["cost"] b = [6, 14, 22, 15, 35, 55, 27, 63, 99] # below line fails with changing dictionary keys in py3 self.assertTrue(all(abs(a - b) / (a + b) < 1e-7)) m = Model(x, [x >= y.prod()]) m.substitutions.update({y: ('sweep', [[2, 3], [5, 7, 11]])}) a = m.solve(verbosity=0)["cost"] b = [10, 14, 22, 15, 21, 33] self.assertTrue(all(abs(a - b) / (a + b) < 1e-7)) m = Model(x, [x >= y.prod()]) m.substitutions.update({y: ('sweep', [[2, 3, 9], [5, 7, 11]])}) self.assertRaises(ValueError, m.solve, verbosity=0)
def test_reassigned_constant_cost(self): # for issue 1131 x = Variable("x") x_min = Variable("x_min", 1) y = Variable("y") with SignomialsEnabled(): m = Model(y, [y + 0.5 >= x, x >= x_min, 6 >= y]) m.localsolve(verbosity=0, solver=self.solver) del m.substitutions[x_min] m.cost = 1 / x_min self.assertNotIn(x_min, m.sp().gp().substitutions) # pylint: disable=no-member
def test_becomes_signomial(self): "Test that a GP does not become an SP after substitutions" x = Variable("x") c = Variable("c") y = Variable("y") m = Model(x, [y >= 1 + c * x, y <= 0.5], {c: -1}) with self.assertRaises(InvalidGPConstraint): with SignomialsEnabled(): m.gp() with self.assertRaises(UnnecessarySGP): m.localsolve(solver=self.solver)
def test_trivial_sp(self): x = Variable('x') y = Variable('y') with SignomialsEnabled(): m = Model(x, [x >= 1 - y, y <= 0.1]) sol = m.localsolve(verbosity=0, solver=self.solver) self.assertAlmostEqual(sol["variables"]["x"], 0.9, self.ndig) with SignomialsEnabled(): m = Model(x, [x + y >= 1, y <= 0.1]) sol = m.localsolve(verbosity=0, solver=self.solver) self.assertAlmostEqual(sol["variables"]["x"], 0.9, self.ndig)
def test_reassigned_constant_cost(self): # for issue 1131 x = Variable('x') x_min = Variable('x_min', 1) y = Variable('y') with SignomialsEnabled(): m = Model(y, [y + 0.5 >= x, x >= x_min, 6 >= y]) m.localsolve(verbosity=0, solver=self.solver) del m.substitutions[x_min] m.cost = 1 / x_min self.assertNotIn(x_min, m.sp().substitutions)
def test_relaxation(self): x = Variable("x") y = Variable("y") with SignomialsEnabled(): constraints = [y + x >= 2, y <= x] objective = x m = Model(objective, constraints) m.localsolve(verbosity=0) # issue #257 A = VectorVariable(2, "A") B = ArrayVariable([2, 2], "B") C = VectorVariable(2, "C") with SignomialsEnabled(): constraints = [A <= B.dot(C), B <= 1, C <= 1] obj = 1 / A[0] + 1 / A[1] m = Model(obj, constraints) m.localsolve(verbosity=0)