mathai 0.4.9__py3-none-any.whl → 0.5.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 +2 -1
- mathai/base.py +1 -3
- mathai/bivariate_inequality.py +296 -0
- mathai/console.py +84 -0
- mathai/factor.py +1 -2
- mathai/linear.py +75 -74
- mathai/parser.py +14 -29
- mathai/tool.py +0 -1
- mathai/univariate_inequality.py +11 -76
- {mathai-0.4.9.dist-info → mathai-0.5.0.dist-info}/METADATA +1 -1
- {mathai-0.4.9.dist-info → mathai-0.5.0.dist-info}/RECORD +13 -11
- {mathai-0.4.9.dist-info → mathai-0.5.0.dist-info}/WHEEL +0 -0
- {mathai-0.4.9.dist-info → mathai-0.5.0.dist-info}/top_level.txt +0 -0
mathai/__init__.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from .ode import diffsolve as ode_solve
|
|
2
2
|
from .ode import diffsolve_sep as ode_shift_term
|
|
3
3
|
|
|
4
|
-
from .linear import linear_solve
|
|
4
|
+
from .linear import linear_solve, linear_or
|
|
5
5
|
|
|
6
6
|
from .expand import expand
|
|
7
7
|
|
|
@@ -42,6 +42,7 @@ from .apart import apart, apart2
|
|
|
42
42
|
from .limit import limit
|
|
43
43
|
|
|
44
44
|
from .univariate_inequality import wavycurvy, absolute, domain, handle_sqrt
|
|
45
|
+
from .bivariate_inequality import inequality_solve
|
|
45
46
|
|
|
46
47
|
from .base import *
|
|
47
48
|
|
mathai/base.py
CHANGED
|
@@ -204,11 +204,9 @@ def compute(eq):
|
|
|
204
204
|
|
|
205
205
|
# Recursive case: compute child values
|
|
206
206
|
values = [compute(child) for child in eq.children]
|
|
207
|
-
|
|
208
|
-
|
|
209
207
|
if None in values:
|
|
210
208
|
return None
|
|
211
|
-
|
|
209
|
+
# Evaluate based on node type
|
|
212
210
|
if eq.name == "f_add":
|
|
213
211
|
return sum(values)
|
|
214
212
|
elif eq.name == "f_sub":
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import math
|
|
2
|
+
from .linear import linear_or
|
|
3
|
+
from functools import reduce
|
|
4
|
+
import operator
|
|
5
|
+
from .base import *
|
|
6
|
+
from .simplify import simplify
|
|
7
|
+
def shoelace_area(vertices):
|
|
8
|
+
n = len(vertices)
|
|
9
|
+
area = 0.0
|
|
10
|
+
for i in range(n):
|
|
11
|
+
j = (i + 1) % n
|
|
12
|
+
area += vertices[i][0] * vertices[j][1]
|
|
13
|
+
area -= vertices[j][0] * vertices[i][1]
|
|
14
|
+
return abs(area) / 2.0
|
|
15
|
+
|
|
16
|
+
def triangle_area(p1, p2, p3):
|
|
17
|
+
area = 0.0
|
|
18
|
+
area += p1[0] * (p2[1] - p3[1])
|
|
19
|
+
area += p2[0] * (p3[1] - p1[1])
|
|
20
|
+
area += p3[0] * (p1[1] - p2[1])
|
|
21
|
+
return abs(area) / 2.0
|
|
22
|
+
|
|
23
|
+
def is_point_inside_polygon(point, vertices):
|
|
24
|
+
if len(vertices) < 3:
|
|
25
|
+
return False
|
|
26
|
+
|
|
27
|
+
polygon_area = shoelace_area(vertices)
|
|
28
|
+
|
|
29
|
+
total_triangle_area = 0.0
|
|
30
|
+
n = len(vertices)
|
|
31
|
+
for i in range(n):
|
|
32
|
+
j = (i + 1) % n
|
|
33
|
+
total_triangle_area += triangle_area(point, vertices[i], vertices[j])
|
|
34
|
+
|
|
35
|
+
tolerance = 1e-5
|
|
36
|
+
return abs(total_triangle_area - polygon_area) < tolerance
|
|
37
|
+
|
|
38
|
+
def distance_point_to_segment(px, py, x1, y1, x2, y2):
|
|
39
|
+
dx, dy = x2 - x1, y2 - y1
|
|
40
|
+
if dx == dy == 0:
|
|
41
|
+
return ((px - x1)**2 + (py - y1)**2)**0.5
|
|
42
|
+
t = max(0, min(1, ((px - x1) * dx + (py - y1) * dy) / (dx*dx + dy*dy)))
|
|
43
|
+
proj_x = x1 + t * dx
|
|
44
|
+
proj_y = y1 + t * dy
|
|
45
|
+
return ((px - proj_x)**2 + (py - proj_y)**2)**0.5
|
|
46
|
+
|
|
47
|
+
def deterministic_middle_point(vertices, grid_resolution=100):
|
|
48
|
+
xs = [v[0] for v in vertices]
|
|
49
|
+
ys = [v[1] for v in vertices]
|
|
50
|
+
xmin, xmax = min(xs), max(xs)
|
|
51
|
+
ymin, ymax = min(ys), max(ys)
|
|
52
|
+
|
|
53
|
+
best_point = None
|
|
54
|
+
max_dist = -1
|
|
55
|
+
|
|
56
|
+
for i in range(grid_resolution + 1):
|
|
57
|
+
for j in range(grid_resolution + 1):
|
|
58
|
+
px = xmin + (xmax - xmin) * i / grid_resolution
|
|
59
|
+
py = ymin + (ymax - ymin) * j / grid_resolution
|
|
60
|
+
if not is_point_inside_polygon((px, py), vertices):
|
|
61
|
+
continue
|
|
62
|
+
min_edge_dist = float('inf')
|
|
63
|
+
n = len(vertices)
|
|
64
|
+
for k in range(n):
|
|
65
|
+
x1, y1 = vertices[k]
|
|
66
|
+
x2, y2 = vertices[(k + 1) % n]
|
|
67
|
+
d = distance_point_to_segment(px, py, x1, y1, x2, y2)
|
|
68
|
+
min_edge_dist = min(min_edge_dist, d)
|
|
69
|
+
if min_edge_dist > max_dist:
|
|
70
|
+
max_dist = min_edge_dist
|
|
71
|
+
best_point = (px, py)
|
|
72
|
+
|
|
73
|
+
return best_point
|
|
74
|
+
|
|
75
|
+
def build(eq):
|
|
76
|
+
if len(eq) <= 1:
|
|
77
|
+
return None
|
|
78
|
+
eq = TreeNode("f_or", eq)
|
|
79
|
+
eq = flatten_tree(eq)
|
|
80
|
+
orig = eq.copy_tree()
|
|
81
|
+
def fxhelper3(eq):
|
|
82
|
+
if eq.name[2:] in "le ge lt gt".split(" "):
|
|
83
|
+
return TreeNode("f_eq", [child.copy_tree() for child in eq.children])
|
|
84
|
+
return TreeNode(eq.name, [fxhelper3(child) for child in eq.children])
|
|
85
|
+
eq = fxhelper3(eq)
|
|
86
|
+
|
|
87
|
+
result = linear_or(eq)
|
|
88
|
+
maxnum = tree_form("d_2")
|
|
89
|
+
if len(result[1]) != 0:
|
|
90
|
+
maxnum = max([max([simplify(item2.fx("abs")) for item2 in item], key=lambda x: compute(x)) for item in result[1]], key=lambda x: compute(x))
|
|
91
|
+
maxnum += 1
|
|
92
|
+
maxnum = simplify(maxnum)
|
|
93
|
+
eq = flatten_tree(eq | simplify(TreeNode("f_or", [TreeNode("f_eq", [tree_form(item)+maxnum, tree_form("d_0")])|\
|
|
94
|
+
TreeNode("f_eq", [tree_form(item)-maxnum, tree_form("d_0")]) for item in vlist(eq)])))
|
|
95
|
+
result2 = linear_or(eq)
|
|
96
|
+
|
|
97
|
+
point_lst = result2[2]
|
|
98
|
+
|
|
99
|
+
def gen(point):
|
|
100
|
+
nonlocal point_lst
|
|
101
|
+
out = []
|
|
102
|
+
for item in point_lst:
|
|
103
|
+
p = None
|
|
104
|
+
if point in item:
|
|
105
|
+
p = item.index(point)
|
|
106
|
+
else:
|
|
107
|
+
continue
|
|
108
|
+
if p < len(item)-1:
|
|
109
|
+
out.append(item[p+1])
|
|
110
|
+
if p > 0:
|
|
111
|
+
out.append(item[p-1])
|
|
112
|
+
return list(set(out))
|
|
113
|
+
start = list(range(len(result2[1])))
|
|
114
|
+
graph= {}
|
|
115
|
+
for item in start:
|
|
116
|
+
graph[item] = gen(item)
|
|
117
|
+
|
|
118
|
+
points = {}
|
|
119
|
+
for index, item in enumerate(result2[1]):
|
|
120
|
+
points[index] = [compute(item2) for item2 in item]
|
|
121
|
+
|
|
122
|
+
res = []
|
|
123
|
+
for index, item in enumerate(result2[1]):
|
|
124
|
+
if any(simplify(item2.fx("abs")-maxnum)!=0 and abs(compute(item2))>compute(maxnum) for item2 in item):
|
|
125
|
+
res.append(index)
|
|
126
|
+
|
|
127
|
+
graph = {k: sorted(v) for k, v in graph.items()}
|
|
128
|
+
|
|
129
|
+
def dfs(current, parent, path, visited, cycles):
|
|
130
|
+
path.append(current)
|
|
131
|
+
visited.add(current)
|
|
132
|
+
for neighbor in graph[current]:
|
|
133
|
+
if neighbor == parent:
|
|
134
|
+
continue
|
|
135
|
+
if neighbor in visited:
|
|
136
|
+
idx = path.index(neighbor)
|
|
137
|
+
cycle = path[idx:]
|
|
138
|
+
cycles.append(cycle)
|
|
139
|
+
else:
|
|
140
|
+
dfs(neighbor, current, path, visited, cycles)
|
|
141
|
+
path.pop()
|
|
142
|
+
visited.remove(current)
|
|
143
|
+
|
|
144
|
+
cycles = []
|
|
145
|
+
for start in sorted(graph.keys()):
|
|
146
|
+
path = []
|
|
147
|
+
visited = set()
|
|
148
|
+
dfs(start, -1, path, visited, cycles)
|
|
149
|
+
|
|
150
|
+
def normalize(cycle):
|
|
151
|
+
k = len(cycle)
|
|
152
|
+
if k < 3:
|
|
153
|
+
return None
|
|
154
|
+
candidates = []
|
|
155
|
+
for direction in [cycle, list(reversed(cycle))]:
|
|
156
|
+
doubled = direction + direction[:-1]
|
|
157
|
+
for i in range(k):
|
|
158
|
+
rot = tuple(doubled[i:i + k])
|
|
159
|
+
candidates.append(rot)
|
|
160
|
+
return min(candidates)
|
|
161
|
+
|
|
162
|
+
unique = set()
|
|
163
|
+
for c in cycles:
|
|
164
|
+
norm = normalize(c)
|
|
165
|
+
if norm:
|
|
166
|
+
unique.add(norm)
|
|
167
|
+
|
|
168
|
+
cycles = sorted(list(unique), key=lambda x: (len(x), x))
|
|
169
|
+
|
|
170
|
+
start = list(range(len(result2[1])))
|
|
171
|
+
for i in range(len(cycles)-1,-1,-1):
|
|
172
|
+
if any(item in cycles[i] for item in res) or\
|
|
173
|
+
any(is_point_inside_polygon([compute(item2) for item2 in list(result2[1][p])], [[compute(item2) for item2 in result2[1][item]] for item in cycles[i]]) for p in list(set(start) - set(cycles[i]))) or\
|
|
174
|
+
any(len(set(graph[item]) & set(cycles[i]))>2 for item in cycles[i]):
|
|
175
|
+
cycles.pop(i)
|
|
176
|
+
|
|
177
|
+
point_lst = [index for index, item in enumerate(result2[1]) if item in result[1]]
|
|
178
|
+
border = []
|
|
179
|
+
for item in start:
|
|
180
|
+
for item2 in graph[item]:
|
|
181
|
+
a = result2[1][item]
|
|
182
|
+
b = result2[1][item2]
|
|
183
|
+
|
|
184
|
+
if a[0] == b[0] and simplify(a[0].fx("abs") - maxnum) == 0:
|
|
185
|
+
continue
|
|
186
|
+
if a[1] == b[1] and simplify(a[1].fx("abs") - maxnum) == 0:
|
|
187
|
+
continue
|
|
188
|
+
border.append(tuple(sorted([item, item2])))
|
|
189
|
+
line = []
|
|
190
|
+
for key in graph.keys():
|
|
191
|
+
for item in list(set(point_lst)&set(graph[key])):
|
|
192
|
+
line.append(tuple(sorted([item, key])))
|
|
193
|
+
line = list(set(line+border))
|
|
194
|
+
point_in = [deterministic_middle_point([[compute(item3) for item3 in result2[1][item2]] for item2 in item]) for item in cycles]
|
|
195
|
+
def work(eq, point):
|
|
196
|
+
if "f_eq" in str_form(eq):
|
|
197
|
+
return False
|
|
198
|
+
nonlocal result2
|
|
199
|
+
if eq.name[:2] == "d_":
|
|
200
|
+
return float(eq.name[2:])
|
|
201
|
+
if eq.name in result2[0]:
|
|
202
|
+
return point[result2[0].index(eq.name)]
|
|
203
|
+
if eq.name == "f_add":
|
|
204
|
+
return sum(work(item, point) for item in eq.children)
|
|
205
|
+
if eq.name == "f_mul":
|
|
206
|
+
return math.prod(work(item, point) for item in eq.children)
|
|
207
|
+
return {"gt":lambda a,b: a>b, "lt":lambda a,b: a<b}[eq.name[2:]](work(eq.children[0], point), work(eq.children[1], point))
|
|
208
|
+
|
|
209
|
+
data = []
|
|
210
|
+
for index, item in enumerate(result2[2][:-4]):
|
|
211
|
+
a = tuple(set(item) & set(point_lst))
|
|
212
|
+
b = tuple(set([tuple(sorted([item[i], item[i+1]])) for i in range(len(item)-1)]) & set(line))
|
|
213
|
+
c = tuple([tuple(item) for index2, item in enumerate(cycles) if work(orig.children[index], point_in[index2])])
|
|
214
|
+
data.append((a,b,c))
|
|
215
|
+
|
|
216
|
+
total = tuple([tuple(point_lst), tuple(line), tuple(cycles)])
|
|
217
|
+
final = {}
|
|
218
|
+
for index, item in enumerate(orig.children):
|
|
219
|
+
final[item] = tuple(data[index])
|
|
220
|
+
return final, total, result2[1]
|
|
221
|
+
|
|
222
|
+
def inequality_solve(eq):
|
|
223
|
+
element = []
|
|
224
|
+
def helper(eq):
|
|
225
|
+
nonlocal element
|
|
226
|
+
if eq.name[2:] in "le ge lt gt eq".split(" ") and "v_" in str_form(eq):
|
|
227
|
+
element.append(eq)
|
|
228
|
+
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
|
229
|
+
helper(eq)
|
|
230
|
+
|
|
231
|
+
out = build(list(set(element)))
|
|
232
|
+
|
|
233
|
+
if out is None:
|
|
234
|
+
return eq
|
|
235
|
+
|
|
236
|
+
def helper2(eq):
|
|
237
|
+
nonlocal out
|
|
238
|
+
if eq == tree_form("s_true"):
|
|
239
|
+
return [set(item) for item in out[1]]
|
|
240
|
+
if eq == tree_form("s_false"):
|
|
241
|
+
return [set(), set(), set()]
|
|
242
|
+
if eq in out[0].keys():
|
|
243
|
+
return [set(item) for item in out[0][eq]]
|
|
244
|
+
if eq.name == "f_or":
|
|
245
|
+
result = [helper2(child) for child in eq.children]
|
|
246
|
+
a = []
|
|
247
|
+
b = []
|
|
248
|
+
c = []
|
|
249
|
+
for item in result:
|
|
250
|
+
a += [item[0]]
|
|
251
|
+
b += [item[1]]
|
|
252
|
+
c += [item[2]]
|
|
253
|
+
x = a[0]
|
|
254
|
+
for item in a[1:]:
|
|
255
|
+
x |= item
|
|
256
|
+
y = b[0]
|
|
257
|
+
for item in b[1:]:
|
|
258
|
+
y |= item
|
|
259
|
+
z = c[0]
|
|
260
|
+
for item in c[1:]:
|
|
261
|
+
z |= item
|
|
262
|
+
return [x, y, z]
|
|
263
|
+
if eq.name == "f_and":
|
|
264
|
+
result = [helper2(child) for child in eq.children]
|
|
265
|
+
a = []
|
|
266
|
+
b = []
|
|
267
|
+
c = []
|
|
268
|
+
for item in result:
|
|
269
|
+
a += [item[0]]
|
|
270
|
+
b += [item[1]]
|
|
271
|
+
c += [item[2]]
|
|
272
|
+
x = a[0]
|
|
273
|
+
for item in a[1:]:
|
|
274
|
+
x &= item
|
|
275
|
+
y = b[0]
|
|
276
|
+
for item in b[1:]:
|
|
277
|
+
y &= item
|
|
278
|
+
z = c[0]
|
|
279
|
+
for item in c[1:]:
|
|
280
|
+
z &= item
|
|
281
|
+
return [x, y, z]
|
|
282
|
+
if eq.name == "f_not":
|
|
283
|
+
eq2 = helper2(eq.children[0])
|
|
284
|
+
a,b,c= eq2
|
|
285
|
+
d,e,f= [set(item) for item in out[1]]
|
|
286
|
+
return [d-a,e-b,f-c]
|
|
287
|
+
out2 = helper2(eq)
|
|
288
|
+
|
|
289
|
+
out = list(out)
|
|
290
|
+
out[1] = [set(item) for item in out[1]]
|
|
291
|
+
|
|
292
|
+
if tuple(out[1]) == tuple(out2):
|
|
293
|
+
return tree_form("s_true")
|
|
294
|
+
if tuple(out2) == (set(), set(), set()):
|
|
295
|
+
return tree_form("s_false")
|
|
296
|
+
return eq
|
mathai/console.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
from .expand import expand
|
|
3
|
+
from .parser import parse
|
|
4
|
+
from .printeq import printeq, printeq_log
|
|
5
|
+
from .simplify import solve, simplify
|
|
6
|
+
|
|
7
|
+
from .diff import diff
|
|
8
|
+
from .base import *
|
|
9
|
+
from .factor import _factorconst, factor
|
|
10
|
+
from .fraction import fraction
|
|
11
|
+
from .inverse import inverse
|
|
12
|
+
from .trig import trig0, trig1, trig2, trig3, trig4
|
|
13
|
+
from .logic import logic0, logic1, logic2, logic3
|
|
14
|
+
from .apart import apart
|
|
15
|
+
|
|
16
|
+
def console():
|
|
17
|
+
eq = None
|
|
18
|
+
orig = None
|
|
19
|
+
while True:
|
|
20
|
+
command = input(">>> ")
|
|
21
|
+
try:
|
|
22
|
+
orig = copy.deepcopy(eq)
|
|
23
|
+
if command == "expand":
|
|
24
|
+
eq = expand(eq)
|
|
25
|
+
elif command.split(" ")[0] == "inverse":
|
|
26
|
+
eq=simplify(eq)
|
|
27
|
+
if eq.name == "f_eq":
|
|
28
|
+
eq3 = eq.children[0]-eq.children[1]
|
|
29
|
+
eq2 = parse(command.split(" ")[1])
|
|
30
|
+
out = inverse(eq3, str_form(eq2))
|
|
31
|
+
eq = TreeNode(eq.name, [eq2,out])
|
|
32
|
+
elif command == "apart":
|
|
33
|
+
eq = apart(eq, vlist(eq)[0])
|
|
34
|
+
elif command == "rawprint":
|
|
35
|
+
print(eq)
|
|
36
|
+
elif command == "logic0":
|
|
37
|
+
eq = logic0(eq)
|
|
38
|
+
elif command == "logic1":
|
|
39
|
+
eq = logic1(eq)
|
|
40
|
+
elif command == "logic2":
|
|
41
|
+
eq = logic2(eq)
|
|
42
|
+
elif command == "logic3":
|
|
43
|
+
eq = logic3(eq)
|
|
44
|
+
elif command == "trig0":
|
|
45
|
+
eq = trig0(eq)
|
|
46
|
+
elif command == "trig1":
|
|
47
|
+
eq = trig1(eq)
|
|
48
|
+
elif command == "factor":
|
|
49
|
+
eq = factor(eq)
|
|
50
|
+
elif command == "trig2":
|
|
51
|
+
eq = trig2(eq)
|
|
52
|
+
elif command == "trig3":
|
|
53
|
+
eq = trig3(eq)
|
|
54
|
+
elif command == "trig4":
|
|
55
|
+
eq = trig4(eq)
|
|
56
|
+
elif command == "simplify":
|
|
57
|
+
eq = _factorconst(eq)
|
|
58
|
+
eq = simplify(eq)
|
|
59
|
+
elif command == "fraction":
|
|
60
|
+
eq = fraction(eq)
|
|
61
|
+
elif command.split(" ")[0] in ["integrate", "sqint", "byparts"]:
|
|
62
|
+
if command.split(" ")[0] == "sqint":
|
|
63
|
+
typesqint()
|
|
64
|
+
elif command.split(" ")[0] == "byparts":
|
|
65
|
+
typebyparts()
|
|
66
|
+
elif command.split(" ")[0] == "integrate":
|
|
67
|
+
typeintegrate()
|
|
68
|
+
out = integrate(eq, parse(command.split(" ")[1]).name)
|
|
69
|
+
if out is None:
|
|
70
|
+
print("failed to integrate")
|
|
71
|
+
else:
|
|
72
|
+
eq, logs = out
|
|
73
|
+
eq = simplify(eq)
|
|
74
|
+
printeq_log(logs)
|
|
75
|
+
print()
|
|
76
|
+
elif command.split(" ")[0] == "diff":
|
|
77
|
+
eq = diff(eq, parse(command.split(" ")[1]).name)
|
|
78
|
+
else:
|
|
79
|
+
eq = parse(command)
|
|
80
|
+
eq = copy.deepcopy(eq)
|
|
81
|
+
printeq(eq)
|
|
82
|
+
except:
|
|
83
|
+
eq = copy.deepcopy(orig)
|
|
84
|
+
print("error")
|
mathai/factor.py
CHANGED
|
@@ -171,8 +171,7 @@ def factor_quar_formula_init():
|
|
|
171
171
|
formula_gen9 = factor_quar_formula_init()
|
|
172
172
|
def factor_helper(equation, complexnum, power=2):
|
|
173
173
|
global formula_gen9
|
|
174
|
-
|
|
175
|
-
return TreeNode(equation.name, [factor_helper(child, complexnum, power) for child in equation.children])
|
|
174
|
+
|
|
176
175
|
maxnum=1
|
|
177
176
|
alloclst = []
|
|
178
177
|
for i in range(0,26):
|
mathai/linear.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from .inverse import inverse
|
|
2
|
+
import itertools
|
|
1
3
|
from .diff import diff
|
|
2
4
|
from .simplify import simplify, solve
|
|
3
5
|
from .fraction import fraction
|
|
@@ -39,30 +41,9 @@ def islinear(eq, fxconst):
|
|
|
39
41
|
return out
|
|
40
42
|
return True
|
|
41
43
|
def linear(eqlist, fxconst):
|
|
42
|
-
final = []
|
|
43
|
-
extra = []
|
|
44
|
-
for i in range(len(eqlist)-1,-1,-1):
|
|
45
|
-
if eqlist[i].name == "f_mul" and not islinear(expand2(eqlist[i]), fxconst):
|
|
46
|
-
if "v_" in str_form(eqlist[i]):
|
|
47
|
-
eqlist[i] = TreeNode("f_mul", [child for child in eqlist[i].children if fxconst(child)])
|
|
48
|
-
if all(islinear(child, fxconst) for child in eqlist[i].children):
|
|
49
|
-
for child in eqlist[i].children:
|
|
50
|
-
extra.append(TreeNode("f_eq", [child, tree_form("d_0")]))
|
|
51
|
-
eqlist.pop(i)
|
|
52
|
-
else:
|
|
53
|
-
final.append(TreeNode("f_eq", [eqlist[i], tree_form("d_0")]))
|
|
54
|
-
eqlist.pop(i)
|
|
55
|
-
|
|
56
|
-
if extra != []:
|
|
57
|
-
final.append(TreeNode("f_or", extra))
|
|
58
|
-
if eqlist == []:
|
|
59
|
-
if len(final)==1:
|
|
60
|
-
|
|
61
|
-
return final[0]
|
|
62
|
-
return TreeNode("f_and", final)
|
|
63
44
|
eqlist = [eq for eq in eqlist if fxconst(eq)]
|
|
64
45
|
if not all(islinear(eq, fxconst) for eq in eqlist):
|
|
65
|
-
return TreeNode("f_and", copy.deepcopy(
|
|
46
|
+
return TreeNode("f_and", copy.deepcopy(eqlist))
|
|
66
47
|
vl = []
|
|
67
48
|
def varlist(eq, fxconst):
|
|
68
49
|
nonlocal vl
|
|
@@ -75,7 +56,7 @@ def linear(eqlist, fxconst):
|
|
|
75
56
|
vl = list(set(vl))
|
|
76
57
|
|
|
77
58
|
if len(vl) > len(eqlist):
|
|
78
|
-
return TreeNode("f_and",
|
|
59
|
+
return TreeNode("f_and", [TreeNode("f_eq", [x, tree_form("d_0")]) for x in eqlist])
|
|
79
60
|
m = []
|
|
80
61
|
for eq in eqlist:
|
|
81
62
|
s = copy.deepcopy(eq)
|
|
@@ -94,63 +75,83 @@ def linear(eqlist, fxconst):
|
|
|
94
75
|
for i in range(len(m)):
|
|
95
76
|
for j in range(len(m[i])):
|
|
96
77
|
m[i][j] = fraction(m[i][j])
|
|
97
|
-
|
|
98
|
-
for item in m:
|
|
99
|
-
if all(item2==tree_form("d_0") for item2 in item[:-1]) and item[-1] != tree_form("d_0"):
|
|
100
|
-
return tree_form("s_false")
|
|
101
78
|
|
|
102
79
|
output = []
|
|
103
80
|
for index, row in enumerate(m):
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
break
|
|
110
|
-
elif item == tree_form("d_0") and count == 1:
|
|
111
|
-
break
|
|
112
|
-
if count == 0:
|
|
113
|
-
continue
|
|
114
|
-
output.append(tree_form(vl[index])+row[-1])
|
|
115
|
-
if len(output) == 1 and len(final)==0:
|
|
81
|
+
if not all(item == 0 for item in row[:-1]):
|
|
82
|
+
output.append(summation([tree_form(vl[index2])*coeff for index2, coeff in enumerate(row[:-1])])+row[-1])
|
|
83
|
+
elif row[-1] != 0:
|
|
84
|
+
return tree_form("s_false")
|
|
85
|
+
if len(output) == 1:
|
|
116
86
|
return TreeNode("f_eq", [output[0], tree_form("d_0")])
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
for child in eq.children:
|
|
131
|
-
out += findeq(child)
|
|
132
|
-
return out
|
|
133
|
-
eqlist = findeq(eq)
|
|
134
|
-
eqlist = [tree_form(x) for x in eqlist]
|
|
135
|
-
eqlist = [rmeq(x) for x in eqlist]
|
|
136
|
-
eqlist = [TreeNode("f_mul", factor_generation(x)) for x in eqlist if x != tree_form("d_0")]
|
|
137
|
-
eqlist = [x.children[0] if len(x.children) == 1 else x for x in eqlist]
|
|
138
|
-
out = None
|
|
87
|
+
if len(output) == 0:
|
|
88
|
+
return tree_form("s_false")
|
|
89
|
+
return TreeNode("f_and", [TreeNode("f_eq", [x, tree_form("d_0")]) for x in output])
|
|
90
|
+
def order_collinear_indices(points, idx):
|
|
91
|
+
"""
|
|
92
|
+
Arrange a subset of collinear points (given by indices) along their line.
|
|
93
|
+
|
|
94
|
+
points: list of (x, y) tuples
|
|
95
|
+
idx: list of indices referring to points
|
|
96
|
+
Returns: list of indices sorted along the line
|
|
97
|
+
"""
|
|
98
|
+
if len(idx) <= 1:
|
|
99
|
+
return idx[:]
|
|
139
100
|
|
|
101
|
+
# Take first two points from the subset to define the line
|
|
102
|
+
p0, p1 = points[idx[0]], points[idx[1]]
|
|
103
|
+
dx, dy = p1[0] - p0[0], p1[1] - p0[1]
|
|
104
|
+
|
|
105
|
+
# Projection factor for sorting
|
|
106
|
+
def projection_factor(i):
|
|
107
|
+
vx, vy = points[i][0] - p0[0], points[i][1] - p0[1]
|
|
108
|
+
return compute((vx * dx + vy * dy) / (dx**2 + dy**2))
|
|
109
|
+
|
|
110
|
+
# Sort indices by projection
|
|
111
|
+
sorted_idx = sorted(idx, key=projection_factor)
|
|
112
|
+
return list(sorted_idx)
|
|
113
|
+
def linear_or(eq):
|
|
114
|
+
eq = simplify(eq)
|
|
115
|
+
eqlst =[]
|
|
116
|
+
if eq.name != "f_or":
|
|
117
|
+
eqlst = [eq]
|
|
118
|
+
else:
|
|
119
|
+
eqlst = eq.children
|
|
120
|
+
v = vlist(eq)
|
|
121
|
+
p = []
|
|
122
|
+
line = {}
|
|
123
|
+
for i in range(len(eqlst)):
|
|
124
|
+
line[i] = []
|
|
125
|
+
for item in itertools.combinations(enumerate(eqlst), 2):
|
|
126
|
+
x, y = item[0][0], item[1][0]
|
|
127
|
+
item = [item[0][1], item[1][1]]
|
|
128
|
+
out = linear_solve(TreeNode("f_and", list(item)))
|
|
129
|
+
if out.name == "f_and" and all(len(vlist(child)) == 1 for child in out.children) and set(vlist(out)) == set(v):
|
|
130
|
+
t = {}
|
|
131
|
+
for child in out.children:
|
|
132
|
+
t[v.index(vlist(child)[0])] = simplify(inverse(child.children[0], vlist(child)[0]))
|
|
133
|
+
t2 = []
|
|
134
|
+
for key in sorted(t.keys()):
|
|
135
|
+
t2.append(t[key])
|
|
136
|
+
t2 = tuple(t2)
|
|
137
|
+
if t2 not in p:
|
|
138
|
+
p.append(t2)
|
|
139
|
+
line[x] += [p.index(t2)]
|
|
140
|
+
line[y] += [p.index(t2)]
|
|
141
|
+
line2 = []
|
|
142
|
+
for key in sorted(line.keys()):
|
|
143
|
+
line2.append(order_collinear_indices(p, list(set(line[key]))))
|
|
144
|
+
return v, p, line2, eqlst
|
|
145
|
+
def linear_solve(eq, lst=None):
|
|
146
|
+
eq = simplify(eq)
|
|
147
|
+
eqlist = []
|
|
148
|
+
if eq.name =="f_and" and all(child.name == "f_eq" and child.children[1] == 0 for child in eq.children):
|
|
149
|
+
eqlist = [child.children[0] for child in eq.children]
|
|
150
|
+
else:
|
|
151
|
+
return eq
|
|
152
|
+
out = None
|
|
140
153
|
if lst is None:
|
|
141
154
|
out = linear(copy.deepcopy(eqlist), lambda x: "v_" in str_form(x))
|
|
142
155
|
else:
|
|
143
156
|
out = linear(copy.deepcopy(eqlist), lambda x: any(contain(x, item) for item in lst))
|
|
144
|
-
|
|
145
|
-
if eq.name in ["f_and", "f_or"] and len(eq.children) == 1:
|
|
146
|
-
return eq.children[0]
|
|
147
|
-
return TreeNode(eq.name, [rms(child) for child in eq.children])
|
|
148
|
-
return rms(out)
|
|
149
|
-
def linear_solve(eq, lst=None):
|
|
150
|
-
if eq.name == "f_and":
|
|
151
|
-
eq2 = copy.deepcopy(eq)
|
|
152
|
-
eq2.name = "f_list"
|
|
153
|
-
return mat0(eq2, lst)
|
|
154
|
-
elif eq.name == "f_eq":
|
|
155
|
-
return mat0(eq, lst)
|
|
156
|
-
return TreeNode(eq.name, [linear_solve(child, lst) for child in eq.children])
|
|
157
|
+
return simplify(out)
|
mathai/parser.py
CHANGED
|
@@ -73,9 +73,15 @@ CNUMBER: /c[0-9]+/
|
|
|
73
73
|
%ignore WS_INLINE
|
|
74
74
|
"""
|
|
75
75
|
|
|
76
|
-
def parse(equation):
|
|
76
|
+
def parse(equation, funclist=None):
|
|
77
77
|
equation = copy.copy(equation.replace(" ", ""))
|
|
78
78
|
grammar2 = copy.deepcopy(grammar)
|
|
79
|
+
if funclist is not None:
|
|
80
|
+
output = grammar2.split("\n")
|
|
81
|
+
for i in range(len(output)):
|
|
82
|
+
if "FUNC_NAME:" in output[i]:
|
|
83
|
+
output[i] = output[i].replace("FUNC_NAME: ", "FUNC_NAME: " + " | ".join(['"' + x + '"' for x in funclist]) + " | ")
|
|
84
|
+
grammar2 = "\n".join(output)
|
|
79
85
|
|
|
80
86
|
parser_main = Lark(grammar2, start='start', parser='lalr')
|
|
81
87
|
parse_tree = parser_main.parse(equation)
|
|
@@ -112,42 +118,21 @@ def parse(equation):
|
|
|
112
118
|
|
|
113
119
|
# Convert function names and constants
|
|
114
120
|
def fxchange(tree_node):
|
|
115
|
-
tmp3 = []
|
|
116
|
-
|
|
117
|
-
# Handle negation
|
|
121
|
+
tmp3 = funclist if funclist is not None else []
|
|
118
122
|
if tree_node.name == "neg":
|
|
119
123
|
child = fxchange(tree_node.children[0])
|
|
124
|
+
# if the child is a number, make it negative
|
|
120
125
|
if child.name.startswith("d_") and re.match(r"d_\d+(\.\d+)?$", child.name):
|
|
121
126
|
return TreeNode("d_" + str(-int(child.name[2:])))
|
|
122
127
|
else:
|
|
128
|
+
# otherwise subtract from zero
|
|
123
129
|
return TreeNode("f_sub", [tree_form("d_0"), child])
|
|
124
|
-
|
|
125
|
-
# Pass through node
|
|
126
130
|
if tree_node.name == "pass_through":
|
|
127
131
|
return fxchange(tree_node.children[0])
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
"index","angle","charge","sum2","electricfield","line","point","sum","transpose",
|
|
133
|
-
"equationrhs","equationlhs","equation","covariance","variance","expect","error",
|
|
134
|
-
"laplace","dot","curl","pdif","diverge","gradient","rad","ge","le","gt","lt",
|
|
135
|
-
"eqtri","linesegment","midpoint","mag","point1","point2","point3","line1","line2",
|
|
136
|
-
"line3","log10","arcsin","arccos","arctan","list","cosec","sec","cot","equiv",
|
|
137
|
-
"or","not","and","circumcenter","eq","sub","add","sin","cos","tan","mul",
|
|
138
|
-
"integrate","dif","pow","div","log","abs"
|
|
139
|
-
]
|
|
140
|
-
|
|
141
|
-
# --- NEW: detect F + digits ---
|
|
142
|
-
if re.match(r"F\d+$", tree_node.name):
|
|
143
|
-
new_name = "f_" + tree_node.name # e.g., F12 → f_F12
|
|
144
|
-
elif tree_node.name in builtin_funcs:
|
|
145
|
-
new_name = "f_" + tree_node.name
|
|
146
|
-
else:
|
|
147
|
-
new_name = "d_" + tree_node.name
|
|
148
|
-
|
|
149
|
-
return TreeNode(new_name, [fxchange(child) for child in tree_node.children])
|
|
150
|
-
|
|
132
|
+
return TreeNode(
|
|
133
|
+
"f_" + tree_node.name if tree_node.name in tmp3 + ["try", "ref", "sqrt","imply","forall","exist","exclude","union","intersection","len","index","angle","charge","sum2","electricfield","line","point","sum","transpose","equationrhs","equationlhs","equation","covariance","variance","expect","error","laplace","dot","curl","pdif","diverge","gradient","rad","ge","le","gt","lt","eqtri","linesegment","midpoint","mag","point1","point2","point3","line1","line2","line3","log10","arcsin","arccos","arctan","list","cosec","sec","cot","equiv","or","not","and","circumcenter","eq","sub","add","sin","cos","tan","mul","integrate","dif","pow","div","log","abs"] else "d_" + tree_node.name,
|
|
134
|
+
[fxchange(child) for child in tree_node.children]
|
|
135
|
+
)
|
|
151
136
|
|
|
152
137
|
tree_node = fxchange(tree_node)
|
|
153
138
|
|
mathai/tool.py
CHANGED
mathai/univariate_inequality.py
CHANGED
|
@@ -9,71 +9,7 @@ from .expand import expand
|
|
|
9
9
|
from .fraction import fraction
|
|
10
10
|
import copy
|
|
11
11
|
from .diff import diff
|
|
12
|
-
|
|
13
|
-
from .factor import merge_sqrt
|
|
14
|
-
from .factor import rationalize_sqrt as rationalize
|
|
15
|
-
|
|
16
|
-
from functools import cmp_to_key
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def arithmetic(eq):
|
|
20
|
-
eq = dowhile(eq, lambda x: handle_sqrt(simplify(merge_sqrt(rationalize(x)))))
|
|
21
|
-
def helper(eq):
|
|
22
|
-
if eq.name[2:] in "le ge gt lt eq".split(" "):
|
|
23
|
-
a, b = frac(eq.children[0]), frac(eq.children[1])
|
|
24
|
-
|
|
25
|
-
if a is not None and b is not None:
|
|
26
|
-
out = {"le": lambda x, y: x <= y, "ge":lambda x, y: x >= y, "lt":lambda x, y: x < y,\
|
|
27
|
-
"gt":lambda x, y: x > y, "eq":lambda x, y: x == y}[eq.name[2:]](a, b)
|
|
28
|
-
if out:
|
|
29
|
-
return tree_form("s_true")
|
|
30
|
-
else:
|
|
31
|
-
return tree_form("s_false")
|
|
32
|
-
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
|
33
|
-
def helper2(eq):
|
|
34
|
-
if eq.children == []:
|
|
35
|
-
if eq == tree_form("s_true"):
|
|
36
|
-
return True
|
|
37
|
-
elif eq == tree_form("s_false"):
|
|
38
|
-
return False
|
|
39
|
-
else:
|
|
40
|
-
return None
|
|
41
|
-
if eq.name == "f_or":
|
|
42
|
-
out = [helper2(child) for child in eq.children]
|
|
43
|
-
if None in out:
|
|
44
|
-
return None
|
|
45
|
-
return any(out)
|
|
46
|
-
if eq.name == "f_and":
|
|
47
|
-
out = [helper2(child) for child in eq.children]
|
|
48
|
-
if None in out:
|
|
49
|
-
return None
|
|
50
|
-
return all(out)
|
|
51
|
-
if eq.name == "f_not":
|
|
52
|
-
out = [helper2(child) for child in eq.children]
|
|
53
|
-
if None in out:
|
|
54
|
-
return None
|
|
55
|
-
return not out[0]
|
|
56
|
-
return None
|
|
57
|
-
|
|
58
|
-
return helper2(eq)
|
|
59
|
-
|
|
60
|
-
def less_than(eq1, eq2):
|
|
61
|
-
return arithmetic(TreeNode("f_le", [eq1,eq2]))
|
|
62
|
-
def equal_to(eq1, eq2):
|
|
63
|
-
return arithmetic(TreeNode("f_eq", [eq1,eq2]))
|
|
64
|
-
def custom_compare(a, b):
|
|
65
|
-
|
|
66
|
-
y = equal_to(a, b)
|
|
67
|
-
if y is not None:
|
|
68
|
-
if y:
|
|
69
|
-
return -1
|
|
70
|
-
x = less_than(a, b)
|
|
71
|
-
if x is not None:
|
|
72
|
-
if x:
|
|
73
|
-
return -1
|
|
74
|
-
else:
|
|
75
|
-
return 1
|
|
76
|
-
return 0
|
|
12
|
+
from .logic import logic0
|
|
77
13
|
def intersection2(domain, lst):
|
|
78
14
|
domain = copy.deepcopy(domain)
|
|
79
15
|
if domain == [True]:
|
|
@@ -87,14 +23,14 @@ def intersection2(domain, lst):
|
|
|
87
23
|
|
|
88
24
|
if isinstance(domain[index], bool) and domain[index]:
|
|
89
25
|
|
|
90
|
-
if index == 0 and
|
|
26
|
+
if index == 0 and compute(item2) < compute(domain[index+1]):
|
|
91
27
|
|
|
92
28
|
out.append(item2)
|
|
93
29
|
break
|
|
94
|
-
elif index == len(domain)-1 and
|
|
30
|
+
elif index == len(domain)-1 and compute(domain[index-1]) < compute(item2):
|
|
95
31
|
out.append(item2)
|
|
96
32
|
break
|
|
97
|
-
elif index != 0 and index != len(domain)-1 and
|
|
33
|
+
elif index != 0 and index != len(domain)-1 and compute(domain[index-1]) < compute(item2) and compute(item2) < compute(domain[index+1]):
|
|
98
34
|
|
|
99
35
|
out.append(item2)
|
|
100
36
|
break
|
|
@@ -128,8 +64,7 @@ def intersection(domain_1, domain_2):
|
|
|
128
64
|
result = domain_1 + domain_2
|
|
129
65
|
result = [item for item in result if not isinstance(item, bool)]
|
|
130
66
|
result = list(set(result))
|
|
131
|
-
|
|
132
|
-
result = sorted(result, key=cmp_to_key(custom_compare))
|
|
67
|
+
result = sorted(result, key=lambda x: compute(x))
|
|
133
68
|
i = len(result)
|
|
134
69
|
while i>=0:
|
|
135
70
|
result.insert(i, True)
|
|
@@ -281,7 +216,7 @@ def helper(eq, var="v_0"):
|
|
|
281
216
|
item = simplify(expand(item))
|
|
282
217
|
|
|
283
218
|
if len(vlist(item)) == 0:
|
|
284
|
-
if
|
|
219
|
+
if compute(item) <0:
|
|
285
220
|
sign = not sign
|
|
286
221
|
continue
|
|
287
222
|
v = vlist(item)[0]
|
|
@@ -295,12 +230,12 @@ def helper(eq, var="v_0"):
|
|
|
295
230
|
a = replace(diff(diff(item, v), v), tree_form(v), tree_form("d_0"))/tree_form("d_2")
|
|
296
231
|
if "v_" in str_form(a):
|
|
297
232
|
return None
|
|
298
|
-
if
|
|
233
|
+
if compute(a) < 0:
|
|
299
234
|
sign = not sign
|
|
300
235
|
continue
|
|
301
236
|
else:
|
|
302
237
|
tmp2 = diff(copy.deepcopy(item))
|
|
303
|
-
if
|
|
238
|
+
if compute(tmp2)<0:
|
|
304
239
|
sign = not sign
|
|
305
240
|
item = simplify(item * tree_form("d_-1"))
|
|
306
241
|
out = inverse(item, vlist(item)[0])
|
|
@@ -312,12 +247,12 @@ def helper(eq, var="v_0"):
|
|
|
312
247
|
a = replace(diff(diff(item, v), v), tree_form(v), tree_form("d_0"))/tree_form("d_2")
|
|
313
248
|
if "v_" in str_form(a):
|
|
314
249
|
return None
|
|
315
|
-
if
|
|
250
|
+
if compute(a) < 0:
|
|
316
251
|
sign = not sign
|
|
317
252
|
continue
|
|
318
253
|
else:
|
|
319
254
|
tmp2 = diff(copy.deepcopy(item))
|
|
320
|
-
if
|
|
255
|
+
if compute(tmp2)<0:
|
|
321
256
|
sign = not sign
|
|
322
257
|
item = simplify(item * tree_form("d_-1"))
|
|
323
258
|
out = inverse(item, vlist(item)[0])
|
|
@@ -329,7 +264,7 @@ def helper(eq, var="v_0"):
|
|
|
329
264
|
critical = [simplify(item) for item in critical]
|
|
330
265
|
critical = Counter(critical)
|
|
331
266
|
|
|
332
|
-
critical = sorted(critical.items(), key=
|
|
267
|
+
critical = sorted(critical.items(), key=lambda x: compute(x[0]))
|
|
333
268
|
|
|
334
269
|
i = len(critical)
|
|
335
270
|
element = sign
|
|
@@ -1,24 +1,26 @@
|
|
|
1
|
-
mathai/__init__.py,sha256=
|
|
1
|
+
mathai/__init__.py,sha256=O3P2_Q64gwo1CmgD4cwhl3fGUQc3wGa0-b9z8MBtFaI,1481
|
|
2
2
|
mathai/apart.py,sha256=VSS3khE9PNuxiRvdU5JDl4IN-KJBSIFjwR17pkhviXI,4197
|
|
3
|
-
mathai/base.py,sha256=
|
|
3
|
+
mathai/base.py,sha256=Ma1oCRbaZP0bp0Qnt_ZjKAh3rt9nZXQ_rmJL0sAoz5c,12730
|
|
4
|
+
mathai/bivariate_inequality.py,sha256=zZlLrs1fywCWyB0L0Ww1G6hh9yltUrQ0Z4DTi4WMWsM,10316
|
|
5
|
+
mathai/console.py,sha256=Sn58iwYE79MLEh67s8X3q6vZjw6g7f9XM1T8_dBBR2o,3048
|
|
4
6
|
mathai/diff.py,sha256=YUBpRsz0qmBkq5vGxeGnvR4nMKjdOQiIXlNMxpij2ns,3051
|
|
5
7
|
mathai/expand.py,sha256=SnBltkpIENMGkP0AYmbMlSc4H-CF5RslO2PcBEkn1BQ,3359
|
|
6
|
-
mathai/factor.py,sha256=
|
|
8
|
+
mathai/factor.py,sha256=Xkx2_lxq-Z-t55dA9F2W4EH-3Uc1CFXj_6oESQdWAHM,11332
|
|
7
9
|
mathai/fraction.py,sha256=Q2ztsh5Bpz6YhML2QU0tfufbAs0Q6J319AhlzKephIY,4396
|
|
8
10
|
mathai/integrate.py,sha256=ewV46QDD0-oiTWpSkmcpcZhBz9StcntbTV1tBLCo1Wo,16502
|
|
9
11
|
mathai/inverse.py,sha256=QCvDrzKquWsZv-BDAzZd9HnU0c3gZvcc44UztHVO5LQ,2919
|
|
10
12
|
mathai/limit.py,sha256=bn7eofIOJv4AIh0-FmLppZ3DKnGfbwOzXks2XOPTOs0,4932
|
|
11
|
-
mathai/linear.py,sha256=
|
|
13
|
+
mathai/linear.py,sha256=53sAEbCHlQUYhhjoUJfhay6x-PuXXPsheFeI9EYxDgc,5448
|
|
12
14
|
mathai/logic.py,sha256=UvHzRmKcO9AD51tRzHmpNSEhgW5gmaf4XPaQKFjGfC4,9653
|
|
13
15
|
mathai/ode.py,sha256=zxxTXAOpt7oSsfpgI4vHsCWKXevmM96ZOBZWWs-vj8Y,4801
|
|
14
|
-
mathai/parser.py,sha256=
|
|
16
|
+
mathai/parser.py,sha256=f7bemieFmp0sbup1NlraMLvZDVFvqKGFknEVtlFRMVk,6979
|
|
15
17
|
mathai/printeq.py,sha256=gIes-pstFOa6FcnpVIVvkjVKuWdsVdo11LlEnmHhakU,1303
|
|
16
18
|
mathai/simplify.py,sha256=nR5IReewrJ7HbxEUzQ2zg9xoFcwI1R5lGjWnX1pBKko,16885
|
|
17
19
|
mathai/structure.py,sha256=4Ww2IAx62RcQSO7_17TZES-DjMWBpcFQtL939FBIHwY,4103
|
|
18
|
-
mathai/tool.py,sha256=
|
|
20
|
+
mathai/tool.py,sha256=r8ejBY4Bnk_t8USYQCuxwmmJ4M-5H5OR6A3VbV7W-5w,6066
|
|
19
21
|
mathai/trig.py,sha256=BQd_Gl_u0g5ZuZIwKozuXKbMinqb6K-OYicrtftn7eg,11174
|
|
20
|
-
mathai/univariate_inequality.py,sha256=
|
|
21
|
-
mathai-0.
|
|
22
|
-
mathai-0.
|
|
23
|
-
mathai-0.
|
|
24
|
-
mathai-0.
|
|
22
|
+
mathai/univariate_inequality.py,sha256=_r-kkiS4Hr-jRN7f-EL_E4svAMFWJP1Ea50HJKKbjfk,14778
|
|
23
|
+
mathai-0.5.0.dist-info/METADATA,sha256=KeObHgS2oretRbmW0yO37o4AIkliWpBN01nO435awO8,7103
|
|
24
|
+
mathai-0.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
25
|
+
mathai-0.5.0.dist-info/top_level.txt,sha256=ROP4l3OhGYw3ihkQGASr18xM9GsK4z3_6whV5AyXLwE,7
|
|
26
|
+
mathai-0.5.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|