mathai 0.2.8__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/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