mathai 0.4.0__py3-none-any.whl → 0.6.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 +18 -11
- mathai/apart.py +41 -12
- mathai/base.py +141 -38
- mathai/bivariate_inequality.py +317 -0
- mathai/diff.py +3 -3
- mathai/expand.py +92 -93
- mathai/factor.py +213 -41
- mathai/fraction.py +2 -2
- mathai/integrate.py +96 -34
- mathai/inverse.py +4 -4
- mathai/limit.py +96 -70
- mathai/linear.py +96 -84
- mathai/logic.py +7 -1
- mathai/matrix.py +228 -0
- mathai/ode.py +124 -0
- mathai/parser.py +13 -7
- mathai/parsetab.py +61 -0
- mathai/printeq.py +12 -9
- mathai/simplify.py +511 -333
- mathai/structure.py +2 -2
- mathai/tool.py +105 -4
- mathai/trig.py +134 -72
- mathai/univariate_inequality.py +78 -30
- {mathai-0.4.0.dist-info → mathai-0.6.9.dist-info}/METADATA +4 -1
- mathai-0.6.9.dist-info/RECORD +28 -0
- {mathai-0.4.0.dist-info → mathai-0.6.9.dist-info}/WHEEL +1 -1
- mathai/search.py +0 -117
- mathai-0.4.0.dist-info/RECORD +0 -25
- {mathai-0.4.0.dist-info → mathai-0.6.9.dist-info}/top_level.txt +0 -0
mathai/factor.py
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import itertools
|
|
2
|
+
from .trig import trig0
|
|
2
3
|
from .parser import parse
|
|
3
4
|
from .structure import transform_formula
|
|
4
5
|
from .base import *
|
|
5
|
-
from .simplify import simplify
|
|
6
|
+
from .simplify import simplify
|
|
6
7
|
from .expand import expand
|
|
7
8
|
import math
|
|
9
|
+
from .tool import poly
|
|
10
|
+
from .fraction import fraction
|
|
8
11
|
|
|
9
12
|
from collections import Counter
|
|
10
13
|
def multiset_intersection(*lists):
|
|
@@ -30,8 +33,8 @@ def term_common2(eq):
|
|
|
30
33
|
return product(s)*summation([product(subtract_sublist(factor_generation(child), s)) for child in eq.children])
|
|
31
34
|
def term_common(eq):
|
|
32
35
|
if eq.name == "f_add":
|
|
33
|
-
return
|
|
34
|
-
return
|
|
36
|
+
return simplify(term_common2(eq))
|
|
37
|
+
return simplify(product([term_common2(item) for item in factor_generation(eq)]))
|
|
35
38
|
def take_common(eq):
|
|
36
39
|
if eq.name == "f_add":
|
|
37
40
|
eq = term_common(eq)
|
|
@@ -41,7 +44,8 @@ def take_common(eq):
|
|
|
41
44
|
eq2 = summation([item2 for index, item2 in enumerate(eq.children) if index in item])
|
|
42
45
|
eq2 = term_common(eq2)
|
|
43
46
|
if eq2.name == "f_mul":
|
|
44
|
-
return take_common(
|
|
47
|
+
return take_common(simplify(summation([item2 for index, item2 in enumerate(eq.children) if index not in item]) + eq2))
|
|
48
|
+
break
|
|
45
49
|
return eq
|
|
46
50
|
return term_common(eq)
|
|
47
51
|
def take_common2(eq):
|
|
@@ -52,10 +56,13 @@ def _factorconst(eq):
|
|
|
52
56
|
def hcf_list(numbers):
|
|
53
57
|
if not numbers:
|
|
54
58
|
return None # empty list
|
|
59
|
+
n = 1
|
|
60
|
+
if math.prod(numbers) < 0:
|
|
61
|
+
n = -1
|
|
55
62
|
hcf = numbers[0]
|
|
56
63
|
for num in numbers[1:]:
|
|
57
|
-
hcf = math.gcd(hcf, num)
|
|
58
|
-
return hcf
|
|
64
|
+
hcf = math.gcd(hcf, abs(num))
|
|
65
|
+
return hcf*n
|
|
59
66
|
def extractnum(eq):
|
|
60
67
|
lst = factor_generation(eq)
|
|
61
68
|
for item in lst:
|
|
@@ -69,65 +76,230 @@ def _factorconst(eq):
|
|
|
69
76
|
if n != 1:
|
|
70
77
|
return tree_form("d_"+str(n))*eq
|
|
71
78
|
return TreeNode(eq.name, [factorconst(child) for child in eq.children])
|
|
79
|
+
|
|
80
|
+
def _merge_sqrt(eq):
|
|
81
|
+
lst= []
|
|
82
|
+
eq2 = []
|
|
83
|
+
for child in factor_generation(eq):
|
|
84
|
+
if frac(child) is not None and frac(child).denominator==1:
|
|
85
|
+
if frac(child)>0:
|
|
86
|
+
eq2.append(child**2)
|
|
87
|
+
elif frac(child)!=-1:
|
|
88
|
+
eq2.append((-child)**2)
|
|
89
|
+
lst.append(tree_form("d_-1"))
|
|
90
|
+
else:
|
|
91
|
+
lst.append(tree_form("d_-1"))
|
|
92
|
+
elif child.name == "f_pow" and frac(child.children[1]) == Fraction(1,2):
|
|
93
|
+
eq2.append(child.children[0])
|
|
94
|
+
else:
|
|
95
|
+
lst.append(child)
|
|
96
|
+
|
|
97
|
+
if len(eq2)>1:
|
|
98
|
+
if lst == []:
|
|
99
|
+
lst= [tree_form("d_1")]
|
|
100
|
+
return simplify(product(eq2)**(tree_form("d_2")**-1)*product(lst))
|
|
101
|
+
return TreeNode(eq.name, [_merge_sqrt(child) for child in eq.children])
|
|
102
|
+
def sqrt_to_a_sqrt_b(n):
|
|
103
|
+
if n == 0:
|
|
104
|
+
return 0, 0
|
|
105
|
+
sign = 1
|
|
106
|
+
if n < 0:
|
|
107
|
+
sign = -1
|
|
108
|
+
m = -n
|
|
109
|
+
else:
|
|
110
|
+
m = n
|
|
111
|
+
|
|
112
|
+
a = 1
|
|
113
|
+
b = 1
|
|
114
|
+
p = 2
|
|
115
|
+
while p * p <= m:
|
|
116
|
+
exp = 0
|
|
117
|
+
while m % p == 0:
|
|
118
|
+
m //= p
|
|
119
|
+
exp += 1
|
|
120
|
+
if exp:
|
|
121
|
+
a *= p ** (exp // 2)
|
|
122
|
+
if exp % 2 == 1:
|
|
123
|
+
b *= p
|
|
124
|
+
p += 1 if p == 2 else 2
|
|
125
|
+
|
|
126
|
+
if m > 1:
|
|
127
|
+
b *= m
|
|
128
|
+
|
|
129
|
+
return sign * a, b
|
|
130
|
+
def merge_sqrt(eq):
|
|
131
|
+
def helper(eq):
|
|
132
|
+
if eq.name == "f_pow" and frac(eq.children[1]) == Fraction(1,2):
|
|
133
|
+
if eq.children[0].name[:2] == "d_":
|
|
134
|
+
n = int(eq.children[0].name[2:])
|
|
135
|
+
a, b =sqrt_to_a_sqrt_b(n)
|
|
136
|
+
return tree_form("d_"+str(b))**(tree_form("d_2")**-1)*tree_form("d_"+str(a))
|
|
137
|
+
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
|
138
|
+
return helper(_merge_sqrt(eq))
|
|
139
|
+
def rationalize_sqrt(eq):
|
|
140
|
+
if eq.name== "f_pow" and frac(eq.children[1]) == Fraction(-1,2):
|
|
141
|
+
eq = eq.children[0]**(tree_form("d_2")**-1)/eq.children[0]
|
|
142
|
+
def term(eq):
|
|
143
|
+
if eq.name == "f_add":
|
|
144
|
+
output = []
|
|
145
|
+
for child in eq.children:
|
|
146
|
+
if any(child2.name == "f_pow" and frac(child2.children[1]) == Fraction(1,2) for child2 in factor_generation(child)):
|
|
147
|
+
output.append(simplify(-child))
|
|
148
|
+
else:
|
|
149
|
+
output.append(child)
|
|
150
|
+
return summation(output)
|
|
151
|
+
return None
|
|
152
|
+
n, d=num_dem(eq)
|
|
153
|
+
n,d=simplify(n), simplify(d)
|
|
154
|
+
|
|
155
|
+
if d != 1:
|
|
156
|
+
t = term(d)
|
|
157
|
+
if t is not None and t!=1:
|
|
158
|
+
|
|
159
|
+
n,d=simplify(expand(simplify(n*t))),simplify(expand(simplify(d*t)))
|
|
160
|
+
tmp= simplify(n/d)
|
|
161
|
+
|
|
162
|
+
tmp = _merge_sqrt(tmp)
|
|
163
|
+
|
|
164
|
+
return tmp
|
|
165
|
+
return TreeNode(eq.name, [rationalize_sqrt(child) for child in eq.children])
|
|
72
166
|
def factorconst(eq):
|
|
73
167
|
return simplify(_factorconst(eq))
|
|
74
|
-
|
|
75
|
-
var = ""
|
|
76
|
-
formula_list = [(f"(A*D^2+B*D+C)", f"A*(D-(-B+(B^2-4*A*C)^(1/2))/(2*A))*(D-(-B-(B^2-4*A*C)^(1/2))/(2*A))")]
|
|
77
|
-
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
|
78
|
-
expr = [[parse("A"), parse("1")], [parse("B"), parse("0"), parse("1")], [parse("C"), parse("0")]]
|
|
79
|
-
return [formula_list, var, expr]
|
|
168
|
+
|
|
80
169
|
def factor_quar_formula_init():
|
|
81
170
|
var = ""
|
|
82
171
|
formula_list = [(f"(A^4+B*A^2+C)", f"(A^2 + sqrt(2*sqrt(C) - B)*A + sqrt(C))*(A^2 - sqrt(2*sqrt(C) - B)*A + sqrt(C))")]
|
|
83
172
|
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
|
84
173
|
expr = [[parse("A")], [parse("B"), parse("0"), parse("1")], [parse("C"), parse("0")]]
|
|
85
174
|
return [formula_list, var, expr]
|
|
86
|
-
|
|
87
|
-
var = ""
|
|
88
|
-
formula_list = [(f"D^3+E", f"(D+E^(1/3))*(D^2-D*E^(1/3)+E^(2/3))"), (f"D^3-E", f"(D-E^(1/3))*(D^2+D*E^(1/3)+E^(2/3))"),\
|
|
89
|
-
(f"-D^3+E", f"(-D+E^(1/3))*(D^2+D*E^(1/3)+E^(2/3))")]
|
|
90
|
-
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
|
91
|
-
expr = [[parse("A")], [parse("B")]]
|
|
92
|
-
return [formula_list, var, expr]
|
|
93
|
-
formula_gen2 = factor_quad_formula_init()
|
|
94
|
-
formula_gen3 = factor_cube_formula_init()
|
|
175
|
+
|
|
95
176
|
formula_gen9 = factor_quar_formula_init()
|
|
177
|
+
|
|
96
178
|
def factor_helper(equation, complexnum, power=2):
|
|
97
|
-
global
|
|
98
|
-
|
|
179
|
+
global formula_gen9
|
|
180
|
+
if equation.name in ["f_or", "f_and", "f_not", "f_eq", "f_gt", "f_lt", "f_ge", "f_le"]:
|
|
181
|
+
return TreeNode(equation.name, [factor_helper(child, complexnum, power) for child in equation.children])
|
|
182
|
+
maxnum=1
|
|
183
|
+
alloclst = []
|
|
184
|
+
for i in range(0,26):
|
|
185
|
+
if "v_"+str(i) not in vlist(equation):
|
|
186
|
+
alloclst.append("v_"+str(i))
|
|
187
|
+
r = alloclst.pop(0)
|
|
188
|
+
fx = None
|
|
189
|
+
curr = None
|
|
99
190
|
def high(eq):
|
|
100
191
|
nonlocal maxnum
|
|
101
192
|
if eq.name == "f_pow" and eq.children[1].name[:2] == "d_":
|
|
102
193
|
n = int(eq.children[1].name[2:])
|
|
103
|
-
if n>power and n % power == 0:
|
|
104
|
-
|
|
194
|
+
if abs(n)>power and abs(n) % power == 0:
|
|
195
|
+
if abs(n)>abs(maxnum):
|
|
196
|
+
maxnum = n
|
|
105
197
|
for child in eq.children:
|
|
106
198
|
high(child)
|
|
107
199
|
def helper(eq):
|
|
108
|
-
nonlocal maxnum
|
|
109
|
-
if eq.name == "f_pow" and eq.children[1].name[:2] == "d_":
|
|
200
|
+
nonlocal maxnum, fx, r
|
|
201
|
+
if eq.name == "f_pow" and eq.children[1].name[:2] == "d_" and eq.children[0] == curr:
|
|
110
202
|
n = int(eq.children[1].name[2:])
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
out= (eq.children[0]**tree_form("d_"+str(sgn*int(n/power))))**power
|
|
203
|
+
if maxnum !=1 and n % maxnum == 0:
|
|
204
|
+
fx = lambda x: replace(x, tree_form(r), curr**tree_form("d_"+str(maxnum)))
|
|
205
|
+
out= tree_form(r)**tree_form("d_"+str(int(n/maxnum)))
|
|
115
206
|
return out
|
|
116
207
|
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
|
117
|
-
high(equation)
|
|
118
208
|
out = None
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
209
|
+
|
|
210
|
+
for i in range(2,4):
|
|
211
|
+
if power == i:
|
|
212
|
+
for curr in vlist(equation):
|
|
213
|
+
curr = tree_form(curr)
|
|
214
|
+
fx = None
|
|
215
|
+
maxnum = 1
|
|
216
|
+
high(equation.copy_tree())
|
|
217
|
+
|
|
218
|
+
if maxnum != 1:
|
|
219
|
+
maxnum= maxnum/power
|
|
220
|
+
maxnum = round(maxnum)
|
|
221
|
+
eq2 = helper(equation.copy_tree())
|
|
222
|
+
if not contain(eq2, tree_form(r)) or (contain(eq2, tree_form(r)) and not contain(eq2,curr)):
|
|
223
|
+
if not contain(eq2, tree_form(r)):
|
|
224
|
+
r = curr.name
|
|
225
|
+
fx = lambda x: x
|
|
226
|
+
|
|
227
|
+
lst = poly(eq2.copy_tree(), r)
|
|
228
|
+
if lst is not None and len(lst)==i+1:
|
|
229
|
+
|
|
230
|
+
success = True
|
|
231
|
+
if i == 2:
|
|
232
|
+
a, b, c = lst
|
|
233
|
+
x1 = (-b+(b**2 - 4*a*c)**(tree_form("d_2")**-1))/(2*a)
|
|
234
|
+
x2 = (-b-(b**2 - 4*a*c)**(tree_form("d_2")**-1))/(2*a)
|
|
235
|
+
x1 = expand(simplify(x1))
|
|
236
|
+
x2 = expand(simplify(x2))
|
|
237
|
+
eq2 = a*(tree_form(r)-x1)*(tree_form(r)-x2)
|
|
238
|
+
if not complexnum and (contain(x1, tree_form("s_i")) or contain(x2, tree_form("s_i"))):
|
|
239
|
+
success = False
|
|
240
|
+
else:
|
|
241
|
+
a, b, c, d = lst
|
|
242
|
+
B, C, D = b/a, c/a, d/a
|
|
243
|
+
p = C-(B**2)/3
|
|
244
|
+
q = 2*B**3/27-B*C/3+D
|
|
245
|
+
t = q**2/4+ p**3/27
|
|
246
|
+
|
|
247
|
+
if compute(t) > 0:
|
|
248
|
+
u = (-q/2+t**(tree_form("d_2")**-1))**(tree_form("d_3")**-1)
|
|
249
|
+
v = (-q/2-t**(tree_form("d_2")**-1))**(tree_form("d_3")**-1)
|
|
250
|
+
y1 = u+v
|
|
251
|
+
three = 3**(tree_form("d_2")**-1)
|
|
252
|
+
y2 = -(u+v)/2+tree_form("s_i")*three*(u-v)/2
|
|
253
|
+
y3 = -(u+v)/2-tree_form("s_i")*three*(u-v)/2
|
|
254
|
+
|
|
255
|
+
else:
|
|
256
|
+
ar = 2*(-p/3)**(tree_form("d_2")**-1)
|
|
257
|
+
phi = ((3*q/(2*p))*(-3/p)**(tree_form("d_2")**-1)).fx("arccos")
|
|
258
|
+
y1 = ar*(phi/3).fx("cos")
|
|
259
|
+
y2 = ar*((phi+2*tree_form("s_pi"))/3).fx("cos")
|
|
260
|
+
y3 = ar*((phi+4*tree_form("s_pi"))/3).fx("cos")
|
|
261
|
+
|
|
262
|
+
x1,x2,x3 = y1-B/3 , y2-B/3, y3-B/3
|
|
263
|
+
x1 = simplify(trig0(simplify(x1)))
|
|
264
|
+
x2 = simplify(trig0(simplify(x2)))
|
|
265
|
+
x3 = simplify(trig0(simplify(x3)))
|
|
266
|
+
|
|
267
|
+
out2 = None
|
|
268
|
+
if not complexnum:
|
|
269
|
+
for item in itertools.combinations([x1,x2,x3],2):
|
|
270
|
+
if all(contain(item2,tree_form("s_i")) for item2 in list(item)):
|
|
271
|
+
out2 = (tree_form(r)-item[0])*(tree_form(r)-item[1])
|
|
272
|
+
break
|
|
273
|
+
if out2 is not None:
|
|
274
|
+
out2 = simplify(fraction(expand(simplify(out2))))
|
|
275
|
+
out3 = None
|
|
276
|
+
for item in [x1, x2, x3]:
|
|
277
|
+
if not contain(item,tree_form("s_i")):
|
|
278
|
+
out3 = item
|
|
279
|
+
break
|
|
280
|
+
eq2 = a*(tree_form(r)-out3)*out2
|
|
281
|
+
|
|
282
|
+
else:
|
|
283
|
+
eq2 = a*(tree_form(r)-x1)*(tree_form(r)-x2)*(tree_form(r)-x3)
|
|
284
|
+
if success:
|
|
285
|
+
equation = fx(eq2)
|
|
286
|
+
break
|
|
287
|
+
|
|
288
|
+
if False and power == 4:
|
|
289
|
+
|
|
124
290
|
out = transform_formula(helper(equation), "v_0", formula_gen9[0], formula_gen9[1], formula_gen9[2])
|
|
291
|
+
|
|
125
292
|
if out is not None:
|
|
126
|
-
out = simplify(
|
|
293
|
+
out = simplify(out)
|
|
127
294
|
if out is not None and (complexnum or (not complexnum and not contain(out, tree_form("s_i")))):
|
|
128
295
|
return out
|
|
296
|
+
|
|
129
297
|
return TreeNode(equation.name, [factor_helper(child, complexnum, power) for child in equation.children])
|
|
130
|
-
def factor(equation
|
|
131
|
-
return
|
|
298
|
+
def factor(equation):
|
|
299
|
+
return simplify(take_common2(simplify(equation)))
|
|
300
|
+
|
|
132
301
|
def factor2(equation, complexnum=False):
|
|
133
|
-
return
|
|
302
|
+
return simplify(factor_helper(simplify(equation), complexnum, 2))
|
|
303
|
+
|
|
304
|
+
def factor3(equation, complexnum=False):
|
|
305
|
+
return simplify(factor_helper(simplify(factor_helper(simplify(equation), complexnum, 2)), complexnum, 3))
|
mathai/fraction.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from .base import *
|
|
2
|
-
from .simplify import
|
|
2
|
+
from .simplify import simplify
|
|
3
3
|
from .expand import expand
|
|
4
4
|
|
|
5
5
|
def fraction(eq):
|
|
@@ -100,4 +100,4 @@ def fraction(eq):
|
|
|
100
100
|
result_map[node] = TreeNode(node.name, children_processed)
|
|
101
101
|
|
|
102
102
|
# Final return
|
|
103
|
-
return
|
|
103
|
+
return simplify(result_map[eq])
|
mathai/integrate.py
CHANGED
|
@@ -3,7 +3,7 @@ from .parser import parse
|
|
|
3
3
|
import itertools
|
|
4
4
|
from .diff import diff
|
|
5
5
|
from .fraction import fraction
|
|
6
|
-
from .simplify import
|
|
6
|
+
from .simplify import simplify
|
|
7
7
|
from .expand import expand
|
|
8
8
|
from .base import *
|
|
9
9
|
from .printeq import printeq_str
|
|
@@ -31,8 +31,13 @@ def integrate_summation(equation):
|
|
|
31
31
|
def subs_heuristic(eq, var):
|
|
32
32
|
output = []
|
|
33
33
|
def collect2(eq):
|
|
34
|
+
if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]) == Fraction(1,2):
|
|
35
|
+
|
|
36
|
+
if eq.children[0] == var:
|
|
37
|
+
output.append(str_form(eq))
|
|
34
38
|
if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]).denominator == 1 and abs(frac(eq.children[1]).numerator) % 2 == 0:
|
|
35
|
-
|
|
39
|
+
if len(eq.children[0].children) == 0 or eq.children[0].children[0] == var:
|
|
40
|
+
output.append(str_form(eq.children[0]**2))
|
|
36
41
|
if eq.name in ["f_pow", "f_sin", "f_cos", "f_arcsin"] and var.name in str_form(eq.children[0]):
|
|
37
42
|
if eq.children[0].name[:2] != "v_":
|
|
38
43
|
output.append(str_form(eq.children[0]))
|
|
@@ -57,12 +62,27 @@ def subs_heuristic(eq, var):
|
|
|
57
62
|
|
|
58
63
|
tmp = list(set([simplify(tree_form(x)) for x in output]))
|
|
59
64
|
tmp = sorted(tmp, key=lambda x: len(str(x)))
|
|
60
|
-
|
|
65
|
+
poly_term = None
|
|
66
|
+
term_degree = 100
|
|
67
|
+
output = []
|
|
68
|
+
for item in tmp:
|
|
69
|
+
n = poly(simplify(item), var.name)
|
|
70
|
+
if n is None:
|
|
71
|
+
output.append(item)
|
|
72
|
+
else:
|
|
73
|
+
if term_degree > len(n):
|
|
74
|
+
poly_term = item
|
|
75
|
+
term_degree = len(n)
|
|
76
|
+
if poly_term is None:
|
|
77
|
+
return tmp
|
|
78
|
+
return [poly_term]+output
|
|
61
79
|
try_index = []
|
|
62
80
|
try_lst = []
|
|
63
81
|
def ref(eq):
|
|
82
|
+
'''
|
|
64
83
|
if eq.name in ["f_try", "f_ref"]:
|
|
65
84
|
return eq
|
|
85
|
+
'''
|
|
66
86
|
if eq.name == "f_integrate":
|
|
67
87
|
return TreeNode("f_try", [eq.fx("ref"), eq])
|
|
68
88
|
return TreeNode(eq.name, [ref(child) for child in eq.children])
|
|
@@ -80,12 +100,12 @@ def _solve_integrate(eq):
|
|
|
80
100
|
if eq.name == "f_ref":
|
|
81
101
|
return eq
|
|
82
102
|
if eq.name == "f_subs":
|
|
83
|
-
if
|
|
103
|
+
if all(item not in str_form(eq.children[0]) for item in ["f_integrate", "f_subs", "f_try"]):
|
|
84
104
|
return replace(eq.children[0], eq.children[1], eq.children[2])
|
|
85
105
|
|
|
86
106
|
if eq.name == "f_try":
|
|
87
107
|
for child in eq.children:
|
|
88
|
-
if
|
|
108
|
+
if all(item not in str_form(child) for item in ["f_integrate", "f_subs", "f_try"]):
|
|
89
109
|
return child
|
|
90
110
|
return TreeNode(eq.name, [_solve_integrate(child) for child in eq.children])
|
|
91
111
|
def handle_try(eq):
|
|
@@ -104,8 +124,6 @@ def handle_try(eq):
|
|
|
104
124
|
else:
|
|
105
125
|
return TreeNode(eq.name, [handle_try(child) for child in eq.children])
|
|
106
126
|
def inteq(eq):
|
|
107
|
-
if "f_ref" not in str_form(eq):
|
|
108
|
-
return eq
|
|
109
127
|
if eq.name == "f_try":
|
|
110
128
|
eq2 = None
|
|
111
129
|
output = []
|
|
@@ -113,35 +131,45 @@ def inteq(eq):
|
|
|
113
131
|
if child.name == "f_ref":
|
|
114
132
|
eq2 = child.children[0]
|
|
115
133
|
break
|
|
134
|
+
if eq2 is None:
|
|
135
|
+
return eq
|
|
136
|
+
printeq(eq)
|
|
116
137
|
for child in eq.children:
|
|
117
138
|
if child.name == "f_ref":
|
|
118
139
|
output.append(child)
|
|
119
140
|
else:
|
|
120
141
|
eq3 = simplify(expand(simplify(eq2 - child)))
|
|
121
142
|
if contain(eq3, eq2):
|
|
122
|
-
|
|
143
|
+
out = inverse(eq3, str_form(eq2))
|
|
144
|
+
if out is None:
|
|
145
|
+
output.append(child)
|
|
146
|
+
else:
|
|
147
|
+
output.append(out)
|
|
123
148
|
else:
|
|
124
149
|
output.append(child)
|
|
150
|
+
printeq(TreeNode("f_try", output))
|
|
151
|
+
print()
|
|
125
152
|
return TreeNode("f_try", output)
|
|
126
153
|
else:
|
|
127
154
|
return TreeNode(eq.name, [inteq(child) for child in eq.children])
|
|
128
155
|
def rm(eq):
|
|
129
156
|
if eq.name == "f_try":
|
|
130
157
|
eq = TreeNode(eq.name, list(set(eq.children)))
|
|
131
|
-
return TreeNode(eq.name, [rm(child) for child in eq.children])
|
|
158
|
+
return TreeNode(eq.name, [rm(child) for child in eq.children if child is not None])
|
|
132
159
|
def solve_integrate(eq):
|
|
133
160
|
|
|
134
161
|
eq2 = dowhile(eq, _solve_integrate)
|
|
135
162
|
eq2 = dowhile(eq2, handle_try)
|
|
136
163
|
eq2 = rm(eq2)
|
|
137
|
-
eq2.
|
|
164
|
+
if eq2.name == "f_try":
|
|
165
|
+
eq2.children = list(set(eq2.children))
|
|
138
166
|
return eq2
|
|
139
167
|
def integrate_subs(equation, term, v1, v2):
|
|
140
168
|
output = []
|
|
141
169
|
orig = equation.copy_tree()
|
|
142
170
|
none = TreeNode("f_integrate",[orig, tree_form(v1)])
|
|
143
171
|
origv2 = copy.deepcopy(v2)
|
|
144
|
-
equation =
|
|
172
|
+
equation = simplify(equation)
|
|
145
173
|
eq = equation
|
|
146
174
|
termeq = term
|
|
147
175
|
t = inverse(copy.deepcopy(termeq), v1)
|
|
@@ -159,13 +187,13 @@ def integrate_subs(equation, term, v1, v2):
|
|
|
159
187
|
|
|
160
188
|
eq2 = replace(diff(g, v1), tree_form(v1), t)
|
|
161
189
|
equation = eq/eq2
|
|
162
|
-
equation =
|
|
190
|
+
equation = simplify(equation)
|
|
163
191
|
|
|
164
192
|
if v1 in str_form(equation):
|
|
165
193
|
|
|
166
194
|
return none
|
|
167
195
|
|
|
168
|
-
return TreeNode("f_subs", [TreeNode("f_integrate", [simplify(
|
|
196
|
+
return dowhile(TreeNode("f_subs", [TreeNode("f_integrate", [simplify(equation), tree_form(origv2)]),tree_form(origv2) ,g]), trig0)
|
|
169
197
|
|
|
170
198
|
def integrate_subs_main(equation):
|
|
171
199
|
if equation.name == "f_ref":
|
|
@@ -291,7 +319,7 @@ def _sqint(equation):
|
|
|
291
319
|
return coll
|
|
292
320
|
|
|
293
321
|
def sqint(eq):
|
|
294
|
-
out = _sqint(eq)
|
|
322
|
+
out = simplify(_sqint(eq))
|
|
295
323
|
if out is None:
|
|
296
324
|
return eq
|
|
297
325
|
return out
|
|
@@ -307,13 +335,20 @@ def byparts(eq):
|
|
|
307
335
|
lst = factor_generation(eq)
|
|
308
336
|
if len(lst) == 3 and len(list(set(lst))) == 1:
|
|
309
337
|
lst = [(lst[0]**2).copy_tree(), lst[0].copy_tree()]
|
|
338
|
+
if len(lst) == 3 and len(list(set(lst))) == 2:
|
|
339
|
+
lst2 = list(set(lst))
|
|
340
|
+
a, b = lst2
|
|
341
|
+
a = a**lst.count(a)
|
|
342
|
+
b = b**lst.count(b)
|
|
343
|
+
lst = [a.copy_tree(), b.copy_tree()]
|
|
310
344
|
if len(lst) == 1:
|
|
311
345
|
lst += [tree_form("d_1")]
|
|
312
346
|
if len(lst) == 2:
|
|
313
347
|
for i in range(2):
|
|
314
348
|
|
|
315
349
|
f, g = [lst[i], lst[1-i]]
|
|
316
|
-
|
|
350
|
+
if contain(f, tree_form("s_e")):
|
|
351
|
+
continue
|
|
317
352
|
out1 = TreeNode("f_integrate", [g.copy_tree(), wrt])
|
|
318
353
|
|
|
319
354
|
|
|
@@ -331,18 +366,20 @@ def byparts(eq):
|
|
|
331
366
|
|
|
332
367
|
def integration_formula_init():
|
|
333
368
|
var = "x"
|
|
334
|
-
formula_list = [
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
369
|
+
formula_list = [
|
|
370
|
+
(f"(A*{var}+B)^C", f"(A*{var}+B)^(C+1)/(A*(C+1))"),
|
|
371
|
+
(f"sin(A*{var}+B)", f"-cos(A*{var}+B)/A"),
|
|
372
|
+
(f"cos(A*{var}+B)", f"sin(A*{var}+B)/A"),
|
|
373
|
+
(f"1/(A*{var}+B)", f"log(abs(A*{var}+B))/A"),
|
|
374
|
+
(f"e^(A*{var}+B)", f"e^(A*{var}+B)/A"),
|
|
375
|
+
(f"1/cos(A*{var}+B)", f"log(abs((1+sin(A*{var}+B))/cos(A*{var}+B)))"),
|
|
376
|
+
(f"1/cos(A*{var}+B)^2", f"tan(A*{var}+B)/A"),
|
|
377
|
+
(f"1/sin(A*{var}+B)", f"log(abs(tan((A*{var}+B)/2)))/A"),
|
|
378
|
+
(f"1/cos(A*{var}+B)^3", f"(sec(A*{var}+B)*tan(A*{var}+B)+log(abs(sec(A*{var}+B)+tan(A*{var}+B))))/(2*A)")
|
|
379
|
+
]
|
|
342
380
|
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
|
343
381
|
expr = [[parse("A"), parse("1")], [parse("B"), parse("0")]]
|
|
344
382
|
return [formula_list, var, expr]
|
|
345
|
-
formula_gen = integration_formula_init()
|
|
346
383
|
def integration_formula_trig():
|
|
347
384
|
var = "x"
|
|
348
385
|
formula_list = [(f"(A+B*sin({var})+C*cos({var}))/(D+E*sin({var})+F*cos({var}))", f"((B*E+C*F)/(E^2+F^2))*{var}+((C*E-B*F)/(E^2+F^2))*log(D+E*sin({var})+F*cos({var}))")]
|
|
@@ -353,15 +390,31 @@ def integration_formula_trig():
|
|
|
353
390
|
return [formula_list, var, expr]
|
|
354
391
|
|
|
355
392
|
|
|
393
|
+
formula_gen = integration_formula_init()
|
|
356
394
|
formula_gen4 = integration_formula_trig()
|
|
357
395
|
|
|
396
|
+
|
|
397
|
+
def integration_formula_ex():
|
|
398
|
+
var = "x"
|
|
399
|
+
formula_list = [
|
|
400
|
+
(
|
|
401
|
+
f"e^(A*{var})*cos(B*{var})",
|
|
402
|
+
f"e^(A*{var})*(A*cos(B*{var}) + B*sin(B*{var}))/(A^2 + B^2)"
|
|
403
|
+
)
|
|
404
|
+
]
|
|
405
|
+
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
|
406
|
+
expr = [[parse("A"), parse("1")], [parse("B"), parse("1")]]
|
|
407
|
+
return [formula_list, var, expr]
|
|
408
|
+
|
|
409
|
+
formula_gen11 = integration_formula_ex()
|
|
358
410
|
def rm_const(equation):
|
|
359
411
|
if equation.name == "f_ref":
|
|
360
412
|
return equation
|
|
361
413
|
eq2 = equation
|
|
362
|
-
if eq2.name == "f_integrate":
|
|
414
|
+
if eq2.name == "f_integrate" and contain(eq2.children[0], eq2.children[1]):
|
|
363
415
|
equation = eq2.children[0]
|
|
364
416
|
wrt = eq2.children[1]
|
|
417
|
+
|
|
365
418
|
lst = factor_generation(equation)
|
|
366
419
|
|
|
367
420
|
lst_const = [item for item in lst if not contain(item, wrt)]
|
|
@@ -376,6 +429,11 @@ def rm_const(equation):
|
|
|
376
429
|
return rm_const(TreeNode("f_integrate",[equation, wrt])) *const
|
|
377
430
|
equation = eq2
|
|
378
431
|
return TreeNode(equation.name, [rm_const(child) for child in equation.children])
|
|
432
|
+
|
|
433
|
+
def shorten(eq):
|
|
434
|
+
if eq.name.startswith("d_"):
|
|
435
|
+
return tree_form("d_0")
|
|
436
|
+
return TreeNode(eq.name, [shorten(child) for child in eq.children])
|
|
379
437
|
def integrate_formula(equation):
|
|
380
438
|
if equation.name == "f_ref":
|
|
381
439
|
return equation.copy_tree()
|
|
@@ -384,17 +442,21 @@ def integrate_formula(equation):
|
|
|
384
442
|
integrand = eq2.children[0]
|
|
385
443
|
wrt = eq2.children[1]
|
|
386
444
|
if integrand == wrt:
|
|
387
|
-
return
|
|
445
|
+
return wrt**2/2 # x^2/2
|
|
388
446
|
if not contain(integrand, wrt):
|
|
389
|
-
return
|
|
447
|
+
return integrand*wrt
|
|
390
448
|
out = transform_formula(simplify(trig0(integrand)), wrt.name, formula_gen[0], formula_gen[1], formula_gen[2])
|
|
391
449
|
if out is not None:
|
|
450
|
+
|
|
392
451
|
return out
|
|
393
|
-
expr_str = str_form(integrand)
|
|
394
|
-
if
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
452
|
+
expr_str = str_form(shorten(integrand))
|
|
453
|
+
if len(expr_str) < 30:
|
|
454
|
+
if expr_str.count("f_sin") + expr_str.count("f_cos") > 2:
|
|
455
|
+
out = transform_formula(integrand, wrt.name, formula_gen4[0], formula_gen4[1], formula_gen4[2])
|
|
456
|
+
if out is not None:
|
|
457
|
+
return out
|
|
458
|
+
if "f_cos" in expr_str and contain(integrand, tree_form("s_e")):
|
|
459
|
+
out = transform_formula(integrand, wrt.name, formula_gen11[0], formula_gen11[1], formula_gen11[2])
|
|
460
|
+
if out is not None:
|
|
461
|
+
return out
|
|
399
462
|
return TreeNode(eq2.name, [integrate_formula(child) for child in eq2.children])
|
|
400
|
-
|
mathai/inverse.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from .base import *
|
|
2
|
-
from .simplify import
|
|
2
|
+
from .simplify import simplify
|
|
3
3
|
from .expand import expand
|
|
4
4
|
def inverse(rhs,term, sign=None):
|
|
5
5
|
term = tree_form(term)
|
|
@@ -9,7 +9,7 @@ def inverse(rhs,term, sign=None):
|
|
|
9
9
|
while not rhs==term:
|
|
10
10
|
if rhs.name == "f_add":
|
|
11
11
|
if all(term in factor_generation(child) for child in rhs.children):
|
|
12
|
-
newrhs =
|
|
12
|
+
newrhs = simplify(expand(rhs*term**-1))
|
|
13
13
|
if not contain(newrhs, term):
|
|
14
14
|
rhs = term * newrhs
|
|
15
15
|
else:
|
|
@@ -61,5 +61,5 @@ def inverse(rhs,term, sign=None):
|
|
|
61
61
|
if count == 0:
|
|
62
62
|
return None
|
|
63
63
|
if sign is None:
|
|
64
|
-
return
|
|
65
|
-
return
|
|
64
|
+
return simplify(lhs)
|
|
65
|
+
return simplify(lhs), sign
|