mathai 0.6.3__py3-none-any.whl → 0.6.5__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/base.py +22 -17
- mathai/matrix.py +142 -19
- mathai/parser.py +2 -0
- mathai/simplify.py +0 -1
- {mathai-0.6.3.dist-info → mathai-0.6.5.dist-info}/METADATA +1 -1
- {mathai-0.6.3.dist-info → mathai-0.6.5.dist-info}/RECORD +8 -8
- {mathai-0.6.3.dist-info → mathai-0.6.5.dist-info}/WHEEL +0 -0
- {mathai-0.6.3.dist-info → mathai-0.6.5.dist-info}/top_level.txt +0 -0
mathai/base.py
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import copy
|
|
2
2
|
from fractions import Fraction
|
|
3
3
|
def contains_list_or_neg(node):
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
if
|
|
4
|
+
stack = [node]
|
|
5
|
+
while stack:
|
|
6
|
+
n = stack.pop()
|
|
7
|
+
if n.name == "f_list" or n.name.startswith("v_-"):
|
|
8
8
|
return True
|
|
9
|
+
stack.extend(n.children)
|
|
9
10
|
return False
|
|
10
11
|
class TreeNode:
|
|
11
12
|
matmul = None
|
|
@@ -30,28 +31,32 @@ class TreeNode:
|
|
|
30
31
|
sortable.append(c)
|
|
31
32
|
else:
|
|
32
33
|
fixed.append(c)
|
|
34
|
+
|
|
35
|
+
if len(sortable) > 1:
|
|
36
|
+
sortable = TreeNode("f_dmul", list(sorted(sortable, key=lambda x: str_form(x))))
|
|
37
|
+
sortable.name = "f_mul"
|
|
38
|
+
|
|
39
|
+
elif len(sortable) == 1:
|
|
40
|
+
sortable = sortable[0]
|
|
41
|
+
|
|
42
|
+
if isinstance(sortable, TreeNode):
|
|
43
|
+
fixed.append(sortable)
|
|
33
44
|
if len(fixed) > 1:
|
|
34
|
-
|
|
45
|
+
self.name = "f_wmul"
|
|
35
46
|
elif len(fixed) == 1:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
sortable.append(fixed)
|
|
39
|
-
if len(sortable)==1 and name == "f_mul":
|
|
40
|
-
self.name = sortable[0].name
|
|
41
|
-
if self.name in ["f_add", "f_mul"]:
|
|
42
|
-
self.children = list(sorted(sortable[0].children, key=lambda x: str_form(x)))
|
|
43
|
-
else:
|
|
44
|
-
self.children = sortable[0].children
|
|
47
|
+
self.name = fixed[0].name
|
|
48
|
+
fixed = fixed[0].children
|
|
45
49
|
|
|
46
|
-
|
|
47
|
-
|
|
50
|
+
|
|
51
|
+
self.children = fixed
|
|
48
52
|
else:
|
|
49
53
|
self.children = children
|
|
50
54
|
|
|
51
55
|
|
|
52
56
|
def fx(self, fxname):
|
|
53
57
|
return TreeNode("f_" + fxname, [self])
|
|
54
|
-
|
|
58
|
+
def copy_tree(self):
|
|
59
|
+
return copy.deepcopy(self)
|
|
55
60
|
def __repr__(self):
|
|
56
61
|
return string_equation(str_form(self))
|
|
57
62
|
|
mathai/matrix.py
CHANGED
|
@@ -32,16 +32,26 @@ def dot(u,v):
|
|
|
32
32
|
s = TreeNode("f_add",[s,TreeNode("f_mul",[a,b])])
|
|
33
33
|
return s
|
|
34
34
|
|
|
35
|
-
def matmul(A,B):
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
def matmul(A, B):
|
|
36
|
+
# A: n × m
|
|
37
|
+
# B: m × p
|
|
38
|
+
|
|
39
|
+
n = len(A)
|
|
40
|
+
m = len(A[0])
|
|
41
|
+
p = len(B[0])
|
|
42
|
+
|
|
43
|
+
if m != len(B):
|
|
38
44
|
raise ValueError("Matrix dimension mismatch")
|
|
39
|
-
|
|
40
|
-
C = [[
|
|
45
|
+
|
|
46
|
+
C = [[tree_form("d_0") for _ in range(p)] for _ in range(n)]
|
|
47
|
+
|
|
41
48
|
for i in range(n):
|
|
42
49
|
for j in range(p):
|
|
43
50
|
for k in range(m):
|
|
44
|
-
C[i][j] = TreeNode(
|
|
51
|
+
C[i][j] = TreeNode(
|
|
52
|
+
"f_add",
|
|
53
|
+
[C[i][j], TreeNode("f_mul", [A[i][k], B[k][j]])]
|
|
54
|
+
)
|
|
45
55
|
return C
|
|
46
56
|
|
|
47
57
|
# ---------- promotion ----------
|
|
@@ -60,6 +70,13 @@ def contains_neg(node):
|
|
|
60
70
|
return True
|
|
61
71
|
# ---------- multiplication (fully simplified) ----------
|
|
62
72
|
def multiply(left,right):
|
|
73
|
+
left2, right2 = left, right
|
|
74
|
+
if left2.name != "f_pow":
|
|
75
|
+
left2 = left2 ** 1
|
|
76
|
+
if right2.name != "f_pow":
|
|
77
|
+
right2 = right2 ** 1
|
|
78
|
+
if left2.name == "f_pow" and right2.name == "f_pow" and left2.children[0]==right2.children[0]:
|
|
79
|
+
return simplify(left2.children[0]**(left2.children[1]+right2.children[1]))
|
|
63
80
|
A,B = promote(left), promote(right)
|
|
64
81
|
|
|
65
82
|
# vector · vector
|
|
@@ -77,25 +94,131 @@ def multiply(left,right):
|
|
|
77
94
|
return py_to_tree([[TreeNode("f_mul",[A,x]) for x in row] for row in B])
|
|
78
95
|
A, B = B, A
|
|
79
96
|
return None
|
|
97
|
+
def add_vec(A, B):
|
|
98
|
+
if len(A) != len(B):
|
|
99
|
+
raise ValueError("Vector dimension mismatch")
|
|
100
|
+
|
|
101
|
+
return [
|
|
102
|
+
TreeNode("f_add", [A[i], B[i]])
|
|
103
|
+
for i in range(len(A))
|
|
104
|
+
]
|
|
105
|
+
def matadd(A, B):
|
|
106
|
+
if len(A) != len(B) or len(A[0]) != len(B[0]):
|
|
107
|
+
raise ValueError("Matrix dimension mismatch")
|
|
108
|
+
|
|
109
|
+
n = len(A)
|
|
110
|
+
m = len(A[0])
|
|
80
111
|
|
|
112
|
+
return [
|
|
113
|
+
[
|
|
114
|
+
TreeNode("f_add", [A[i][j], B[i][j]])
|
|
115
|
+
for j in range(m)
|
|
116
|
+
]
|
|
117
|
+
for i in range(n)
|
|
118
|
+
]
|
|
119
|
+
def addition(left,right):
|
|
120
|
+
A,B = promote(left), promote(right)
|
|
121
|
+
# vector + vector
|
|
122
|
+
if is_vector(A) and is_vector(B):
|
|
123
|
+
return add_vec(A,B)
|
|
124
|
+
# matrix + matrix
|
|
125
|
+
if is_matrix(A) and is_matrix(B):
|
|
126
|
+
return py_to_tree(matadd(A,B))
|
|
127
|
+
return None
|
|
128
|
+
'''
|
|
81
129
|
def fold_wmul(eq):
|
|
82
|
-
if eq.name=="
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
130
|
+
if eq.name == "f_pow" and eq.children[1].name.startswith("d_"):
|
|
131
|
+
n = int(eq.children[1].name[2:])
|
|
132
|
+
if n == 1:
|
|
133
|
+
eq = eq.children[0]
|
|
134
|
+
elif n > 1:
|
|
135
|
+
tmp = promote(eq.children[0])
|
|
136
|
+
if is_matrix(tmp):
|
|
137
|
+
orig =tmp
|
|
138
|
+
for i in range(n-1):
|
|
139
|
+
tmp = matmul(orig, tmp)
|
|
140
|
+
eq = py_to_tree(tmp)
|
|
141
|
+
elif eq.name in ["f_wmul", "f_add"]:
|
|
142
|
+
if len(eq.children) == 1:
|
|
143
|
+
eq = eq.children[0]
|
|
144
|
+
else:
|
|
145
|
+
i = len(eq.children)-1
|
|
146
|
+
while i>0:
|
|
147
|
+
if eq.name == "f_wmul":
|
|
148
|
+
out = multiply(eq.children[i-1], eq.children[i])
|
|
149
|
+
else:
|
|
150
|
+
out = addition(eq.children[i-1], eq.children[i])
|
|
151
|
+
if out is not None:
|
|
152
|
+
eq.children.pop(i)
|
|
153
|
+
eq.children.pop(i-1)
|
|
154
|
+
eq.children.insert(i-1,out)
|
|
155
|
+
i = i-1
|
|
92
156
|
return TreeNode(eq.name, [fold_wmul(child) for child in eq.children])
|
|
157
|
+
'''
|
|
158
|
+
def fold_wmul(root):
|
|
159
|
+
# Post-order traversal using explicit stack
|
|
160
|
+
stack = [(root, False)]
|
|
161
|
+
newnode = {}
|
|
162
|
+
|
|
163
|
+
while stack:
|
|
164
|
+
node, visited = stack.pop()
|
|
165
|
+
|
|
166
|
+
if not visited:
|
|
167
|
+
# First time: push back as visited, then children
|
|
168
|
+
stack.append((node, True))
|
|
169
|
+
for child in node.children:
|
|
170
|
+
stack.append((child, False))
|
|
171
|
+
else:
|
|
172
|
+
# All children already processed
|
|
173
|
+
children = [newnode[c] for c in node.children]
|
|
174
|
+
eq = TreeNode(node.name, children)
|
|
175
|
+
|
|
176
|
+
# ---- original rewrite logic ----
|
|
177
|
+
|
|
178
|
+
if eq.name == "f_pow" and eq.children[1].name.startswith("d_"):
|
|
179
|
+
n = int(eq.children[1].name[2:])
|
|
180
|
+
if n == 1:
|
|
181
|
+
eq = eq.children[0]
|
|
182
|
+
elif n > 1:
|
|
183
|
+
tmp = promote(eq.children[0])
|
|
184
|
+
if is_matrix(tmp):
|
|
185
|
+
orig = tmp
|
|
186
|
+
for _ in range(n - 1):
|
|
187
|
+
tmp = matmul(orig, tmp)
|
|
188
|
+
eq = py_to_tree(tmp)
|
|
189
|
+
|
|
190
|
+
elif eq.name in ["f_wmul", "f_add"]:
|
|
191
|
+
if len(eq.children) == 1:
|
|
192
|
+
eq = eq.children[0]
|
|
193
|
+
else:
|
|
194
|
+
i = len(eq.children) - 1
|
|
195
|
+
while i > 0:
|
|
196
|
+
if eq.name == "f_wmul":
|
|
197
|
+
out = multiply(eq.children[i - 1], eq.children[i])
|
|
198
|
+
else:
|
|
199
|
+
out = addition(eq.children[i - 1], eq.children[i])
|
|
200
|
+
|
|
201
|
+
if out is not None:
|
|
202
|
+
eq.children.pop(i)
|
|
203
|
+
eq.children.pop(i - 1)
|
|
204
|
+
eq.children.insert(i - 1, out)
|
|
205
|
+
i -= 1
|
|
206
|
+
|
|
207
|
+
# --------------------------------
|
|
208
|
+
|
|
209
|
+
newnode[node] = eq
|
|
210
|
+
|
|
211
|
+
return newnode[root]
|
|
212
|
+
|
|
93
213
|
def flat(eq):
|
|
94
|
-
return flatten_tree(
|
|
95
|
-
def
|
|
214
|
+
return flatten_tree(eq, ["f_wmul"])
|
|
215
|
+
def use(eq):
|
|
216
|
+
return TreeNode(eq.name, [use(child) for child in eq.children])
|
|
217
|
+
def _matrix_solve(eq):
|
|
96
218
|
if TreeNode.matmul == True:
|
|
97
219
|
TreeNode.matmul = False
|
|
98
|
-
eq = simplify(eq)
|
|
99
220
|
eq = flat(dowhile(eq, lambda x: fold_wmul(flat(x))))
|
|
100
221
|
TreeNode.matmul = True
|
|
101
222
|
return eq
|
|
223
|
+
def matrix_solve(eq):
|
|
224
|
+
return _matrix_solve(eq)
|
mathai/parser.py
CHANGED
mathai/simplify.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
mathai/__init__.py,sha256=gzddzgNCG3Bg5BnqrDYvO71SzK4hu9fbo4nGEaDaG5Q,1554
|
|
2
2
|
mathai/apart.py,sha256=VSS3khE9PNuxiRvdU5JDl4IN-KJBSIFjwR17pkhviXI,4197
|
|
3
|
-
mathai/base.py,sha256=
|
|
3
|
+
mathai/base.py,sha256=aTyWgaQUmJ31OVEkm9K71JN02Pz0zk4rSta7xkdQK8g,15582
|
|
4
4
|
mathai/bivariate_inequality.py,sha256=Da-A1kqVynR0tNOlEI7GSTf5T2vNkcF4etL9-EoyPJg,11415
|
|
5
5
|
mathai/console.py,sha256=Sn58iwYE79MLEh67s8X3q6vZjw6g7f9XM1T8_dBBR2o,3048
|
|
6
6
|
mathai/diff.py,sha256=RSTwlfeddvYXUDShCeRdcPjsmAS8Vf5OkYJAaUBPaiM,3060
|
|
@@ -12,17 +12,17 @@ mathai/inverse.py,sha256=ya7P8WjzfaAL3UXL7xqOh5GaIsXLDZ-F6lZFy3IEgaQ,2931
|
|
|
12
12
|
mathai/limit.py,sha256=9F8i9UZh2xb-V8A5Sd1gdhDf9c2RFgpE1GdNn9MvbWI,5703
|
|
13
13
|
mathai/linear.py,sha256=viGlPU8BPrjLWHlyNUvnfPHNH5d4ZBImiQMdyXaKGg0,5702
|
|
14
14
|
mathai/logic.py,sha256=Ndz4Fd6aNCmzFlqoPyyIpSmV_BXmYHsurePjLyZJoNc,9809
|
|
15
|
-
mathai/matrix.py,sha256=
|
|
15
|
+
mathai/matrix.py,sha256=a3SeAjrsg2wVKy-uETOGTCEClL3NMBxGsLOM15sHEwY,7177
|
|
16
16
|
mathai/ode.py,sha256=zxxTXAOpt7oSsfpgI4vHsCWKXevmM96ZOBZWWs-vj8Y,4801
|
|
17
|
-
mathai/parser.py,sha256=
|
|
17
|
+
mathai/parser.py,sha256=YzXCW5MmwL3J0BhR0ZrPS2wnfz77uB_enBXPjITc-a0,7303
|
|
18
18
|
mathai/parsetab.py,sha256=TL-4jvRM_Tx6ipwet8CFJc2DkjR4tGsbrGF_r4IC8xI,9651
|
|
19
19
|
mathai/printeq.py,sha256=MKsR6-qXig80R07vLnFPYHQMeS41FrMVj3n3arrhJpQ,1329
|
|
20
|
-
mathai/simplify.py,sha256=
|
|
20
|
+
mathai/simplify.py,sha256=nvpwTLEgnGeXgc9NGGmQLAjKZ9c4XTdEVqAuo04oSrw,19588
|
|
21
21
|
mathai/structure.py,sha256=wrU7kqphSN7CqaVffyHHXD2-3t5My_Z_TtYFoUe_lTU,4099
|
|
22
22
|
mathai/tool.py,sha256=ozcXTXLbKUnyPM9r9kz9M43YA2CBcWezcqLZfEs8rpc,6051
|
|
23
23
|
mathai/trig.py,sha256=fnBbfiopcQzFg4ya1BoO5M0X_aCBnse2bjnKh1juw4I,11223
|
|
24
24
|
mathai/univariate_inequality.py,sha256=LPFdWgC1y5zBwnsy1wwZxj-yP_SbqFDhCmTTzhuwoiY,16469
|
|
25
|
-
mathai-0.6.
|
|
26
|
-
mathai-0.6.
|
|
27
|
-
mathai-0.6.
|
|
28
|
-
mathai-0.6.
|
|
25
|
+
mathai-0.6.5.dist-info/METADATA,sha256=jLOXmfTrc1arF3RvTQdTST_-xoMdZJuakP21omUBwcs,7103
|
|
26
|
+
mathai-0.6.5.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
27
|
+
mathai-0.6.5.dist-info/top_level.txt,sha256=ROP4l3OhGYw3ihkQGASr18xM9GsK4z3_6whV5AyXLwE,7
|
|
28
|
+
mathai-0.6.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|