mathai 0.6.7__tar.gz → 0.6.8__tar.gz
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-0.6.7 → mathai-0.6.8}/PKG-INFO +1 -1
- {mathai-0.6.7 → mathai-0.6.8}/mathai/base.py +2 -0
- mathai-0.6.8/mathai/expand.py +129 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/matrix.py +5 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/parser.py +1 -2
- {mathai-0.6.7 → mathai-0.6.8}/mathai/simplify.py +6 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai.egg-info/PKG-INFO +1 -1
- {mathai-0.6.7 → mathai-0.6.8}/setup.py +1 -1
- mathai-0.6.7/mathai/expand.py +0 -124
- {mathai-0.6.7 → mathai-0.6.8}/README.md +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/__init__.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/apart.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/bivariate_inequality.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/console.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/diff.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/factor.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/fraction.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/integrate.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/inverse.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/limit.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/linear.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/logic.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/ode.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/parsetab.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/printeq.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/structure.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/tool.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/trig.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai/univariate_inequality.py +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai.egg-info/SOURCES.txt +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai.egg-info/dependency_links.txt +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai.egg-info/requires.txt +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/mathai.egg-info/top_level.txt +0 -0
- {mathai-0.6.7 → mathai-0.6.8}/setup.cfg +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import itertools
|
|
2
|
+
from .base import *
|
|
3
|
+
from .simplify import simplify
|
|
4
|
+
'''
|
|
5
|
+
def _expand(equation):
|
|
6
|
+
eq = equation
|
|
7
|
+
eq.children = [_expand(flatten_tree(child)) for child in eq.children]
|
|
8
|
+
if eq.name == "f_pow":
|
|
9
|
+
n = frac(eq.children[1])
|
|
10
|
+
if n is not None and n.denominator == 1 and n.numerator > 1:
|
|
11
|
+
power_children = []
|
|
12
|
+
for i in range(n.numerator):
|
|
13
|
+
power_children.append(eq.children[0])
|
|
14
|
+
return _expand(flatten_tree(TreeNode("f_mul", power_children)))
|
|
15
|
+
if eq.name == "f_mul":
|
|
16
|
+
lone_children = tree_form("d_1")
|
|
17
|
+
bracket_children = []
|
|
18
|
+
for i in range(len(eq.children)-1,-1,-1):
|
|
19
|
+
if eq.children[i].name == "f_add":
|
|
20
|
+
bracket_children.append(eq.children[i])
|
|
21
|
+
elif eq.children[i].name == "f_pow" and eq.children[i].children[0].name == "f_add":
|
|
22
|
+
n = frac(eq.children[i].children[1])
|
|
23
|
+
if n is not None and n.denominator == 1 and n.numerator > 1:
|
|
24
|
+
for j in range(n.numerator):
|
|
25
|
+
bracket_children.append(eq.children[i].children[0])
|
|
26
|
+
else:
|
|
27
|
+
lone_children = lone_children * eq.children[i]
|
|
28
|
+
else:
|
|
29
|
+
lone_children = lone_children * eq.children[i]
|
|
30
|
+
lone_children = simplify(lone_children)
|
|
31
|
+
while bracket_children != []:
|
|
32
|
+
tmp = tree_form("d_0")
|
|
33
|
+
for i in range(len(bracket_children[0].children)):
|
|
34
|
+
if lone_children.name == "f_add":
|
|
35
|
+
for j in range(len(lone_children.children)):
|
|
36
|
+
tmp = tmp + bracket_children[0].children[i] * lone_children.children[j]
|
|
37
|
+
else:
|
|
38
|
+
tmp = tmp + lone_children * bracket_children[0].children[i]
|
|
39
|
+
lone_children = flatten_tree(simplify(tmp))
|
|
40
|
+
bracket_children.pop(0)
|
|
41
|
+
return lone_children
|
|
42
|
+
return eq
|
|
43
|
+
'''
|
|
44
|
+
def is_expandable(child):
|
|
45
|
+
if child.name == "f_add":
|
|
46
|
+
return True
|
|
47
|
+
if child.name == "f_pow" and child.children[0].name == "f_add":
|
|
48
|
+
n = frac(child.children[1])
|
|
49
|
+
return n is not None and n.denominator == 1 and n.numerator > 1
|
|
50
|
+
return False
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def expand_terms(child):
|
|
54
|
+
if child.name == "f_add":
|
|
55
|
+
return child.children
|
|
56
|
+
n = frac(child.children[1]).numerator
|
|
57
|
+
return child.children[0].children * n
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _expand(equation):
|
|
61
|
+
stack = [(equation, 0, [])]
|
|
62
|
+
|
|
63
|
+
while stack:
|
|
64
|
+
node, idx, done = stack.pop()
|
|
65
|
+
|
|
66
|
+
if idx >= len(node.children):
|
|
67
|
+
node.children = done
|
|
68
|
+
|
|
69
|
+
# ===== f_pow =====
|
|
70
|
+
if node.name == "f_pow":
|
|
71
|
+
n = frac(node.children[1])
|
|
72
|
+
if n and n.denominator == 1 and n.numerator > 1:
|
|
73
|
+
node = flatten_tree(
|
|
74
|
+
TreeNode("f_mul", [node.children[0]] * n.numerator)
|
|
75
|
+
)
|
|
76
|
+
stack.append((node, 0, []))
|
|
77
|
+
continue
|
|
78
|
+
|
|
79
|
+
# ===== f_mul =====
|
|
80
|
+
elif node.name == "f_mul":
|
|
81
|
+
children = node.children
|
|
82
|
+
k = len(children)
|
|
83
|
+
|
|
84
|
+
# ---- find expandable index (L→R, then R→L) ----
|
|
85
|
+
idxs = list(range(k)) + list(reversed(range(k)))
|
|
86
|
+
seen = set()
|
|
87
|
+
expand_i = None
|
|
88
|
+
|
|
89
|
+
for i in idxs:
|
|
90
|
+
if i in seen:
|
|
91
|
+
continue
|
|
92
|
+
seen.add(i)
|
|
93
|
+
if is_expandable(children[i]):
|
|
94
|
+
expand_i = i
|
|
95
|
+
break
|
|
96
|
+
|
|
97
|
+
if expand_i is not None:
|
|
98
|
+
left = children[:expand_i]
|
|
99
|
+
right = children[expand_i + 1:]
|
|
100
|
+
expandable = children[expand_i]
|
|
101
|
+
|
|
102
|
+
out = tree_form("d_0")
|
|
103
|
+
for term in expand_terms(expandable):
|
|
104
|
+
prod = term
|
|
105
|
+
for r in right:
|
|
106
|
+
prod = prod * r
|
|
107
|
+
for l in reversed(left):
|
|
108
|
+
prod = l * prod
|
|
109
|
+
out = out + prod
|
|
110
|
+
|
|
111
|
+
node = flatten_tree(simplify(out))
|
|
112
|
+
|
|
113
|
+
# ===== return =====
|
|
114
|
+
if stack:
|
|
115
|
+
parent, pidx, acc = stack.pop()
|
|
116
|
+
acc.append(node)
|
|
117
|
+
stack.append((parent, pidx + 1, acc))
|
|
118
|
+
else:
|
|
119
|
+
return node
|
|
120
|
+
|
|
121
|
+
else:
|
|
122
|
+
stack.append((node, idx, done))
|
|
123
|
+
child = flatten_tree(node.children[idx])
|
|
124
|
+
stack.append((child, 0, []))
|
|
125
|
+
|
|
126
|
+
def expand(eq):
|
|
127
|
+
if TreeNode.matmul == True:
|
|
128
|
+
eq = tree_form(str_form(eq).replace("f_wmul", "f_mul"))
|
|
129
|
+
return _expand(eq)
|
|
@@ -70,6 +70,10 @@ def contains_neg(node):
|
|
|
70
70
|
return True
|
|
71
71
|
# ---------- multiplication (fully simplified) ----------
|
|
72
72
|
def multiply(left,right):
|
|
73
|
+
if left == tree_form("d_1"):
|
|
74
|
+
return right
|
|
75
|
+
if right == tree_form("d_1"):
|
|
76
|
+
return left
|
|
73
77
|
left2, right2 = left, right
|
|
74
78
|
if left2.name != "f_pow":
|
|
75
79
|
left2 = left2 ** 1
|
|
@@ -217,6 +221,7 @@ def use(eq):
|
|
|
217
221
|
def _matrix_solve(eq):
|
|
218
222
|
if TreeNode.matmul == True:
|
|
219
223
|
TreeNode.matmul = False
|
|
224
|
+
eq = use(eq)
|
|
220
225
|
eq = dowhile(eq, lambda x: fold_wmul(flat(x)))
|
|
221
226
|
TreeNode.matmul = True
|
|
222
227
|
return eq
|
|
@@ -152,8 +152,7 @@ def parse(equation, funclist=None):
|
|
|
152
152
|
return tree_form("v_" + str(int(tree_node.name[3:])+100))
|
|
153
153
|
tree_node.children = [rfx(child) for child in tree_node.children]
|
|
154
154
|
return tree_node
|
|
155
|
-
|
|
156
|
-
return TreeNode(eq.name, [use(child) for child in eq.children])
|
|
155
|
+
|
|
157
156
|
tree_node = rfx(tree_node)
|
|
158
157
|
tree_node = flatten_tree(tree_node, ["f_wmul"])
|
|
159
158
|
if TreeNode.matmul == True:
|
|
@@ -500,6 +500,11 @@ def solve3(eq):
|
|
|
500
500
|
def simplify(eq, basic=True):
|
|
501
501
|
if eq is None:
|
|
502
502
|
return None
|
|
503
|
+
orig = TreeNode.matmul
|
|
504
|
+
if TreeNode.matmul == True:
|
|
505
|
+
TreeNode.matmul = False
|
|
506
|
+
eq = use(tree_form(str_form(eq).replace("f_w","f_")))
|
|
507
|
+
|
|
503
508
|
if eq.name == "f_and" or eq.name == "f_not" or eq.name == "f_or":
|
|
504
509
|
new_children = []
|
|
505
510
|
for child in eq.children:
|
|
@@ -519,4 +524,5 @@ def simplify(eq, basic=True):
|
|
|
519
524
|
if basic:
|
|
520
525
|
eq = convert_to_basic(eq)
|
|
521
526
|
eq = solve3(eq)
|
|
527
|
+
TreeNode.matmul = orig
|
|
522
528
|
return eq
|
mathai-0.6.7/mathai/expand.py
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import itertools
|
|
2
|
-
from .base import *
|
|
3
|
-
from .simplify import simplify
|
|
4
|
-
'''
|
|
5
|
-
def _expand(equation):
|
|
6
|
-
eq = equation
|
|
7
|
-
eq.children = [_expand(flatten_tree(child)) for child in eq.children]
|
|
8
|
-
if eq.name == "f_pow":
|
|
9
|
-
n = frac(eq.children[1])
|
|
10
|
-
if n is not None and n.denominator == 1 and n.numerator > 1:
|
|
11
|
-
power_children = []
|
|
12
|
-
for i in range(n.numerator):
|
|
13
|
-
power_children.append(eq.children[0])
|
|
14
|
-
return _expand(flatten_tree(TreeNode("f_mul", power_children)))
|
|
15
|
-
if eq.name == "f_mul":
|
|
16
|
-
lone_children = tree_form("d_1")
|
|
17
|
-
bracket_children = []
|
|
18
|
-
for i in range(len(eq.children)-1,-1,-1):
|
|
19
|
-
if eq.children[i].name == "f_add":
|
|
20
|
-
bracket_children.append(eq.children[i])
|
|
21
|
-
elif eq.children[i].name == "f_pow" and eq.children[i].children[0].name == "f_add":
|
|
22
|
-
n = frac(eq.children[i].children[1])
|
|
23
|
-
if n is not None and n.denominator == 1 and n.numerator > 1:
|
|
24
|
-
for j in range(n.numerator):
|
|
25
|
-
bracket_children.append(eq.children[i].children[0])
|
|
26
|
-
else:
|
|
27
|
-
lone_children = lone_children * eq.children[i]
|
|
28
|
-
else:
|
|
29
|
-
lone_children = lone_children * eq.children[i]
|
|
30
|
-
lone_children = simplify(lone_children)
|
|
31
|
-
while bracket_children != []:
|
|
32
|
-
tmp = tree_form("d_0")
|
|
33
|
-
for i in range(len(bracket_children[0].children)):
|
|
34
|
-
if lone_children.name == "f_add":
|
|
35
|
-
for j in range(len(lone_children.children)):
|
|
36
|
-
tmp = tmp + bracket_children[0].children[i] * lone_children.children[j]
|
|
37
|
-
else:
|
|
38
|
-
tmp = tmp + lone_children * bracket_children[0].children[i]
|
|
39
|
-
lone_children = flatten_tree(simplify(tmp))
|
|
40
|
-
bracket_children.pop(0)
|
|
41
|
-
return lone_children
|
|
42
|
-
return eq
|
|
43
|
-
'''
|
|
44
|
-
def _expand(equation):
|
|
45
|
-
"""Iterative version of _expand without recursion."""
|
|
46
|
-
# Stack: (node, child_index, partially_processed_children)
|
|
47
|
-
stack = [(equation, 0, [])]
|
|
48
|
-
|
|
49
|
-
while stack:
|
|
50
|
-
node, child_index, processed_children = stack.pop()
|
|
51
|
-
|
|
52
|
-
# If all children are processed
|
|
53
|
-
if child_index >= len(node.children):
|
|
54
|
-
# Replace children with processed versions
|
|
55
|
-
node.children = processed_children
|
|
56
|
-
|
|
57
|
-
# === Handle f_pow ===
|
|
58
|
-
if node.name == "f_pow":
|
|
59
|
-
n = frac(node.children[1])
|
|
60
|
-
if n is not None and n.denominator == 1 and n.numerator > 1:
|
|
61
|
-
# Convert power to repeated multiplication
|
|
62
|
-
power_children = [node.children[0] for _ in range(n.numerator)]
|
|
63
|
-
new_node = TreeNode("f_mul", power_children)
|
|
64
|
-
# Flatten tree
|
|
65
|
-
node = flatten_tree(new_node)
|
|
66
|
-
# Push it back for further processing
|
|
67
|
-
stack.append((node, 0, []))
|
|
68
|
-
continue
|
|
69
|
-
|
|
70
|
-
# === Handle f_mul ===
|
|
71
|
-
elif node.name == "f_mul":
|
|
72
|
-
# Separate lone children and bracket children
|
|
73
|
-
lone_children = tree_form("d_1")
|
|
74
|
-
bracket_children = []
|
|
75
|
-
|
|
76
|
-
# Iterate in reverse (like original)
|
|
77
|
-
for child in reversed(node.children):
|
|
78
|
-
if child.name == "f_add":
|
|
79
|
-
bracket_children.append(child)
|
|
80
|
-
elif child.name == "f_pow" and child.children[0].name == "f_add":
|
|
81
|
-
n = frac(child.children[1])
|
|
82
|
-
if n is not None and n.denominator == 1 and n.numerator > 1:
|
|
83
|
-
for _ in range(n.numerator):
|
|
84
|
-
bracket_children.append(child.children[0])
|
|
85
|
-
else:
|
|
86
|
-
lone_children = lone_children * child
|
|
87
|
-
else:
|
|
88
|
-
lone_children = lone_children * child
|
|
89
|
-
|
|
90
|
-
lone_children = simplify(lone_children)
|
|
91
|
-
|
|
92
|
-
# Distribute bracket children over lone children iteratively
|
|
93
|
-
while bracket_children:
|
|
94
|
-
tmp = tree_form("d_0")
|
|
95
|
-
bracket = bracket_children.pop(0)
|
|
96
|
-
for bc in bracket.children:
|
|
97
|
-
if lone_children.name == "f_add":
|
|
98
|
-
for lc in lone_children.children:
|
|
99
|
-
tmp = tmp + bc * lc
|
|
100
|
-
else:
|
|
101
|
-
tmp = tmp + bc * lone_children
|
|
102
|
-
# Simplify after each distribution
|
|
103
|
-
lone_children = flatten_tree(simplify(tmp))
|
|
104
|
-
|
|
105
|
-
node = lone_children
|
|
106
|
-
|
|
107
|
-
# === Return node to parent ===
|
|
108
|
-
if stack:
|
|
109
|
-
parent, idx, parent_children = stack.pop()
|
|
110
|
-
parent_children.append(node)
|
|
111
|
-
stack.append((parent, idx + 1, parent_children))
|
|
112
|
-
else:
|
|
113
|
-
# Root node fully expanded
|
|
114
|
-
return node
|
|
115
|
-
|
|
116
|
-
else:
|
|
117
|
-
# Push current node back for next child
|
|
118
|
-
stack.append((node, child_index, processed_children))
|
|
119
|
-
# Push the child to process next
|
|
120
|
-
child = flatten_tree(node.children[child_index])
|
|
121
|
-
stack.append((child, 0, []))
|
|
122
|
-
|
|
123
|
-
def expand(eq):
|
|
124
|
-
return _expand(eq)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|