def test_eval_numpy(self): m = ConcreteModel() m.p = Param([1,2], mutable=True) m.x = Var() data = np.array([[0,-1,2], [.1,.2,.3], [4,5,6]]) cMap = ComponentMap() cMap[m.p[1]] = data[0] cMap[m.p[2]] = data[1] cMap[m.x] = data[2] npe = NumpyEvaluator(cMap) result = npe.walk_expression(sin(m.x)) assert pytest.approx(result[0], rel=1e-12) == sin(4) assert pytest.approx(result[1], rel=1e-12) == sin(5) assert pytest.approx(result[2], rel=1e-12) == sin(6) result = npe.walk_expression(abs(m.x * m.p[1] - m.p[2])) assert pytest.approx(result[0], rel=1e-12) == .1 assert pytest.approx(result[1], rel=1e-12) == -((-1*5)-.2) assert pytest.approx(result[2], rel=1e-12) == (2*6-.3) result = npe.walk_expression(atan(m.x)) assert pytest.approx(result[0], rel=1e-12) == atan(4) assert pytest.approx(result[1], rel=1e-12) == atan(5) assert pytest.approx(result[2], rel=1e-12) == atan(6) result = npe.walk_expression(atanh(m.p[2])) assert pytest.approx(result[0], rel=1e-12) == atanh(.1) assert pytest.approx(result[1], rel=1e-12) == atanh(.2) assert pytest.approx(result[2], rel=1e-12) == atanh(.3)
def declare_ineq_angle_diff_branch_lbub(model, index_set, branches, coordinate_type=CoordinateType.POLAR): """ Create the inequality constraints for the angle difference bounds between interconnected buses. """ m = model con_set = decl.declare_set('_con_ineq_angle_diff_branch_lbub', model=model, index_set=index_set) m.ineq_angle_diff_branch_lb = pe.Constraint(con_set) m.ineq_angle_diff_branch_ub = pe.Constraint(con_set) if coordinate_type == CoordinateType.POLAR: for branch_name in con_set: from_bus = branches[branch_name]['from_bus'] to_bus = branches[branch_name]['to_bus'] m.ineq_angle_diff_branch_lb[branch_name] = \ branches[branch_name]['angle_diff_min'] <= m.va[from_bus] - m.va[to_bus] m.ineq_angle_diff_branch_ub[branch_name] = \ m.va[from_bus] - m.va[to_bus] <= branches[branch_name]['angle_diff_max'] elif coordinate_type == CoordinateType.RECTANGULAR: for branch_name in con_set: from_bus = branches[branch_name]['from_bus'] to_bus = branches[branch_name]['to_bus'] m.ineq_angle_diff_branch_lb[branch_name] = \ branches[branch_name]['angle_diff_min'] <= pe.atan(m.vj[from_bus]/m.vr[from_bus]) \ - pe.atan(m.vj[to_bus]/m.vr[to_bus]) m.ineq_angle_diff_branch_ub[branch_name] = \ pe.atan(m.vj[from_bus] / m.vr[from_bus]) \ - pe.atan(m.vj[to_bus] / m.vr[to_bus]) <= branches[branch_name]['angle_diff_max']
def _relax_leaf_to_root_arctan(node, values, aux_var_map, degree_map, parent_block, relaxation_side_map, counter): arg = values[0] degree = degree_map[arg] if degree == 0: res = pe.atan(arg) degree_map[res] = 0 return res elif (id(arg), 'arctan') in aux_var_map: _aux_var, relaxation = aux_var_map[id(arg), 'arctan'] relaxation_side = relaxation_side_map[node] if relaxation_side != relaxation.relaxation_side: relaxation.relaxation_side = RelaxationSide.BOTH degree_map[_aux_var] = 1 return _aux_var else: _aux_var = _get_aux_var(parent_block, pe.atan(arg)) arg = replace_sub_expression_with_aux_var(arg, parent_block) relaxation_side = relaxation_side_map[node] degree_map[_aux_var] = 1 relaxation = PWArctanRelaxation() relaxation.set_input(x=arg, aux_var=_aux_var, relaxation_side=relaxation_side) aux_var_map[id(arg), 'arctan'] = (_aux_var, relaxation) setattr(parent_block.relaxations, 'rel'+str(counter), relaxation) counter.increment() return _aux_var
def test_eval_numpy(self): m = ConcreteModel() m.p = Param([1,2], mutable=True) m.x = Var() data = np.array([[0,-1,2], [.1,.2,.3], [4,5,6]]) cMap = ComponentMap() cMap[m.p[1]] = data[0] cMap[m.p[2]] = data[1] cMap[m.x] = data[2] npe = NumpyEvaluator(cMap) result = npe.walk_expression(sin(m.x)) self.assertEqual(result[0], sin(4)) self.assertEqual(result[1], sin(5)) self.assertEqual(result[2], sin(6)) result = npe.walk_expression(abs(m.x * m.p[1] - m.p[2])) self.assertEqual(result[0], .1) self.assertEqual(result[1], -((-1*5)-.2)) self.assertEqual(result[2], (2*6-.3)) result = npe.walk_expression(atan(m.x)) self.assertEqual(result[0], atan(4)) self.assertEqual(result[1], atan(5)) self.assertEqual(result[2], atan(6)) result = npe.walk_expression(atanh(m.p[2])) self.assertEqual(result[0], atanh(.1)) self.assertEqual(result[1], atanh(.2)) self.assertEqual(result[2], atanh(.3))
def get_pyomo_model(): m = aml.ConcreteModel() m.x = aml.Var(initialize=10.0) m.y = aml.Var(initialize=0.0) m.c0 = aml.Constraint(expr=aml.atan(m.x) >= 0) m.c1 = aml.Constraint(expr=aml.atan(m.y) >= 0) m.o = aml.Objective(expr=aml.atan(m.x)) return m
def eq_cosine_partition(lower_bound, upper_bound, Q): #Divides the domain [lower_bound, upper_bound] into Q pieces of equal curvature for the cosine function. Domain must be contained in (-pi/2, pi/2) if Q == 1: return [lower_bound, upper_bound] total_curvature = pe.atan(pe.sin(upper_bound)) - pe.atan( pe.sin(lower_bound)) breakpoints = [lower_bound] for i in range(Q - 1): breakpoints.append( pe.asin( pe.tan(total_curvature / Q + pe.atan(pe.sin(breakpoints[i]))))) breakpoints.append(upper_bound) return breakpoints
def get_pyomo_model(): m = aml.ConcreteModel() N = 4 NP = 100 PI_2 = 2.0 * math.atan(1.0) X = [1.0, 0.0, 0.0, 0.5] Y = [0.0, 1.0, -1.0, 0.0] m.I = range(N) m.v1 = aml.Var(initialize=-40.0) m.w1 = aml.Var(initialize=5.0) m.d = aml.Var(bounds=(1e-8, None), initialize=1.0) m.a = aml.Var(bounds=(1.0, None), initialize=2.0) m.t = aml.Var(bounds=(0.0, 6.2831852), initialize=1.5) m.r = aml.Var(bounds=(0.39, None), initialize=0.75) m.f = aml.Var() m.s1 = aml.Var(bounds=(-0.99, 0.99)) m.s2 = aml.Var(bounds=(-0.99, 0.99)) def eq_1(m, i): return ((m.v1 + m.a * m.d * aml.cos(m.t) - X[i])**2 + (m.w1 + m.a * m.d * aml.sin(m.t) - Y[i])**2 - (m.d + m.r)**2 <= 0) m.eq_1 = aml.Constraint(m.I, rule=eq_1) def eq_2(m, i): return (m.v1 - X[i])**2 + (m.w1 - Y[i])**2 - (m.a * m.d + m.r)**2 >= 0.0 m.eq_2 = aml.Constraint(m.I, rule=eq_2) m.add_1 = aml.Constraint( expr=(m.s1 == -((m.a + m.d)**2 - (m.a * m.d + m.r)**2 + (m.d + m.r)**2) / (2 * (m.d + m.r) * m.a * m.d))) m.add_2 = aml.Constraint( expr=(m.s2 == ((m.a + m.d)**2 + (m.a * m.d + m.r)**2 - (m.d + m.r)**2) / (2 * (m.a * m.d + m.r) * m.a * m.d))) m.obj = aml.Objective( expr=((m.d + m.r) * (m.d + m.r) * (PI_2 - aml.atan(m.s1 / (aml.sqrt(1 - m.s1 * m.s1)))) - (m.a * m.d + m.r) * (m.a * m.d + m.r) * (PI_2 - aml.atan(m.s2 / (aml.sqrt(1 - m.s2 * m.s2)))) + (m.d + m.r) * m.a * m.d * aml.sin((PI_2 - aml.atan(m.s1 / (aml.sqrt(1 - m.s1 * m.s1))))))) return m
def test_atan(self): m = pe.Block(concrete=True) m.x = pe.Var() m.c = pe.Constraint(expr=pe.inequality(body=pe.atan(m.x), lower=-0.5, upper=0.5)) fbbt(m) self.assertAlmostEqual(pe.value(m.x.lb), math.tan(-0.5)) self.assertAlmostEqual(pe.value(m.x.ub), math.tan(0.5))
def test_atan(self): m = pyo.ConcreteModel() m.x = pyo.Var(initialize=2.0) e = pyo.atan(m.x) derivs = reverse_ad(e) symbolic = reverse_sd(e) self.assertAlmostEqual(derivs[m.x], pyo.value(symbolic[m.x]), tol + 3) self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol)
def test_atan(self): m = pe.ConcreteModel() m.x = pe.Var(initialize=2.0) e = pe.atan(m.x) derivs = reverse_ad(e) symbolic = reverse_sd(e) self.assertAlmostEqual(derivs[m.x], pe.value(symbolic[m.x]), tol+3) self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol)
def soft_switch(x, scale=1.0): """Approximates 0 for x <= 0 and 1 for x > 0 Args: x scale (float, optional): order of magnitude of expected values. Defaults to 1.0. """ a = scale_to_a(scale) return atan(a * x) / pi + 0.5
def test_trig_fuctions(self): m = ConcreteModel() m.x = Var() e = differentiate(sin(m.x), wrt=m.x) self.assertTrue(e.is_expression_type()) self.assertEqual(s(e), s(cos(m.x))) e = differentiate(cos(m.x), wrt=m.x) self.assertTrue(e.is_expression_type()) self.assertEqual(s(e), s(-1.0*sin(m.x))) e = differentiate(tan(m.x), wrt=m.x) self.assertTrue(e.is_expression_type()) self.assertEqual(s(e), s(1.+tan(m.x)**2.)) e = differentiate(sinh(m.x), wrt=m.x) self.assertTrue(e.is_expression_type()) self.assertEqual(s(e), s(cosh(m.x))) e = differentiate(cosh(m.x), wrt=m.x) self.assertTrue(e.is_expression_type()) self.assertEqual(s(e), s(sinh(m.x))) e = differentiate(tanh(m.x), wrt=m.x) self.assertTrue(e.is_expression_type()) self.assertEqual(s(e), s(1.0-tanh(m.x)**2.0)) e = differentiate(asin(m.x), wrt=m.x) self.assertTrue(e.is_expression_type()) self.assertEqual(s(e), s((1.0 + (-1.0)*m.x**2.)**-0.5)) e = differentiate(acos(m.x), wrt=m.x) self.assertTrue(e.is_expression_type()) self.assertEqual(s(e), s(-1.*(1.+ (-1.0)*m.x**2.)**-0.5)) e = differentiate(atan(m.x), wrt=m.x) self.assertTrue(e.is_expression_type()) self.assertEqual(s(e), s((1.+m.x**2.)**-1.)) e = differentiate(asinh(m.x), wrt=m.x) self.assertTrue(e.is_expression_type()) self.assertEqual(s(e), s((1.+m.x**2)**-.5)) e = differentiate(acosh(m.x), wrt=m.x) self.assertTrue(e.is_expression_type()) self.assertEqual(s(e), s((-1.+m.x**2.)**-.5)) e = differentiate(atanh(m.x), wrt=m.x) self.assertTrue(e.is_expression_type()) self.assertEqual(s(e), s((1.+(-1.0)*m.x**2.)**-1.))
def test_unary_expressions(self): m = ConcreteModel() m.x = Var() m.y = Var() m.z = Var() m.a = Var() m.b = Var() m.c = Var() m.d = Var() m.c1 = Constraint(expr=0 <= sin(m.x)) m.c2 = Constraint(expr=0 <= cos(m.y)) m.c3 = Constraint(expr=0 <= tan(m.z)) m.c4 = Constraint(expr=0 <= asin(m.a)) m.c5 = Constraint(expr=0 <= acos(m.b)) m.c6 = Constraint(expr=0 <= atan(m.c)) m.c7 = Constraint(expr=0 <= sqrt(m.d)) m.o = Objective(expr=m.x) self.assertTrue(satisfiable(m) is not False)
def test_unary_expressions(self): m = ConcreteModel() m.x = Var() m.y = Var() m.z = Var() m.a = Var() m.b = Var() m.c = Var() m.d = Var() m.c1 = Constraint(expr=0 <= sin(m.x)) m.c2 = Constraint(expr=0 <= cos(m.y)) m.c3 = Constraint(expr=0 <= tan(m.z)) m.c4 = Constraint(expr=0 <= asin(m.a)) m.c5 = Constraint(expr=0 <= acos(m.b)) m.c6 = Constraint(expr=0 <= atan(m.c)) m.c7 = Constraint(expr=0 <= sqrt(m.d)) m.o = Objective(expr=m.x) self.assertTrue(satisfiable(m) is not False)
def test_arcfcn_to_string(self): m = ConcreteModel() m.x = Var() lbl = NumericLabeler('x') smap = SymbolMap(lbl) tc = StorageTreeChecker(m) self.assertEqual(expression_to_string(asin(m.x), tc, lbl, smap=smap), ("arcsin(x1)", False)) self.assertEqual(expression_to_string(acos(m.x), tc, lbl, smap=smap), ("arccos(x1)", False)) self.assertEqual(expression_to_string(atan(m.x), tc, lbl, smap=smap), ("arctan(x1)", False)) with self.assertRaisesRegexp( RuntimeError, "GAMS files cannot represent the unary function asinh"): expression_to_string(asinh(m.x), tc, lbl, smap=smap) with self.assertRaisesRegexp( RuntimeError, "GAMS files cannot represent the unary function acosh"): expression_to_string(acosh(m.x), tc, lbl, smap=smap) with self.assertRaisesRegexp( RuntimeError, "GAMS files cannot represent the unary function atanh"): expression_to_string(atanh(m.x), tc, lbl, smap=smap)
def pw_arctan_relaxation(b, x, w, x_pts, relaxation_side=RelaxationSide.BOTH, pw_repn='INC', safety_tol=1e-10): """ This function creates piecewise relaxations to relax "w=sin(x)" for -pi/2 <= x <= pi/2. Parameters ---------- b: pyo.Block x: pyomo.core.base.var.SimpleVar or pyomo.core.base.var._GeneralVarData The "x" variable in sin(x). The lower bound on x must greater than or equal to -pi/2 and the upper bound on x must be less than or equal to pi/2. w: pyomo.core.base.var.SimpleVar or pyomo.core.base.var._GeneralVarData The auxillary variable replacing sin(x) x_pts: list of float A list of floating point numbers to define the points over which the piecewise representation will be generated. This list must be ordered, and it is expected that the first point (x_pts[0]) is equal to x.lb and the last point (x_pts[-1]) is equal to x.ub relaxation_side: minlp.RelaxationSide Provide the desired side for the relaxation (OVER, UNDER, or BOTH) pw_repn: str This must be one of the valid strings for the peicewise representation to use (directly from the Piecewise component). Use help(Piecewise) to learn more. safety_tol: float amount to lift the overestimator or drop the underestimator. This is used to ensure none of the feasible region is cut off by error in computing the over and under estimators. """ check_var_pts(x, x_pts) expr = pyo.atan(x) _eval = _FxExpr(expr, x) xlb = x_pts[0] xub = x_pts[-1] if x.is_fixed() or xlb == xub: b.x_fixed_con = pyo.Constraint(expr=w == pyo.value(expr)) return if xlb == -math.inf or xub == math.inf: return OE_tangent_x, OE_tangent_slope, OE_tangent_intercept = _compute_arctan_overestimator_tangent_point( xlb) UE_tangent_x, UE_tangent_slope, UE_tangent_intercept = _compute_arctan_underestimator_tangent_point( xub) non_piecewise_overestimators_pts = [] non_piecewise_underestimator_pts = [] if relaxation_side == RelaxationSide.OVER: if OE_tangent_x < xub: new_x_pts = [i for i in x_pts if i < OE_tangent_x] new_x_pts.append(xub) non_piecewise_overestimators_pts = [OE_tangent_x] non_piecewise_overestimators_pts.extend(i for i in x_pts if i > OE_tangent_x) x_pts = new_x_pts elif relaxation_side == RelaxationSide.UNDER: if UE_tangent_x > xlb: new_x_pts = [xlb] new_x_pts.extend(i for i in x_pts if i > UE_tangent_x) non_piecewise_underestimator_pts = [ i for i in x_pts if i < UE_tangent_x ] non_piecewise_underestimator_pts.append(UE_tangent_x) x_pts = new_x_pts b.non_piecewise_overestimators = pyo.ConstraintList() b.non_piecewise_underestimators = pyo.ConstraintList() for pt in non_piecewise_overestimators_pts: b.non_piecewise_overestimators.add(w <= math.atan(pt) + safety_tol + (x - pt) * _eval.deriv(pt)) for pt in non_piecewise_underestimator_pts: b.non_piecewise_underestimators.add(w >= math.atan(pt) - safety_tol + (x - pt) * _eval.deriv(pt)) intervals = [] for i in range(len(x_pts) - 1): intervals.append((x_pts[i], x_pts[i + 1])) b.interval_set = pyo.Set(initialize=range(len(intervals))) b.x = pyo.Var(b.interval_set) b.w = pyo.Var(b.interval_set) if len(intervals) == 1: b.lam = pyo.Param(b.interval_set, mutable=True) b.lam[0].value = 1.0 else: b.lam = pyo.Var(b.interval_set, within=pyo.Binary) b.x_lb = pyo.ConstraintList() b.x_ub = pyo.ConstraintList() b.x_sum = pyo.Constraint(expr=x == sum(b.x[i] for i in b.interval_set)) b.w_sum = pyo.Constraint(expr=w == sum(b.w[i] for i in b.interval_set)) b.lam_sum = pyo.Constraint(expr=sum(b.lam[i] for i in b.interval_set) == 1) b.overestimators = pyo.ConstraintList() b.underestimators = pyo.ConstraintList() for i, tup in enumerate(intervals): x0 = tup[0] x1 = tup[1] b.x_lb.add(x0 * b.lam[i] <= b.x[i]) b.x_ub.add(b.x[i] <= x1 * b.lam[i]) # Overestimators if relaxation_side in {RelaxationSide.OVER, RelaxationSide.BOTH}: if x0 < 0 and x1 <= 0: slope = (math.atan(x1) - math.atan(x0)) / (x1 - x0) intercept = math.atan(x0) - slope * x0 b.overestimators.add(b.w[i] <= slope * b.x[i] + (intercept + safety_tol) * b.lam[i]) elif (x0 < 0) and (x1 > 0): tangent_x, tangent_slope, tangent_intercept = _compute_arctan_overestimator_tangent_point( x0) if tangent_x <= x1: b.overestimators.add( b.w[i] <= tangent_slope * b.x[i] + (tangent_intercept + safety_tol) * b.lam[i]) b.overestimators.add( b.w[i] <= _eval.deriv(x1) * b.x[i] + (math.atan(x1) - x1 * _eval.deriv(x1) + safety_tol) * b.lam[i]) else: slope = (math.atan(x1) - math.atan(x0)) / (x1 - x0) intercept = math.atan(x0) - slope * x0 b.overestimators.add(b.w[i] <= slope * b.x[i] + (intercept + safety_tol) * b.lam[i]) else: b.overestimators.add( b.w[i] <= _eval.deriv(x0) * b.x[i] + (math.atan(x0) - x0 * _eval.deriv(x0) + safety_tol) * b.lam[i]) b.overestimators.add( b.w[i] <= _eval.deriv(x1) * b.x[i] + (math.atan(x1) - x1 * _eval.deriv(x1) + safety_tol) * b.lam[i]) # Underestimators if relaxation_side in {RelaxationSide.UNDER, RelaxationSide.BOTH}: if x0 >= 0 and x1 > 0: slope = (math.atan(x1) - math.atan(x0)) / (x1 - x0) intercept = math.atan(x0) - slope * x0 b.underestimators.add(b.w[i] >= slope * b.x[i] + (intercept - safety_tol) * b.lam[i]) elif (x1 > 0) and (x0 < 0): tangent_x, tangent_slope, tangent_intercept = _compute_arctan_underestimator_tangent_point( x1) if tangent_x >= x0: b.underestimators.add( b.w[i] >= tangent_slope * b.x[i] + (tangent_intercept - safety_tol) * b.lam[i]) b.underestimators.add( b.w[i] >= _eval.deriv(x0) * b.x[i] + (math.atan(x0) - x0 * _eval.deriv(x0) - safety_tol) * b.lam[i]) else: slope = (math.atan(x1) - math.atan(x0)) / (x1 - x0) intercept = math.atan(x0) - slope * x0 b.underestimators.add(b.w[i] >= slope * b.x[i] + (intercept - safety_tol) * b.lam[i]) else: b.underestimators.add( b.w[i] >= _eval.deriv(x0) * b.x[i] + (math.atan(x0) - x0 * _eval.deriv(x0) - safety_tol) * b.lam[i]) b.underestimators.add( b.w[i] >= _eval.deriv(x1) * b.x[i] + (math.atan(x1) - x1 * _eval.deriv(x1) - safety_tol) * b.lam[i]) return x_pts
def test_get_check_units_on_all_expressions(self): # this method is going to test all the expression types that should work # to be defensive, we will also test that we actually have the expected expression type # therefore, if the expression system changes and we get a different expression type, # we will know we need to change these tests uc = units kg = uc.kg m = uc.m model = ConcreteModel() model.x = Var() model.y = Var() model.z = Var() model.p = Param(initialize=42.0, mutable=True) model.xkg = Var(units=kg) model.ym = Var(units=m) # test equality self._get_check_units_ok(3.0*kg == 1.0*kg, uc, 'kg', EXPR.EqualityExpression) self._get_check_units_fail(3.0*kg == 2.0*m, uc, EXPR.EqualityExpression) # test inequality self._get_check_units_ok(3.0*kg <= 1.0*kg, uc, 'kg', EXPR.InequalityExpression) self._get_check_units_fail(3.0*kg <= 2.0*m, uc, EXPR.InequalityExpression) self._get_check_units_ok(3.0*kg >= 1.0*kg, uc, 'kg', EXPR.InequalityExpression) self._get_check_units_fail(3.0*kg >= 2.0*m, uc, EXPR.InequalityExpression) # test RangedExpression self._get_check_units_ok(inequality(3.0*kg, 4.0*kg, 5.0*kg), uc, 'kg', EXPR.RangedExpression) self._get_check_units_fail(inequality(3.0*m, 4.0*kg, 5.0*kg), uc, EXPR.RangedExpression) self._get_check_units_fail(inequality(3.0*kg, 4.0*m, 5.0*kg), uc, EXPR.RangedExpression) self._get_check_units_fail(inequality(3.0*kg, 4.0*kg, 5.0*m), uc, EXPR.RangedExpression) # test SumExpression, NPV_SumExpression self._get_check_units_ok(3.0*model.x*kg + 1.0*model.y*kg + 3.65*model.z*kg, uc, 'kg', EXPR.SumExpression) self._get_check_units_fail(3.0*model.x*kg + 1.0*model.y*m + 3.65*model.z*kg, uc, EXPR.SumExpression) self._get_check_units_ok(3.0*kg + 1.0*kg + 2.0*kg, uc, 'kg', EXPR.NPV_SumExpression) self._get_check_units_fail(3.0*kg + 1.0*kg + 2.0*m, uc, EXPR.NPV_SumExpression) # test ProductExpression, NPV_ProductExpression self._get_check_units_ok(model.x*kg * model.y*m, uc, 'kg*m', EXPR.ProductExpression) self._get_check_units_ok(3.0*kg * 1.0*m, uc, 'kg*m', EXPR.NPV_ProductExpression) self._get_check_units_ok(3.0*kg*m, uc, 'kg*m', EXPR.NPV_ProductExpression) # I don't think that there are combinations that can "fail" for products # test MonomialTermExpression self._get_check_units_ok(model.x*kg, uc, 'kg', EXPR.MonomialTermExpression) # test DivisionExpression, NPV_DivisionExpression self._get_check_units_ok(1.0/(model.x*kg), uc, '1/kg', EXPR.DivisionExpression) self._get_check_units_ok(2.0/kg, uc, '1/kg', EXPR.NPV_DivisionExpression) self._get_check_units_ok((model.x*kg)/1.0, uc, 'kg', EXPR.MonomialTermExpression) self._get_check_units_ok(kg/2.0, uc, 'kg', EXPR.NPV_DivisionExpression) self._get_check_units_ok(model.y*m/(model.x*kg), uc, 'm/kg', EXPR.DivisionExpression) self._get_check_units_ok(m/kg, uc, 'm/kg', EXPR.NPV_DivisionExpression) # I don't think that there are combinations that can "fail" for products # test PowExpression, NPV_PowExpression # ToDo: fix the str representation to combine the powers or the expression system self._get_check_units_ok((model.x*kg**2)**3, uc, 'kg**6', EXPR.PowExpression) # would want this to be kg**6 self._get_check_units_fail(kg**model.x, uc, EXPR.PowExpression, UnitsError) self._get_check_units_fail(model.x**kg, uc, EXPR.PowExpression, UnitsError) self._get_check_units_ok(kg**2, uc, 'kg**2', EXPR.NPV_PowExpression) self._get_check_units_fail(3.0**kg, uc, EXPR.NPV_PowExpression, UnitsError) # test NegationExpression, NPV_NegationExpression self._get_check_units_ok(-(kg*model.x*model.y), uc, 'kg', EXPR.NegationExpression) self._get_check_units_ok(-kg, uc, 'kg', EXPR.NPV_NegationExpression) # don't think there are combinations that fan "fail" for negation # test AbsExpression, NPV_AbsExpression self._get_check_units_ok(abs(kg*model.x), uc, 'kg', EXPR.AbsExpression) self._get_check_units_ok(abs(kg), uc, 'kg', EXPR.NPV_AbsExpression) # don't think there are combinations that fan "fail" for abs # test the different UnaryFunctionExpression / NPV_UnaryFunctionExpression types # log self._get_check_units_ok(log(3.0*model.x), uc, None, EXPR.UnaryFunctionExpression) self._get_check_units_fail(log(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(log(3.0*model.p), uc, None, EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(log(3.0*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # log10 self._get_check_units_ok(log10(3.0*model.x), uc, None, EXPR.UnaryFunctionExpression) self._get_check_units_fail(log10(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(log10(3.0*model.p), uc, None, EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(log10(3.0*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # sin self._get_check_units_ok(sin(3.0*model.x*uc.radians), uc, None, EXPR.UnaryFunctionExpression) self._get_check_units_fail(sin(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_fail(sin(3.0*kg*model.x*uc.kg), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(sin(3.0*model.p*uc.radians), uc, None, EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(sin(3.0*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # cos self._get_check_units_ok(cos(3.0*model.x*uc.radians), uc, None, EXPR.UnaryFunctionExpression) self._get_check_units_fail(cos(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_fail(cos(3.0*kg*model.x*uc.kg), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(cos(3.0*model.p*uc.radians), uc, None, EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(cos(3.0*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # tan self._get_check_units_ok(tan(3.0*model.x*uc.radians), uc, None, EXPR.UnaryFunctionExpression) self._get_check_units_fail(tan(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_fail(tan(3.0*kg*model.x*uc.kg), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(tan(3.0*model.p*uc.radians), uc, None, EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(tan(3.0*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # sin self._get_check_units_ok(sinh(3.0*model.x*uc.radians), uc, None, EXPR.UnaryFunctionExpression) self._get_check_units_fail(sinh(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_fail(sinh(3.0*kg*model.x*uc.kg), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(sinh(3.0*model.p*uc.radians), uc, None, EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(sinh(3.0*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # cos self._get_check_units_ok(cosh(3.0*model.x*uc.radians), uc, None, EXPR.UnaryFunctionExpression) self._get_check_units_fail(cosh(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_fail(cosh(3.0*kg*model.x*uc.kg), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(cosh(3.0*model.p*uc.radians), uc, None, EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(cosh(3.0*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # tan self._get_check_units_ok(tanh(3.0*model.x*uc.radians), uc, None, EXPR.UnaryFunctionExpression) self._get_check_units_fail(tanh(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_fail(tanh(3.0*kg*model.x*uc.kg), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(tanh(3.0*model.p*uc.radians), uc, None, EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(tanh(3.0*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # asin self._get_check_units_ok(asin(3.0*model.x), uc, 'rad', EXPR.UnaryFunctionExpression) self._get_check_units_fail(asin(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(asin(3.0*model.p), uc, 'rad', EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(asin(3.0*model.p*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # acos self._get_check_units_ok(acos(3.0*model.x), uc, 'rad', EXPR.UnaryFunctionExpression) self._get_check_units_fail(acos(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(acos(3.0*model.p), uc, 'rad', EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(acos(3.0*model.p*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # atan self._get_check_units_ok(atan(3.0*model.x), uc, 'rad', EXPR.UnaryFunctionExpression) self._get_check_units_fail(atan(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(atan(3.0*model.p), uc, 'rad', EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(atan(3.0*model.p*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # exp self._get_check_units_ok(exp(3.0*model.x), uc, None, EXPR.UnaryFunctionExpression) self._get_check_units_fail(exp(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(exp(3.0*model.p), uc, None, EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(exp(3.0*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # sqrt self._get_check_units_ok(sqrt(3.0*model.x), uc, None, EXPR.UnaryFunctionExpression) self._get_check_units_ok(sqrt(3.0*model.x*kg**2), uc, 'kg', EXPR.UnaryFunctionExpression) self._get_check_units_ok(sqrt(3.0*model.x*kg), uc, 'kg**0.5', EXPR.UnaryFunctionExpression) self._get_check_units_ok(sqrt(3.0*model.p), uc, None, EXPR.NPV_UnaryFunctionExpression) self._get_check_units_ok(sqrt(3.0*model.p*kg**2), uc, 'kg', EXPR.NPV_UnaryFunctionExpression) self._get_check_units_ok(sqrt(3.0*model.p*kg), uc, 'kg**0.5', EXPR.NPV_UnaryFunctionExpression) # asinh self._get_check_units_ok(asinh(3.0*model.x), uc, 'rad', EXPR.UnaryFunctionExpression) self._get_check_units_fail(asinh(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(asinh(3.0*model.p), uc, 'rad', EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(asinh(3.0*model.p*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # acosh self._get_check_units_ok(acosh(3.0*model.x), uc, 'rad', EXPR.UnaryFunctionExpression) self._get_check_units_fail(acosh(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(acosh(3.0*model.p), uc, 'rad', EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(acosh(3.0*model.p*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # atanh self._get_check_units_ok(atanh(3.0*model.x), uc, 'rad', EXPR.UnaryFunctionExpression) self._get_check_units_fail(atanh(3.0*kg*model.x), uc, EXPR.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(atanh(3.0*model.p), uc, 'rad', EXPR.NPV_UnaryFunctionExpression) self._get_check_units_fail(atanh(3.0*model.p*kg), uc, EXPR.NPV_UnaryFunctionExpression, UnitsError) # ceil self._get_check_units_ok(ceil(kg*model.x), uc, 'kg', EXPR.UnaryFunctionExpression) self._get_check_units_ok(ceil(kg), uc, 'kg', EXPR.NPV_UnaryFunctionExpression) # don't think there are combinations that fan "fail" for ceil # floor self._get_check_units_ok(floor(kg*model.x), uc, 'kg', EXPR.UnaryFunctionExpression) self._get_check_units_ok(floor(kg), uc, 'kg', EXPR.NPV_UnaryFunctionExpression) # don't think there are combinations that fan "fail" for floor # test Expr_ifExpression # consistent if, consistent then/else self._get_check_units_ok(EXPR.Expr_if(IF=model.x*kg + kg >= 2.0*kg, THEN=model.x*kg, ELSE=model.y*kg), uc, 'kg', EXPR.Expr_ifExpression) # unitless if, consistent then/else self._get_check_units_ok(EXPR.Expr_if(IF=model.x >= 2.0, THEN=model.x*kg, ELSE=model.y*kg), uc, 'kg', EXPR.Expr_ifExpression) # consistent if, unitless then/else self._get_check_units_ok(EXPR.Expr_if(IF=model.x*kg + kg >= 2.0*kg, THEN=model.x, ELSE=model.x), uc, None, EXPR.Expr_ifExpression) # inconsistent then/else self._get_check_units_fail(EXPR.Expr_if(IF=model.x >= 2.0, THEN=model.x*m, ELSE=model.y*kg), uc, EXPR.Expr_ifExpression) # inconsistent then/else NPV self._get_check_units_fail(EXPR.Expr_if(IF=model.x >= 2.0, THEN=model.p*m, ELSE=model.p*kg), uc, EXPR.Expr_ifExpression) # inconsistent then/else NPV units only self._get_check_units_fail(EXPR.Expr_if(IF=model.x >= 2.0, THEN=m, ELSE=kg), uc, EXPR.Expr_ifExpression) # test EXPR.IndexTemplate and GetItemExpression model.S = Set() i = EXPR.IndexTemplate(model.S) j = EXPR.IndexTemplate(model.S) self._get_check_units_ok(i, uc, None, EXPR.IndexTemplate) model.mat = Var(model.S, model.S) self._get_check_units_ok(model.mat[i,j+1], uc, None, EXPR.GetItemExpression) # test ExternalFunctionExpression, NPV_ExternalFunctionExpression model.ef = ExternalFunction(python_callback_function) self._get_check_units_ok(model.ef(model.x, model.y), uc, None, EXPR.ExternalFunctionExpression) self._get_check_units_ok(model.ef(1.0, 2.0), uc, None, EXPR.NPV_ExternalFunctionExpression) self._get_check_units_fail(model.ef(model.x*kg, model.y), uc, EXPR.ExternalFunctionExpression, UnitsError) self._get_check_units_fail(model.ef(2.0*kg, 1.0), uc, EXPR.NPV_ExternalFunctionExpression, UnitsError) # test ExternalFunctionExpression, NPV_ExternalFunctionExpression model.ef2 = ExternalFunction(python_callback_function, units=uc.kg) self._get_check_units_ok(model.ef2(model.x, model.y), uc, 'kg', EXPR.ExternalFunctionExpression) self._get_check_units_ok(model.ef2(1.0, 2.0), uc, 'kg', EXPR.NPV_ExternalFunctionExpression) self._get_check_units_fail(model.ef2(model.x*kg, model.y), uc, EXPR.ExternalFunctionExpression, UnitsError) self._get_check_units_fail(model.ef2(2.0*kg, 1.0), uc, EXPR.NPV_ExternalFunctionExpression, UnitsError) # test ExternalFunctionExpression, NPV_ExternalFunctionExpression model.ef3 = ExternalFunction(python_callback_function, units=uc.kg, arg_units=[uc.kg, uc.m]) self._get_check_units_fail(model.ef3(model.x, model.y), uc, EXPR.ExternalFunctionExpression) self._get_check_units_fail(model.ef3(1.0, 2.0), uc, EXPR.NPV_ExternalFunctionExpression) self._get_check_units_fail(model.ef3(model.x*kg, model.y), uc, EXPR.ExternalFunctionExpression, UnitsError) self._get_check_units_fail(model.ef3(2.0*kg, 1.0), uc, EXPR.NPV_ExternalFunctionExpression, UnitsError) self._get_check_units_ok(model.ef3(2.0*kg, 1.0*uc.m), uc, 'kg', EXPR.NPV_ExternalFunctionExpression) self._get_check_units_ok(model.ef3(model.x*kg, model.y*m), uc, 'kg', EXPR.ExternalFunctionExpression) self._get_check_units_ok(model.ef3(model.xkg, model.ym), uc, 'kg', EXPR.ExternalFunctionExpression) self._get_check_units_fail(model.ef3(model.ym, model.xkg), uc, EXPR.ExternalFunctionExpression, InconsistentUnitsError)
model.uidx = pyo.Set(initialize=range(0, nu)) # create state and input variables model.x = pyo.Var(model.xidx, model.tidx) model.u = pyo.Var(model.uidx, model.tidx) # Objective model.cost = pyo.Objective(expr=sum( (model.x[0, t] - xDesired[t])**2 for t in model.tidx if t < N), sense=pyo.minimize) model.constraint1 = pyo.Constraint( model.xidx, rule=lambda model, i: model.x[i, 0] == 0.0) model.constraint2 = pyo.Constraint( model.tidx, rule=lambda model, t: model.x[0, t + 1] == model.x[0, t] + Ts * (pyo.sin(model.x[0, t]) + gamma * pyo.atan(model.x[1, t])) if t < N else pyo.Constraint.Skip) model.constraint3 = pyo.Constraint( model.tidx, rule=lambda model, t: model.x[1, t + 1] == model.x[1, t] + (Ts / tau) * (model.x[1, t] - model.u[0, t]) if t < N else pyo.Constraint.Skip) model.constraint4 = pyo.Constraint(model.tidx, rule=lambda model, t: model.u[0, t + 1] - model.u[0, t] <= +Ts * udotlim if t < N - 1 else pyo.Constraint.Skip) model.constraint5 = pyo.Constraint(model.tidx, rule=lambda model, t: model.u[0, t + 1] - model.u[0, t] >= -Ts * udotlim if t < N - 1 else pyo.Constraint.Skip) model.constraint6 = pyo.Constraint( expr=0.975 * xDesired[N] - model.x[0, N] <= 0.0)
# pick a value in the domain of all of these functions model.ONE = Var(initialize=1) model.ZERO = Var(initialize=0) model.obj = Objective(expr=model.ONE + model.ZERO) model.c_log = Constraint(expr=log(model.ONE) == 0) model.c_log10 = Constraint(expr=log10(model.ONE) == 0) model.c_sin = Constraint(expr=sin(model.ZERO) == 0) model.c_cos = Constraint(expr=cos(model.ZERO) == 1) model.c_tan = Constraint(expr=tan(model.ZERO) == 0) model.c_sinh = Constraint(expr=sinh(model.ZERO) == 0) model.c_cosh = Constraint(expr=cosh(model.ZERO) == 1) model.c_tanh = Constraint(expr=tanh(model.ZERO) == 0) model.c_asin = Constraint(expr=asin(model.ZERO) == 0) model.c_acos = Constraint(expr=acos(model.ZERO) == pi / 2) model.c_atan = Constraint(expr=atan(model.ZERO) == 0) model.c_asinh = Constraint(expr=asinh(model.ZERO) == 0) model.c_acosh = Constraint(expr=acosh((e**2 + model.ONE) / (2 * e)) == 0) model.c_atanh = Constraint(expr=atanh(model.ZERO) == 0) model.c_exp = Constraint(expr=exp(model.ZERO) == 1) model.c_sqrt = Constraint(expr=sqrt(model.ONE) == 1) model.c_ceil = Constraint(expr=ceil(model.ONE) == 1) model.c_floor = Constraint(expr=floor(model.ONE) == 1) model.c_abs = Constraint(expr=abs(model.ONE) == 1)
model.x = pyo.Var(model.xidx, model.tidx) model.u = pyo.Var(model.uidx, model.tidx) model.cost = pyo.Objective( expr = sum((model.x[0,t] - xDesired[t])**2 for t in model.tidx if t<N), sense = pyo.minimize ) # constraints model.cons1 =pyo.Constraint( model.xidx, rule = lambda model, i: model.x[i,0] == 0 ) model.cons2 = pyo.Constraint( model.tidx, rule = lambda model,t: model.x[0,t+1] == model.x[0,t]+ Ts * (pyo.sin(model.x[0,t]) + Gamma * pyo.atan(model.x[1,t])) if t<N else pyo.Constraint.Skip ) model.cons3 = pyo.Constraint( model.tidx, rule = lambda model,t: model.x[1,t+1] == model.x[1,t] + Ts/Tau * model.x[1,t] - model.u[0,t] if t < N else pyo.Constraint.Skip ) model.cons4 = pyo.Constraint( model.tidx, rule = lambda model,t: model.u[0,t+1] - model.u[0,t] >= -Ts * UdotLim if t<N-1 else pyo.Constraint.Skip ) model.cons5 = pyo.Constraint( model.tidx, rule = lambda model,t: