def test_basic(self): """Basic substitution, symbolic""" x = Variable('x') y = Variable('y') p = 1 + x**2 q = p.sub({x: y**2}) self.assertEqual(q, 1 + y**4) self.assertEqual(x.sub({x: y}), y)
def test_quantity_sub(self): if gpkit.units: x = Variable("x", 1, "cm") y = Variable("y", 1) self.assertEqual(x.sub({x: 1*gpkit.units.m}).c.magnitude, 100) # NOTE: uncomment the below if requiring Quantity substitutions # self.assertRaises(ValueError, x.sub, x, 1) self.assertRaises(ValueError, x.sub, {x: 1*gpkit.units.N}) self.assertRaises(ValueError, y.sub, {y: 1*gpkit.units.N}) v = gpkit.VectorVariable(3, "v", "cm") subbed = v.sub({v: [1, 2, 3]*gpkit.units.m}) self.assertEqual([z.c.magnitude for z in subbed], [100, 200, 300])
def test_string_mutation(self): x = Variable("x", "m") descr_before = list(x.exp)[0].descr y = x.sub("x", "y") descr_after = list(x.exp)[0].descr self.assertEqual(descr_before, descr_after) x_changed_descr = dict(descr_before) x_changed_descr["name"] = "y" y_descr = list(y.exp)[0].descr self.assertEqual(x_changed_descr["name"], y_descr["name"]) if not isinstance(descr_before["units"], str): self.assertAlmostEqual(x_changed_descr["units"]/y_descr["units"], 1.0) self.assertEqual(x.sub("x", x), x)
def test_signomial(self): """Test Signomial substitution""" D = Variable('D', units="N") x = Variable('x', units="N") y = Variable('y', units="N") a = Variable('a') with SignomialsEnabled(): sc = (a*x + (1 - a)*y - D) subbed = sc.sub({a: 0.1}) self.assertEqual(subbed, 0.1*x + 0.9*y - D) self.assertTrue(isinstance(subbed, Signomial)) subbed = sc.sub({a: 2.0}) self.assertTrue(isinstance(subbed, Signomial)) self.assertEqual(subbed, 2*x - y - D) _ = a.sub({a: -1}).value # fix monomial assumptions
def test_mono_lower_bound(self): "Test monomial approximation" x = Variable('x') y = Variable('y') p = y**2 + 1 self.assertRaises(TypeError, lambda: y.mono_lower_bound({y: 1})) self.assertEqual(p.mono_lower_bound({y: 1}), 2*y) self.assertEqual(p.mono_lower_bound({y: 0}), 1) self.assertEqual((x*y**2 + 1).mono_lower_bound({y: 1, x: 1}), 2*y*x**0.5) # test with units d = Variable('d', units='ft') h = Variable('h', units='ft') p = (d*h**2 + h*d**2) m = p.mono_lower_bound({d: 1, h: 1}) self.assertEqual(m, 2*(d*h)**1.5)
def test_scalar_units(self): x = Variable("x", "m") xvk = x.key y = Variable("y", "km") yvk = y.key units_exist = bool(x.units) for x_ in ["x", xvk, x]: for y_ in ["y", yvk, y]: if not isinstance(y_, str) and units_exist: expected = 0.001 else: expected = 1.0 self.assertAlmostEqual(expected, mag(x.sub(x_, y_).c)) if units_exist: z = Variable("z", "s") self.assertRaises(ValueError, y.sub, y, z)
def test_variable(self): """Test special single-argument substitution for Variable""" x = Variable('x') y = Variable('y') m = x*y**2 self.assertEqual(x.sub(3), 3) self.assertEqual(x.sub(y), y) self.assertEqual(x.sub(m), m) # make sure x was not mutated self.assertEqual(x, Variable('x')) self.assertNotEqual(x.sub(3), Variable('x')) # also make sure the old way works self.assertEqual(x.sub({x: 3}), 3) self.assertEqual(x.sub({x: y}), y) # and for vectors xvec = VectorVariable(3, 'x') self.assertEqual(xvec[1].sub(3), 3)
def test_mono_lower_bound(self): "Test monomial approximation" x = Variable('x') y = Variable('y') p = y**2 + 1 self.assertRaises(TypeError, lambda: y.mono_lower_bound({y: 1})) # TODO: remove pylint warning below after Nomials refactor # pylint is confused because it thinks p is a Signomial # pylint: disable=no-member self.assertEqual(p.mono_lower_bound({y: 1}), 2*y) self.assertEqual(p.mono_lower_bound({y: 0}), 1) self.assertEqual((x*y**2 + 1).mono_lower_bound({y: 1, x: 1}), 2*y*x**0.5) # test with units d = Variable('d', units='ft') h = Variable('h', units='ft') p = (d*h**2 + h*d**2) m = p.mono_lower_bound({d: 1, h: 1}) self.assertEqual(m, 2*(d*h)**1.5)
def test_diff(self): "Test differentiation (!!)" x = Variable('x') y = Variable('y') self.assertEqual(x.diff(x), 1) self.assertEqual(x.diff(y), 0) self.assertEqual((y**2).diff(y), 2*y) self.assertEqual((x + y**2).diff(y), 2*y) self.assertEqual((x + y**2).diff('x'), 1) self.assertEqual((x + x*y**2).diff(y), 2*x*y) self.assertEqual((2*y).diff(y), 2) # test with units x = Variable('x', units='ft') d = (3*x**2).diff(x) self.assertEqual(d, 6*x) # test negative exponent d = (1 + 1/y).diff(y) with SignomialsEnabled(): expected = -y**-2 self.assertEqual(d, expected)
def test_quantity_sub(self): if gpkit.units: x = Variable("x", 1, "cm") y = Variable("y", 1) self.assertEqual(x.sub({x: 1*gpkit.units.m}).c.magnitude, 100) # NOTE: uncomment the below if requiring Quantity substitutions # self.assertRaises(ValueError, x.sub, x, 1) self.assertRaises(ValueError, x.sub, {x: 1*gpkit.ureg.N}) self.assertRaises(ValueError, y.sub, {y: 1*gpkit.ureg.N}) v = gpkit.VectorVariable(3, "v", "cm") subbed = v.sub({v: [1, 2, 3]*gpkit.ureg.m}) self.assertEqual([z.c.magnitude for z in subbed], [100, 200, 300]) v = VectorVariable(1, "v", "km") v_min = VectorVariable(1, "v_min", "km") m = Model(v.prod(), [v >= v_min], {v_min: [2*gpkit.units("nmi")]}) cost = m.solve(verbosity=0)["cost"] self.assertAlmostEqual(cost/(3.704*gpkit.ureg("km")), 1.0) m = Model(v.prod(), [v >= v_min], {v_min: np.array([2])*gpkit.units("nmi")}) cost = m.solve(verbosity=0)["cost"] self.assertAlmostEqual(cost/(3.704*gpkit.ureg("km")), 1.0)
def setup(self): # define the structures of the rocket. # includes upper rocket airframe, nosecone, fins constraints = [] components = self.components = [] ######### components ########## m = self.m = Variable("m", "kg", "Mass of Structures") if len(components) > 0: constraints += [Tight([m >= sum(comp.m for comp in components)])] ######### constraints ######### m_fins = self.m_fins = Variable("m_{fins}", 1.2, "kg", "Mass of fins and mounting of fins") m_nc = self.m_nc = Variable("m_{nc}", 0.5, "kg", "Mass of nose cone") m_tube = self.m_tube = Variable("m_{tube}", 4, "kg") m_booster_struc = self.m_booster_struc = Variable( "m_{booster_struc}", 0.3, "kg", "Mass needed to mount boosters") constraints += [m >= m_fins + m_nc + m_tube + m_booster_struc] return [constraints, components]
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 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, 11]])}) a = m.solve(verbosity=0)["cost"] b = [10, 14, 22, 15, 21, 33] # 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], [9, 11], [13, 15]])}) self.assertRaises(ValueError, m.solve)
def setup(self, hptexp1, lptexp1): self.hptexp1 = hptexp1 self.lptexp1 = lptexp1 #define new variables #turbines Cpt1 = Variable('C_{p_{t1}}', 1280, 'J/kg/K', "Cp Value for Combustion Products in HP Turbine" ) #1300K gamma = 1.318 Cpt2 = Variable('C_{p_{t2}}', 1184, 'J/kg/K', "Cp Value for Combustion Products in LP Turbine" ) #800K gamma = 1.354 #-------------------------diffuser pressure ratios-------------------------- pitn = Variable('\\pi_{tn}', '-', 'Turbine Nozzle Pressure Ratio') #---------------------------efficiencies & takeoffs----------------------- # Note: HP and LP shaft efficiencies smear losses for electrical power etaHPshaft = Variable( '\eta_{HPshaft}', '-', 'Power Transmission Efficiency of High Pressure Shaft') etaLPshaft = Variable( '\eta_{LPshaft}', '-', 'Power Transmission Efficiency of Low Pressure Shaft')
def setup(self,aircraft,state): self.aircraft = aircraft self.engineP = aircraft.engine.dynamic(state) self.wingP = aircraft.wing.dynamic(state) self.fuseP = aircraft.fuse.dynamic(state) self.Pmodels = [self.engineP, self.wingP, self.fuseP] # Free variables C_D = Variable("C_D", "-", "drag coefficient") D = Variable("D", "N", "total drag force") LoD = Variable('L/D','-','lift-to-drag ratio') V = Variable("V", "m/s", "cruising speed") constraints = [] constraints += [self.engineP['T'] * V <= self.aircraft.engine['\\eta_{prop}'] * self.engineP['P_{shaft}'], C_D >= self.fuseP['C_{D_{fuse}}'] + self.wingP['C_{D_{wpar}}'] + self.wingP['C_{D_{ind}}'], D >= 0.5 * state['\\rho'] * self.aircraft['S'] * C_D * V ** 2, self.wingP['Re'] == (state['\\rho'] / state['\\mu']) * V * (self.aircraft['S'] / self.aircraft['A']) ** 0.5, self.fuseP['Re_{fuse}'] == state['\\rho']*V*self.aircraft.fuse['l_{fuse}']/state['\\mu'], LoD == self.wingP['C_L'] / C_D] return constraints, self.Pmodels
def test_unbounded_debugging(self): "Test nearly-dual-feasible problems" x = Variable("x") y = Variable("y") m = Model(x * y, [x * y**1.01 >= 100]) with self.assertRaises((DualInfeasible, UnknownInfeasible)): m.solve(self.solver, verbosity=0) # test one-sided bound m = Model(x * y, Bounded(m, lower=0.001)) sol = m.solve(self.solver, verbosity=0) bounds = sol["boundedness"] self.assertEqual(bounds["sensitive to lower bound of 0.001"], set([x.key])) # end test one-sided bound m = Model(x * y, [x * y**1.01 >= 100]) m = Model(x * y, Bounded(m)) sol = m.solve(self.solver, verbosity=0) bounds = sol["boundedness"] # depends on solver, platform, whims of the numerical deities if "sensitive to upper bound of 1e+30" in bounds: # pragma: no cover self.assertIn(y.key, bounds["sensitive to upper bound of 1e+30"]) else: # pragma: no cover self.assertIn(x.key, bounds["sensitive to lower bound of 1e-30"])
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 setup(self, aircraft, state, **kwargs): #submodels self.aircraft = aircraft self.aircraftP = aircraft.dynamic(state) self.wingP = self.aircraftP.wingP self.fuseP = self.aircraftP.fuseP self.engineP = self.aircraftP.engineP #variable definitions theta = Variable('\\theta', '-', 'Aircraft Climb Angle') excessP = Variable('P_{excess}', 'W', 'Excess Power During Climb') RC = Variable('RC', 'feet/min', 'Rate of Climb/Decent') dhft = Variable('dhft', 'feet', 'Change in Altitude Per Climb Segment [feet]') RngClimb = Variable('R_{climb}', 'nautical_miles', 'Down Range Covered in Each Climb Segment') #constraints constraints = [] constraints.extend([ self.aircraft['numeng']*self.engineP['F'] >= self.aircraftP['D'] + self.aircraftP['W_{avg}'] * theta, #climb rate constraints TCS([excessP + state['V'] * self.aircraftP['D'] <= state['V'] * aircraft['numeng'] * self.engineP['F']]), RC == excessP/self.aircraftP['W_{avg}'], RC >= 500*units('ft/min'), #make the small angle approximation and compute theta theta * state['V'] == RC, dhft == self.aircraftP['tmin'] * RC, #makes a small angle assumption during climb RngClimb == self.aircraftP['thr']*state['V'], ]) return constraints, self.aircraftP
def setup(self, S, R, l): W = Variable("W", "lbf", "fuselage skin weight") m = Variable("m", "kg", "fuselage skin mass") g = Variable("g", 9.81, "m/s^2", "Gravitational acceleration") rhokevlar = Variable("\\rho_{kevlar}", 1.3629, "g/cm**3", "kevlar density") t = Variable("t", "in", "skin thickness") tmin = Variable("t_{min}", 0.03, "in", "minimum skin thickness") I = Variable("I", "m**4", "wing skin moment of inertia") Ig = Variable("I_G", "kg*m**2", "mass moment of inertia") E = Variable("E", 30, "GPa", "Young's Modulus of Kevlar") constraints = [ m >= S * rhokevlar * t, W >= m * g, t >= tmin, I <= np.pi * R**3 * t, Ig >= m * (4 * R**2 + 4 * R * t + t**2), l == l, E == E ] return constraints
def get_params_dict(df, feature_names, target_name): columns_dict = {} for c in df.columns: if c.endswith('_'): v = c[:-1] else: v = c columns_dict[c] = v df.rename(columns=columns_dict, inplace=True) params_dict = {} # Decision variable for value in [0, 1]: variable_name = (target_name, value) params_dict[variable_name] = (Variable(str(variable_name)), 0.0) for feature in feature_names: for v1 in [0, 1]: for v2 in [0, 1]: variable_name = (feature, v1, v2) params_dict[variable_name] = (Variable(str(variable_name)), 0.0) feature_names.append(target_name) df_selected = df.filter(items=feature_names) for i, row in df_selected.iterrows(): v2 = row[target_name] variable_name = (target_name, v2) expo_info = params_dict[variable_name] params_dict[variable_name] = (expo_info[0], expo_info[1] + 1.0) for j, column in row.iteritems(): if (j != target_name): variable_name = (j, column, v2) expo_info = params_dict[variable_name] params_dict[variable_name] = (expo_info[0], expo_info[1] + 1.0) return params_dict
def setup(self, aircraft, state, **kwargs): self.aircraft = aircraft self.aircraftP = AircraftP(aircraft, state) self.wingP = self.aircraftP.wingP self.fuseP = self.aircraftP.fuseP #variable definitions z_bre = Variable('z_{bre}', '-', 'Breguet Parameter') Rng = Variable('Rng', 'nautical_miles', 'Cruise Segment Range') 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) ]), #time self.aircraftP['thr'] * state['V'] == Rng, ]) return constraints, self.aircraftP
def test_init(self): "Test multiple ways to create a Monomial" m = Monomial({'x': 2, 'y': -1}, 5) m2 = Monomial({'x': 2, 'y': -1}, 5) x, = m.varkeys["x"] y, = m.varkeys["y"] self.assertEqual(m.varlocs, {x: [0], y: [0]}) self.assertEqual(m.exp, {x: 2, y: -1}) self.assertEqual(m.c, 5) self.assertEqual(m, m2) # default c and a m = Variable('x') x, = m.varkeys["x"] self.assertEqual(m.varlocs, {x: [0]}) self.assertEqual(m.exp, {x: 1}) self.assertEqual(m.c, 1) # single (string) var with non-default c m = 0.1 * Variable('tau') tau, = m.varkeys["tau"] self.assertEqual(m.varlocs, {tau: [0]}) self.assertEqual(m.exp, {tau: 1}) # pylint: disable=no-member self.assertEqual(m.c, .1) # pylint: disable=no-member # variable names not compatible with python namespaces crazy_varstr = 'what the !!!/$**?' m = Monomial({'x': 1, crazy_varstr: .5}, 25) crazy_varkey, = m.varkeys[crazy_varstr] self.assertTrue(crazy_varkey in m.exp) # non-positive c raises self.assertRaises(InvalidPosynomial, Monomial, -2) self.assertRaises(InvalidPosynomial, Monomial, -1.) self.assertRaises(InvalidPosynomial, Monomial, 0) self.assertRaises(InvalidPosynomial, Monomial, 0.0) # can create nameless Variables x1 = Variable() x2 = Variable() V = Variable('V') vel = Variable('V') self.assertNotEqual(x1, x2) self.assertEqual(V, vel) # test label kwarg x = Variable('x', label='dummy variable') self.assertEqual(list(x.exp)[0].descr['label'], 'dummy variable') _ = hash(m) _ = hash(x) _ = hash(Monomial(x))
def test_mul(self): "Test monomial multiplication" x = Monomial({"x": 1, "y": -1}, 4) # test integer division self.assertEqual(x / 5, Monomial({"x": 1, "y": -1}, 0.8)) # divide by scalar self.assertEqual(x * 9, Monomial({"x": 1, "y": -1}, 36)) # divide by Monomial y = x * Variable("z") self.assertEqual(y, Monomial({"x": 1, "y": -1, "z": 1}, 4)) # make sure x unchanged self.assertEqual(x, Monomial({"x": 1, "y": -1}, 4)) # mixed new and old vars z = x * Monomial({"x": -1, "t": 2}, .5) self.assertEqual(z, Monomial({"x": 0, "y": -1, "t": 2}, 2)) x0 = Variable("x0") self.assertEqual(0.0, 0.0 * x0) x1 = Variable("x1") n_hat = [1, 0] p = n_hat[0] * x0 + n_hat[1] * x1 self.assertEqual(p, x0) self.assertNotEqual((x + 1), (x + 1) * gpkit.units("m"))
def test_sp_relaxation(self): w = Variable("w") x = Variable("x") y = Variable("y") z = Variable("z") with SignomialsEnabled(): m = Model(x, [x + y >= w, x + y <= z / 2, y <= x, y >= 1], { z: 3, w: 3 }) r1 = ConstantsRelaxed(m) self.assertEqual(len(r1.varkeys), 8) with self.assertRaises(ValueError): _ = Model(x * r1.relaxvars, r1) # no "prod" sp = Model(x * r1.relaxvars.prod()**10, r1).sp(use_pccp=False) cost = sp.localsolve(verbosity=0, solver=self.solver)["cost"] self.assertAlmostEqual(cost / 1024, 1, self.ndig) m.debug(verbosity=0, solver=self.solver) with SignomialsEnabled(): m = Model(x, [x + y >= z, x + y <= z / 2, y <= x, y >= 1], {z: 3}) if self.solver != "cvxopt": m.debug(verbosity=0, solver=self.solver) r2 = ConstraintsRelaxed(m) self.assertEqual(len(r2.varkeys), 7) sp = Model(x * r2.relaxvars.prod()**10, r2).sp(use_pccp=False) cost = sp.localsolve(verbosity=0, solver=self.solver)["cost"] self.assertAlmostEqual(cost / 1024, 1, self.ndig) with SignomialsEnabled(): m = Model(x, [x + y >= z, x + y <= z / 2, y <= x, y >= 1], {z: 3}) if self.solver != "cvxopt": m.debug(verbosity=0, solver=self.solver) r3 = ConstraintsRelaxedEqually(m) self.assertEqual(len(r3.varkeys), 4) sp = Model(x * r3.relaxvar**10, r3).sp(use_pccp=False) cost = sp.localsolve(verbosity=0, solver=self.solver)["cost"] self.assertAlmostEqual(cost / (32 * 0.8786796585), 1, self.ndig)
def test_sp_relaxation(self): w = Variable('w') x = Variable('x') y = Variable('y') z = Variable('z') with SignomialsEnabled(): m = Model(x, [x + y >= w, x + y <= z / 2, y <= x, y >= 1], { z: 3, w: 3 }) r1 = ConstantsRelaxed(m) self.assertEqual(len(r1.varkeys), 8) with self.assertRaises(ValueError): mr1 = Model(x * r1.relaxvars, r1) # no 'prod' mr1 = Model(x * r1.relaxvars.prod()**10, r1) cost1 = mr1.localsolve(verbosity=0, solver=self.solver)["cost"] self.assertAlmostEqual(cost1 / 1024, 1, self.ndig) m.debug(verbosity=0, solver=self.solver) with SignomialsEnabled(): m = Model(x, [x + y >= z, x + y <= z / 2, y <= x, y >= 1], {z: 3}) if self.solver != "cvxopt": m.debug(verbosity=0, solver=self.solver) r2 = ConstraintsRelaxed(m) self.assertEqual(len(r2.varkeys), 7) mr2 = Model(x * r2.relaxvars.prod()**10, r2) cost2 = mr2.localsolve(verbosity=0, solver=self.solver)["cost"] self.assertAlmostEqual(cost2 / 1024, 1, self.ndig) with SignomialsEnabled(): m = Model(x, [x + y >= z, x + y <= z / 2, y <= x, y >= 1], {z: 3}) if self.solver != "cvxopt": m.debug(verbosity=0, solver=self.solver) r3 = ConstraintsRelaxedEqually(m) self.assertEqual(len(r3.varkeys), 4) mr3 = Model(x * r3.relaxvar**10, r3) cost3 = mr3.localsolve(verbosity=0, solver=self.solver)["cost"] self.assertAlmostEqual(cost3 / (32 * 0.8786796585), 1, self.ndig)
def setup(self): constraints = [] components = self.components = [] ####### components ###### m = self.m = Variable("m", "kg", "Mass of Engine Tank") if len(components) > 0: constraints += [Tight([m >= sum(comp.m for comp in components)])] ####### constraints += [m >= 2 * ureg.kg] return [components, constraints]
def test_call_time(self): N = 20 x = VectorVariable(N, 'x', 'm') y = VectorVariable(N, 'y', 'm') z1 = VectorVariable(N, 'z1', 'm') z2 = VectorVariable(N, 'z2', 'm') z3 = VectorVariable(N, 'z3', 'm') z4 = VectorVariable(N, 'z4', 'm') L = Variable('L', 5, 'm') prob = Model(sum(x), [x >= y, y >= z1, z1 >= z2, z2 >= z3, z3 >= z4, z4 >= L]) sol = prob.solve(verbosity=0) t1 = time.time() _ = sol(z1) self.assertLess(time.time() - t1, 0.05)
def test_quantity_sub(self): if gpkit.units: x = Variable("x", 1, "cm") y = Variable("y", 1) self.assertEqual(x.sub({x: 1 * gpkit.units.m}).c.magnitude, 100) # NOTE: uncomment the below if requiring Quantity substitutions # self.assertRaises(ValueError, x.sub, x, 1) self.assertRaises(DimensionalityError, x.sub, {x: 1 * gpkit.ureg.N}) self.assertRaises(DimensionalityError, y.sub, {y: 1 * gpkit.ureg.N}) v = gpkit.VectorVariable(3, "v", "cm") subbed = v.sub({v: [1, 2, 3] * gpkit.ureg.m}) self.assertEqual([z.c.magnitude for z in subbed], [100, 200, 300]) v = VectorVariable(1, "v", "km") v_min = VectorVariable(1, "v_min", "km") m = Model(v.prod(), [v >= v_min], {v_min: [2 * gpkit.units("nmi")]}) cost = m.solve(verbosity=0)["cost"] self.assertAlmostEqual(cost / 3.704, 1.0) m = Model(v.prod(), [v >= v_min], {v_min: np.array([2]) * gpkit.units("nmi")}) cost = m.solve(verbosity=0)["cost"] self.assertAlmostEqual(cost / 3.704, 1.0)
def test_init(self): "Test Posynomial construction" x = Variable('x') y = Variable('y') ms = [Monomial({'x': 1, 'y': 2}, 3.14), 0.5*Variable('y'), Monomial({'x': 3, 'y': 1}, 6), Monomial(2)] exps, cs = [], [] for m in ms: cs += m.cs.tolist() exps += m.exps hmap = NomialMap(zip(exps, cs)) hmap.units_of_product(None) p = Posynomial(hmap) # check arithmetic p2 = 3.14*x*y**2 + y/2 + x**3*6*y + 2 self.assertEqual(p, p2) self.assertEqual(p, sum(ms)) _ = hash(p2) hmap = NomialMap({HashVector({'m': 1, 'v': 2}): 0.5, HashVector({'m': 1, 'g': 1, 'h': 1}): 1}) hmap.units_of_product(None) p = Posynomial(hmap) m, = p.varkeys["m"] g, = p.varkeys["g"] h, = p.varkeys["h"] v, = p.varkeys["v"] self.assertTrue(all(isinstance(x, float) for x in p.cs)) self.assertEqual(len(p.exps), 2) self.assertEqual(set(p.varlocs), set([m, g, h, v])) self.assertEqual(p.varlocs[g], p.varlocs[h]) self.assertNotEqual(p.varlocs[g], p.varlocs[v]) self.assertEqual(len(p.varlocs[m]), 2) self.assertTrue(all(len(p.varlocs[key]) == 1 for key in [g, h, v]))
def setup(self): W = Variable("W", 2540, "lbf", "aircraft weight") S = Variable("S", 55.17,"ft**2", "wing planform area") CL_max = Variable("C_{L_{max, land}}", 2.5,"-", "Landing CL_max") Pshaftmax = Variable("P_{shaft-max}", 200., "hp", "Maximum shaft power") AR = Variable("AR", 10, "-", "Aspect ratio") e = Variable("e", 1, "-", "Span efficiency") return []
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): # Dimensional constants BSFC_ref = Variable("BSFC_{ref}", 0.32, "lbf/(hp*hr)", "reference brake specific fuel consumption") eta_prop = Variable("\\eta_{prop}",0.8,'-',"propeller efficiency") P_shaft_ref = Variable("P_{shaft,ref}", 10, "hp", "reference MSL maximum shaft power") W_e_ref = Variable("W_{e,ref}", 10, "lbf","reference engine weight") h_ref = Variable("h_{ref}", 15000,'ft','engine lapse reference altitude') # Free variables P_shaft_max = Variable("P_{shaft,max}","kW","MSL maximum shaft power") W_e = Variable("W_e","N","engine weight") constraints = [(W_e/W_e_ref) == 1.27847 * (P_shaft_max/P_shaft_ref)**0.772392] return constraints
def setup(self, aircraft, revenue_mission, deadhead_mission): N_passengers = revenue_mission.passengers.N trip_distance = revenue_mission.cruise_segment.d_segment self.cpt = cpt = Variable("cost_per_trip", "-", "Cost for one trip") self.cptpp = cptpp = Variable( "cost_per_trip_per_passenger", "-", "Cost for one trip, per passenger carried on revenue trip") self.cpt_passenger_km = cpt_passenger_km = Variable( "cost_per_passenger_km", "km**-1", "Cost per trip, per seat (passenger) kilometer") self.cpt_revenue = cpt_revenue = Variable( "revenue_cost_per_trip", "-", "Portion of the cost per trip incurred during the revenue-generating flights" ) self.cpt_deadhead = cpt_deadhead = Variable( "deadhead_cost_per_trip", "-", "Portion of the cost per trip incurred during the deadhead flights" ) self.deadhead_ratio = deadhead_ratio = Variable( "deadhead_ratio", "-", "Number of deadhead missions per total missions") self.NdNr = NdNr = Variable( "N_{deadhead}/N_{revenue}", "-", "Number of deadhead missions per revenue mission") self.revenue_mission_cost = revenue_mission_cost = RevenueMissionCost( aircraft=aircraft, mission=revenue_mission) self.deadhead_mission_cost = deadhead_mission_cost = DeadheadMissionCost( aircraft=aircraft, mission=deadhead_mission) self.mission_costs = mission_costs = [ revenue_mission_cost, deadhead_mission_cost ] constraints = [mission_costs] constraints += [1. >= deadhead_ratio * (NdNr**-1 + 1.) ] # Obtained via algebraic manipulation constraints += [cpt_revenue == revenue_mission_cost.cost_per_mission] constraints += [ cpt_deadhead == deadhead_mission_cost.cost_per_mission * NdNr ] constraints += [cpt >= cpt_revenue + cpt_deadhead] constraints += [cpt == cptpp * N_passengers] constraints += [cpt == cpt_passenger_km * N_passengers * trip_distance] return constraints
def setup(self, Nclimb, Ncruise, enginestate, eng, Nfleet=0, **kwargs): #create submodels self.fuse = Fuselage() self.wing = Wing() if Nfleet != 0: self.engine = Engine(True, Nclimb + Ncruise, enginestate, eng, Nfleet) else: self.engine = Engine(True, Nclimb + Ncruise, enginestate, eng) #variable definitions numeng = Variable('numeng', '-', 'Number of Engines') self.components = [self.fuse, self.wing, self.engine] return self.components
def test_vector_init(self): N = 6 Weight = 50000 xi_dist = 6 * Weight / float(N) * ( (np.array(range(1, N + 1)) - .5 / float(N)) / float(N) - (np.array(range(1, N + 1)) - .5 / float(N))**2 / float(N)**2) xi = VectorVariable(N, "xi", xi_dist, "N", "Constant Thrust per Bin") P = Variable("P", "N", "Total Power") phys_constraints = [P >= xi.sum()] objective = P eqns = phys_constraints m = Model(objective, eqns) sol = m.solve(verbosity=0) a, b = sol("xi"), xi_dist * gpkit.ureg.N self.assertTrue(all(abs(a - b) / (a + b) < 1e-7))
def setup(self, h=0 * ureg.m): self.v = v = Variable("v", "m/s", "Flight speed") self.L = L = Variable("L", "N", "Lift") self.T = T = Variable("T", "N", "Thrust") self.D = D = Variable("D", "N", "Drag") self.L_D = L_D = Variable("L/D", "-", "Lift-to-drag ratio") self.P_electric = P_electric = Variable( "P_{electric}", "kW", "Electrical power draw (from the battery)") self.P_shaft = P_shaft = Variable("P_{shaft}", "kW", "Shaft power (to all rotors)") self.P_shaft_thrust = P_shaft_thrust = Variable( "P_{shaft,thrust}", "kW", "Shaft power (to generate thrust)") self.P_shaft_tailRotor = P_shaft_tailRotor = Variable( "P_{shaft,tailRotor}", "kW", "Shaft power (to the tail rotor)") self.atmosphere = atmosphere = FixedStandardAtmosphere(h) constraints = [atmosphere] constraints += [L_D == L / D] return constraints
def test_bad_elements(self): x = Variable("x") with self.assertRaises(ValueError): _ = Model(x, [x == "A"]) with self.assertRaises(ValueError): _ = Model(x, [x >= 1, x == "A"]) with self.assertRaises(ValueError): _ = Model(x, [x >= 1, x == "A", x >= 1, ]) with self.assertRaises(ValueError): _ = Model(x, [x == "A", x >= 1]) v = VectorVariable(2, "v") with self.assertRaises(ValueError): _ = Model(x, [v == "A"]) with self.assertRaises(ValueError): _ = Model(x, [v <= ["A", "B"]]) with self.assertRaises(ValueError): _ = Model(x, [v >= ["A", "B"]])
def test_init(self): "Test multiple ways to create a Monomial" m = Monomial({"x": 2, "y": -1}, 5) m2 = Monomial({"x": 2, "y": -1}, 5) x, = m.varkeys["x"] y, = m.varkeys["y"] self.assertEqual(m.exp, {x: 2, y: -1}) self.assertEqual(m.c, 5) self.assertEqual(m, m2) # default c and a v = Variable("x") x, = v.varkeys["x"] self.assertEqual(v.exp, {x: 1}) self.assertEqual(v.c, 1) # single (string) var with non-default c v = 0.1 * Variable("tau") tau, = v.varkeys["tau"] # pylint: disable=no-member self.assertEqual(v.exp, {tau: 1}) # pylint: disable=no-member self.assertEqual(v.c, .1) # pylint: disable=no-member # variable names not compatible with python namespaces crazy_varstr = "what the !!!/$**?" m = Monomial({"x": 1, crazy_varstr: .5}, 25) crazy_varkey, = m.varkeys[crazy_varstr] self.assertTrue(crazy_varkey in m.exp) # non-positive c raises self.assertRaises(InvalidPosynomial, Monomial, -2) self.assertRaises(InvalidPosynomial, Monomial, -1) self.assertRaises(InvalidPosynomial, Monomial, 0) self.assertRaises(InvalidPosynomial, Monomial, 0.0) # can create nameless Variables x1 = Variable() x2 = Variable() V = Variable("V") vel = Variable("V") self.assertNotEqual(x1, x2) self.assertEqual(V, vel) # test label kwarg x = Variable("x", label="dummy variable") self.assertEqual(list(x.exp)[0].descr["label"], "dummy variable") _ = hash(m) _ = hash(x) _ = hash(Monomial(x))
def setup(self): # Env. constants alt_top = Variable('h_{top}', 10000, 'm', 'highest altitude valid') #a_MSL = Variable('a_{MSL}',340.20,'m/s','Speed of sound at MSL') mu_MSL = Variable('\\mu_{MSL}', 1.778e-5, "kg/m/s", 'dynamic viscosity at MSL', pr=4.) #nu_MSL = Variable('\\nu_{MSL}', 1.4524e-5, 'm^2/s', 'kinematic viscosity at MSL') #T_MSL = Variable('T_{MSL}', 288.19, 'K', 'temperature at MSL') rho_MSL = Variable("\\rho_{MSL}", 1.2256, "kg/m^3", "density of air at MSL", pr=5.) #p_MSL = Variable('P_{MSL}', 101308, 'Pa', 'pressure at MSL') alt = Variable('h', 'm', 'altitude') #a = Variable('a','m/s','Speed of sound') mu = Variable('\\mu', "kg/m/s", 'dynamic viscosity', pr=4.) #nu = Variable('\\nu', 'm^2/s', 'kinematic viscosity') #p = Variable('P', 'Pa', 'pressure') #T = Variable('T', 'K', 'temperature ') rho = Variable("\\rho", "kg/m^3", "density of air", pr=5.) # Defining ratios needed for constraints alt_rat = alt / alt_top #a_rat = a/a_MSL mu_rat = mu / mu_MSL #nu_rat = nu/nu_MSL #p_rat = p/p_MSL rho_rat = rho / rho_MSL #T_rat = T/T_MSL constraints = [] with SignomialsEnabled(): constraints += [ alt <= alt_top, #a_rat ** -0.0140 >= 1.00 * (alt_rat) ** 1.20e-05 + 0.00173 * (alt_rat) ** 1.13, SignomialEquality( mu_rat**-0.00795, 1.00 * (alt_rat)**1.33e-05 + 0.00156 * (alt_rat)**1.17), #nu_rat ** 0.00490 >= 1.00 * (alt_rat) ** 1.67e-05,# + 0.00424 * (alt_rat) ** 1.10, #p_rat ** -0.00318 >= 1.00 * (alt_rat) ** 2.18e-05,# + 0.00416 * (alt_rat) ** 1.12, SignomialEquality( rho_rat**-0.00336, 1.00 * (alt_rat)**1.72e-05 + 0.00357 * (alt_rat)**1.11), #T_rat ** -0.00706 >= 1.00 * (alt_rat) ** 1.21e-05,# + 0.00173 * (alt_rat) ** 1.13, ] return constraints
def setup(self): W = Variable("W", "lbf", "motor weight") Pmax = Variable("P_{max}", "W", "max power") Bpm = Variable("B_{PM}", 4140.8, "W/kg", "power mass ratio") m = Variable("m", "kg", "motor mass") g = Variable("g", 9.81, "m/s**2", "gravitational constant") eta = Variable("\\eta", 0.95, "-", "motor efficiency") constraints = [Pmax == Bpm*m, W >= m*g] return constraints
def test_unitless_monomial_sub(self): "Tests that dimensionless and undimensioned subs can interact." x = Variable("x", "-") y = Variable("y") self.assertEqual(x.sub({x: y}), y)
def test_to(self): if gpkit.units: x = Variable("x", "ft") self.assertEqual(x.to("inch").c.magnitude, 12)