def test_sqrt(self): m = pyo.ConcreteModel() m.x = pyo.Var(initialize=2.0) m.y = pyo.Var(initialize=3.0) e = pyo.sqrt(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_abs(self): m = pyo.ConcreteModel() m.x = pyo.Var(initialize=2.0) e = 2 * abs(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) m.x.value = -2 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) m.x.value = 0 with self.assertRaisesRegex( DifferentiationException, r'Cannot differentiate abs\(x\) at x=0'): reverse_ad(e)
def test_pow(self): m = pe.ConcreteModel() m.x = pe.Var(initialize=2.0) m.y = pe.Var(initialize=3.0) e = m.x**m.y derivs = reverse_ad(e) symbolic = reverse_sd(e) self.assertAlmostEqual(derivs[m.x], pe.value(symbolic[m.x]), tol + 3) self.assertAlmostEqual(derivs[m.y], pe.value(symbolic[m.y]), tol + 3) self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol) self.assertAlmostEqual(derivs[m.y], approx_deriv(e, m.y), tol)
def test_linear_expression(self): m = pyo.ConcreteModel() m.x = pyo.Var(initialize=2.0) m.y = pyo.Var(initialize=3.0) m.p = pyo.Param(initialize=2.5, mutable=True) e = LinearExpression(constant=m.p, linear_vars=[m.x, m.y], linear_coefs=[1.8, m.p]) e = pyo.log(e) derivs = reverse_ad(e) symbolic = reverse_sd(e) for v in [m.x, m.y, m.p]: self.assertAlmostEqual(derivs[v], pyo.value(symbolic[v]), tol) self.assertAlmostEqual(derivs[v], approx_deriv(e, v), tol)
def test_nested_named_expressions(self): m = pyo.ConcreteModel() m.x = pyo.Var(initialize=0.23) m.y = pyo.Var(initialize=0.88) m.a = pyo.Expression(expr=(m.x + 1)**2) m.b = pyo.Expression(expr=3 * (m.a + m.y)) e = 2 * m.a + 2 * m.b + 2 * m.b + 2 * m.a 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) self.assertAlmostEqual(derivs[m.y], pyo.value(symbolic[m.y]), tol + 3) self.assertAlmostEqual(derivs[m.y], approx_deriv(e, m.y), tol)
def test_duplicate_expressions(self): m = pyo.ConcreteModel() m.x = pyo.Var(initialize=0.23) m.y = pyo.Var(initialize=0.88) a = (m.x + 1)**2 b = 3 * (a + m.y) e = 2 * a + 2 * b + 2 * b + 2 * a 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) self.assertAlmostEqual(derivs[m.y], pyo.value(symbolic[m.y]), tol + 3) self.assertAlmostEqual(derivs[m.y], approx_deriv(e, m.y), tol)
def test_external(self): DLL = find_GSL() if not DLL: self.skipTest('Could not find the amplgsl.dll library') m = pyo.ConcreteModel() m.hypot = pyo.ExternalFunction(library=DLL, function='gsl_hypot') m.x = pyo.Var(initialize=0.5) m.y = pyo.Var(initialize=1.5) e = 2 * m.hypot(m.x, m.x * m.y) derivs = reverse_ad(e) self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol) self.assertAlmostEqual(derivs[m.y], approx_deriv(e, m.y), tol)
def test_multiple_named_expressions(self): m = pyo.ConcreteModel() m.x = pyo.Var() m.y = pyo.Var() m.x.value = 1 m.y.value = 1 m.E = pyo.Expression(expr=m.x * m.y) e = m.E - m.E derivs = reverse_ad(e) self.assertAlmostEqual(derivs[m.x], 0) self.assertAlmostEqual(derivs[m.y], 0) symbolic = reverse_sd(e) self.assertAlmostEqual(pyo.value(symbolic[m.x]), 0) self.assertAlmostEqual(pyo.value(symbolic[m.y]), 0)
def test_nested(self): m = pyo.ConcreteModel() m.x = pyo.Var(initialize=2) m.y = pyo.Var(initialize=3) m.p = pyo.Param(initialize=0.5, mutable=True) e = pyo.exp(m.x**m.p + 3.2 * m.y - 12) derivs = reverse_ad(e) symbolic = reverse_sd(e) self.assertAlmostEqual(derivs[m.x], pyo.value(symbolic[m.x]), tol + 3) self.assertAlmostEqual(derivs[m.y], pyo.value(symbolic[m.y]), tol + 3) self.assertAlmostEqual(derivs[m.p], pyo.value(symbolic[m.p]), tol + 3) self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol) self.assertAlmostEqual(derivs[m.y], approx_deriv(e, m.y), tol) self.assertAlmostEqual(derivs[m.p], approx_deriv(e, m.p), tol)
def test_expressiondata(self): m = pyo.ConcreteModel() m.x = pyo.Var(initialize=3) m.e = pyo.Expression(expr=m.x * 2) @m.Expression([1, 2]) def e2(m, i): if i == 1: return m.x + 4 else: return m.x ** 2 m.o = pyo.Objective(expr=m.e + 1 + m.e2[1] + m.e2[2]) derivs = reverse_ad(m.o.expr) symbolic = reverse_sd(m.o.expr) self.assertAlmostEqual(derivs[m.x], pyo.value(symbolic[m.x]), tol)