mathai 0.4.8__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 -3
- mathai/bivariate_inequality.py +296 -0
- mathai/linear.py +75 -74
- {mathai-0.4.8.dist-info → mathai-0.5.0.dist-info}/METADATA +1 -1
- {mathai-0.4.8.dist-info → mathai-0.5.0.dist-info}/RECORD +7 -6
- {mathai-0.4.8.dist-info → mathai-0.5.0.dist-info}/WHEEL +0 -0
- {mathai-0.4.8.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
|
|
|
@@ -39,11 +39,10 @@ from .logic import logic0, logic1, logic2, logic3
|
|
|
39
39
|
|
|
40
40
|
from .apart import apart, apart2
|
|
41
41
|
|
|
42
|
-
from .console import console
|
|
43
|
-
|
|
44
42
|
from .limit import limit
|
|
45
43
|
|
|
46
44
|
from .univariate_inequality import wavycurvy, absolute, domain, handle_sqrt
|
|
45
|
+
from .bivariate_inequality import inequality_solve
|
|
47
46
|
|
|
48
47
|
from .base import *
|
|
49
48
|
|
|
@@ -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/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)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
mathai/__init__.py,sha256=
|
|
1
|
+
mathai/__init__.py,sha256=O3P2_Q64gwo1CmgD4cwhl3fGUQc3wGa0-b9z8MBtFaI,1481
|
|
2
2
|
mathai/apart.py,sha256=VSS3khE9PNuxiRvdU5JDl4IN-KJBSIFjwR17pkhviXI,4197
|
|
3
3
|
mathai/base.py,sha256=Ma1oCRbaZP0bp0Qnt_ZjKAh3rt9nZXQ_rmJL0sAoz5c,12730
|
|
4
|
+
mathai/bivariate_inequality.py,sha256=zZlLrs1fywCWyB0L0Ww1G6hh9yltUrQ0Z4DTi4WMWsM,10316
|
|
4
5
|
mathai/console.py,sha256=Sn58iwYE79MLEh67s8X3q6vZjw6g7f9XM1T8_dBBR2o,3048
|
|
5
6
|
mathai/diff.py,sha256=YUBpRsz0qmBkq5vGxeGnvR4nMKjdOQiIXlNMxpij2ns,3051
|
|
6
7
|
mathai/expand.py,sha256=SnBltkpIENMGkP0AYmbMlSc4H-CF5RslO2PcBEkn1BQ,3359
|
|
@@ -9,7 +10,7 @@ mathai/fraction.py,sha256=Q2ztsh5Bpz6YhML2QU0tfufbAs0Q6J319AhlzKephIY,4396
|
|
|
9
10
|
mathai/integrate.py,sha256=ewV46QDD0-oiTWpSkmcpcZhBz9StcntbTV1tBLCo1Wo,16502
|
|
10
11
|
mathai/inverse.py,sha256=QCvDrzKquWsZv-BDAzZd9HnU0c3gZvcc44UztHVO5LQ,2919
|
|
11
12
|
mathai/limit.py,sha256=bn7eofIOJv4AIh0-FmLppZ3DKnGfbwOzXks2XOPTOs0,4932
|
|
12
|
-
mathai/linear.py,sha256=
|
|
13
|
+
mathai/linear.py,sha256=53sAEbCHlQUYhhjoUJfhay6x-PuXXPsheFeI9EYxDgc,5448
|
|
13
14
|
mathai/logic.py,sha256=UvHzRmKcO9AD51tRzHmpNSEhgW5gmaf4XPaQKFjGfC4,9653
|
|
14
15
|
mathai/ode.py,sha256=zxxTXAOpt7oSsfpgI4vHsCWKXevmM96ZOBZWWs-vj8Y,4801
|
|
15
16
|
mathai/parser.py,sha256=f7bemieFmp0sbup1NlraMLvZDVFvqKGFknEVtlFRMVk,6979
|
|
@@ -19,7 +20,7 @@ mathai/structure.py,sha256=4Ww2IAx62RcQSO7_17TZES-DjMWBpcFQtL939FBIHwY,4103
|
|
|
19
20
|
mathai/tool.py,sha256=r8ejBY4Bnk_t8USYQCuxwmmJ4M-5H5OR6A3VbV7W-5w,6066
|
|
20
21
|
mathai/trig.py,sha256=BQd_Gl_u0g5ZuZIwKozuXKbMinqb6K-OYicrtftn7eg,11174
|
|
21
22
|
mathai/univariate_inequality.py,sha256=_r-kkiS4Hr-jRN7f-EL_E4svAMFWJP1Ea50HJKKbjfk,14778
|
|
22
|
-
mathai-0.
|
|
23
|
-
mathai-0.
|
|
24
|
-
mathai-0.
|
|
25
|
-
mathai-0.
|
|
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
|