mathai 0.7.7__py3-none-any.whl → 0.7.9__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 -2
- mathai/base.py +0 -1
- mathai/diff.py +86 -4
- mathai/fraction.py +90 -87
- mathai/integrate.py +11 -5
- mathai/ode.py +226 -89
- mathai/parser.py +2 -3
- mathai/pde.py +41 -80
- mathai/structure.py +3 -3
- {mathai-0.7.7.dist-info → mathai-0.7.9.dist-info}/METADATA +1 -1
- {mathai-0.7.7.dist-info → mathai-0.7.9.dist-info}/RECORD +13 -13
- {mathai-0.7.7.dist-info → mathai-0.7.9.dist-info}/WHEEL +0 -0
- {mathai-0.7.7.dist-info → mathai-0.7.9.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 .pde import pde_sep, want
|
|
4
|
+
from .pde import pde_sep, want, absorb
|
|
5
5
|
|
|
6
6
|
from .linear import linear_solve, linear_or
|
|
7
7
|
|
|
@@ -21,7 +21,7 @@ from .integrate import rm_const as integrate_const
|
|
|
21
21
|
from .integrate import solve_integrate as integrate_clean
|
|
22
22
|
from .integrate import integrate_formula
|
|
23
23
|
|
|
24
|
-
from .diff import diff
|
|
24
|
+
from .diff import diff, diff2
|
|
25
25
|
|
|
26
26
|
from .factor import factor as factor1
|
|
27
27
|
from .factor import factor2, factor3
|
mathai/base.py
CHANGED
mathai/diff.py
CHANGED
|
@@ -1,6 +1,87 @@
|
|
|
1
|
+
from .trig import trig0
|
|
1
2
|
from .simplify import simplify
|
|
2
3
|
from .base import *
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
def helper(eq):
|
|
6
|
+
name = eq.name
|
|
7
|
+
if name in ["f_dif", "f_pdif"]:
|
|
8
|
+
if eq.children[0].name == "f_add":
|
|
9
|
+
return summation([TreeNode(name, [child, eq.children[1]]) for child in eq.children[0].children])
|
|
10
|
+
|
|
11
|
+
if eq.children[0].name == "f_mul":
|
|
12
|
+
return summation([product([TreeNode(name, [child, eq.children[1]]) if index==index2 else child for index2, child in enumerate(eq.children[0].children)])\
|
|
13
|
+
for index in range(len(eq.children[0].children))])
|
|
14
|
+
if eq.children[0].name == "f_pow" and "v_" not in str_form(eq.children[0].children[1]):
|
|
15
|
+
base, power = eq.children[0].children
|
|
16
|
+
dbase = TreeNode(name, [base, eq.children[1]])
|
|
17
|
+
b1 = power - tree_form("d_1")
|
|
18
|
+
bab1 = TreeNode("f_pow", [base, b1])
|
|
19
|
+
return power * bab1 * dbase
|
|
20
|
+
|
|
21
|
+
if eq.children[0].name == "f_pow":
|
|
22
|
+
a, b = eq.children
|
|
23
|
+
return a**b * ((b/a) * TreeNode(name, [a, eq.children[1]]) + a.fx("log") * TreeNode(name, [b, eq.children[1]]))
|
|
24
|
+
|
|
25
|
+
if "v_" not in str_form(eq.children[0]):
|
|
26
|
+
return tree_form("d_0")
|
|
27
|
+
|
|
28
|
+
if eq.children[0] == eq.children[1]:
|
|
29
|
+
return tree_form("d_1")
|
|
30
|
+
|
|
31
|
+
if name == "f_pdif" and not contain(eq.children[0], eq.children[1]):
|
|
32
|
+
return tree_form("d_0")
|
|
33
|
+
if eq.children[0].name == "f_sin":
|
|
34
|
+
eq.children[0].name = "f_cos"
|
|
35
|
+
d = TreeNode(name, [eq.children[0].children[0], eq.children[1]])
|
|
36
|
+
return d*eq.children[0]
|
|
37
|
+
if eq.children[0].name == "f_cos":
|
|
38
|
+
eq.children[0].name = "f_sin"
|
|
39
|
+
d = TreeNode(name, [eq.children[0].children[0], eq.children[1]])
|
|
40
|
+
return tree_form("d_-1")*d*eq.children[0]
|
|
41
|
+
if eq.children[0].name == "f_tan":
|
|
42
|
+
d = TreeNode(name, [eq.children[0].children[0], eq.children[1]])
|
|
43
|
+
return d/(eq.children[0].children[0].fx("cos")*eq.children[0].children[0].fx("cos"))
|
|
44
|
+
if eq.children[0].name == "f_log":
|
|
45
|
+
d = TreeNode(name, [eq.children[0].children[0], eq.children[1]])
|
|
46
|
+
return d*(tree_form("d_1")/eq.children[0].children[0])
|
|
47
|
+
if eq.children[0].name == "f_arcsin":
|
|
48
|
+
d = TreeNode(name, [eq.children[0].children[0], eq.children[1]])
|
|
49
|
+
return d/(tree_form("d_1")-eq.children[0].children[0]*eq.children[0].children[0])**(tree_form("d_2")**-1)
|
|
50
|
+
if eq.children[0].name == "f_arccos":
|
|
51
|
+
d = TreeNode(name, [eq.children[0].children[0], eq.children[1]])
|
|
52
|
+
return tree_form("d_-1")*d/(tree_form("d_1")-eq.children[0].children[0]*eq.children[0].children[0])**(tree_form("d_2")**-1)
|
|
53
|
+
if eq.children[0].name == "f_arctan":
|
|
54
|
+
d = TreeNode(name, [eq.children[0].children[0], eq.children[1]])
|
|
55
|
+
return d/(tree_form("d_1")+eq.children[0].children[0]*eq.children[0].children[0])
|
|
56
|
+
|
|
57
|
+
return eq
|
|
58
|
+
|
|
59
|
+
def diff3(eq):
|
|
60
|
+
eq = simplify(eq)
|
|
61
|
+
|
|
62
|
+
stack = [(eq, False)]
|
|
63
|
+
out = {}
|
|
64
|
+
|
|
65
|
+
while stack:
|
|
66
|
+
node, visited = stack.pop()
|
|
67
|
+
|
|
68
|
+
if not visited:
|
|
69
|
+
stack.append((node, True))
|
|
70
|
+
for c in node.children:
|
|
71
|
+
stack.append((c, False))
|
|
72
|
+
continue
|
|
73
|
+
|
|
74
|
+
new_children = [out[c] for c in node.children]
|
|
75
|
+
rebuilt = TreeNode(node.name, new_children)
|
|
76
|
+
rebuilt = helper(rebuilt)
|
|
77
|
+
rebuilt = simplify(rebuilt)
|
|
78
|
+
|
|
79
|
+
out[node] = rebuilt
|
|
80
|
+
|
|
81
|
+
return out[eq]
|
|
82
|
+
|
|
83
|
+
def diff2(eq):
|
|
84
|
+
return dowhile(eq, diff3)
|
|
4
85
|
def diff(equation, var="v_0"):
|
|
5
86
|
def diffeq(eq):
|
|
6
87
|
eq = simplify(eq)
|
|
@@ -54,7 +135,7 @@ def diff(equation, var="v_0"):
|
|
|
54
135
|
bab1 = TreeNode("f_pow", [base, b1])
|
|
55
136
|
return power * bab1 * dbase
|
|
56
137
|
return TreeNode("f_dif", [eq, tree_form(var)])
|
|
57
|
-
def
|
|
138
|
+
def helper2(equation, var="v_0"):
|
|
58
139
|
if equation.name == "f_dif":
|
|
59
140
|
if equation.children[0].name == var:
|
|
60
141
|
return tree_form("d_1")
|
|
@@ -62,7 +143,7 @@ def diff(equation, var="v_0"):
|
|
|
62
143
|
return tree_form("d_0")
|
|
63
144
|
else:
|
|
64
145
|
return equation
|
|
65
|
-
return TreeNode(equation.name, [
|
|
146
|
+
return TreeNode(equation.name, [helper2(child, var) for child in equation.children])
|
|
66
147
|
def calc(eq):
|
|
67
148
|
if eq.name == "f_dif":
|
|
68
149
|
return diffeq(trig0(eq.children[0]))
|
|
@@ -70,5 +151,6 @@ def diff(equation, var="v_0"):
|
|
|
70
151
|
if var is None:
|
|
71
152
|
return simplify(calc(equation))
|
|
72
153
|
equation = diffeq(trig0(equation))
|
|
73
|
-
equation =
|
|
154
|
+
equation = helper2(equation, var)
|
|
74
155
|
return simplify(equation)
|
|
156
|
+
|
mathai/fraction.py
CHANGED
|
@@ -2,102 +2,105 @@ from .base import *
|
|
|
2
2
|
from .simplify import simplify
|
|
3
3
|
from .expand import expand
|
|
4
4
|
|
|
5
|
-
def fraction(eq):
|
|
6
|
-
stack = [(eq, None)] # (current_node, parent_processed_children)
|
|
7
|
-
result_map = {} # Map original nodes to their processed TreeNode
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
def fraction(expr):
|
|
7
|
+
if expr is None:
|
|
8
|
+
return None
|
|
9
|
+
|
|
10
|
+
expr = simplify(expr)
|
|
11
|
+
|
|
12
|
+
# -----------------------------
|
|
13
|
+
# leaf
|
|
14
|
+
# -----------------------------
|
|
15
|
+
if expr.children == []:
|
|
16
|
+
return expr
|
|
11
17
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
continue
|
|
18
|
+
# recurse first (inner-most first)
|
|
19
|
+
children = [fraction(c) for c in expr.children]
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
# -----------------------------
|
|
22
|
+
# ADDITION: collect denominators
|
|
23
|
+
# -----------------------------
|
|
24
|
+
if expr.name == "f_add":
|
|
25
|
+
terms = []
|
|
20
26
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
for c in children:
|
|
28
|
+
# term is a multiplication
|
|
29
|
+
if c.name == "f_mul":
|
|
30
|
+
num = []
|
|
31
|
+
den = []
|
|
32
|
+
for f in c.children:
|
|
33
|
+
if (
|
|
34
|
+
f.name == "f_pow"
|
|
35
|
+
and f.children[1].name.startswith("d_")
|
|
36
|
+
and int(f.children[1].name[2:]) < 0
|
|
37
|
+
):
|
|
38
|
+
n = int(f.children[1].name[2:])
|
|
39
|
+
den.append(
|
|
40
|
+
f.children[0]
|
|
41
|
+
if n == -1
|
|
42
|
+
else TreeNode("f_pow", [f.children[0], tree_form(f"d_{-n}")])
|
|
43
|
+
)
|
|
44
|
+
else:
|
|
45
|
+
num.append(f)
|
|
46
|
+
terms.append((num, den))
|
|
30
47
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
# pure reciprocal
|
|
49
|
+
elif (
|
|
50
|
+
c.name == "f_pow"
|
|
51
|
+
and c.children[1].name.startswith("d_")
|
|
52
|
+
and int(c.children[1].name[2:]) < 0
|
|
53
|
+
):
|
|
54
|
+
n = int(c.children[1].name[2:])
|
|
55
|
+
terms.append(([], [
|
|
56
|
+
c.children[0]
|
|
57
|
+
if n == -1
|
|
58
|
+
else TreeNode("f_pow", [c.children[0], tree_form(f"d_{-n}")])
|
|
59
|
+
]))
|
|
37
60
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
child_processed = result_map[child]
|
|
42
|
-
if child_processed.name == "f_pow" and child_processed.children[1].name[:2] == "d_" and int(child_processed.children[1].name[2:]) < 0:
|
|
43
|
-
den = []
|
|
44
|
-
n = int(child_processed.children[1].name[2:])
|
|
45
|
-
if n == -1:
|
|
46
|
-
den.append(child_processed.children[0])
|
|
47
|
-
else:
|
|
48
|
-
den.append(TreeNode("f_pow", [child_processed.children[0], tree_form("d_" + str(-n))]))
|
|
49
|
-
con.append([[], den])
|
|
50
|
-
elif child_processed.name == "f_mul":
|
|
51
|
-
num = []
|
|
52
|
-
den = []
|
|
53
|
-
for child2 in child_processed.children:
|
|
54
|
-
if child2.name == "f_pow" and child2.children[1].name[:2] == "d_" and int(child2.children[1].name[2:]) < 0:
|
|
55
|
-
n = int(child2.children[1].name[2:])
|
|
56
|
-
if n == -1:
|
|
57
|
-
den.append(child2.children[0])
|
|
58
|
-
else:
|
|
59
|
-
den.append(TreeNode("f_pow", [child2.children[0], tree_form("d_" + str(-n))]))
|
|
60
|
-
else:
|
|
61
|
-
num.append(child2)
|
|
62
|
-
con.append([num, den])
|
|
63
|
-
else:
|
|
64
|
-
con.append([[child_processed], []])
|
|
61
|
+
# normal term
|
|
62
|
+
else:
|
|
63
|
+
terms.append(([c], []))
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
for i in range(len(con)):
|
|
70
|
-
b_children = con[i][0].copy()
|
|
71
|
-
for j in range(len(con)):
|
|
72
|
-
if i == j:
|
|
73
|
-
continue
|
|
74
|
-
b_children += con[j][1]
|
|
75
|
-
if len(b_children) == 0:
|
|
76
|
-
b_children = [tree_form("d_1")]
|
|
77
|
-
elif len(b_children) == 1:
|
|
78
|
-
b_children = b_children
|
|
79
|
-
else:
|
|
80
|
-
b_children = [TreeNode("f_mul", b_children)]
|
|
81
|
-
a_children += b_children if isinstance(b_children, list) else [b_children]
|
|
65
|
+
# if no denominators → rebuild normally
|
|
66
|
+
if not any(den for _, den in terms):
|
|
67
|
+
return TreeNode("f_add", children)
|
|
82
68
|
|
|
83
|
-
|
|
69
|
+
# -----------------------------
|
|
70
|
+
# build numerator
|
|
71
|
+
# -----------------------------
|
|
72
|
+
num_terms = []
|
|
73
|
+
for i, (num_i, _) in enumerate(terms):
|
|
74
|
+
acc = list(num_i)
|
|
75
|
+
for j, (_, den_j) in enumerate(terms):
|
|
76
|
+
if i != j:
|
|
77
|
+
acc += den_j
|
|
78
|
+
if not acc:
|
|
79
|
+
acc = [tree_form("d_1")]
|
|
80
|
+
num_terms.append(
|
|
81
|
+
acc[0] if len(acc) == 1 else TreeNode("f_mul", acc)
|
|
82
|
+
)
|
|
84
83
|
|
|
85
|
-
|
|
86
|
-
c_children = []
|
|
87
|
-
for i in range(len(con)):
|
|
88
|
-
c_children += con[i][1]
|
|
89
|
-
if len(c_children) == 1:
|
|
90
|
-
c = c_children[0]
|
|
91
|
-
else:
|
|
92
|
-
c = TreeNode("f_mul", c_children)
|
|
93
|
-
c = TreeNode("f_pow", [c, tree_form("d_-1")])
|
|
84
|
+
numerator = TreeNode("f_add", num_terms)
|
|
94
85
|
|
|
95
|
-
|
|
96
|
-
|
|
86
|
+
# -----------------------------
|
|
87
|
+
# build denominator
|
|
88
|
+
# -----------------------------
|
|
89
|
+
den_all = []
|
|
90
|
+
for _, den in terms:
|
|
91
|
+
den_all += den
|
|
97
92
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
93
|
+
denom = den_all[0] if len(den_all) == 1 else TreeNode("f_mul", den_all)
|
|
94
|
+
denom = TreeNode("f_pow", [denom, tree_form("d_-1")])
|
|
95
|
+
|
|
96
|
+
return simplify(
|
|
97
|
+
TreeNode(
|
|
98
|
+
"f_mul",
|
|
99
|
+
[simplify(expand(numerator)), denom],
|
|
100
|
+
)
|
|
101
|
+
)
|
|
101
102
|
|
|
102
|
-
#
|
|
103
|
-
|
|
103
|
+
# -----------------------------
|
|
104
|
+
# default reconstruction
|
|
105
|
+
# -----------------------------
|
|
106
|
+
return TreeNode(expr.name, children)
|
mathai/integrate.py
CHANGED
|
@@ -97,6 +97,8 @@ def place_try2(eq):
|
|
|
97
97
|
return eq.children[try_lst.pop(0)]
|
|
98
98
|
return TreeNode(eq.name, [place_try2(child) for child in eq.children])
|
|
99
99
|
def _solve_integrate(eq):
|
|
100
|
+
if eq is None:
|
|
101
|
+
return None
|
|
100
102
|
if eq.name == "f_ref":
|
|
101
103
|
return eq
|
|
102
104
|
if eq.name == "f_subs":
|
|
@@ -153,14 +155,18 @@ def inteq(eq):
|
|
|
153
155
|
else:
|
|
154
156
|
return TreeNode(eq.name, [inteq(child) for child in eq.children])
|
|
155
157
|
def rm(eq):
|
|
158
|
+
if eq is None:
|
|
159
|
+
return None
|
|
156
160
|
if eq.name == "f_try":
|
|
157
161
|
eq = TreeNode(eq.name, list(set(eq.children)))
|
|
158
162
|
return TreeNode(eq.name, [rm(child) for child in eq.children if child is not None])
|
|
159
163
|
def solve_integrate(eq):
|
|
160
164
|
|
|
161
165
|
eq2 = dowhile(eq, _solve_integrate)
|
|
162
|
-
eq2 = dowhile(eq2, handle_try)
|
|
166
|
+
#eq2 = dowhile(eq2, handle_try)
|
|
163
167
|
eq2 = rm(eq2)
|
|
168
|
+
if eq2 is None:
|
|
169
|
+
return None
|
|
164
170
|
if eq2.name == "f_try":
|
|
165
171
|
eq2.children = list(set(eq2.children))
|
|
166
172
|
return eq2
|
|
@@ -409,8 +415,8 @@ def integration_formula_ex():
|
|
|
409
415
|
|
|
410
416
|
formula_gen11 = integration_formula_ex()
|
|
411
417
|
def rm_const(equation):
|
|
412
|
-
if equation
|
|
413
|
-
return
|
|
418
|
+
if equation is None:
|
|
419
|
+
return None
|
|
414
420
|
eq2 = equation
|
|
415
421
|
if eq2.name == "f_integrate" and contain(eq2.children[0], eq2.children[1]):
|
|
416
422
|
equation = eq2.children[0]
|
|
@@ -436,8 +442,8 @@ def shorten(eq):
|
|
|
436
442
|
return tree_form("d_0")
|
|
437
443
|
return TreeNode(eq.name, [shorten(child) for child in eq.children])
|
|
438
444
|
def integrate_formula(equation):
|
|
439
|
-
if equation
|
|
440
|
-
return
|
|
445
|
+
if equation is None:
|
|
446
|
+
return None
|
|
441
447
|
eq2 = equation.copy_tree()
|
|
442
448
|
if eq2.name == "f_integrate":
|
|
443
449
|
integrand = eq2.children[0]
|
mathai/ode.py
CHANGED
|
@@ -1,54 +1,120 @@
|
|
|
1
|
+
import itertools
|
|
1
2
|
from collections import Counter
|
|
2
|
-
from .diff import diff
|
|
3
|
-
from .factor import factor
|
|
3
|
+
from .diff import diff, diff2
|
|
4
|
+
from .factor import factor, factor2, term_common2
|
|
4
5
|
from .expand import expand
|
|
5
6
|
from .base import *
|
|
6
7
|
from .fraction import fraction
|
|
7
8
|
from .simplify import simplify
|
|
8
9
|
import copy
|
|
10
|
+
from .inverse import inverse
|
|
11
|
+
from .parser import parse
|
|
9
12
|
|
|
13
|
+
def rev(eq):
|
|
14
|
+
tmp = factor_generation(eq)
|
|
15
|
+
if tree_form("v_0").fx("dif")**-1 in tmp or tree_form("v_1").fx("dif")**-1 in tmp:
|
|
16
|
+
return False
|
|
17
|
+
for child in eq.children:
|
|
18
|
+
if not rev(child):
|
|
19
|
+
return False
|
|
20
|
+
return True
|
|
21
|
+
node_count = 100
|
|
22
|
+
def kkk(lhs, rhs, depth=5):
|
|
23
|
+
global node_count
|
|
24
|
+
lst = [simplify(lhs), simplify(rhs)]
|
|
25
|
+
orig = copy.deepcopy(lst)
|
|
26
|
+
if not contain(lst[0], tree_form("v_1")) and not contain(lst[1], tree_form("v_0")):
|
|
27
|
+
if not contain(lst[0], tree_form("v_0")) and not contain(lst[1], tree_form("v_1")):
|
|
28
|
+
return lst, False
|
|
29
|
+
return lst, True
|
|
30
|
+
node_count -= 1
|
|
31
|
+
|
|
32
|
+
if depth < 0 or node_count < 0:
|
|
33
|
+
return lst, False
|
|
34
|
+
for j in range(2):
|
|
35
|
+
for i in range(2):
|
|
36
|
+
if lst[i].name in ["f_mul", "f_add"]:
|
|
37
|
+
for child in lst[i].children:
|
|
38
|
+
out = child
|
|
39
|
+
if j == 0:
|
|
40
|
+
if contain(out, tree_form(f"v_{i}")) or not contain(out, tree_form(f"v_{1-i}")):
|
|
41
|
+
continue
|
|
42
|
+
if contain(out, tree_form(f"v_{i}")) and not contain(out, tree_form(f"v_{1-i}")):
|
|
43
|
+
continue
|
|
44
|
+
|
|
45
|
+
if lst[i].name == "f_add":
|
|
46
|
+
lst[i] = lst[i] - out
|
|
47
|
+
lst[1-i] = lst[1-i] - out
|
|
48
|
+
elif lst[i].name == "f_mul":
|
|
49
|
+
lst[i] = lst[i] / out
|
|
50
|
+
lst[1-i] = lst[1-i] / out
|
|
51
|
+
else:
|
|
52
|
+
continue
|
|
53
|
+
|
|
54
|
+
output = kkk(lst[0], lst[1], depth-1)
|
|
55
|
+
lst = orig
|
|
56
|
+
|
|
57
|
+
if output[1]:
|
|
58
|
+
return output
|
|
59
|
+
|
|
60
|
+
return lst, False
|
|
61
|
+
def clr(eq):
|
|
62
|
+
return simplify(product([item for item in factor_generation(eq) if "f_add" in str_form(item)]))
|
|
10
63
|
def inversediff(lhs, rhs):
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
for
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
64
|
+
global node_count
|
|
65
|
+
eq = simplify(fraction(TreeNode("f_eq", [lhs-rhs, tree_form("d_0")]))).children[0]
|
|
66
|
+
eq = simplify(term_common2(eq))
|
|
67
|
+
eq = clr(eq)
|
|
68
|
+
|
|
69
|
+
out= None
|
|
70
|
+
if eq.name == "f_add":
|
|
71
|
+
h = {}
|
|
72
|
+
n = [eq]
|
|
73
|
+
for i in range(len(eq.children)-2,1,-1):
|
|
74
|
+
for item in itertools.combinations(list(range(len(eq.children))), i):
|
|
75
|
+
item = tuple(sorted(list(item)))
|
|
76
|
+
tmp = simplify(term_common2(simplify(summation([eq.children[x] for x in item]))))
|
|
77
|
+
if tmp.name == "f_mul":
|
|
78
|
+
h[item] = tmp
|
|
79
|
+
|
|
80
|
+
for item in itertools.combinations(list(h.keys()),2):
|
|
81
|
+
|
|
82
|
+
g = []
|
|
83
|
+
for x in item:
|
|
84
|
+
g += x
|
|
85
|
+
if sum([len(x) for x in item]) == len(set(g)):
|
|
86
|
+
pass
|
|
87
|
+
else:
|
|
88
|
+
continue
|
|
89
|
+
|
|
90
|
+
item2 = summation([eq.children[x] for x in list(set(range(len(eq.children)))-set(g))])
|
|
91
|
+
n.append(simplify(term_common2(simplify(h[item[0]] + h[item[1]]))+item2))
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
for item in list(set(n)):
|
|
95
|
+
|
|
96
|
+
item = clr(item)
|
|
97
|
+
node_count = 100
|
|
98
|
+
|
|
99
|
+
tmp = kkk(item, tree_form("d_0"))
|
|
100
|
+
|
|
101
|
+
if tmp[1]:
|
|
102
|
+
out = tmp[0]
|
|
103
|
+
break
|
|
104
|
+
else:
|
|
105
|
+
node_count = 100
|
|
106
|
+
tmp = kkk(eq, tree_form("d_0"))
|
|
107
|
+
if tmp[1]:
|
|
108
|
+
out = tmp[0]
|
|
109
|
+
if out is None:
|
|
110
|
+
return None
|
|
111
|
+
out = [simplify(fraction(item)) for item in out]
|
|
112
|
+
|
|
113
|
+
if not rev(out[0]) and not rev(out[1]):
|
|
114
|
+
|
|
115
|
+
out[0] = fraction(1/out[0])
|
|
116
|
+
out[1] = fraction(1/out[1])
|
|
117
|
+
return simplify(e0(out[0]-out[1]))
|
|
52
118
|
|
|
53
119
|
def allocvar():
|
|
54
120
|
return tree_form("v_101")
|
|
@@ -62,38 +128,28 @@ def esolve(s):
|
|
|
62
128
|
return product([tree_form("s_e")**child for child in s.children]) - tree_form("d_1")
|
|
63
129
|
return TreeNode(s.name, [esolve(child) for child in s.children])
|
|
64
130
|
def diffsolve_sep2(eq):
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
s = []
|
|
68
|
-
eq = simplify(expand(eq))
|
|
69
|
-
eq = e1(eq)
|
|
70
|
-
|
|
71
|
-
def vlor1(eq):
|
|
72
|
-
if contain(eq, tree_form("v_0")) and not contain(eq, tree_form("v_1")):
|
|
73
|
-
return True
|
|
74
|
-
if contain(eq, tree_form("v_1")) and not contain(eq, tree_form("v_0")):
|
|
75
|
-
return True
|
|
76
|
-
return False
|
|
77
|
-
if eq.name == "f_add" and all(vlor1(child) and [str_form(x) for x in factor_generation(copy.deepcopy(child))].count(str_form(tree_form(vlist(child)[0]).fx("dif")))==1 for child in eq.children):
|
|
78
|
-
for child in eq.children:
|
|
79
|
-
v = vlist(child)[0]
|
|
80
|
-
v2 = tree_form(v).fx("dif")
|
|
81
|
-
child = replace(child, v2, tree_form("d_1"))
|
|
82
|
-
child = simplify(child)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
tmp6 = TreeNode("f_integrate", [child, tree_form(v)])
|
|
86
|
-
s.append(tmp6)
|
|
87
|
-
|
|
88
|
-
if s[-1] is None:
|
|
89
|
-
return None
|
|
90
|
-
s.append(allocvar())
|
|
91
|
-
else:
|
|
131
|
+
lst = None
|
|
132
|
+
if eq is None:
|
|
92
133
|
return None
|
|
93
|
-
|
|
94
|
-
|
|
134
|
+
eq = eq.children[0]
|
|
135
|
+
if eq.name == "f_add":
|
|
136
|
+
lst = list(eq.children)
|
|
137
|
+
else:
|
|
138
|
+
lst = [eq]
|
|
139
|
+
s = [allocvar()]
|
|
140
|
+
|
|
141
|
+
for item in lst:
|
|
142
|
+
item = simplify(item)
|
|
143
|
+
tmp = factor_generation(item)
|
|
144
|
+
|
|
145
|
+
tmp2 = product([k for k in tmp if k.name != "f_dif"])
|
|
146
|
+
|
|
147
|
+
if tree_form("v_0").fx("dif") in tmp:
|
|
148
|
+
s.append(TreeNode("f_integrate", [tmp2, tree_form("v_0")]))
|
|
149
|
+
elif tree_form("v_1").fx("dif") in tmp:
|
|
150
|
+
s.append(TreeNode("f_integrate", [tmp2, tree_form("v_1")]))
|
|
95
151
|
|
|
96
|
-
return
|
|
152
|
+
return TreeNode("f_eq", [summation(s), tree_form("d_0")])
|
|
97
153
|
def e0(eq):
|
|
98
154
|
return TreeNode("f_eq", [eq, tree_form("d_0")])
|
|
99
155
|
def e1(eq):
|
|
@@ -110,58 +166,85 @@ def groupe(eq):
|
|
|
110
166
|
|
|
111
167
|
def diffsolve_sep(eq):
|
|
112
168
|
eq = epowersplit(eq)
|
|
113
|
-
|
|
169
|
+
|
|
114
170
|
eq = inversediff(tree_form("d_0"), eq.children[0].copy_tree())
|
|
171
|
+
|
|
115
172
|
return eq
|
|
116
173
|
|
|
117
174
|
def diffsolve(eq):
|
|
118
175
|
orig = eq.copy_tree()
|
|
119
|
-
|
|
176
|
+
eq = diff2(eq)
|
|
177
|
+
eq = subs2(eq, order(eq))
|
|
178
|
+
eq = fraction(simplify(fraction(eq)))
|
|
179
|
+
|
|
180
|
+
if order(eq) == 2:
|
|
181
|
+
for i in range(2):
|
|
182
|
+
out = second_order_dif(eq, tree_form(f"v_{i}"), tree_form(f"v_{1-i}"))
|
|
183
|
+
if out is not None:
|
|
184
|
+
return out
|
|
185
|
+
return orig
|
|
120
186
|
|
|
121
187
|
eq = diffsolve_sep2(diffsolve_sep(eq))
|
|
188
|
+
|
|
122
189
|
if eq is None:
|
|
123
190
|
for i in range(2):
|
|
124
191
|
a = tree_form(f"v_{i}")
|
|
125
192
|
b = tree_form(f"v_{1-i}")
|
|
126
193
|
c = tree_form("v_2")
|
|
127
|
-
eq2 =
|
|
128
|
-
|
|
194
|
+
eq2 = orig
|
|
195
|
+
|
|
196
|
+
eq2 = subs2(eq2, 1)
|
|
197
|
+
eq2 = replace(eq2, b, b*a)
|
|
198
|
+
eq2 = subs3(eq2)
|
|
199
|
+
|
|
200
|
+
eq2 = simplify(fraction(simplify(eq2)))
|
|
201
|
+
|
|
129
202
|
eq2 = diffsolve_sep(eq2)
|
|
203
|
+
|
|
130
204
|
eq2 = diffsolve_sep2(eq2)
|
|
131
205
|
if eq2 is not None:
|
|
132
206
|
return e0(TreeNode("f_subs", [replace(eq2.children[0],b,c), c,b/a]).fx("try"))
|
|
133
207
|
eq = orig
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
208
|
+
eq = simplify(eq)
|
|
209
|
+
eq = subs2(eq, 1)
|
|
210
|
+
eq = fraction(eq)
|
|
211
|
+
for i in range(2):
|
|
212
|
+
|
|
213
|
+
out = linear_dif(eq, tree_form(f"v_{i}"), tree_form(f"v_{1-i}"))
|
|
214
|
+
if out is not None:
|
|
215
|
+
return out
|
|
216
|
+
return orig
|
|
217
|
+
else:
|
|
218
|
+
return eq
|
|
219
|
+
|
|
142
220
|
def clist(x):
|
|
143
221
|
return list(x.elements())
|
|
144
222
|
def collect_term(eq, term_lst):
|
|
145
223
|
|
|
146
224
|
lst = None
|
|
147
225
|
if eq.name == "f_add":
|
|
148
|
-
lst = eq.children
|
|
226
|
+
lst = copy.deepcopy(eq.children)
|
|
149
227
|
else:
|
|
150
228
|
lst = [eq]
|
|
151
229
|
|
|
152
230
|
other = []
|
|
153
231
|
dic = {}
|
|
154
|
-
term_lst = sorted(term_lst, key=lambda x: -len(factor_generation(x)))
|
|
232
|
+
term_lst = list(sorted(term_lst, key=lambda x: -len(factor_generation(x))))
|
|
233
|
+
for item in term_lst:
|
|
234
|
+
dic[item] = tree_form("d_0")
|
|
155
235
|
for item2 in lst:
|
|
156
236
|
done = True
|
|
157
237
|
tmp2 = Counter(factor_generation(item2))
|
|
158
238
|
for index, item in enumerate(term_lst):
|
|
239
|
+
|
|
159
240
|
tmp = Counter(factor_generation(item))
|
|
160
241
|
|
|
161
|
-
if (tmp2&tmp) == tmp
|
|
242
|
+
if (tmp2&tmp) == tmp:
|
|
162
243
|
if item in dic.keys():
|
|
244
|
+
|
|
163
245
|
dic[item] += product(clist(tmp2-tmp))
|
|
164
246
|
else:
|
|
247
|
+
|
|
165
248
|
dic[item] = product(clist(tmp2-tmp))
|
|
166
249
|
done = False
|
|
167
250
|
break
|
|
@@ -172,8 +255,61 @@ def collect_term(eq, term_lst):
|
|
|
172
255
|
for key in dic.keys():
|
|
173
256
|
dic[key] = simplify(dic[key])
|
|
174
257
|
return [dic, simplify(other)]
|
|
258
|
+
def order(eq,m=0):
|
|
259
|
+
best = m
|
|
260
|
+
if eq.name in ["f_pdif", "f_dif"]:
|
|
261
|
+
out = order(eq.children[0], m+1)
|
|
262
|
+
best = max(out, best)
|
|
263
|
+
else:
|
|
264
|
+
for child in eq.children:
|
|
265
|
+
out = order(child, m)
|
|
266
|
+
best = max(out, best)
|
|
267
|
+
return best
|
|
268
|
+
def subs2(eq, orde):
|
|
269
|
+
if eq.name in ["f_dif", "f_pdif"] and len(eq.children) == 2:
|
|
270
|
+
if orde == 1:
|
|
271
|
+
return eq.children[0].fx("dif")/eq.children[1].fx("dif")
|
|
272
|
+
else:
|
|
273
|
+
return subs2(TreeNode("f_dif", eq.children), orde)
|
|
274
|
+
return TreeNode(eq.name, [subs2(child, orde) for child in eq.children])
|
|
275
|
+
def subs3(eq):
|
|
276
|
+
if eq.name == "f_dif" and eq.children[0].name == "f_add":
|
|
277
|
+
return summation([subs3(child.fx("dif")) for child in eq.children[0].children])
|
|
278
|
+
if eq.name == "f_dif" and eq.children[0].name == "f_mul":
|
|
279
|
+
return summation([product([subs3(child.fx("dif")) if index==index2 else child for index2, child in enumerate(eq.children[0].children)]) for index in range(len(eq.children[0].children))])
|
|
280
|
+
return TreeNode(eq.name, [subs3(child) for child in eq.children])
|
|
281
|
+
def second_order_dif(eq, a, b):
|
|
282
|
+
eq = simplify(eq)
|
|
283
|
+
nn = [TreeNode("f_dif", [TreeNode("f_dif", [b,a]),a]), TreeNode("f_dif", [b,a]), b]
|
|
284
|
+
out = collect_term(eq.children[0], nn)
|
|
285
|
+
if out[1] == tree_form("d_0"):
|
|
286
|
+
tmp = out[0][nn[0]]
|
|
287
|
+
if tmp != tree_form("d_0"):
|
|
288
|
+
for key in out[0].keys():
|
|
289
|
+
out[0][key] = simplify(out[0][key]/tmp)
|
|
290
|
+
|
|
291
|
+
B = out[0][nn[1]]
|
|
292
|
+
C = out[0][nn[2]]
|
|
293
|
+
|
|
294
|
+
if all(all(not contain(item, item2) for item2 in [a,b]) for item in [B, C]):
|
|
295
|
+
r = parse("r")
|
|
296
|
+
s = simplify(factor2(simplify(TreeNode("f_eq", [r**2 + B*r + C, tree_form("d_0")])), True))
|
|
297
|
+
r1, r2 = [inverse(item, r.name) for item in s.children[0].children]
|
|
298
|
+
out = None
|
|
299
|
+
if contain(r1, tree_form("s_i")):
|
|
300
|
+
real = simplify(fraction((r1+r2)/tree_form("d_2")))
|
|
301
|
+
imagine = simplify((r1-real)/tree_form("s_i"))
|
|
302
|
+
out = tree_form("s_e")**(real*a)*(tree_form("v_101")*(imagine*a).fx("cos")+tree_form("v_102")*(imagine*a).fx("sin"))
|
|
303
|
+
elif fraction(simplify(r1-r2)) == tree_form("d_0"):
|
|
304
|
+
out =(tree_form("v_101")+tree_form("v_102")*a)*tree_form("s_e")**(r1*a)
|
|
305
|
+
else:
|
|
306
|
+
out = tree_form("v_101")*tree_form("s_e")**(r1*a) + tree_form("v_102")*tree_form("s_e")**(r2*a)
|
|
307
|
+
return TreeNode("f_eq", [b, out])
|
|
308
|
+
return None
|
|
309
|
+
|
|
175
310
|
def linear_dif(eq, a, b):
|
|
176
311
|
eq = simplify(eq)
|
|
312
|
+
|
|
177
313
|
out = collect_term(eq.children[0], [b.fx("dif"), b*a.fx("dif"), a.fx("dif")])
|
|
178
314
|
|
|
179
315
|
if out[1] == tree_form("d_0"):
|
|
@@ -183,7 +319,8 @@ def linear_dif(eq, a, b):
|
|
|
183
319
|
for key in out[0].keys():
|
|
184
320
|
out[0][key] = simplify(out[0][key]/tmp)
|
|
185
321
|
p, q = out[0][b*a.fx("dif")], -out[0][a.fx("dif")]
|
|
186
|
-
|
|
322
|
+
if contain(p, b) or contain(q, b):
|
|
323
|
+
return None
|
|
187
324
|
f = tree_form("s_e") ** TreeNode("f_integrate", [p, a])
|
|
188
325
|
return simplify(TreeNode("f_eq", [b*f, TreeNode("f_integrate", [q*f, a])+allocvar()]))
|
|
189
326
|
return None
|
mathai/parser.py
CHANGED
|
@@ -60,7 +60,7 @@ grammar = """
|
|
|
60
60
|
| ESCAPED_STRING -> string
|
|
61
61
|
| CAPITAL_ID -> matrix
|
|
62
62
|
|
|
63
|
-
FUNC_NAME: "midpoint" | "ref" | "expect" | "covariance" | "variance" | "subs" | "try" | "limit" | "forall" | "limitpinf" | "imply" | "exist" | "len" | "sum" | "angle" | "line" | "sum2" | "charge" | "electricfield" | "perm" | "point" | "equationrhs" | "transpose" | "equationlhs" | "equation" | "error" | "covariance" | "variance" | "expect" | "mag" | "rad" | "laplace" | "diverge" | "pdif" | "gradient" | "curl" | "point1" | "point2" | "dot" | "point3" | "line1" | "line2" | "line3" | "sin" | "circumcenter" | "eqtri" | "linesegment" | "cos" | "tan" | "log" | "sqrt" | "integrate" | "dif" | "abs" | "cosec" | "sec" | "cot" | "arctan" | "arcsin" | "arccos" | "log10"
|
|
63
|
+
FUNC_NAME: "midpoint" | "ref" | "expect" | "U" | "covariance" | "variance" | "subs" | "try" | "limit" | "forall" | "limitpinf" | "imply" | "exist" | "len" | "sum" | "angle" | "line" | "sum2" | "charge" | "electricfield" | "perm" | "point" | "equationrhs" | "transpose" | "equationlhs" | "equation" | "error" | "covariance" | "variance" | "expect" | "mag" | "rad" | "laplace" | "diverge" | "pdif" | "gradient" | "curl" | "point1" | "point2" | "dot" | "point3" | "line1" | "line2" | "line3" | "sin" | "circumcenter" | "eqtri" | "linesegment" | "cos" | "tan" | "log" | "sqrt" | "integrate" | "dif" | "abs" | "cosec" | "sec" | "cot" | "arctan" | "arcsin" | "arccos" | "log10"
|
|
64
64
|
|
|
65
65
|
VARIABLE: /[a-z]/ | "nabla" | "pi" | "kc" | "hbar" | "em" | "ec" | "anot" | "false" | "true"
|
|
66
66
|
|
|
@@ -131,7 +131,7 @@ def parse(equation, funclist=None):
|
|
|
131
131
|
if tree_node.name == "pass_through":
|
|
132
132
|
return fxchange(tree_node.children[0])
|
|
133
133
|
return TreeNode(
|
|
134
|
-
"f_" + tree_node.name if tree_node.name in tmp3 + ["limitpinf", "limit", "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", "cross", "wmul","integrate","dif","pow","div","log","abs"] else "d_" + tree_node.name,
|
|
134
|
+
"f_" + tree_node.name if tree_node.name in tmp3 + ["U", "limitpinf", "limit", "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", "cross", "wmul","integrate","dif","pow","div","log","abs"] else "d_" + tree_node.name,
|
|
135
135
|
[fxchange(child) for child in tree_node.children]
|
|
136
136
|
)
|
|
137
137
|
|
|
@@ -155,5 +155,4 @@ def parse(equation, funclist=None):
|
|
|
155
155
|
return tree_node
|
|
156
156
|
|
|
157
157
|
tree_node = rfx(tree_node)
|
|
158
|
-
tree_node = flatten_tree(tree_node)
|
|
159
158
|
return tree_node
|
mathai/pde.py
CHANGED
|
@@ -1,89 +1,22 @@
|
|
|
1
|
-
from .
|
|
1
|
+
from .expand import expand
|
|
2
|
+
from .ode import diffsolve, inversediff, order, groupe, epowersplit, subs2
|
|
2
3
|
from .base import *
|
|
3
4
|
from .simplify import simplify
|
|
4
|
-
from .diff import
|
|
5
|
+
from .diff import diff2
|
|
5
6
|
from .fraction import fraction
|
|
6
7
|
from .parser import parse
|
|
7
8
|
from .inverse import inverse
|
|
9
|
+
from .factor import factor
|
|
10
|
+
|
|
8
11
|
def capital2(eq):
|
|
9
|
-
if eq.name == "f_pdif":
|
|
12
|
+
if eq.name == "f_pdif" and eq.children[0].name != "f_pdif":
|
|
10
13
|
return eq.children[0]
|
|
11
14
|
for child in eq.children:
|
|
12
15
|
out = capital2(child)
|
|
13
16
|
if out is not None:
|
|
14
17
|
return out
|
|
15
18
|
return None
|
|
16
|
-
def subs(eq, r2):
|
|
17
|
-
if eq.name == "f_dif":
|
|
18
|
-
return TreeNode("f_pdif", eq.children)
|
|
19
|
-
if eq == r2:
|
|
20
|
-
return parse("x").fx("X") * parse("y").fx("Y")
|
|
21
|
-
if eq.name == "f_pdif":
|
|
22
|
-
return subs(diff(subs(eq.children[0], r2), str_form(eq.children[1])), r2)
|
|
23
|
-
return TreeNode(eq.name, [subs(child, r2) for child in eq.children])
|
|
24
|
-
def inverse_pde(lhs, rhs, depth=3):
|
|
25
|
-
if depth < 0:
|
|
26
|
-
return None
|
|
27
|
-
|
|
28
|
-
lhs = simplify(lhs.copy_tree())
|
|
29
|
-
rhs = simplify(rhs.copy_tree())
|
|
30
|
-
|
|
31
|
-
# separation check: lhs has no y, rhs has no x
|
|
32
|
-
lhs_str = str_form(lhs)
|
|
33
|
-
rhs_str = str_form(rhs)
|
|
34
|
-
|
|
35
|
-
if "v_1" not in lhs_str and "v_0" not in rhs_str:
|
|
36
|
-
return [lhs, rhs]
|
|
37
|
-
|
|
38
|
-
sides = [lhs, rhs]
|
|
39
|
-
|
|
40
|
-
for side in range(2):
|
|
41
|
-
eq = sides[side]
|
|
42
|
-
|
|
43
|
-
if eq.name not in ("f_add", "f_mul"):
|
|
44
|
-
continue
|
|
45
|
-
|
|
46
|
-
# iterate over a COPY — never mutate while iterating
|
|
47
|
-
for i, child in enumerate(eq.children.copy()):
|
|
48
|
-
# rebuild remaining expression safely
|
|
49
|
-
rest_children = [
|
|
50
|
-
c.copy_tree()
|
|
51
|
-
for j, c in enumerate(eq.children)
|
|
52
|
-
if j != i
|
|
53
|
-
]
|
|
54
|
-
|
|
55
|
-
if not rest_children:
|
|
56
|
-
continue
|
|
57
19
|
|
|
58
|
-
if len(rest_children) == 1:
|
|
59
|
-
rest = rest_children[0]
|
|
60
|
-
else:
|
|
61
|
-
rest = TreeNode(eq.name, rest_children)
|
|
62
|
-
|
|
63
|
-
other = sides[1 - side].copy_tree()
|
|
64
|
-
|
|
65
|
-
# move term across
|
|
66
|
-
if eq.name == "f_add":
|
|
67
|
-
moved = TreeNode("f_add", [other, -child.copy_tree()])
|
|
68
|
-
else: # f_mul
|
|
69
|
-
moved = TreeNode("f_mul", [other, TreeNode("f_pow", [child.copy_tree(), tree_form("d_-1")])])
|
|
70
|
-
|
|
71
|
-
moved = simplify(moved)
|
|
72
|
-
rest = simplify(rest)
|
|
73
|
-
|
|
74
|
-
if side == 0:
|
|
75
|
-
out = inverse_pde(rest, moved, depth - 1)
|
|
76
|
-
else:
|
|
77
|
-
out = inverse_pde(moved, rest, depth - 1)
|
|
78
|
-
|
|
79
|
-
if out is not None:
|
|
80
|
-
return out
|
|
81
|
-
|
|
82
|
-
return None
|
|
83
|
-
def subs2(eq):
|
|
84
|
-
if eq.name == "f_pdif":
|
|
85
|
-
return eq.children[0].fx("dif")/eq.children[1].fx("dif")
|
|
86
|
-
return TreeNode(eq.name, [subs2(child) for child in eq.children])
|
|
87
20
|
def capital(eq):
|
|
88
21
|
if eq.name[:2] == "f_" and eq.name != eq.name.lower():
|
|
89
22
|
return eq
|
|
@@ -97,13 +30,17 @@ def abs_const(eq):
|
|
|
97
30
|
return tree_form("v_101")*eq.children[0]
|
|
98
31
|
return TreeNode(eq.name, [abs_const(child) for child in eq.children])
|
|
99
32
|
def want(eq):
|
|
33
|
+
if eq is None:
|
|
34
|
+
return None
|
|
100
35
|
if eq.name == "f_want":
|
|
36
|
+
|
|
101
37
|
eq2 = eq.children[0]
|
|
102
38
|
v = [tree_form(item) for item in vlist(eq.children[0])]
|
|
103
39
|
lst = {}
|
|
104
40
|
if eq.children[1].name == "f_and":
|
|
105
41
|
for item in eq.children[1].children:
|
|
106
42
|
item = abs_const(item)
|
|
43
|
+
item = groupe(item)
|
|
107
44
|
for item2 in v:
|
|
108
45
|
if contain(item, item2):
|
|
109
46
|
out = inverse(item.children[0], str_form(item2))
|
|
@@ -113,26 +50,50 @@ def want(eq):
|
|
|
113
50
|
for key in lst.keys():
|
|
114
51
|
eq2 = replace(eq2, key, lst[key])
|
|
115
52
|
if len(lst.keys()) == len(v):
|
|
116
|
-
return simplify(eq2)
|
|
53
|
+
return fraction(groupe(simplify(eq2)))
|
|
117
54
|
return TreeNode(eq.name, [want(child) for child in eq.children])
|
|
55
|
+
def absorb2(eq):
|
|
56
|
+
if "v_103" in vlist(eq):
|
|
57
|
+
v = vlist(eq)
|
|
58
|
+
v.remove("v_103")
|
|
59
|
+
if set(v)<set(["v_101", "v_102"]):
|
|
60
|
+
return tree_form("v_103")
|
|
61
|
+
if ["v_101"] == vlist(eq):
|
|
62
|
+
return tree_form("v_101")
|
|
63
|
+
if ["v_102"] == vlist(eq):
|
|
64
|
+
return tree_form("v_102")
|
|
65
|
+
if ["v_103"] == vlist(eq):
|
|
66
|
+
return tree_form("v_103")
|
|
67
|
+
return TreeNode(eq.name, [absorb2(child) for child in eq.children])
|
|
68
|
+
def absorb(eq):
|
|
69
|
+
return dowhile(epowersplit(eq), absorb2)
|
|
118
70
|
def pde_sep(eq):
|
|
119
71
|
if eq.name == "f_eq":
|
|
120
72
|
eq = eq.children[0]
|
|
121
|
-
r2 =
|
|
73
|
+
r2 = parse("U(x,y)")
|
|
74
|
+
eq = replace(eq, r2, parse("x").fx("X") * parse("y").fx("Y"))
|
|
75
|
+
|
|
76
|
+
eq = fraction(simplify(fraction(TreeNode("f_eq", [diff2(eq), tree_form("d_0")]))))
|
|
77
|
+
|
|
78
|
+
out = inversediff(eq.children[0], tree_form("d_0"))
|
|
122
79
|
|
|
123
|
-
eq = simplify(fraction(subs(eq, r2)))
|
|
124
|
-
out = inverse_pde(eq,tree_form("d_0"))
|
|
125
80
|
if out is not None:
|
|
126
|
-
out = list(out)
|
|
81
|
+
out = list(out.children[0].children)
|
|
82
|
+
if contain(out[0], tree_form("v_1")):
|
|
83
|
+
out = out[::-1]
|
|
84
|
+
out[0] = simplify(-out[0])
|
|
85
|
+
|
|
127
86
|
lst = []
|
|
128
87
|
for i in range(2):
|
|
129
|
-
|
|
130
|
-
out[i] = TreeNode("f_eq", [out[i], tree_form("
|
|
88
|
+
|
|
89
|
+
out[i] = TreeNode("f_eq", [out[i], tree_form("v_103")])
|
|
131
90
|
out[i] = fraction(simplify(out[i]))
|
|
132
91
|
r = capital(out[i])
|
|
133
92
|
lst.append(r)
|
|
134
93
|
out[i] = replace(out[i], r, tree_form(f"v_{1-i}"))
|
|
94
|
+
out[i] = tree_form(str_form(out[i]).replace("f_pdif", "f_dif"))
|
|
135
95
|
out[i] = diffsolve(out[i])
|
|
96
|
+
|
|
136
97
|
out[i] = replace(out[i], tree_form(f"v_{1-i}"), r)
|
|
137
98
|
out = TreeNode("f_eq", [r2, TreeNode("f_want", [product(lst), TreeNode("f_and", out)])])
|
|
138
99
|
return replace(replace(out, lst[0], parse("a")), lst[1], parse("b"))
|
mathai/structure.py
CHANGED
|
@@ -2,7 +2,7 @@ import itertools
|
|
|
2
2
|
from .simplify import simplify
|
|
3
3
|
from .base import *
|
|
4
4
|
|
|
5
|
-
def structure(equation, formula, formula_out=None, only_const=False):
|
|
5
|
+
def structure(equation, formula, formula_out=None, only_const=False, wrt=None):
|
|
6
6
|
varlist = {}
|
|
7
7
|
def helper(equation, formula):
|
|
8
8
|
nonlocal varlist
|
|
@@ -60,7 +60,7 @@ def structure(equation, formula, formula_out=None, only_const=False):
|
|
|
60
60
|
for item in lst(formula):
|
|
61
61
|
varlist = {}
|
|
62
62
|
if helper(equation, item):
|
|
63
|
-
if only_const and any(
|
|
63
|
+
if only_const and any(contain(varlist[key], tree_form(wrt)) for key in varlist.keys()):
|
|
64
64
|
continue
|
|
65
65
|
if formula_out is None:
|
|
66
66
|
return varlist
|
|
@@ -90,7 +90,7 @@ def transform_formula(equation, wrt, formula_list, var, expr):
|
|
|
90
90
|
if var != "":
|
|
91
91
|
p = True
|
|
92
92
|
try:
|
|
93
|
-
out = structure(equation.copy_tree(), copy.deepcopy(item[0]), copy.deepcopy(item[1]), p)
|
|
93
|
+
out = structure(equation.copy_tree(), copy.deepcopy(item[0]), copy.deepcopy(item[1]), p, wrt)
|
|
94
94
|
if out is not None:
|
|
95
95
|
out = simplify(out)
|
|
96
96
|
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
mathai/__init__.py,sha256=
|
|
1
|
+
mathai/__init__.py,sha256=JdRPSes54qhzvi6f8Rni2sXljzzirrWZsaCmu9W9rws,1525
|
|
2
2
|
mathai/apart.py,sha256=VSS3khE9PNuxiRvdU5JDl4IN-KJBSIFjwR17pkhviXI,4197
|
|
3
|
-
mathai/base.py,sha256=
|
|
3
|
+
mathai/base.py,sha256=zha7eOnfLjJuQcwi29rE0588U1R8v-0zulVPatr2aQo,14843
|
|
4
4
|
mathai/bivariate_inequality.py,sha256=Da-A1kqVynR0tNOlEI7GSTf5T2vNkcF4etL9-EoyPJg,11415
|
|
5
5
|
mathai/console.py,sha256=Sn58iwYE79MLEh67s8X3q6vZjw6g7f9XM1T8_dBBR2o,3048
|
|
6
|
-
mathai/diff.py,sha256=
|
|
6
|
+
mathai/diff.py,sha256=GEiAGMCTT0dO-ULTUGvTlBKy-Io-r2xcgvFJfmqGurY,6879
|
|
7
7
|
mathai/expand.py,sha256=IuzMX6emCT480VE27aCtR0eWU-rJ2VElvRLVa2xcRw0,2582
|
|
8
8
|
mathai/factor.py,sha256=mz_UlPuAqwvsextLB0FM5KWIuuDiMMKG51bXrofqzw8,12830
|
|
9
|
-
mathai/fraction.py,sha256=
|
|
10
|
-
mathai/integrate.py,sha256=
|
|
9
|
+
mathai/fraction.py,sha256=jCIDurenm6grPWNDSY_67zci6fmsIhKG24qm2gbmYtQ,3322
|
|
10
|
+
mathai/integrate.py,sha256=6Ik_uAzkLyOWCE9M7mqwH_SVTvEdiG0-UYS2KsDgjLI,17454
|
|
11
11
|
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
15
|
mathai/matrix.py,sha256=MFe6tUL4a3jYuP13fXWGwER_34AbqfoOK5kHwVHfsKk,7169
|
|
16
|
-
mathai/ode.py,sha256=
|
|
17
|
-
mathai/parser.py,sha256=
|
|
16
|
+
mathai/ode.py,sha256=F0Z_Zv2YsnVf4HwIJmqvIenjONaItzy5H739THkLvcU,11616
|
|
17
|
+
mathai/parser.py,sha256=7NWPPzci7MZazkGG_q5uUyKCOZ_-rqvOhp9UZjzBNc4,7100
|
|
18
18
|
mathai/parsetab.py,sha256=TL-4jvRM_Tx6ipwet8CFJc2DkjR4tGsbrGF_r4IC8xI,9651
|
|
19
|
-
mathai/pde.py,sha256=
|
|
19
|
+
mathai/pde.py,sha256=KL1UFPrfyp8lI1p-mXUaEPo4Yia2GkCw9oZT2R1zhKI,3576
|
|
20
20
|
mathai/printeq.py,sha256=4UgLJo-vV_YlVw_3QUQY_jQMHrFnG-ZKAyVZsd7yD6o,1450
|
|
21
21
|
mathai/simplify.py,sha256=bCtYyLyc3pY04hta-MU62ii5-O4zUwGHjs1Q4WBYEvY,19680
|
|
22
22
|
mathai/statistics.py,sha256=ifmaXFzRc6vIgPFWP-9EDfZZYmmMGw-WEKhoQZUaHXo,884
|
|
23
|
-
mathai/structure.py,sha256=
|
|
23
|
+
mathai/structure.py,sha256=u4usB0yPnem2VscgEBqKWxRN9Y4tTjymEaQh1de5Bsk,4121
|
|
24
24
|
mathai/tool.py,sha256=ozcXTXLbKUnyPM9r9kz9M43YA2CBcWezcqLZfEs8rpc,6051
|
|
25
25
|
mathai/trig.py,sha256=fnBbfiopcQzFg4ya1BoO5M0X_aCBnse2bjnKh1juw4I,11223
|
|
26
26
|
mathai/univariate_inequality.py,sha256=LPFdWgC1y5zBwnsy1wwZxj-yP_SbqFDhCmTTzhuwoiY,16469
|
|
27
|
-
mathai-0.7.
|
|
28
|
-
mathai-0.7.
|
|
29
|
-
mathai-0.7.
|
|
30
|
-
mathai-0.7.
|
|
27
|
+
mathai-0.7.9.dist-info/METADATA,sha256=KuLNc-p43qoo0WX2rG-VBhOVbknBxYm9ZZy8pI8SKr8,7735
|
|
28
|
+
mathai-0.7.9.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
29
|
+
mathai-0.7.9.dist-info/top_level.txt,sha256=ROP4l3OhGYw3ihkQGASr18xM9GsK4z3_6whV5AyXLwE,7
|
|
30
|
+
mathai-0.7.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|