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"The shared non-mathematical backbone of all Nomials"
2from .data import NomialData
3from ..small_classes import Numbers, FixedScalar
4from ..repr_conventions import MUL, UNICODE_EXPONENTS
7def nomial_latex_helper(c, pos_vars, neg_vars):
8 """Combines (varlatex, exponent) tuples,
9 separated by positive vs negative exponent, into a single latex string."""
10 pvarstrs = ['%s^{%.2g}' % (varl, x) if "%.2g" % x != "1" else varl
11 for (varl, x) in pos_vars]
12 nvarstrs = ['%s^{%.2g}' % (varl, -x) if "%.2g" % -x != "1" else varl
13 for (varl, x) in neg_vars]
14 pvarstr = " ".join(sorted(pvarstrs))
15 nvarstr = " ".join(sorted(nvarstrs))
16 cstr = "%.2g" % c
17 if pos_vars and cstr in ["1", "-1"]:
18 cstr = cstr[:-1]
19 else:
20 cstr = "%.4g" % c
21 if "e" in cstr: # use exponential notation
22 idx = cstr.index("e")
23 cstr = "%s \\times 10^{%i}" % (cstr[:idx], int(cstr[idx+1:]))
25 if pos_vars and neg_vars:
26 return "%s\\frac{%s}{%s}" % (cstr, pvarstr, nvarstr)
27 if neg_vars and not pos_vars:
28 return "\\frac{%s}{%s}" % (cstr, nvarstr)
29 if pos_vars:
30 return "%s%s" % (cstr, pvarstr)
31 return "%s" % cstr
34class Nomial(NomialData):
35 "Shared non-mathematical properties of all nomials"
36 sub = None
38 def str_without(self, excluded=()):
39 "String representation, excluding fields ('units', varkey attributes)"
40 units = "" if "units" in excluded else self.unitstr(" [%s]")
41 if hasattr(self, "key"):
42 return self.key.str_without(excluded) + units # pylint: disable=no-member
43 if self.ast:
44 return self.parse_ast(excluded) + units
45 mstrs = []
46 for exp, c in self.hmap.items():
47 varstrs = []
48 for (var, x) in exp.items():
49 if not x:
50 continue
51 varstr = var.str_without(excluded)
52 if UNICODE_EXPONENTS and int(x) == x and 2 <= x <= 9:
53 x = int(x)
54 if x in (2, 3):
55 varstr += chr(176+x)
56 elif x in (4, 5, 6, 7, 8, 9):
57 varstr += chr(8304+x)
58 elif x != 1:
59 varstr += "^%.2g" % x
60 varstrs.append(varstr)
61 varstrs.sort()
62 cstr = "%.3g" % c
63 if cstr == "-1" and varstrs:
64 mstrs.append("-" + "·".join(varstrs))
65 else:
66 cstr = [cstr] if (cstr != "1" or not varstrs) else []
67 mstrs.append(MUL.join(cstr + varstrs))
68 return " + ".join(sorted(mstrs)) + units
70 def latex(self, excluded=()): # TODO: add ast parsing here
71 "Latex representation, parsing `excluded` just as .str_without does"
72 mstrs = []
73 for exp, c in self.hmap.items():
74 pos_vars, neg_vars = [], []
75 for var, x in exp.items():
76 if x > 0:
77 pos_vars.append((var.latex(excluded), x))
78 elif x < 0:
79 neg_vars.append((var.latex(excluded), x))
80 mstrs.append(nomial_latex_helper(c, pos_vars, neg_vars))
82 if "units" in excluded:
83 return " + ".join(sorted(mstrs))
84 units = self.unitstr(r"\mathrm{~\left[ %s \right]}", ":L~")
85 units_tf = units.replace("frac", "tfrac").replace(r"\cdot", r"\cdot ")
86 return " + ".join(sorted(mstrs)) + units_tf
88 @property
89 def value(self):
90 """Self, with values substituted for variables that have values
92 Returns
93 -------
94 float, if no symbolic variables remain after substitution
95 (Monomial, Posynomial, or Nomial), otherwise.
96 """
97 if isinstance(self, FixedScalar):
98 return self.cs[0]
99 p = self.sub({k: k.value for k in self.vks if "value" in k.descr}) # pylint: disable=not-callable
100 return p.cs[0] if isinstance(p, FixedScalar) else p
102 def __eq__(self, other):
103 "True if self and other are algebraically identical."
104 if isinstance(other, Numbers):
105 return isinstance(self, FixedScalar) and self.value == other
106 return super().__eq__(other)
108 __hash__ = NomialData.__hash__
109 # pylint: disable=multiple-statements
110 def __ne__(self, other): return not Nomial.__eq__(self, other)
111 def __radd__(self, other): return self.__add__(other, rev=True) # pylint: disable=no-member
112 def __rmul__(self, other): return self.__mul__(other, rev=True) # pylint: disable=no-member
114 def prod(self):
115 "Return self for compatibility with NomialArray"
116 return self
118 sum = prod