mathai 0.2.7__py3-none-any.whl → 0.2.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 +16 -16
- mathai/apart.py +103 -103
- mathai/base.py +355 -354
- mathai/console.py +84 -84
- mathai/diff.py +65 -65
- mathai/expand.py +58 -58
- mathai/factor.py +125 -125
- mathai/fraction.py +59 -59
- mathai/integrate.py +346 -346
- mathai/inverse.py +65 -65
- mathai/limit.py +130 -130
- mathai/linear.py +152 -152
- mathai/logic.py +224 -224
- mathai/parser.py +154 -154
- mathai/printeq.py +34 -34
- mathai/simplify.py +358 -358
- mathai/structure.py +103 -103
- mathai/tool.py +35 -35
- mathai/trig.py +169 -169
- mathai/univariate_inequality.py +410 -414
- {mathai-0.2.7.dist-info → mathai-0.2.9.dist-info}/METADATA +231 -231
- mathai-0.2.9.dist-info/RECORD +24 -0
- {mathai-0.2.7.dist-info → mathai-0.2.9.dist-info}/WHEEL +1 -1
- mathai-0.2.7.dist-info/RECORD +0 -24
- {mathai-0.2.7.dist-info → mathai-0.2.9.dist-info}/top_level.txt +0 -0
mathai/integrate.py
CHANGED
@@ -1,346 +1,346 @@
|
|
1
|
-
from .parser import parse
|
2
|
-
import itertools
|
3
|
-
from .diff import diff
|
4
|
-
from .fraction import fraction
|
5
|
-
from .simplify import solve, simplify
|
6
|
-
from .expand import expand
|
7
|
-
from .base import *
|
8
|
-
from .printeq import printeq_str
|
9
|
-
from .structure import transform_formula
|
10
|
-
from .inverse import inverse
|
11
|
-
from .tool import poly
|
12
|
-
from fractions import Fraction
|
13
|
-
from .printeq import printeq
|
14
|
-
def integrate_summation(equation, wrt, tab, inf):
|
15
|
-
logs= []
|
16
|
-
orig = copy.deepcopy(equation)
|
17
|
-
for i in range(2):
|
18
|
-
|
19
|
-
if equation.name == "f_add":
|
20
|
-
logs += [(tab, f"by integration over sums {', '.join([printeq_str(simplify(child)) for child in equation.children])}")]
|
21
|
-
answer = []
|
22
|
-
for child in equation.children:
|
23
|
-
out = integrate(child, wrt, tab+1, inf)
|
24
|
-
if out is None:
|
25
|
-
return None
|
26
|
-
logs += out[1]
|
27
|
-
answer.append(out[0])
|
28
|
-
return summation(answer), logs
|
29
|
-
if i == 0:
|
30
|
-
|
31
|
-
tmp = expand(simplify(fraction(simplify(equation))))
|
32
|
-
|
33
|
-
logs += [(tab, f"integrating {printeq_str(simplify(equation))} will be the same thing as integrating {printeq_str(simplify(tmp))}")]
|
34
|
-
|
35
|
-
equation = tmp
|
36
|
-
if equation.name != "f_add" and orig != equation:
|
37
|
-
out = integrate(equation, wrt, tab+1, inf)
|
38
|
-
if out is None:
|
39
|
-
return None
|
40
|
-
return out[0], logs+out[1]
|
41
|
-
return None
|
42
|
-
|
43
|
-
def subs_heuristic(eq, var):
|
44
|
-
output = []
|
45
|
-
def collect2(eq):
|
46
|
-
if eq.name == "f_pow" and frac(eq.children[1]) is not None and abs(frac(eq.children[1])) == Fraction(1,2):
|
47
|
-
output.append(str_form(eq.children[0].fx("sqrt")))
|
48
|
-
if eq.name in ["f_pow", "f_sin", "f_cos", "f_arcsin"] and eq.children[0].name[:2] != "v_" and var in str_form(eq.children[0]):
|
49
|
-
output.append(str_form(eq.children[0]))
|
50
|
-
if eq.name == "f_pow" and eq.children[0].name == "s_e" and "v_" in str_form(eq):
|
51
|
-
if eq.children[1].name[:2] != "v_":
|
52
|
-
output.append(str_form(eq.children[1]))
|
53
|
-
output.append(str_form(eq))
|
54
|
-
|
55
|
-
for child in eq.children:
|
56
|
-
collect2(child)
|
57
|
-
def collect3(eq):
|
58
|
-
if eq.name in ["f_sin", "f_cos"]:
|
59
|
-
output.append(str_form(eq.children[0].fx("cos")))
|
60
|
-
for child in eq.children:
|
61
|
-
collect3(child)
|
62
|
-
collect2(eq)
|
63
|
-
if output == []:
|
64
|
-
collect3(eq)
|
65
|
-
tmp = sorted(output, key=lambda x: len(x))
|
66
|
-
tmp = [simplify(tree_form(x)) for x in tmp]
|
67
|
-
|
68
|
-
return tmp
|
69
|
-
|
70
|
-
def integrate_subs(equation, term, v1, v2, tab, inf):
|
71
|
-
|
72
|
-
origv2 = copy.deepcopy(v2)
|
73
|
-
equation = solve(equation)
|
74
|
-
eq = equation
|
75
|
-
termeq = term
|
76
|
-
t = inverse(copy.deepcopy(termeq), v1)
|
77
|
-
g = inverse(termeq, v2)
|
78
|
-
|
79
|
-
if g is None:
|
80
|
-
return None
|
81
|
-
if t is None:
|
82
|
-
return None
|
83
|
-
else:
|
84
|
-
t = expand(t)
|
85
|
-
eq = replace(eq, tree_form(v1), t)
|
86
|
-
|
87
|
-
eq2 = replace(diff(g, v1), tree_form(v1), t)
|
88
|
-
equation = eq/eq2
|
89
|
-
equation = solve(equation)
|
90
|
-
|
91
|
-
lst = [ equation]
|
92
|
-
for eq in lst:
|
93
|
-
if v1 in str_form(eq):
|
94
|
-
continue
|
95
|
-
|
96
|
-
eq = expand(simplify(eq))
|
97
|
-
|
98
|
-
out = integrate(eq, origv2, tab+1, inf)
|
99
|
-
|
100
|
-
if out is None:
|
101
|
-
continue
|
102
|
-
tmp, logs = out
|
103
|
-
tmp = replace(tmp, tree_form(v2), g)
|
104
|
-
return tmp, [(tab, f"substituted {str(tree_form(origv2))}={printeq_str(simplify(g))}, integrating {printeq_str(simplify(eq))} wrt {str(tree_form(origv2))}")]+logs+\
|
105
|
-
[(tab, f"substituting back to {printeq_str(simplify(out[0]))} which is the result after integration")]
|
106
|
-
return None
|
107
|
-
|
108
|
-
def integrate_subs_main(equation, wrt, tab, inf):
|
109
|
-
v2 = "v_"+str(int(wrt[2:])+1)
|
110
|
-
for item in subs_heuristic(equation, wrt):
|
111
|
-
x = tree_form(v2)-item
|
112
|
-
|
113
|
-
tmp3 = integrate_subs(equation, x, wrt, v2, tab, inf)
|
114
|
-
|
115
|
-
if tmp3 is not None:
|
116
|
-
return tmp3[0], tmp3[1]
|
117
|
-
return None
|
118
|
-
def sqint(equation, var="v_0", depth=0, inf=0):
|
119
|
-
typeint = "sqint"
|
120
|
-
logs = []
|
121
|
-
def sgn(eq):
|
122
|
-
if compute(eq) <0:
|
123
|
-
return tree_form("d_-1"), tree_form("d_-1")*eq
|
124
|
-
return tree_form("d_1"), eq
|
125
|
-
one = tree_form("d_1")
|
126
|
-
two = tree_form("d_2")
|
127
|
-
four = tree_form("d_4")
|
128
|
-
three = tree_form("d_3")
|
129
|
-
root = tree_form("d_2")**-1
|
130
|
-
zero = tree_form("d_0")
|
131
|
-
|
132
|
-
n, d = num_dem(equation)
|
133
|
-
n, d = simplify(n), simplify(d)
|
134
|
-
term = [simplify(x) for x in factor_generation(d)]
|
135
|
-
const = product([item for item in term if "v_" not in str_form(item)])
|
136
|
-
term = [item for item in term if "v_" in str_form(item)]
|
137
|
-
mode = False
|
138
|
-
if all(item.name == "f_pow" and simplify(item.children[1]-root) == zero for item in term):
|
139
|
-
d = simplify(expand(const**two*product([item.children[0] for item in term])))
|
140
|
-
else:
|
141
|
-
mode = True
|
142
|
-
if any(item.name == "f_pow" and simplify(item.children[1]-root) == zero for item in term):
|
143
|
-
return None
|
144
|
-
if vlist(equation) == []:
|
145
|
-
return None
|
146
|
-
v = vlist(equation)[0]
|
147
|
-
x = tree_form(v)
|
148
|
-
|
149
|
-
np = poly(n, v)
|
150
|
-
|
151
|
-
dp = poly(d, v)
|
152
|
-
|
153
|
-
if np is None or dp is None:
|
154
|
-
return None
|
155
|
-
|
156
|
-
if len(np) == 1 and len(dp) == 3:
|
157
|
-
k, a, b, c = np+dp
|
158
|
-
if a == zero:
|
159
|
-
return None
|
160
|
-
s1, s2 = sgn(a)
|
161
|
-
const = (four*a*c - b**two)/(four*a)
|
162
|
-
t1, t2 = sgn(const)
|
163
|
-
la = s2**root
|
164
|
-
lb = b*s2**root/(two*a)
|
165
|
-
|
166
|
-
if mode:
|
167
|
-
if s1 == one:
|
168
|
-
if t1 == one:
|
169
|
-
return k*((la*x+lb)/t2**root).fx("arctan")/(la * t2**root), logs
|
170
|
-
else:
|
171
|
-
return None
|
172
|
-
else:
|
173
|
-
if t1 == one:
|
174
|
-
return None
|
175
|
-
else:
|
176
|
-
_, t2 = sgn(-const)
|
177
|
-
return -k*((la*x+lb)/t2**root).fx("arctan")/(la * t2**root), logs
|
178
|
-
if s1 == one:
|
179
|
-
if t1 == one:
|
180
|
-
return simplify(k*(la*x + lb + ((la*x + lb)**two + t2)**root).fx("abs").fx("log")/la), logs
|
181
|
-
else:
|
182
|
-
return simplify(k*(la*x + lb + ((la*x + lb)**two - t2)**root).fx("abs").fx("log")/la), logs
|
183
|
-
|
184
|
-
else:
|
185
|
-
if t1 == one:
|
186
|
-
return k*((la*x + lb)/t2**root).fx("arcsin")/la, logs
|
187
|
-
else:
|
188
|
-
return None
|
189
|
-
if len(np) == 2 and len(dp) == 3:
|
190
|
-
|
191
|
-
p, q, a, b, c = np+dp
|
192
|
-
if a == zero:
|
193
|
-
return None
|
194
|
-
A = p/(two*a)
|
195
|
-
B = q - A*b
|
196
|
-
t = a*x**two + b*x + c
|
197
|
-
|
198
|
-
if not mode:
|
199
|
-
tmp = sqint(simplify(one/t**root), var, depth, inf)
|
200
|
-
if tmp is None:
|
201
|
-
tmp = integrate(simplify(one/t**root), var, depth, inf)
|
202
|
-
if tmp is None:
|
203
|
-
return None
|
204
|
-
log2 = tmp[1]
|
205
|
-
tmp = tmp[0]
|
206
|
-
|
207
|
-
else:
|
208
|
-
log2 = tmp[1]
|
209
|
-
tmp = tmp[0]
|
210
|
-
return A*two*t**root + tmp*B, logs+log2
|
211
|
-
else:
|
212
|
-
tmp = sqint(simplify(one/t), var, depth, inf)
|
213
|
-
if tmp is None:
|
214
|
-
tmp = integrate(simplify(one/t), var, depth, inf)
|
215
|
-
|
216
|
-
if tmp is None:
|
217
|
-
return None
|
218
|
-
log2 = tmp[1]
|
219
|
-
tmp = tmp[0]
|
220
|
-
|
221
|
-
else:
|
222
|
-
log2 = tmp[1]
|
223
|
-
tmp = tmp[0]
|
224
|
-
return A*t.fx("abs").fx("log") + tmp*B, logs+log2
|
225
|
-
return None
|
226
|
-
typeint = "integrate"
|
227
|
-
def typeintegrate():
|
228
|
-
global typeint
|
229
|
-
typeint= "integrate"
|
230
|
-
def typesqint():
|
231
|
-
global typeint
|
232
|
-
typeint= "sqint"
|
233
|
-
def typebyparts():
|
234
|
-
global typeint
|
235
|
-
typeint= "byparts"
|
236
|
-
def byparts(eq, wrt="v_0", tab=0, inf=0):
|
237
|
-
typebyparts()
|
238
|
-
out = rm_const(eq, wrt, tab, inf)
|
239
|
-
if out is not None:
|
240
|
-
return out
|
241
|
-
|
242
|
-
lst = factor_generation(eq)
|
243
|
-
for item in [tree_form("d_1"), diff(lst[0])]:
|
244
|
-
if len(lst) == 1:
|
245
|
-
lst += [item]
|
246
|
-
elif len(lst)==2 and item != 1:
|
247
|
-
break
|
248
|
-
if len(lst) == 2:
|
249
|
-
for i in range(2):
|
250
|
-
|
251
|
-
f, g = copy.deepcopy([lst[i], lst[1-i]])
|
252
|
-
|
253
|
-
logs = [(tab, f"trying integration by parts, f = {printeq_str(simplify(f))} and g = {printeq_str(simplify(g))}")]
|
254
|
-
typeintegrate()
|
255
|
-
out1 = integrate(copy.deepcopy(g), wrt, tab+1, inf)
|
256
|
-
typebyparts()
|
257
|
-
|
258
|
-
if out1 is None:
|
259
|
-
continue
|
260
|
-
|
261
|
-
typeintegrate()
|
262
|
-
out2 = integrate(simplify(diff(copy.deepcopy(f), wrt)*out1[0]), wrt, tab+1, inf)
|
263
|
-
|
264
|
-
typebyparts()
|
265
|
-
if out2 is None:
|
266
|
-
continue
|
267
|
-
|
268
|
-
return copy.deepcopy([simplify(copy.deepcopy(f) * out1[0] - out2[0]), logs+out1[1]+out2[1]])
|
269
|
-
return None
|
270
|
-
def integration_formula_init():
|
271
|
-
var = "x"
|
272
|
-
formula_list = [(f"(A*{var}+B)^C", f"(A*{var}+B)^(C+1)/(A*(C+1))"),\
|
273
|
-
(f"sin(A*{var}+B)", f"-cos(A*{var}+B)/A"),\
|
274
|
-
(f"cos(A*{var}+B)", f"sin(A*{var}+B)/A"),\
|
275
|
-
(f"1/(A*{var}+B)", f"log(abs(A*{var}+B))/A"),\
|
276
|
-
(f"e^(A*{var}+B)", f"e^(A*{var}+B)/A"),\
|
277
|
-
(f"abs(A*{var}+B)", f"(A*{var}+B)*abs(A*{var}+B)/(2*A)")]
|
278
|
-
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
279
|
-
expr = [[parse("A"), parse("1")], [parse("B"), parse("0")]]
|
280
|
-
return [formula_list, var, expr]
|
281
|
-
formula_gen = integration_formula_init()
|
282
|
-
|
283
|
-
def rm_const(equation, wrt="v_0", tab=0, inf=0, logs=[]):
|
284
|
-
lst = factor_generation(equation)
|
285
|
-
|
286
|
-
lst_const = [item for item in lst if not contain(item, tree_form(wrt))]
|
287
|
-
if lst_const != []:
|
288
|
-
equation = product([item for item in lst if contain(item, tree_form(wrt))])
|
289
|
-
const = product(lst_const)
|
290
|
-
const = simplify(const)
|
291
|
-
if const != 1 and not contain(const, tree_form("s_i")):
|
292
|
-
|
293
|
-
equation = simplify(equation)
|
294
|
-
out = None
|
295
|
-
if typeint == "byparts":
|
296
|
-
out = byparts(equation, wrt, tab+1, inf)
|
297
|
-
else:
|
298
|
-
out = integrate(equation, wrt, tab+1, inf)
|
299
|
-
if out is None:
|
300
|
-
return None
|
301
|
-
out = (out[0]*const, out[1])
|
302
|
-
return out[0], logs+\
|
303
|
-
[(tab, f"extracted the constant {printeq_str(simplify(const))}, now integrating the equation {printeq_str(simplify(equation))} only")]+out[1]+\
|
304
|
-
[(tab, f"result is {printeq_str(simplify(out[0]))}")]
|
305
|
-
return None
|
306
|
-
def integrate(equation, wrt="v_0", tab=0, inf=0):
|
307
|
-
|
308
|
-
global formula_list, var, expr
|
309
|
-
global typeint
|
310
|
-
|
311
|
-
equation = simplify(equation)
|
312
|
-
|
313
|
-
logs = []
|
314
|
-
if tab == 0:
|
315
|
-
logs += [(tab, f"the given question is to integrate {printeq_str(simplify(equation))} wrt to {str(tree_form(wrt))}")]
|
316
|
-
|
317
|
-
if equation == tree_form(wrt):
|
318
|
-
return equation**2/2,[]
|
319
|
-
if not contain(equation,tree_form(wrt)):
|
320
|
-
return tree_form(wrt)*equation,logs
|
321
|
-
out = transform_formula(equation, wrt, formula_gen[0], formula_gen[1], formula_gen[2])
|
322
|
-
if out is not None:
|
323
|
-
return out, logs
|
324
|
-
|
325
|
-
out = rm_const(equation, wrt, tab, inf, logs)
|
326
|
-
if out is not None:
|
327
|
-
return out
|
328
|
-
out = integrate_summation(equation, wrt, tab, inf)
|
329
|
-
if out is not None:
|
330
|
-
return out[0], logs+out[1]+[(tab, f"result is {printeq_str(simplify(out[0]))}")]
|
331
|
-
out = None
|
332
|
-
if typeint in ["sqint"]:
|
333
|
-
out = sqint(equation, wrt, tab+1, inf)
|
334
|
-
if out is not None:
|
335
|
-
return out[0], logs+out[1]+[(tab, f"result is {printeq_str(simplify(out[0]))}")]
|
336
|
-
if typeint in ["byparts", "integrate"]:
|
337
|
-
if inf==0:
|
338
|
-
out = integrate_subs_main(equation, wrt, tab, inf+1)
|
339
|
-
if out is not None:
|
340
|
-
return out[0], logs+out[1]+[(tab, f"result is {printeq_str(simplify(out[0]))}")]
|
341
|
-
if typeint == "byparts":
|
342
|
-
|
343
|
-
out = byparts(copy.deepcopy(equation), wrt, tab, inf)
|
344
|
-
if out is not None:
|
345
|
-
return out[0], logs+out[1]+[(tab, f"result is {printeq_str(simplify(out[0]))}")]
|
346
|
-
return None
|
1
|
+
from .parser import parse
|
2
|
+
import itertools
|
3
|
+
from .diff import diff
|
4
|
+
from .fraction import fraction
|
5
|
+
from .simplify import solve, simplify
|
6
|
+
from .expand import expand
|
7
|
+
from .base import *
|
8
|
+
from .printeq import printeq_str
|
9
|
+
from .structure import transform_formula
|
10
|
+
from .inverse import inverse
|
11
|
+
from .tool import poly
|
12
|
+
from fractions import Fraction
|
13
|
+
from .printeq import printeq
|
14
|
+
def integrate_summation(equation, wrt, tab, inf):
|
15
|
+
logs= []
|
16
|
+
orig = copy.deepcopy(equation)
|
17
|
+
for i in range(2):
|
18
|
+
|
19
|
+
if equation.name == "f_add":
|
20
|
+
logs += [(tab, f"by integration over sums {', '.join([printeq_str(simplify(child)) for child in equation.children])}")]
|
21
|
+
answer = []
|
22
|
+
for child in equation.children:
|
23
|
+
out = integrate(child, wrt, tab+1, inf)
|
24
|
+
if out is None:
|
25
|
+
return None
|
26
|
+
logs += out[1]
|
27
|
+
answer.append(out[0])
|
28
|
+
return summation(answer), logs
|
29
|
+
if i == 0:
|
30
|
+
|
31
|
+
tmp = expand(simplify(fraction(simplify(equation))))
|
32
|
+
|
33
|
+
logs += [(tab, f"integrating {printeq_str(simplify(equation))} will be the same thing as integrating {printeq_str(simplify(tmp))}")]
|
34
|
+
|
35
|
+
equation = tmp
|
36
|
+
if equation.name != "f_add" and orig != equation:
|
37
|
+
out = integrate(equation, wrt, tab+1, inf)
|
38
|
+
if out is None:
|
39
|
+
return None
|
40
|
+
return out[0], logs+out[1]
|
41
|
+
return None
|
42
|
+
|
43
|
+
def subs_heuristic(eq, var):
|
44
|
+
output = []
|
45
|
+
def collect2(eq):
|
46
|
+
if eq.name == "f_pow" and frac(eq.children[1]) is not None and abs(frac(eq.children[1])) == Fraction(1,2):
|
47
|
+
output.append(str_form(eq.children[0].fx("sqrt")))
|
48
|
+
if eq.name in ["f_pow", "f_sin", "f_cos", "f_arcsin"] and eq.children[0].name[:2] != "v_" and var in str_form(eq.children[0]):
|
49
|
+
output.append(str_form(eq.children[0]))
|
50
|
+
if eq.name == "f_pow" and eq.children[0].name == "s_e" and "v_" in str_form(eq):
|
51
|
+
if eq.children[1].name[:2] != "v_":
|
52
|
+
output.append(str_form(eq.children[1]))
|
53
|
+
output.append(str_form(eq))
|
54
|
+
|
55
|
+
for child in eq.children:
|
56
|
+
collect2(child)
|
57
|
+
def collect3(eq):
|
58
|
+
if eq.name in ["f_sin", "f_cos"]:
|
59
|
+
output.append(str_form(eq.children[0].fx("cos")))
|
60
|
+
for child in eq.children:
|
61
|
+
collect3(child)
|
62
|
+
collect2(eq)
|
63
|
+
if output == []:
|
64
|
+
collect3(eq)
|
65
|
+
tmp = sorted(output, key=lambda x: len(x))
|
66
|
+
tmp = [simplify(tree_form(x)) for x in tmp]
|
67
|
+
|
68
|
+
return tmp
|
69
|
+
|
70
|
+
def integrate_subs(equation, term, v1, v2, tab, inf):
|
71
|
+
|
72
|
+
origv2 = copy.deepcopy(v2)
|
73
|
+
equation = solve(equation)
|
74
|
+
eq = equation
|
75
|
+
termeq = term
|
76
|
+
t = inverse(copy.deepcopy(termeq), v1)
|
77
|
+
g = inverse(termeq, v2)
|
78
|
+
|
79
|
+
if g is None:
|
80
|
+
return None
|
81
|
+
if t is None:
|
82
|
+
return None
|
83
|
+
else:
|
84
|
+
t = expand(t)
|
85
|
+
eq = replace(eq, tree_form(v1), t)
|
86
|
+
|
87
|
+
eq2 = replace(diff(g, v1), tree_form(v1), t)
|
88
|
+
equation = eq/eq2
|
89
|
+
equation = solve(equation)
|
90
|
+
|
91
|
+
lst = [ equation]
|
92
|
+
for eq in lst:
|
93
|
+
if v1 in str_form(eq):
|
94
|
+
continue
|
95
|
+
|
96
|
+
eq = expand(simplify(eq))
|
97
|
+
|
98
|
+
out = integrate(eq, origv2, tab+1, inf)
|
99
|
+
|
100
|
+
if out is None:
|
101
|
+
continue
|
102
|
+
tmp, logs = out
|
103
|
+
tmp = replace(tmp, tree_form(v2), g)
|
104
|
+
return tmp, [(tab, f"substituted {str(tree_form(origv2))}={printeq_str(simplify(g))}, integrating {printeq_str(simplify(eq))} wrt {str(tree_form(origv2))}")]+logs+\
|
105
|
+
[(tab, f"substituting back to {printeq_str(simplify(out[0]))} which is the result after integration")]
|
106
|
+
return None
|
107
|
+
|
108
|
+
def integrate_subs_main(equation, wrt, tab, inf):
|
109
|
+
v2 = "v_"+str(int(wrt[2:])+1)
|
110
|
+
for item in subs_heuristic(equation, wrt):
|
111
|
+
x = tree_form(v2)-item
|
112
|
+
|
113
|
+
tmp3 = integrate_subs(equation, x, wrt, v2, tab, inf)
|
114
|
+
|
115
|
+
if tmp3 is not None:
|
116
|
+
return tmp3[0], tmp3[1]
|
117
|
+
return None
|
118
|
+
def sqint(equation, var="v_0", depth=0, inf=0):
|
119
|
+
typeint = "sqint"
|
120
|
+
logs = []
|
121
|
+
def sgn(eq):
|
122
|
+
if compute(eq) <0:
|
123
|
+
return tree_form("d_-1"), tree_form("d_-1")*eq
|
124
|
+
return tree_form("d_1"), eq
|
125
|
+
one = tree_form("d_1")
|
126
|
+
two = tree_form("d_2")
|
127
|
+
four = tree_form("d_4")
|
128
|
+
three = tree_form("d_3")
|
129
|
+
root = tree_form("d_2")**-1
|
130
|
+
zero = tree_form("d_0")
|
131
|
+
|
132
|
+
n, d = num_dem(equation)
|
133
|
+
n, d = simplify(n), simplify(d)
|
134
|
+
term = [simplify(x) for x in factor_generation(d)]
|
135
|
+
const = product([item for item in term if "v_" not in str_form(item)])
|
136
|
+
term = [item for item in term if "v_" in str_form(item)]
|
137
|
+
mode = False
|
138
|
+
if all(item.name == "f_pow" and simplify(item.children[1]-root) == zero for item in term):
|
139
|
+
d = simplify(expand(const**two*product([item.children[0] for item in term])))
|
140
|
+
else:
|
141
|
+
mode = True
|
142
|
+
if any(item.name == "f_pow" and simplify(item.children[1]-root) == zero for item in term):
|
143
|
+
return None
|
144
|
+
if vlist(equation) == []:
|
145
|
+
return None
|
146
|
+
v = vlist(equation)[0]
|
147
|
+
x = tree_form(v)
|
148
|
+
|
149
|
+
np = poly(n, v)
|
150
|
+
|
151
|
+
dp = poly(d, v)
|
152
|
+
|
153
|
+
if np is None or dp is None:
|
154
|
+
return None
|
155
|
+
|
156
|
+
if len(np) == 1 and len(dp) == 3:
|
157
|
+
k, a, b, c = np+dp
|
158
|
+
if a == zero:
|
159
|
+
return None
|
160
|
+
s1, s2 = sgn(a)
|
161
|
+
const = (four*a*c - b**two)/(four*a)
|
162
|
+
t1, t2 = sgn(const)
|
163
|
+
la = s2**root
|
164
|
+
lb = b*s2**root/(two*a)
|
165
|
+
|
166
|
+
if mode:
|
167
|
+
if s1 == one:
|
168
|
+
if t1 == one:
|
169
|
+
return k*((la*x+lb)/t2**root).fx("arctan")/(la * t2**root), logs
|
170
|
+
else:
|
171
|
+
return None
|
172
|
+
else:
|
173
|
+
if t1 == one:
|
174
|
+
return None
|
175
|
+
else:
|
176
|
+
_, t2 = sgn(-const)
|
177
|
+
return -k*((la*x+lb)/t2**root).fx("arctan")/(la * t2**root), logs
|
178
|
+
if s1 == one:
|
179
|
+
if t1 == one:
|
180
|
+
return simplify(k*(la*x + lb + ((la*x + lb)**two + t2)**root).fx("abs").fx("log")/la), logs
|
181
|
+
else:
|
182
|
+
return simplify(k*(la*x + lb + ((la*x + lb)**two - t2)**root).fx("abs").fx("log")/la), logs
|
183
|
+
|
184
|
+
else:
|
185
|
+
if t1 == one:
|
186
|
+
return k*((la*x + lb)/t2**root).fx("arcsin")/la, logs
|
187
|
+
else:
|
188
|
+
return None
|
189
|
+
if len(np) == 2 and len(dp) == 3:
|
190
|
+
|
191
|
+
p, q, a, b, c = np+dp
|
192
|
+
if a == zero:
|
193
|
+
return None
|
194
|
+
A = p/(two*a)
|
195
|
+
B = q - A*b
|
196
|
+
t = a*x**two + b*x + c
|
197
|
+
|
198
|
+
if not mode:
|
199
|
+
tmp = sqint(simplify(one/t**root), var, depth, inf)
|
200
|
+
if tmp is None:
|
201
|
+
tmp = integrate(simplify(one/t**root), var, depth, inf)
|
202
|
+
if tmp is None:
|
203
|
+
return None
|
204
|
+
log2 = tmp[1]
|
205
|
+
tmp = tmp[0]
|
206
|
+
|
207
|
+
else:
|
208
|
+
log2 = tmp[1]
|
209
|
+
tmp = tmp[0]
|
210
|
+
return A*two*t**root + tmp*B, logs+log2
|
211
|
+
else:
|
212
|
+
tmp = sqint(simplify(one/t), var, depth, inf)
|
213
|
+
if tmp is None:
|
214
|
+
tmp = integrate(simplify(one/t), var, depth, inf)
|
215
|
+
|
216
|
+
if tmp is None:
|
217
|
+
return None
|
218
|
+
log2 = tmp[1]
|
219
|
+
tmp = tmp[0]
|
220
|
+
|
221
|
+
else:
|
222
|
+
log2 = tmp[1]
|
223
|
+
tmp = tmp[0]
|
224
|
+
return A*t.fx("abs").fx("log") + tmp*B, logs+log2
|
225
|
+
return None
|
226
|
+
typeint = "integrate"
|
227
|
+
def typeintegrate():
|
228
|
+
global typeint
|
229
|
+
typeint= "integrate"
|
230
|
+
def typesqint():
|
231
|
+
global typeint
|
232
|
+
typeint= "sqint"
|
233
|
+
def typebyparts():
|
234
|
+
global typeint
|
235
|
+
typeint= "byparts"
|
236
|
+
def byparts(eq, wrt="v_0", tab=0, inf=0):
|
237
|
+
typebyparts()
|
238
|
+
out = rm_const(eq, wrt, tab, inf)
|
239
|
+
if out is not None:
|
240
|
+
return out
|
241
|
+
|
242
|
+
lst = factor_generation(eq)
|
243
|
+
for item in [tree_form("d_1"), diff(lst[0])]:
|
244
|
+
if len(lst) == 1:
|
245
|
+
lst += [item]
|
246
|
+
elif len(lst)==2 and item != 1:
|
247
|
+
break
|
248
|
+
if len(lst) == 2:
|
249
|
+
for i in range(2):
|
250
|
+
|
251
|
+
f, g = copy.deepcopy([lst[i], lst[1-i]])
|
252
|
+
|
253
|
+
logs = [(tab, f"trying integration by parts, f = {printeq_str(simplify(f))} and g = {printeq_str(simplify(g))}")]
|
254
|
+
typeintegrate()
|
255
|
+
out1 = integrate(copy.deepcopy(g), wrt, tab+1, inf)
|
256
|
+
typebyparts()
|
257
|
+
|
258
|
+
if out1 is None:
|
259
|
+
continue
|
260
|
+
|
261
|
+
typeintegrate()
|
262
|
+
out2 = integrate(simplify(diff(copy.deepcopy(f), wrt)*out1[0]), wrt, tab+1, inf)
|
263
|
+
|
264
|
+
typebyparts()
|
265
|
+
if out2 is None:
|
266
|
+
continue
|
267
|
+
|
268
|
+
return copy.deepcopy([simplify(copy.deepcopy(f) * out1[0] - out2[0]), logs+out1[1]+out2[1]])
|
269
|
+
return None
|
270
|
+
def integration_formula_init():
|
271
|
+
var = "x"
|
272
|
+
formula_list = [(f"(A*{var}+B)^C", f"(A*{var}+B)^(C+1)/(A*(C+1))"),\
|
273
|
+
(f"sin(A*{var}+B)", f"-cos(A*{var}+B)/A"),\
|
274
|
+
(f"cos(A*{var}+B)", f"sin(A*{var}+B)/A"),\
|
275
|
+
(f"1/(A*{var}+B)", f"log(abs(A*{var}+B))/A"),\
|
276
|
+
(f"e^(A*{var}+B)", f"e^(A*{var}+B)/A"),\
|
277
|
+
(f"abs(A*{var}+B)", f"(A*{var}+B)*abs(A*{var}+B)/(2*A)")]
|
278
|
+
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
279
|
+
expr = [[parse("A"), parse("1")], [parse("B"), parse("0")]]
|
280
|
+
return [formula_list, var, expr]
|
281
|
+
formula_gen = integration_formula_init()
|
282
|
+
|
283
|
+
def rm_const(equation, wrt="v_0", tab=0, inf=0, logs=[]):
|
284
|
+
lst = factor_generation(equation)
|
285
|
+
|
286
|
+
lst_const = [item for item in lst if not contain(item, tree_form(wrt))]
|
287
|
+
if lst_const != []:
|
288
|
+
equation = product([item for item in lst if contain(item, tree_form(wrt))])
|
289
|
+
const = product(lst_const)
|
290
|
+
const = simplify(const)
|
291
|
+
if const != 1 and not contain(const, tree_form("s_i")):
|
292
|
+
|
293
|
+
equation = simplify(equation)
|
294
|
+
out = None
|
295
|
+
if typeint == "byparts":
|
296
|
+
out = byparts(equation, wrt, tab+1, inf)
|
297
|
+
else:
|
298
|
+
out = integrate(equation, wrt, tab+1, inf)
|
299
|
+
if out is None:
|
300
|
+
return None
|
301
|
+
out = (out[0]*const, out[1])
|
302
|
+
return out[0], logs+\
|
303
|
+
[(tab, f"extracted the constant {printeq_str(simplify(const))}, now integrating the equation {printeq_str(simplify(equation))} only")]+out[1]+\
|
304
|
+
[(tab, f"result is {printeq_str(simplify(out[0]))}")]
|
305
|
+
return None
|
306
|
+
def integrate(equation, wrt="v_0", tab=0, inf=0):
|
307
|
+
|
308
|
+
global formula_list, var, expr
|
309
|
+
global typeint
|
310
|
+
|
311
|
+
equation = simplify(equation)
|
312
|
+
|
313
|
+
logs = []
|
314
|
+
if tab == 0:
|
315
|
+
logs += [(tab, f"the given question is to integrate {printeq_str(simplify(equation))} wrt to {str(tree_form(wrt))}")]
|
316
|
+
|
317
|
+
if equation == tree_form(wrt):
|
318
|
+
return equation**2/2,[]
|
319
|
+
if not contain(equation,tree_form(wrt)):
|
320
|
+
return tree_form(wrt)*equation,logs
|
321
|
+
out = transform_formula(equation, wrt, formula_gen[0], formula_gen[1], formula_gen[2])
|
322
|
+
if out is not None:
|
323
|
+
return out, logs
|
324
|
+
|
325
|
+
out = rm_const(equation, wrt, tab, inf, logs)
|
326
|
+
if out is not None:
|
327
|
+
return out
|
328
|
+
out = integrate_summation(equation, wrt, tab, inf)
|
329
|
+
if out is not None:
|
330
|
+
return out[0], logs+out[1]+[(tab, f"result is {printeq_str(simplify(out[0]))}")]
|
331
|
+
out = None
|
332
|
+
if typeint in ["sqint"]:
|
333
|
+
out = sqint(equation, wrt, tab+1, inf)
|
334
|
+
if out is not None:
|
335
|
+
return out[0], logs+out[1]+[(tab, f"result is {printeq_str(simplify(out[0]))}")]
|
336
|
+
if typeint in ["byparts", "integrate"]:
|
337
|
+
if inf==0:
|
338
|
+
out = integrate_subs_main(equation, wrt, tab, inf+1)
|
339
|
+
if out is not None:
|
340
|
+
return out[0], logs+out[1]+[(tab, f"result is {printeq_str(simplify(out[0]))}")]
|
341
|
+
if typeint == "byparts":
|
342
|
+
|
343
|
+
out = byparts(copy.deepcopy(equation), wrt, tab, inf)
|
344
|
+
if out is not None:
|
345
|
+
return out[0], logs+out[1]+[(tab, f"result is {printeq_str(simplify(out[0]))}")]
|
346
|
+
return None
|