Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"Implements Tight"
2from .set import ConstraintSet
3from ..nomials import PosynomialInequality, SignomialInequality
4from ..small_scripts import mag
5from ..small_scripts import appendsolwarning
6from .. import SignomialsEnabled
9class Tight(ConstraintSet):
10 "ConstraintSet whose inequalities must result in an equality."
11 reltol = 1e-3
13 def __init__(self, constraints, *, reltol=None, **kwargs):
14 super().__init__(constraints)
15 self.reltol = reltol or self.reltol
16 self.__dict__.update(kwargs) # NOTE: for Berk's use in labelling
18 def process_result(self, result):
19 "Checks that all constraints are satisfied with equality"
20 super().process_result(result)
21 variables = result["variables"]
22 for constraint in self.flat():
23 rel_diff = 0
24 if isinstance(constraint, PosynomialInequality):
25 leftsubbed = constraint.left.sub(variables).value
26 rightsubbed = constraint.right.sub(variables).value
27 rel_diff = abs(1 - leftsubbed/rightsubbed)
28 elif isinstance(constraint, SignomialInequality):
29 siglt0, = constraint.unsubbed
30 posy, negy = siglt0.posy_negy()
31 posy = posy.sub(variables).value
32 negy = negy.sub(variables).value
33 rel_diff = abs(1 - posy/negy)
34 if rel_diff >= self.reltol:
35 # do another substitution for the sake of printing
36 with SignomialsEnabled():
37 leftsubbed = constraint.left.sub(variables).value
38 rightsubbed = constraint.right.sub(variables).value
39 if rel_diff >= self.reltol:
40 msg = ("Constraint [%.100s... %s %.100s...] is not tight:"
41 " the left hand side evaluated to %s but"
42 " the right hand side evaluated to %s"
43 " (Allowable error: %s%%, Actual error: %.2g%%)" %
44 (constraint.left, constraint.oper, constraint.right,
45 leftsubbed, rightsubbed,
46 self.reltol*100, mag(rel_diff)*100))
47 if hasattr(leftsubbed, "magnitude"):
48 rightsubbed = rightsubbed.to(leftsubbed.units).magnitude
49 leftsubbed = leftsubbed.magnitude
50 constraint.tightvalues = (leftsubbed, constraint.oper,
51 rightsubbed)
52 constraint.rel_diff = rel_diff
53 appendsolwarning(msg, constraint, result,
54 "Unexpectedly Loose Constraints")