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(InvalidPosynomial): m.localsolve(verbosity=0, solver=self.solver)
def setup(self): x = Variable("x") y = Variable("y", 2.) z = Variable("z") with SignomialsEnabled(): constraints = [z <= x**2 + y, x * z == 2] self.cost = 1 / z return constraints
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_posyslt1(self): x = Variable("x") y = Variable("y") with SignomialsEnabled(): sc = (x + y >= x * y) # make sure that the error type doesn't change on our users with self.assertRaises(InvalidGPConstraint): _ = sc.as_posyslt1()
def test_init(self): "Test initialization and types" D = Variable('D', units="N") x1, x2, x3 = (Variable("x_%s" % i, units="N") for i in range(3)) with SignomialsEnabled(): sc = (D >= x1 + x2 - x3) self.assertTrue(isinstance(sc, SignomialConstraint)) self.assertFalse(isinstance(sc, Posynomial))
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)
def test_init(self): "Test Signomial construction" x = Monomial('x') y = Monomial('y') with SignomialsEnabled(): self.assertEqual(str(1 - x - y**2 - 1), "-x + -y**2") self.assertEqual((1 - x / y**2).latex(), "-\\frac{x}{y^{2}} + 1") self.assertRaises(TypeError, lambda: x - y)
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}, verbosity=0) # 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 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_exp, = gp.hmaps[1] # first after cost self.assertEqual(first_gp_constr_posy_exp[x.key], -1. / 3)
def example_sp(): x = Variable('x') y = Variable('y') a = Variable('a', 1, pr=10) b = Variable('b', 1, pr=10) constraints = [] with SignomialsEnabled(): constraints = constraints + [x >= 1 - a * y, b * y <= 0.1] return Model(x, constraints)
def setup(self, N=5): self.wing = WingGP.setup(self, N=N) mw = Variable("m_w", "-", "span wise effectiveness") with SignomialsEnabled(): constraints = [mw * (1 + 2 / self.planform["AR"]) >= 2 * np.pi] return self.wing, constraints
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) first_gp_constr_posy = m.program.gps[0].constraints[0].as_posyslt1()[0] self.assertEqual(first_gp_constr_posy.exp[x.key], -1./3)
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)
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, solver=self.solver) sol = m.localsolve(self.solver, verbosity=0) self.assertAlmostEqual(sol["variables"]["x"], 0.9, self.ndig)
def test_init(self): "Test Signomial construction" x = Variable("x") y = Variable("y") with SignomialsEnabled(): if sys.platform[:3] != "win": self.assertEqual(str(1 - x - y**2 - 1), "1 - x - y² - 1") self.assertEqual((1 - x / y**2).latex(), "-\\frac{x}{y^{2}} + 1") _ = hash(1 - x / y**2) self.assertRaises(TypeError, lambda: x - y)
def test_init(self): "Test Signomial construction" x = Variable('x') y = Variable('y') with SignomialsEnabled(): if sys.version_info <= (3, 0): self.assertEqual(str(1 - x - y**2 - 1), "1 - x - y^2 - 1") self.assertEqual((1 - x/y**2).latex(), "-\\frac{x}{y^{2}} + 1") _ = hash(1 - x/y**2) self.assertRaises(TypeError, lambda: x-y)
def test_impossible(self): x = Variable('x') y = Variable('y') z = Variable('z') with SignomialsEnabled(): m1 = Model(x, [x + y >= z, x >= y]) m1.substitutions.update({'x': 0, 'y': 0}) with self.assertRaises(ValueError): _ = m1.localsolve(solver=self.solver)
def setup(self): exec parse_variables(Section.__doc__) constraints = [ # Taking averages, A_in * A_out == A_avg**2, # Volume of chamber V_chamb == A_avg * l, # Area ratio A_in / A_out == k_A, # Mass flow rate rho_in * u_in * A_in == mdot_in, rho_out * u_out * A_out == mdot_out, # Chamber pressure P_chamb**2 == P_in * P_out, # Product generation rate q == rho_p * A_b * r, A_b == l_b * l, A_p_out + r * l_b * dt <= A_p_in, # Stagnation quantities P_t_in >= P_in + 0.5 * rho_in * u_in**2, T_t_in >= T_in + u_in**2 / (2 * c_p), # Ideal gas law P_out == rho_out * R * T_out, # Pressure increase P_out + dP <= P_in, # Making sure burn surface length is feasible l_b >= 2 * np.pi**0.5 * (A_avg)**0.5, l_b <= l_b_max * 2 * np.pi**0.5 * (A_avg)**0.5, # Constraining areas Tight([A_avg + A_p_in <= np.pi * radius**2]), ] with SignomialsEnabled(): constraints += [ # Flow acceleration (conservation of momentum) # Note: assumes constant rate of burn through the chamber dP + rho_in * u_in**2 >= q * u_out / V_chamb * (2. / 3. * l) + rho_in * u_in * u_out, # Burn rate (Saint-Robert's Law, coefficients taken for Space Shuttle SRM) Tight([ r >= r_c * (P_chamb / 1e6 * units('1/Pa'))**0.35 * (1 + 0.5 * r_k * (u_in + u_out)) ]), # Mass flows Tight([mdot_in + q >= mdot_out]), mdot_out >= mdot_in, # Temperatures Tight([ T_t_out * mdot_out <= mdot_in * T_t_in + q * T_amb + q * k_comb_p / c_p ]), # Stagnation quantities Tight([P_t_out <= P_out + 0.5 * rho_out * u_out**2]), Tight([T_t_out <= T_out + u_out**2 / (2 * c_p)]), ] return constraints
def setup(self, aircraft, state, **kwargs): self.aircraft = aircraft self.aircraftP = AircraftP(aircraft, state) self.wingP = self.aircraftP.wingP self.fuseP = self.aircraftP.fuseP self.engineP = self.aircraftP.engineP #variable definitions z_bre = Variable('z_{bre}', '-', 'Breguet Parameter') Rng = Variable('Rng', 'nautical_miles', 'Cruise Segment Range') TotRng = Variable('TotRng', 'nautical_miles', 'Total Cruise Range') #new varibales for the TASOPT flight profile gammaCruise = Variable('\\gamma_{cruise}', '-', 'Cruise Climb Angle') RCCruise = Variable('RC_{cruise}', 'ft/min', 'Cruise Climb Rate') excessP = Variable('P_{excess}', 'W', 'Excess Power During Cruise') constraints = [] ## constraints.extend([ #taylor series expansion to get the weight term ## TCS([self.aircraftP['W_{burn}']/self.aircraftP['W_{end}'] >= ## te_exp_minus1(z_bre, nterm=3)]), ## ## #breguet range eqn ## TCS([z_bre >= (self.engineP['TSFC'] * self.aircraftP['thr']* ## self.aircraftP['D']) / self.aircraftP['W_{avg}']]), ## #time ## self.aircraftP['thr'] * state['V'] == Rng, ## ]) #new constarints for the TASOPT flight profile with SignomialsEnabled(): constraints.extend([ #compute the cruise climb angle state['\\rho']*self.aircraftP['V']**2 == gammaCruise * state["P_{atm}"] * self.aircraftP['M']**2, #compute the cruise climb rate self.aircraftP['V'] * gammaCruise == RCCruise, #constraint on drag and thrust self.aircraft['numeng']*self.engineP['thrust'] >= self.aircraftP['D'] + self.aircraftP['W_{avg}'] * gammaCruise, RCCruise == excessP/self.aircraftP['W_{avg}'], #climb rate constraints TCS([excessP + state['V'] * self.aircraftP['D'] <= state['V'] * aircraft['numeng'] * self.engineP['thrust']]), #time TCS([self.aircraftP['thr'] * state['V'] >= Rng + (.5*gammaCruise**2)*self.aircraftP['thr'] * state['V']]), ]) return constraints, self.aircraftP
def setup(self, nt, nx): exec parse_variables(Rocket.__doc__) self.nt = nt self.nx = nx self.nozzle = Nozzle() with Vectorize(nt): self.nozzlePerformance = NozzlePerformance(self.nozzle) self.section = SRM(nx) constraints = [ # Limiting nozzle size to cross-sectional area # self.nozzle.A_e <= np.pi*r**2, # Equal time segments self.section.dt == t_T/nt, # All fuel is consumed self.section.A_p_out[:,-1] == 1e-20*np.ones(nx)*np.pi*r**2, A_fuel == self.section.A_p_in[:,0], T_target == self.nozzlePerformance.T, c_T == self.nozzlePerformance.c_T, # Fuel parameters self.section.k_comb_p == k_comb_p, self.section.rho_p == rho_p, ] for i in range(nt-1): constraints += [ # Decreasing fuel self.section.A_p_out[:, i] == self.section.A_p_in[:, i+1], # Decreasing sectional area self.section.A_in[:,i] <= self.section.A_in[:,i+1], self.section.A_out[:,i] <= self.section.A_out[:,i+1], ] for i in range(nt): constraints += [ # Rocket length is section length, self.section.radius[i] == r, self.section.l[i] == l, # Matching nozzle and section conditions self.nozzlePerformance.mdot[i] == self.section.mdot_out[i], self.nozzlePerformance.T_t[i] == self.section.T_t_out[i], # Maximum chamber pressure self.section.P_chamb[:, i] <= P_max, self.nozzlePerformance.P_star[i] <= P_max, ] with SignomialsEnabled(): constraints += [ # Matching nozzle stagnation pressure Tight([self.nozzlePerformance.P_t[i] <= s[i]*(self.section.P_out[i] + 0.5*self.section.rho_out[i]*self.section.u_out[i]**2)], name='PtNozzle', printwarning=True), s[i]*self.nozzlePerformance.P_t[i] >= self.section.P_out[i] + 0.5*self.section.rho_out[i]*self.section.u_out[i]**2, s[i] >= 1 ] return constraints, self.nozzle, self.nozzlePerformance, self.section
def setup(self, aircraft, sp=False): fs = FlightState() A = Variable("A", "m/s**2", "log fit equation helper 1") B = Variable("B", "1/m", "log fit equation helper 2") g = Variable("g", 9.81, "m/s**2", "gravitational constant") mu = Variable("\\mu_b", 0.025, "-", "coefficient of friction") T = Variable("T", "lbf", "take off thrust") cda = Variable("CDA", 0.024, "-", "parasite drag coefficient") CLg = Variable("C_{L_g}", "-", "ground lift coefficient") CDg = Variable("C_{D_g}", "-", "grag ground coefficient") cdp = Variable("c_{d_{p_{stall}}}", 0.025, "-", "profile drag at Vstallx1.2") Kg = Variable("K_g", 0.04, "-", "ground-effect induced drag parameter") CLto = Variable("C_{L_{TO}}", 3.5, "-", "max lift coefficient") Vstall = Variable("V_{stall}", "knots", "stall velocity") e = Variable("e", 0.8, "-", "span efficiency") zsto = Variable("z_{S_{TO}}", "-", "take off distance helper variable") Sto = Variable("S_{TO}", "ft", "take off distance") Sground = Variable("S_{ground}", "ft", "ground roll") etaprop = Variable("\\eta_{prop}", 0.8, "-", "propellor efficiency") msafety = Variable("m_{fac}", 1.4, "-", "safety margin") path = os.path.dirname(os.path.abspath(__file__)) df = pd.read_csv(path + os.sep + "logfit.csv") fd = df.to_dict(orient="records")[0] constraints = [ T / aircraft.topvar("W") >= A / g + mu, T <= aircraft["P_{shaft-max}"] * etaprop / fs["V"], CDg >= 0.024 + cdp + CLto**2 / pi / aircraft["AR"] / e, Vstall == (2 * aircraft.topvar("W") / fs["\\rho"] / aircraft.wing["S"] / CLto)**0.5, fs["V"] == 1.3 * Vstall, FitCS(fd, zsto, [A / g, B * fs["V"]**2 / g]), Sground >= 1.0 / 2.0 / B * zsto, Sto / msafety >= Sground ] if sp: with SignomialsEnabled(): constraints.extend([ (B * aircraft.topvar("W") / g + 0.5 * fs["\\rho"] * aircraft.wing["S"] * mu * CLto >= 0.5 * fs["\\rho"] * aircraft.wing["S"] * CDg) ]) else: constraints.extend([ B >= (g / aircraft.topvar("W") * 0.5 * fs["\\rho"] * aircraft.wing["S"] * CDg) ]) return constraints, fs
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_values_vs_subs(self): # Substitutions update method x = Variable("x") y = Variable("y") z = Variable("z") with SignomialsEnabled(): constraints = [x + y >= z, y >= x - 1] m = Model(x + y * z, constraints) m.substitutions.update({"z": 5}) sol = m.localsolve(verbosity=0) self.assertAlmostEqual(sol["cost"], 13, self.ndig) # Constant variable declaration method z = Variable("z", 5) with SignomialsEnabled(): constraints = [x + y >= z, y >= x - 1] m = Model(x + y * z, constraints) sol = m.localsolve(verbosity=0) self.assertAlmostEqual(sol["cost"], 13, self.ndig)
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(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_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_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_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(RuntimeWarning): with SignomialsEnabled(): _ = m.gp() with self.assertRaises(RuntimeWarning): _ = m.localsolve(solver=self.solver)
def test_vector_sub(self): x = VectorVariable(3, "x") y = VectorVariable(3, "y") ymax = VectorVariable(3, "ymax") with SignomialsEnabled(): # issue1077 links to a case that failed for SPs only m = Model(x.prod(), [x + y >= 1, y <= ymax]) m.substitutions["ymax"] = [0.3, 0.5, 0.8] m.localsolve(verbosity=0)
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 test_small_signomial(self): x = Variable('x') z = Variable('z') local_ndig = 4 nonzero_adder = 0.1 # TODO: support reaching zero, issue #348 with SignomialsEnabled(): J = 0.01 * (x - 1)**2 + nonzero_adder m = Model(z, [z >= J]) sol = m.localsolve(verbosity=0) self.assertAlmostEqual(sol['cost'], nonzero_adder, local_ndig) self.assertAlmostEqual(sol('x'), 0.987, 3)