mathai 0.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mathai/__init__.py +53 -0
- mathai/apart.py +142 -0
- mathai/base.py +419 -0
- mathai/bivariate_inequality.py +317 -0
- mathai/console.py +84 -0
- mathai/diff.py +68 -0
- mathai/expand.py +124 -0
- mathai/factor.py +304 -0
- mathai/fraction.py +103 -0
- mathai/integrate.py +459 -0
- mathai/inverse.py +65 -0
- mathai/limit.py +156 -0
- mathai/linear.py +165 -0
- mathai/logic.py +230 -0
- mathai/matrix.py +22 -0
- mathai/ode.py +124 -0
- mathai/parser.py +158 -0
- mathai/printeq.py +34 -0
- mathai/simplify.py +521 -0
- mathai/structure.py +103 -0
- mathai/tool.py +163 -0
- mathai/trig.py +276 -0
- mathai/univariate_inequality.py +458 -0
- mathai-0.6.0.dist-info/METADATA +234 -0
- mathai-0.6.0.dist-info/RECORD +27 -0
- mathai-0.6.0.dist-info/WHEEL +5 -0
- mathai-0.6.0.dist-info/top_level.txt +1 -0
mathai/__init__.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from .ode import diffsolve as ode_solve
|
|
2
|
+
from .ode import diffsolve_sep as ode_shift_term
|
|
3
|
+
|
|
4
|
+
from .linear import linear_solve, linear_or
|
|
5
|
+
|
|
6
|
+
from .expand import expand
|
|
7
|
+
|
|
8
|
+
from .parser import parse
|
|
9
|
+
|
|
10
|
+
from .printeq import printeq, printeq_log, printeq_str
|
|
11
|
+
|
|
12
|
+
from .simplify import simplify
|
|
13
|
+
|
|
14
|
+
from .integrate import ref as integrate_save
|
|
15
|
+
from .integrate import integrate_subs_main as integrate_subs
|
|
16
|
+
from .integrate import byparts as integrate_byparts
|
|
17
|
+
from .integrate import sqint as integrate_fraction
|
|
18
|
+
from .integrate import integrate_summation
|
|
19
|
+
from .integrate import rm_const as integrate_const
|
|
20
|
+
from .integrate import solve_integrate as integrate_clean
|
|
21
|
+
from .integrate import inteq as integrate_recursive
|
|
22
|
+
from .integrate import integrate_formula
|
|
23
|
+
|
|
24
|
+
from .diff import diff
|
|
25
|
+
|
|
26
|
+
from .factor import factor as factor1
|
|
27
|
+
from .factor import factor2, factor3
|
|
28
|
+
from .factor import rationalize_sqrt as rationalize
|
|
29
|
+
from .factor import merge_sqrt
|
|
30
|
+
from .factor import factorconst as factor0
|
|
31
|
+
|
|
32
|
+
from .fraction import fraction
|
|
33
|
+
|
|
34
|
+
from .inverse import inverse
|
|
35
|
+
|
|
36
|
+
from .trig import trig0, trig1, trig2, trig3, trig4
|
|
37
|
+
|
|
38
|
+
from .logic import logic0, logic1, logic2, logic3, logic_n
|
|
39
|
+
|
|
40
|
+
from .apart import apart, apart2
|
|
41
|
+
|
|
42
|
+
from .limit import limit1, limit2, limit0, limit3
|
|
43
|
+
|
|
44
|
+
from .univariate_inequality import wavycurvy, absolute, domain, handle_sqrt, prepare
|
|
45
|
+
from .bivariate_inequality import inequality_solve
|
|
46
|
+
|
|
47
|
+
from .matrix import uncommute
|
|
48
|
+
|
|
49
|
+
from .base import *
|
|
50
|
+
|
|
51
|
+
from .tool import enclose_const
|
|
52
|
+
from .tool import poly_simplify
|
|
53
|
+
from .tool import longdiv
|
mathai/apart.py
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
from .linear import linear_solve
|
|
2
|
+
from .expand import expand
|
|
3
|
+
from .simplify import simplify
|
|
4
|
+
|
|
5
|
+
from .diff import diff
|
|
6
|
+
from .inverse import inverse
|
|
7
|
+
from .base import *
|
|
8
|
+
import math
|
|
9
|
+
from .factor import factor2
|
|
10
|
+
from .tool import poly, enclose_const, longdiv
|
|
11
|
+
|
|
12
|
+
def _apart(eq, v=None):
|
|
13
|
+
|
|
14
|
+
if v is None:
|
|
15
|
+
if len(vlist(eq)) == 0:
|
|
16
|
+
return eq
|
|
17
|
+
v = vlist(eq)[0]
|
|
18
|
+
origv = vlist(eq)
|
|
19
|
+
|
|
20
|
+
if eq.name != "f_mul":
|
|
21
|
+
return eq
|
|
22
|
+
|
|
23
|
+
if any("f_"+item in str_form(eq) for item in "sin cos tan log".split(" ")):
|
|
24
|
+
return eq
|
|
25
|
+
|
|
26
|
+
def exclude(eq):
|
|
27
|
+
if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]).denominator != 1:
|
|
28
|
+
return False
|
|
29
|
+
if any(not exclude(child) for child in eq.children):
|
|
30
|
+
return False
|
|
31
|
+
return True
|
|
32
|
+
|
|
33
|
+
if not exclude(eq):
|
|
34
|
+
return eq
|
|
35
|
+
|
|
36
|
+
def countfac(lst, eq):
|
|
37
|
+
count=0
|
|
38
|
+
for item in lst:
|
|
39
|
+
if simplify(expand(simplify(eq - item))) == tree_form("d_0"):
|
|
40
|
+
count += 1
|
|
41
|
+
return tree_form("d_"+str(count))
|
|
42
|
+
|
|
43
|
+
alloclst = []
|
|
44
|
+
for i in range(0,26):
|
|
45
|
+
if "v_"+str(i) not in vlist(eq):
|
|
46
|
+
alloclst.append(tree_form("v_"+str(i)))
|
|
47
|
+
|
|
48
|
+
nn, d = num_dem(eq)
|
|
49
|
+
|
|
50
|
+
s = []
|
|
51
|
+
facd = [simplify(x) for x in factor_generation(simplify(d))]
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
facd2 = remove_duplicates_custom(facd, lambda m, n: simplify(expand(simplify(m-n))) == tree_form("d_0"))
|
|
55
|
+
|
|
56
|
+
if len(facd2) == 1:
|
|
57
|
+
return eq
|
|
58
|
+
x = tree_form(v)
|
|
59
|
+
num = []
|
|
60
|
+
dem = []
|
|
61
|
+
|
|
62
|
+
for item in facd2:
|
|
63
|
+
|
|
64
|
+
g = countfac(facd, item)
|
|
65
|
+
for n in range(int(g.name[2:])):
|
|
66
|
+
n = n+1
|
|
67
|
+
if n > 3:
|
|
68
|
+
return eq
|
|
69
|
+
n = tree_form("d_"+str(n))
|
|
70
|
+
|
|
71
|
+
l = len(poly(item, v))
|
|
72
|
+
if l == 3:
|
|
73
|
+
a = alloclst.pop(0)
|
|
74
|
+
b = alloclst.pop(0)
|
|
75
|
+
if n == tree_form("d_1"):
|
|
76
|
+
num.append(a*x+ b)
|
|
77
|
+
dem.append(item)
|
|
78
|
+
s.append((a*x+ b)/item)
|
|
79
|
+
else:
|
|
80
|
+
num.append(a*x+ b)
|
|
81
|
+
dem.append(item**n)
|
|
82
|
+
s.append((a*x+ b)/item**n)
|
|
83
|
+
elif l == 2:
|
|
84
|
+
a = alloclst.pop(0)
|
|
85
|
+
if n == tree_form("d_1"):
|
|
86
|
+
num.append(a)
|
|
87
|
+
dem.append(item)
|
|
88
|
+
s.append(a/item)
|
|
89
|
+
else:
|
|
90
|
+
num.append(a)
|
|
91
|
+
dem.append(item**n)
|
|
92
|
+
s.append(a/item**n)
|
|
93
|
+
else:
|
|
94
|
+
|
|
95
|
+
return eq
|
|
96
|
+
final3 = summation(s)
|
|
97
|
+
|
|
98
|
+
eq2 = simplify(nn*product(dem)/d)
|
|
99
|
+
|
|
100
|
+
final2 = []
|
|
101
|
+
for i in range(len(num)):
|
|
102
|
+
final2.append(product([dem[k] for k in range(len(dem)) if i != k])*num[i])
|
|
103
|
+
|
|
104
|
+
final = summation(final2)
|
|
105
|
+
|
|
106
|
+
s = simplify(TreeNode("f_eq", [final-eq2, tree_form("d_0")]))
|
|
107
|
+
|
|
108
|
+
lst = poly(s.children[0], v)
|
|
109
|
+
|
|
110
|
+
lst = [TreeNode("f_eq", [item, tree_form("d_0")]) for item in lst if "v_" in str_form(item)]
|
|
111
|
+
lst2 = []
|
|
112
|
+
for item in lst:
|
|
113
|
+
lst2+=vlist(item)
|
|
114
|
+
origv = list(set(lst2)-set(origv))
|
|
115
|
+
|
|
116
|
+
out = linear_solve(TreeNode("f_and", lst), [tree_form(item) for item in origv])
|
|
117
|
+
for item in out.children:
|
|
118
|
+
|
|
119
|
+
final3 = replace(final3, tree_form(list(set(vlist(item))&set(origv))[0]), inverse(item.children[0], list(set(vlist(item))&set(origv))[0]))
|
|
120
|
+
final4 = simplify(final3)
|
|
121
|
+
|
|
122
|
+
return final4
|
|
123
|
+
def apart2(eq):
|
|
124
|
+
if eq.name == "f_mul":
|
|
125
|
+
|
|
126
|
+
a, b = num_dem(eq)
|
|
127
|
+
|
|
128
|
+
tmp = longdiv(a, b, 2, 1)
|
|
129
|
+
|
|
130
|
+
if tmp is not None:
|
|
131
|
+
return simplify(tmp[0]+tmp[1]/b)
|
|
132
|
+
return TreeNode(eq.name, [apart2(child) for child in eq.children])
|
|
133
|
+
def apart(eq):
|
|
134
|
+
eq = factor2(simplify(eq))
|
|
135
|
+
eq, fx = enclose_const(eq)
|
|
136
|
+
def helper(eq):
|
|
137
|
+
eq2 = _apart(eq)
|
|
138
|
+
if eq != eq2:
|
|
139
|
+
return eq2
|
|
140
|
+
|
|
141
|
+
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
|
142
|
+
return fx(helper(eq))
|
mathai/base.py
ADDED
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
from fractions import Fraction
|
|
3
|
+
|
|
4
|
+
class TreeNode:
|
|
5
|
+
def __init__(self, name, children=[]):
|
|
6
|
+
|
|
7
|
+
children = [child.copy_tree() for child in children]
|
|
8
|
+
self.name = name
|
|
9
|
+
if name in ["f_add", "f_mul"]:
|
|
10
|
+
self.children = sorted(children, key=lambda x: str_form(x))
|
|
11
|
+
else:
|
|
12
|
+
self.children = children
|
|
13
|
+
|
|
14
|
+
def fx(self, fxname):
|
|
15
|
+
return TreeNode("f_" + fxname, [self])
|
|
16
|
+
def copy_tree(node):
|
|
17
|
+
if node is None:
|
|
18
|
+
return None
|
|
19
|
+
|
|
20
|
+
return tree_form(str_form(node))
|
|
21
|
+
|
|
22
|
+
def __repr__(self):
|
|
23
|
+
return string_equation(str_form(self))
|
|
24
|
+
|
|
25
|
+
def __eq__(self, other):
|
|
26
|
+
if isinstance(other, int):
|
|
27
|
+
other = tree_form("d_" + str(other))
|
|
28
|
+
elif not isinstance(other, TreeNode):
|
|
29
|
+
return NotImplemented
|
|
30
|
+
return str_form(self) == str_form(other)
|
|
31
|
+
|
|
32
|
+
def __add__(self, other):
|
|
33
|
+
if isinstance(other, int):
|
|
34
|
+
other = tree_form("d_" + str(other))
|
|
35
|
+
return TreeNode("f_add", [self, other])
|
|
36
|
+
|
|
37
|
+
def __radd__(self, other):
|
|
38
|
+
return self.__add__(other)
|
|
39
|
+
|
|
40
|
+
def __mul__(self, other):
|
|
41
|
+
if isinstance(other, int):
|
|
42
|
+
other = tree_form("d_" + str(other))
|
|
43
|
+
return TreeNode("f_mul", [self, other])
|
|
44
|
+
|
|
45
|
+
def __rmul__(self, other):
|
|
46
|
+
return self.__mul__(other)
|
|
47
|
+
|
|
48
|
+
def __sub__(self, other):
|
|
49
|
+
if isinstance(other, int):
|
|
50
|
+
other = tree_form("d_" + str(other))
|
|
51
|
+
return self + (tree_form("d_-1") * other)
|
|
52
|
+
|
|
53
|
+
def __rsub__(self, other):
|
|
54
|
+
if isinstance(other, int):
|
|
55
|
+
other = tree_form("d_" + str(other))
|
|
56
|
+
return other + (tree_form("d_-1") * self)
|
|
57
|
+
|
|
58
|
+
def __pow__(self, other):
|
|
59
|
+
if isinstance(other, int):
|
|
60
|
+
other = tree_form("d_" + str(other))
|
|
61
|
+
return TreeNode("f_pow", [self, other])
|
|
62
|
+
|
|
63
|
+
def __rpow__(self, other):
|
|
64
|
+
if isinstance(other, int):
|
|
65
|
+
other = tree_form("d_" + str(other))
|
|
66
|
+
return TreeNode("f_pow", [other, self])
|
|
67
|
+
|
|
68
|
+
def __truediv__(self, other):
|
|
69
|
+
if isinstance(other, int):
|
|
70
|
+
other = tree_form("d_" + str(other))
|
|
71
|
+
return self * (other ** tree_form("d_-1"))
|
|
72
|
+
|
|
73
|
+
def __rtruediv__(self, other):
|
|
74
|
+
if isinstance(other, int):
|
|
75
|
+
other = tree_form("d_" + str(other))
|
|
76
|
+
return other * (self ** tree_form("d_-1"))
|
|
77
|
+
|
|
78
|
+
def __and__(self, other):
|
|
79
|
+
if isinstance(other, int):
|
|
80
|
+
other = tree_form("d_" + str(other))
|
|
81
|
+
return TreeNode("f_and", [self, other])
|
|
82
|
+
|
|
83
|
+
def __rand__(self, other):
|
|
84
|
+
return self.__and__(other)
|
|
85
|
+
|
|
86
|
+
def __or__(self, other):
|
|
87
|
+
if isinstance(other, int):
|
|
88
|
+
other = tree_form("d_" + str(other))
|
|
89
|
+
return TreeNode("f_or", [self, other])
|
|
90
|
+
|
|
91
|
+
def __ror__(self, other):
|
|
92
|
+
return self.__or__(other)
|
|
93
|
+
|
|
94
|
+
def __neg__(self):
|
|
95
|
+
return tree_form("d_-1") * self
|
|
96
|
+
|
|
97
|
+
def __hash__(self):
|
|
98
|
+
return hash(str_form(self))
|
|
99
|
+
|
|
100
|
+
def str_form(node):
|
|
101
|
+
def recursive_str(node, depth=0):
|
|
102
|
+
result = "{}{}".format(' ' * depth, node.name)
|
|
103
|
+
for child in node.children:
|
|
104
|
+
result += "\n" + recursive_str(child, depth + 1)
|
|
105
|
+
return result
|
|
106
|
+
if not isinstance(node, TreeNode):
|
|
107
|
+
return "d_"+str(node)
|
|
108
|
+
return recursive_str(node)
|
|
109
|
+
def replace(equation, find, r):
|
|
110
|
+
if str_form(equation) == str_form(find):
|
|
111
|
+
return r
|
|
112
|
+
col = TreeNode(equation.name, [])
|
|
113
|
+
for child in equation.children:
|
|
114
|
+
col.children.append(replace(child, find, r))
|
|
115
|
+
return col
|
|
116
|
+
|
|
117
|
+
def contain(equation, what):
|
|
118
|
+
if equation == what:
|
|
119
|
+
return True
|
|
120
|
+
if equation.children == []:
|
|
121
|
+
return False
|
|
122
|
+
return any(contain(child, what) for child in equation.children)
|
|
123
|
+
def remove_duplicates_custom(lst, rcustom):
|
|
124
|
+
result = []
|
|
125
|
+
for item in lst:
|
|
126
|
+
if not any(rcustom(item, x) for x in result):
|
|
127
|
+
result.append(item)
|
|
128
|
+
return result
|
|
129
|
+
def frac_to_tree(f):
|
|
130
|
+
if isinstance(f, int):
|
|
131
|
+
f = Fraction(f)
|
|
132
|
+
if f.numerator == 0:
|
|
133
|
+
return tree_form("d_0")
|
|
134
|
+
if f.numerator == 1:
|
|
135
|
+
if f.denominator == 1:
|
|
136
|
+
return tree_form("d_1")
|
|
137
|
+
return tree_form("d_"+str(f.denominator))**tree_form("d_-1")
|
|
138
|
+
if f.denominator == 1:
|
|
139
|
+
return tree_form("d_"+str(f.numerator))
|
|
140
|
+
else:
|
|
141
|
+
return tree_form("d_"+str(f.numerator))/tree_form("d_"+str(f.denominator))
|
|
142
|
+
def perfect_root(n, r):
|
|
143
|
+
if r <= 0 or (n < 0 and r % 2 == 0):
|
|
144
|
+
return False, None
|
|
145
|
+
|
|
146
|
+
lo = 0
|
|
147
|
+
hi = n if n > 1 else 1
|
|
148
|
+
|
|
149
|
+
while lo <= hi:
|
|
150
|
+
mid = lo + (hi - lo) // 2
|
|
151
|
+
pow_val = 1
|
|
152
|
+
|
|
153
|
+
for _ in range(r):
|
|
154
|
+
pow_val *= mid
|
|
155
|
+
if pow_val > n:
|
|
156
|
+
break
|
|
157
|
+
|
|
158
|
+
if pow_val == n:
|
|
159
|
+
return True, mid
|
|
160
|
+
elif pow_val < n:
|
|
161
|
+
lo = mid + 1
|
|
162
|
+
else:
|
|
163
|
+
hi = mid - 1
|
|
164
|
+
|
|
165
|
+
return False, None
|
|
166
|
+
|
|
167
|
+
def frac(eq):
|
|
168
|
+
if eq.name[:2] == "d_":
|
|
169
|
+
return Fraction(int(eq.name[2:]))
|
|
170
|
+
if eq.name == "f_add":
|
|
171
|
+
p = frac(eq.children[0])
|
|
172
|
+
if p is None:
|
|
173
|
+
return None
|
|
174
|
+
for child in eq.children[1:]:
|
|
175
|
+
tmp = frac(child)
|
|
176
|
+
if isinstance(tmp, Fraction):
|
|
177
|
+
p+= tmp
|
|
178
|
+
else:
|
|
179
|
+
return None
|
|
180
|
+
return p
|
|
181
|
+
if eq.name == "f_mul":
|
|
182
|
+
p = frac(eq.children[0])
|
|
183
|
+
if p is None:
|
|
184
|
+
return None
|
|
185
|
+
for child in eq.children[1:]:
|
|
186
|
+
tmp = frac(child)
|
|
187
|
+
if isinstance(tmp, Fraction):
|
|
188
|
+
p*= tmp
|
|
189
|
+
else:
|
|
190
|
+
return None
|
|
191
|
+
return p
|
|
192
|
+
if eq.name == "f_pow":
|
|
193
|
+
a = frac(eq.children[0])
|
|
194
|
+
b = frac(eq.children[1])
|
|
195
|
+
if a is None or b is None:
|
|
196
|
+
return None
|
|
197
|
+
if a == 0 and b <= 0:
|
|
198
|
+
return None
|
|
199
|
+
if b.denominator == 1:
|
|
200
|
+
return a ** b.numerator
|
|
201
|
+
found_c, c = perfect_root(a.numerator, b.denominator)
|
|
202
|
+
found_d, d = perfect_root(a.denominator, b.denominator)
|
|
203
|
+
if found_c and found_d:
|
|
204
|
+
return Fraction(c,d) ** b.numerator
|
|
205
|
+
return None
|
|
206
|
+
return None
|
|
207
|
+
def factor_generation(eq):
|
|
208
|
+
output = []
|
|
209
|
+
if eq.name != "f_mul":
|
|
210
|
+
eq = TreeNode("f_mul", [eq])
|
|
211
|
+
if eq.name == "f_mul":
|
|
212
|
+
for child in eq.children:
|
|
213
|
+
if child.name == "f_pow":
|
|
214
|
+
if child.children[1].name[:2] != "d_":
|
|
215
|
+
output.append(child)
|
|
216
|
+
continue
|
|
217
|
+
if frac(child.children[1]) is not None and frac(child.children[1]).denominator == 1:
|
|
218
|
+
n = int(child.children[1].name[2:])
|
|
219
|
+
if n < 0:
|
|
220
|
+
for i in range(-n):
|
|
221
|
+
out = factor_generation(child.children[0])
|
|
222
|
+
out = [x**-1 for x in out]
|
|
223
|
+
output += out
|
|
224
|
+
#output.append(child.children[0]**-1)
|
|
225
|
+
else:
|
|
226
|
+
for i in range(n):
|
|
227
|
+
output.append(child.children[0])
|
|
228
|
+
else:
|
|
229
|
+
output.append(child)
|
|
230
|
+
else:
|
|
231
|
+
output.append(child)
|
|
232
|
+
|
|
233
|
+
return output
|
|
234
|
+
import math
|
|
235
|
+
|
|
236
|
+
def compute(eq):
|
|
237
|
+
# Base case: leaf node
|
|
238
|
+
if eq.children == []:
|
|
239
|
+
if eq.name == "s_e":
|
|
240
|
+
return math.e
|
|
241
|
+
elif eq.name == "s_pi":
|
|
242
|
+
return math.pi
|
|
243
|
+
elif eq.name.startswith("d_"):
|
|
244
|
+
return float(eq.name[2:])
|
|
245
|
+
else:
|
|
246
|
+
return None
|
|
247
|
+
|
|
248
|
+
# Recursive case: compute child values
|
|
249
|
+
values = [compute(child) for child in eq.children]
|
|
250
|
+
if None in values:
|
|
251
|
+
return None
|
|
252
|
+
# Evaluate based on node type
|
|
253
|
+
if eq.name == "f_add":
|
|
254
|
+
return sum(values)
|
|
255
|
+
elif eq.name == "f_abs":
|
|
256
|
+
return math.fabs(values[0])
|
|
257
|
+
elif eq.name == "f_sub":
|
|
258
|
+
return values[0] - values[1]
|
|
259
|
+
elif eq.name == "f_rad":
|
|
260
|
+
return values[0] * math.pi / 180
|
|
261
|
+
elif eq.name == "f_mul":
|
|
262
|
+
result = 1.0
|
|
263
|
+
for v in values:
|
|
264
|
+
result *= v
|
|
265
|
+
return result
|
|
266
|
+
elif eq.name == "f_neg":
|
|
267
|
+
return -values[0]
|
|
268
|
+
elif eq.name == "f_div":
|
|
269
|
+
return values[0] / values[1]
|
|
270
|
+
elif eq.name == "f_pow":
|
|
271
|
+
return values[0] ** values[1]
|
|
272
|
+
elif eq.name == "f_sin":
|
|
273
|
+
return math.sin(values[0])
|
|
274
|
+
elif eq.name == "f_cos":
|
|
275
|
+
return math.cos(values[0])
|
|
276
|
+
elif eq.name == "f_tan":
|
|
277
|
+
return math.tan(values[0])
|
|
278
|
+
elif eq.name == "f_arcsin":
|
|
279
|
+
return math.asin(values[0])
|
|
280
|
+
elif eq.name == "f_arccos":
|
|
281
|
+
return math.acos(values[0])
|
|
282
|
+
elif eq.name == "f_arctan":
|
|
283
|
+
return math.atan(values[0])
|
|
284
|
+
elif eq.name == "f_log":
|
|
285
|
+
return math.log(values[0])
|
|
286
|
+
else:
|
|
287
|
+
return None
|
|
288
|
+
|
|
289
|
+
def num_dem(equation):
|
|
290
|
+
num = tree_form("d_1")
|
|
291
|
+
den = tree_form("d_1")
|
|
292
|
+
for item in factor_generation(equation):
|
|
293
|
+
if item.name == "f_pow":
|
|
294
|
+
c = frac(item.children[1])
|
|
295
|
+
if c is not None and c < 0:
|
|
296
|
+
t = frac_to_tree(-c)
|
|
297
|
+
if t == tree_form("d_1"):
|
|
298
|
+
den = den * item.children[0]
|
|
299
|
+
else:
|
|
300
|
+
den = den * item.children[0]**t
|
|
301
|
+
else:
|
|
302
|
+
den = den * item
|
|
303
|
+
else:
|
|
304
|
+
num = num*item
|
|
305
|
+
return num, den
|
|
306
|
+
|
|
307
|
+
def summation(lst):
|
|
308
|
+
if len(lst) == 0:
|
|
309
|
+
return tree_form("d_0")
|
|
310
|
+
s = lst[0]
|
|
311
|
+
for item in lst[1:]:
|
|
312
|
+
s += item
|
|
313
|
+
return s
|
|
314
|
+
def vlist(eq):
|
|
315
|
+
out = []
|
|
316
|
+
if eq.name[:2] == "v_":
|
|
317
|
+
out.append(eq.name)
|
|
318
|
+
for child in eq.children:
|
|
319
|
+
out += vlist(child)
|
|
320
|
+
return sorted(list(set(out)), key=lambda x: int(x[2:]))
|
|
321
|
+
def product(lst):
|
|
322
|
+
if lst == []:
|
|
323
|
+
return tree_form("d_1")
|
|
324
|
+
s = lst[0]
|
|
325
|
+
for item in lst[1:]:
|
|
326
|
+
s *= item
|
|
327
|
+
return s
|
|
328
|
+
def flatten_tree(node):
|
|
329
|
+
if not node.children:
|
|
330
|
+
return node
|
|
331
|
+
if node.name in ("f_add", "f_mul", "f_and", "f_or"):
|
|
332
|
+
merged_children = []
|
|
333
|
+
for child in node.children:
|
|
334
|
+
flattened_child = flatten_tree(child)
|
|
335
|
+
if flattened_child.name == node.name:
|
|
336
|
+
merged_children.extend(flattened_child.children)
|
|
337
|
+
else:
|
|
338
|
+
merged_children.append(flattened_child)
|
|
339
|
+
return TreeNode(node.name, merged_children)
|
|
340
|
+
else:
|
|
341
|
+
node.children = [flatten_tree(child) for child in node.children]
|
|
342
|
+
return node
|
|
343
|
+
def dowhile(eq, fx):
|
|
344
|
+
if eq is None:
|
|
345
|
+
return None
|
|
346
|
+
while True:
|
|
347
|
+
orig = eq.copy_tree()
|
|
348
|
+
eq2 = fx(eq)
|
|
349
|
+
if eq2 is None:
|
|
350
|
+
return None
|
|
351
|
+
eq = eq2.copy_tree()
|
|
352
|
+
if eq == orig:
|
|
353
|
+
return orig
|
|
354
|
+
def tree_form(tabbed_strings):
|
|
355
|
+
lines = tabbed_strings.split("\n")
|
|
356
|
+
root = TreeNode("Root")
|
|
357
|
+
current_level_nodes = {0: root}
|
|
358
|
+
stack = [root]
|
|
359
|
+
for line in lines:
|
|
360
|
+
level = line.count(' ')
|
|
361
|
+
node_name = line.strip()
|
|
362
|
+
node = TreeNode(node_name)
|
|
363
|
+
while len(stack) > level + 1:
|
|
364
|
+
stack.pop()
|
|
365
|
+
parent_node = stack[-1]
|
|
366
|
+
parent_node.children.append(node)
|
|
367
|
+
current_level_nodes[level] = node
|
|
368
|
+
stack.append(node)
|
|
369
|
+
return root.children[0]
|
|
370
|
+
def string_equation_helper(equation_tree):
|
|
371
|
+
if equation_tree.children == []:
|
|
372
|
+
if equation_tree.name[:2]=="g_":
|
|
373
|
+
return '"'+equation_tree.name[2:]+'"'
|
|
374
|
+
return equation_tree.name
|
|
375
|
+
extra = ""
|
|
376
|
+
if equation_tree.name == "f_neg":
|
|
377
|
+
return "-"+string_equation_helper(equation_tree.children[0])
|
|
378
|
+
if equation_tree.name == "f_not":
|
|
379
|
+
return "~"+string_equation_helper(equation_tree.children[0])
|
|
380
|
+
if equation_tree.name == "f_list":
|
|
381
|
+
return "["+",".join([string_equation_helper(child) for child in equation_tree.children])+"]"
|
|
382
|
+
if equation_tree.name == "f_index":
|
|
383
|
+
return string_equation_helper(equation_tree.children[0])+"["+",".join([string_equation_helper(child) for child in equation_tree.children[1:]])+"]"
|
|
384
|
+
s = "("
|
|
385
|
+
if len(equation_tree.children) == 1 or equation_tree.name[2:] in [chr(ord("A")+i) for i in range(26)]+["limitpinf", "subs", "try", "ref","limit", "integrate", "exist", "forall", "sum2", "int", "pdif", "dif", "A", "B", "C", "covariance", "sum"]:
|
|
386
|
+
s = equation_tree.name[2:] + s
|
|
387
|
+
sign = {"f_not":"~", "f_addw":"+", "f_mulw":"*", "f_intersection":"&", "f_union":"|", "f_sum2":",", "f_exist":",", "f_forall":",", "f_sum":",","f_covariance": ",", "f_B":",", "f_imply":"->", "f_ge":">=", "f_le":"<=", "f_gt":">", "f_lt":"<", "f_cosec":"?" , "f_equiv": "<->", "f_sec":"?", "f_cot": "?", "f_dot": ".", "f_circumcenter":"?", "f_transpose":"?", "f_exp":"?", "f_abs":"?", "f_log":"?", "f_and":"&", "f_or":"|", "f_sub":"-", "f_neg":"?", "f_inv":"?", "f_add": "+", "f_mul": "*", "f_pow": "^", "f_poly": ",", "f_div": "/", "f_sub": "-", "f_dif": ",", "f_sin": "?", "f_cos": "?", "f_tan": "?", "f_eq": "=", "f_sqrt": "?"}
|
|
388
|
+
arr = []
|
|
389
|
+
k = None
|
|
390
|
+
if equation_tree.name not in sign.keys():
|
|
391
|
+
k = ","
|
|
392
|
+
else:
|
|
393
|
+
k = sign[equation_tree.name]
|
|
394
|
+
for child in equation_tree.children:
|
|
395
|
+
arr.append(string_equation_helper(child.copy_tree()))
|
|
396
|
+
outfinal = s + k.join(arr) + ")"+extra
|
|
397
|
+
|
|
398
|
+
return outfinal.replace("+-", "-")
|
|
399
|
+
def string_equation(eq):
|
|
400
|
+
alpha = ["x", "y", "z"]+[chr(x+ord("a")) for x in range(0,23)]
|
|
401
|
+
beta = [chr(x+ord("A")) for x in range(0,26)]
|
|
402
|
+
eq = tree_form(eq)
|
|
403
|
+
|
|
404
|
+
for i, letter in enumerate(alpha):
|
|
405
|
+
eq = replace(eq, tree_form("v_"+str(i)), tree_form(letter))
|
|
406
|
+
for i, letter in enumerate(beta):
|
|
407
|
+
eq = replace(eq, tree_form("v_-"+str(i+1)), tree_form(letter))
|
|
408
|
+
for i in range(100, 150):
|
|
409
|
+
eq = replace(eq, tree_form("v_"+str(i)), tree_form("c"+str(i-100)))
|
|
410
|
+
eq = str_form(eq)
|
|
411
|
+
|
|
412
|
+
eq = eq.replace("d_", "")
|
|
413
|
+
eq = eq.replace("s_", "")
|
|
414
|
+
eq = eq.replace("v_", "")
|
|
415
|
+
eq = eq.replace("'", "")
|
|
416
|
+
outfinal = string_equation_helper(tree_form(eq))
|
|
417
|
+
if outfinal[0] == "(" and outfinal[-1] == ")":
|
|
418
|
+
return outfinal[1:-1]
|
|
419
|
+
return outfinal
|