mathai 0.6.0__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 ADDED
@@ -0,0 +1,459 @@
1
+ from .factor import factor2
2
+ from .parser import parse
3
+ import itertools
4
+ from .diff import diff
5
+ from .fraction import fraction
6
+ from .simplify import simplify
7
+ from .expand import expand
8
+ from .base import *
9
+ from .printeq import printeq_str
10
+ from .structure import transform_formula
11
+ from .inverse import inverse
12
+ from .tool import poly
13
+ from fractions import Fraction
14
+ from .printeq import printeq
15
+ from .trig import trig0, trig2, trig3, trig4
16
+ from .apart import apart
17
+
18
+ def integrate_summation(equation):
19
+ if equation.name == "f_ref":
20
+ return equation
21
+
22
+ eq2 = equation
23
+ if eq2.name == "f_integrate":
24
+ equation = eq2.children[0]
25
+ wrt = eq2.children[1]
26
+ if equation.name == "f_add":
27
+ return summation([TreeNode("f_integrate", [child, wrt]) for child in equation.children])
28
+ equation = eq2
29
+
30
+ return TreeNode(equation.name, [integrate_summation(child) for child in equation.children])
31
+ def subs_heuristic(eq, var):
32
+ output = []
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))
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:
39
+ if len(eq.children[0].children) == 0 or eq.children[0].children[0] == var:
40
+ output.append(str_form(eq.children[0]**2))
41
+ if eq.name in ["f_pow", "f_sin", "f_cos", "f_arcsin"] and var.name in str_form(eq.children[0]):
42
+ if eq.children[0].name[:2] != "v_":
43
+ output.append(str_form(eq.children[0]))
44
+ if eq.name in ["f_sin", "f_cos"]:
45
+ output.append(str_form(eq))
46
+ if eq.name == "f_pow" and eq.children[0].name == "s_e" and "v_" in str_form(eq):
47
+ if eq.children[1].name[:2] != "v_":
48
+ output.append(str_form(eq.children[1]))
49
+ output.append(str_form(eq))
50
+ for child in eq.children:
51
+ collect2(child)
52
+ def collect3(eq):
53
+ if eq.name in ["f_sin", "f_cos"]:
54
+ output.append(str_form(eq.children[0].fx("cos")))
55
+ for child in eq.children:
56
+ collect3(child)
57
+ collect2(eq)
58
+
59
+ if output == []:
60
+ collect3(eq)
61
+
62
+
63
+ tmp = list(set([simplify(tree_form(x)) for x in output]))
64
+ tmp = sorted(tmp, key=lambda x: len(str(x)))
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
79
+ try_index = []
80
+ try_lst = []
81
+ def ref(eq):
82
+ '''
83
+ if eq.name in ["f_try", "f_ref"]:
84
+ return eq
85
+ '''
86
+ if eq.name == "f_integrate":
87
+ return TreeNode("f_try", [eq.fx("ref"), eq])
88
+ return TreeNode(eq.name, [ref(child) for child in eq.children])
89
+ def place_try(eq):
90
+ global try_index
91
+ if eq.name == "f_try":
92
+ try_index.append(list(range(len(eq.children))))
93
+ return TreeNode(eq.name, [place_try(child) for child in eq.children])
94
+ def place_try2(eq):
95
+ global try_lst
96
+ if eq.name == "f_try":
97
+ return eq.children[try_lst.pop(0)]
98
+ return TreeNode(eq.name, [place_try2(child) for child in eq.children])
99
+ def _solve_integrate(eq):
100
+ if eq.name == "f_ref":
101
+ return eq
102
+ if eq.name == "f_subs":
103
+ if all(item not in str_form(eq.children[0]) for item in ["f_integrate", "f_subs", "f_try"]):
104
+ return replace(eq.children[0], eq.children[1], eq.children[2])
105
+
106
+ if eq.name == "f_try":
107
+ for child in eq.children:
108
+ if all(item not in str_form(child) for item in ["f_integrate", "f_subs", "f_try"]):
109
+ return child
110
+ return TreeNode(eq.name, [_solve_integrate(child) for child in eq.children])
111
+ def handle_try(eq):
112
+ global try_lst, try_index
113
+ if eq.name == "f_try":
114
+ try_lst = []
115
+ try_index = []
116
+ for child in eq.children:
117
+ place_try(child)
118
+ output = []
119
+ for item in itertools.product(*try_index):
120
+ try_lst = list(item)
121
+ output += [place_try2(child) for child in eq.children]
122
+
123
+ return TreeNode("f_try", output)
124
+ else:
125
+ return TreeNode(eq.name, [handle_try(child) for child in eq.children])
126
+ def inteq(eq):
127
+ if eq.name == "f_try":
128
+ eq2 = None
129
+ output = []
130
+ for child in eq.children:
131
+ if child.name == "f_ref":
132
+ eq2 = child.children[0]
133
+ break
134
+ if eq2 is None:
135
+ return eq
136
+ printeq(eq)
137
+ for child in eq.children:
138
+ if child.name == "f_ref":
139
+ output.append(child)
140
+ else:
141
+ eq3 = simplify(expand(simplify(eq2 - child)))
142
+ if contain(eq3, eq2):
143
+ out = inverse(eq3, str_form(eq2))
144
+ if out is None:
145
+ output.append(child)
146
+ else:
147
+ output.append(out)
148
+ else:
149
+ output.append(child)
150
+ printeq(TreeNode("f_try", output))
151
+ print()
152
+ return TreeNode("f_try", output)
153
+ else:
154
+ return TreeNode(eq.name, [inteq(child) for child in eq.children])
155
+ def rm(eq):
156
+ if eq.name == "f_try":
157
+ eq = TreeNode(eq.name, list(set(eq.children)))
158
+ return TreeNode(eq.name, [rm(child) for child in eq.children if child is not None])
159
+ def solve_integrate(eq):
160
+
161
+ eq2 = dowhile(eq, _solve_integrate)
162
+ eq2 = dowhile(eq2, handle_try)
163
+ eq2 = rm(eq2)
164
+ if eq2.name == "f_try":
165
+ eq2.children = list(set(eq2.children))
166
+ return eq2
167
+ def integrate_subs(equation, term, v1, v2):
168
+ output = []
169
+ orig = equation.copy_tree()
170
+ none = TreeNode("f_integrate",[orig, tree_form(v1)])
171
+ origv2 = copy.deepcopy(v2)
172
+ equation = simplify(equation)
173
+ eq = equation
174
+ termeq = term
175
+ t = inverse(copy.deepcopy(termeq), v1)
176
+
177
+ g = inverse(termeq, v2)
178
+
179
+ if g is None:
180
+ return none
181
+ if t is None:
182
+ return none
183
+ else:
184
+
185
+ t = expand(t)
186
+ eq = replace(eq, tree_form(v1), t)
187
+
188
+ eq2 = replace(diff(g, v1), tree_form(v1), t)
189
+ equation = eq/eq2
190
+ equation = simplify(equation)
191
+
192
+ if v1 in str_form(equation):
193
+
194
+ return none
195
+
196
+ return dowhile(TreeNode("f_subs", [TreeNode("f_integrate", [simplify(equation), tree_form(origv2)]),tree_form(origv2) ,g]), trig0)
197
+
198
+ def integrate_subs_main(equation):
199
+ if equation.name == "f_ref":
200
+ return equation
201
+ eq2 = equation
202
+ if eq2.name == "f_integrate":
203
+ output = [eq2]
204
+ wrt = eq2.children[1]
205
+ eq = equation.children[0]
206
+ v2 = "v_"+str(int(wrt.name[2:])+1)
207
+ for item in subs_heuristic(eq, wrt):
208
+ x = tree_form(v2)-item
209
+ output.append(integrate_subs(eq, x, wrt.name, v2))
210
+ output = list(set(output))
211
+ if len(output) == 1:
212
+ return output[0]
213
+
214
+ return TreeNode("f_try", [item.copy_tree() for item in output])
215
+ else:
216
+ return TreeNode(equation.name, [integrate_subs_main(child) for child in equation.children])
217
+
218
+ def _sqint(equation):
219
+ def sgn(eq):
220
+ if compute(eq) <0:
221
+ return tree_form("d_-1"), tree_form("d_-1")*eq
222
+ return tree_form("d_1"), eq
223
+ eq2 = equation
224
+ if eq2.name == "f_integrate":
225
+ equation = eq2.children[0]
226
+ var = eq2.children[1]
227
+
228
+ one = tree_form("d_1")
229
+ two = tree_form("d_2")
230
+ four = tree_form("d_4")
231
+ three = tree_form("d_3")
232
+ root = tree_form("d_2")**-1
233
+ zero = tree_form("d_0")
234
+
235
+ n, d = num_dem(equation)
236
+ n, d = simplify(n), simplify(d)
237
+ term = [simplify(x) for x in factor_generation(d)]
238
+ const = product([item for item in term if "v_" not in str_form(item)])
239
+ term = [item for item in term if "v_" in str_form(item)]
240
+ mode = False
241
+ if all(item.name == "f_pow" and simplify(item.children[1]-root) == zero for item in term):
242
+ d = simplify(expand(const**two*product([item.children[0] for item in term])))
243
+ else:
244
+ mode = True
245
+ if any(item.name == "f_pow" and simplify(item.children[1]-root) == zero for item in term):
246
+ return None
247
+ if vlist(equation) == []:
248
+ return None
249
+ v = vlist(equation)[0]
250
+ x = tree_form(v)
251
+
252
+ np = poly(n, v)
253
+
254
+ dp = poly(d, v)
255
+
256
+ if np is None or dp is None:
257
+ return None
258
+
259
+ if len(np) == 1 and len(dp) == 3:
260
+ k, a, b, c = np+dp
261
+ if a == zero:
262
+ return None
263
+ s1, s2 = sgn(a)
264
+ const = (four*a*c - b**two)/(four*a)
265
+ t1, t2 = sgn(const)
266
+ la = s2**root
267
+ lb = b*s2**root/(two*a)
268
+
269
+ if mode:
270
+ if s1 == one:
271
+ if t1 == one:
272
+ return k*((la*x+lb)/t2**root).fx("arctan")/(la * t2**root)
273
+ else:
274
+ return None
275
+ else:
276
+ if t1 == one:
277
+ return None
278
+ else:
279
+ _, t2 = sgn(-const)
280
+ return -k*((la*x+lb)/t2**root).fx("arctan")/(la * t2**root)
281
+ if s1 == one:
282
+ if t1 == one:
283
+ return simplify(k*(la*x + lb + ((la*x + lb)**two + t2)**root).fx("abs").fx("log")/la)
284
+ else:
285
+ return simplify(k*(la*x + lb + ((la*x + lb)**two - t2)**root).fx("abs").fx("log")/la)
286
+
287
+ else:
288
+ if t1 == one:
289
+ return k*((la*x + lb)/t2**root).fx("arcsin")/la
290
+ else:
291
+ return None
292
+ if len(np) == 2 and len(dp) == 3:
293
+
294
+ p, q, a, b, c = np+dp
295
+ if a == zero:
296
+ return None
297
+ A = p/(two*a)
298
+ B = q - A*b
299
+ t = a*x**two + b*x + c
300
+
301
+ if not mode:
302
+ tmp = _sqint(TreeNode("f_integrate", [simplify(one/t**root), var]))
303
+ if tmp is None:
304
+ tmp = TreeNode("f_integrate", [simplify(one/t**root), var])
305
+ return A*two*t**root + tmp*B
306
+ else:
307
+ tmp = _sqint(TreeNode("f_integrate", [simplify(one/t), var]))
308
+ if tmp is None:
309
+ tmp = TreeNode("f_integrate", [simplify(one/t), var])
310
+ return A*t.fx("abs").fx("log") + tmp*B
311
+ equation = eq2
312
+ coll = TreeNode(equation.name, [])
313
+ for child in equation.children:
314
+ out = _sqint(child)
315
+ if out is None:
316
+ coll.children.append(child)
317
+ else:
318
+ coll.children.append(out)
319
+ return coll
320
+
321
+ def sqint(eq):
322
+ out = simplify(_sqint(eq))
323
+ if out is None:
324
+ return eq
325
+ return out
326
+
327
+ def byparts(eq):
328
+ if eq.name == "f_ref":
329
+ return eq
330
+ eq2 = eq
331
+ if eq2.name == "f_integrate":
332
+ output = []
333
+ eq = eq2.children[0]
334
+ wrt = eq2.children[1]
335
+ lst = factor_generation(eq)
336
+ if len(lst) == 3 and len(list(set(lst))) == 1:
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()]
344
+ if len(lst) == 1:
345
+ lst += [tree_form("d_1")]
346
+ if len(lst) == 2:
347
+ for i in range(2):
348
+
349
+ f, g = [lst[i], lst[1-i]]
350
+ if contain(f, tree_form("s_e")):
351
+ continue
352
+ out1 = TreeNode("f_integrate", [g.copy_tree(), wrt])
353
+
354
+
355
+ out2 = TreeNode("f_integrate", [simplify(diff(f.copy_tree(), wrt.name)*out1), wrt])
356
+
357
+ output.append(simplify(f.copy_tree() * out1 - out2))
358
+ if len(output) == 0:
359
+ pass
360
+ elif len(output) == 1:
361
+ return output[0]
362
+ else:
363
+ return TreeNode("f_try", output)
364
+ eq = eq2
365
+ return TreeNode(eq.name, [byparts(child) for child in eq.children])
366
+
367
+ def integration_formula_init():
368
+ var = "x"
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
+ ]
380
+ formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
381
+ expr = [[parse("A"), parse("1")], [parse("B"), parse("0")]]
382
+ return [formula_list, var, expr]
383
+ formula_gen = integration_formula_init()
384
+ def integration_formula_trig():
385
+ var = "x"
386
+ 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}))")]
387
+ formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
388
+ expr = [[parse("A"), parse("0"), parse("1")], [parse("B"), parse("0"), parse("1")],\
389
+ [parse("C"), parse("0"), parse("1")], [parse("D"), parse("0"), parse("1")],\
390
+ [parse("E"), parse("0"), parse("1")], [parse("F"), parse("0"), parse("1")]]
391
+ return [formula_list, var, expr]
392
+ formula_gen4 = integration_formula_trig()
393
+
394
+ def integration_formula_ex():
395
+ var = "x"
396
+ formula_list = [
397
+ (
398
+ f"e^(A*{var})*cos(B*{var})",
399
+ f"e^(A*{var})*(A*cos(B*{var}) + B*sin(B*{var}))/(A^2 + B^2)"
400
+ )
401
+ ]
402
+ formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
403
+ expr = [[parse("A"), parse("1")], [parse("B"), parse("1")]]
404
+ return [formula_list, var, expr]
405
+
406
+ formula_gen11 = integration_formula_ex()
407
+ def rm_const(equation):
408
+ if equation.name == "f_ref":
409
+ return equation
410
+ eq2 = equation
411
+ if eq2.name == "f_integrate" and contain(eq2.children[0], eq2.children[1]):
412
+ equation = eq2.children[0]
413
+ wrt = eq2.children[1]
414
+
415
+ lst = factor_generation(equation)
416
+
417
+ lst_const = [item for item in lst if not contain(item, wrt)]
418
+ if lst_const != []:
419
+
420
+ equation = product([item for item in lst if contain(item, wrt)]).copy_tree()
421
+ const = product(lst_const)
422
+ const = simplify(const)
423
+
424
+ if not contain(const, tree_form("s_i")):
425
+
426
+ return rm_const(TreeNode("f_integrate",[equation, wrt])) *const
427
+ equation = eq2
428
+ return TreeNode(equation.name, [rm_const(child) for child in equation.children])
429
+
430
+ def shorten(eq):
431
+ if eq.name.startswith("d_"):
432
+ return tree_form("d_0")
433
+ return TreeNode(eq.name, [shorten(child) for child in eq.children])
434
+ def integrate_formula(equation):
435
+ if equation.name == "f_ref":
436
+ return equation.copy_tree()
437
+ eq2 = equation.copy_tree()
438
+ if eq2.name == "f_integrate":
439
+ integrand = eq2.children[0]
440
+ wrt = eq2.children[1]
441
+ if integrand == wrt:
442
+ return wrt**2/2 # x^2/2
443
+ if not contain(integrand, wrt):
444
+ return integrand*wrt
445
+ out = transform_formula(simplify(trig0(integrand)), wrt.name, formula_gen[0], formula_gen[1], formula_gen[2])
446
+ if out is not None:
447
+
448
+ return out
449
+ expr_str = str_form(shorten(integrand))
450
+ if len(expr_str) < 30:
451
+ if expr_str.count("f_sin") + expr_str.count("f_cos") > 2:
452
+ out = transform_formula(integrand, wrt.name, formula_gen4[0], formula_gen4[1], formula_gen4[2])
453
+ if out is not None:
454
+ return out
455
+ if "f_cos" in expr_str and contain(integrand, tree_form("s_e")):
456
+ out = transform_formula(integrand, wrt.name, formula_gen11[0], formula_gen11[1], formula_gen11[2])
457
+ if out is not None:
458
+ return out
459
+ return TreeNode(eq2.name, [integrate_formula(child) for child in eq2.children])
mathai/inverse.py ADDED
@@ -0,0 +1,65 @@
1
+ from .base import *
2
+ from .simplify import simplify
3
+ from .expand import expand
4
+ def inverse(rhs,term, sign=None):
5
+ term = tree_form(term)
6
+ lhs = tree_form("d_0")
7
+ count = 15
8
+
9
+ while not rhs==term:
10
+ if rhs.name == "f_add":
11
+ if all(term in factor_generation(child) for child in rhs.children):
12
+ newrhs = simplify(expand(rhs*term**-1))
13
+ if not contain(newrhs, term):
14
+ rhs = term * newrhs
15
+ else:
16
+ for i in range(len(rhs.children)-1,-1,-1):
17
+ if not contain(rhs.children[i], term):
18
+ lhs = lhs - rhs.children[i]
19
+ rhs.children.pop(i)
20
+ elif rhs.name == "f_mul":
21
+ for i in range(len(rhs.children)-1,-1,-1):
22
+ if not contain(rhs.children[i], term):
23
+ lhs = lhs * rhs.children[i]**-1
24
+ if sign is not None:
25
+ if "v_" in str_form(rhs.children[i]):
26
+ return None
27
+ if compute(rhs.children[i]**-1) < 0:
28
+ sign = not sign
29
+
30
+ rhs.children.pop(i)
31
+ elif rhs.name == "f_pow" and contain(rhs.children[0], term):
32
+ lhs = lhs ** (tree_form("d_1")/rhs.children[1])
33
+ rhs = copy.deepcopy(rhs.children[0])
34
+ elif rhs.name == "f_sin" and contain(rhs.children[0], term):
35
+ lhs = lhs.fx("arcsin")
36
+ rhs = copy.deepcopy(rhs.children[0])
37
+ elif rhs.name == "f_arcsin" and contain(rhs.children[0], term):
38
+ lhs = lhs.fx("sin")
39
+ rhs = copy.deepcopy(rhs.children[0])
40
+ elif rhs.name == "f_arccos" and contain(rhs.children[0], term):
41
+ lhs = lhs.fx("cos")
42
+ rhs = copy.deepcopy(rhs.children[0])
43
+ elif rhs.name == "f_cos" and contain(rhs.children[0], term):
44
+ lhs = lhs.fx("arccos")
45
+ rhs = copy.deepcopy(rhs.children[0])
46
+ elif rhs.name == "f_log" and contain(rhs.children[0], term):
47
+ lhs = tree_form("s_e")**lhs
48
+ rhs = copy.deepcopy(rhs.children[0])
49
+ elif rhs.name == "f_pow" and rhs.children[0].name == "s_e" and contain(rhs.children[1], term):
50
+ lhs = lhs.fx("log")
51
+ rhs = copy.deepcopy(rhs.children[1].fx("log"))
52
+ elif rhs.name == "f_tan" and contain(rhs.children[0], term):
53
+ lhs = lhs.fx("arctan")
54
+ rhs = copy.deepcopy(rhs.children[0])
55
+ elif rhs.name == "f_arctan" and contain(rhs.children[0], term):
56
+ lhs = lhs.fx("tan")
57
+ rhs = copy.deepcopy(rhs.children[0])
58
+ if len(rhs.children) == 1:
59
+ rhs = rhs.children[0]
60
+ count -= 1
61
+ if count == 0:
62
+ return None
63
+ if sign is None:
64
+ return simplify(lhs)
65
+ return simplify(lhs), sign
mathai/limit.py ADDED
@@ -0,0 +1,156 @@
1
+ from .structure import structure
2
+ from .base import *
3
+ from .parser import parse
4
+ from .simplify import simplify
5
+ from .expand import expand
6
+ from .diff import diff
7
+ from .trig import trig0
8
+ from .fraction import fraction
9
+ from .printeq import printeq
10
+ tab=0
11
+ def substitute_val(eq, val, var="v_0"):
12
+ eq = replace(eq, tree_form(var), tree_form("d_"+str(val)))
13
+ return eq
14
+
15
+ def subslimit(equation, var):
16
+ equation2 = trig0(replace(equation, var, tree_form("d_0")))
17
+
18
+ try:
19
+ tmp = simplify(equation2)
20
+ return simplify(expand(tmp))
21
+ except:
22
+ return None
23
+
24
+ def check(num, den, var):
25
+ n, d = None, None
26
+
27
+ n, d = (dowhile(replace(e, tree_form(var), tree_form("d_0")), lambda x: trig0(simplify(x))) for e in (num, den))
28
+
29
+ if n is None or d is None:
30
+ return False
31
+ if n == 0 and d == 0: return True
32
+ if d != 0:
33
+ return simplify(n/d)
34
+ return False
35
+ def lhospital(num, den, steps,var):
36
+
37
+ out = check(num, den, var)
38
+
39
+ if isinstance(out, TreeNode):
40
+ return out
41
+ for _ in range(steps):
42
+ num2, den2 = map(lambda e: simplify(diff(e, var)), (num, den))
43
+ out = check(num2, den2, var)
44
+ if out is True:
45
+ num, den = num2, den2
46
+ continue
47
+ if out is False:
48
+ eq2 = simplify(fraction(simplify(num/den)))
49
+ return eq2
50
+ return out
51
+ def lhospital2(eq, var):
52
+ eq= simplify(eq)
53
+ if eq is None:
54
+ return None
55
+ if not contain(eq, tree_form(var)):
56
+ return eq
57
+ num, dem = [simplify(item) for item in num_dem(eq)]
58
+ if num is None or dem is None:
59
+ return eq
60
+
61
+ return lhospital(num, dem, 10,var)
62
+ def limit0(equation):
63
+ if equation.name == "f_ref":
64
+ return equation
65
+ eq2 = equation
66
+ g = ["f_limit", "f_limitpinf", "f_limitninf"]
67
+ if eq2.name in g and contain(eq2.children[0], eq2.children[1]):
68
+ equation = eq2.children[0]
69
+ wrt = eq2.children[1]
70
+ lst = factor_generation(equation)
71
+
72
+ lst_const = [item for item in lst if not contain(item, wrt)]
73
+ if lst_const != []:
74
+
75
+ equation = product([item for item in lst if contain(item, wrt)]).copy_tree()
76
+ const = product(lst_const)
77
+ const = simplify(const)
78
+
79
+ if not contain(const, tree_form("s_i")):
80
+
81
+ return limit0(TreeNode(equation.name,[equation, wrt])) *const
82
+ equation = eq2
83
+ return TreeNode(equation.name, [limit0(child) for child in equation.children])
84
+ def limit2(eq):
85
+ g = ["f_limit", "f_limitpinf", "f_limitninf"]
86
+ if eq.name in g and eq.children[0].name == "f_add":
87
+ eq = summation([TreeNode(eq.name, [child, eq.children[1]]) for child in eq.children[0].children])
88
+ return TreeNode(eq.name, [limit2(child) for child in eq.children])
89
+ def limit1(eq):
90
+ if eq.name == "f_limit":
91
+ a, b = limit(eq.children[0], eq.children[1].name)
92
+ if b:
93
+ return a
94
+ else:
95
+ return TreeNode(eq.name, [a, eq.children[1]])
96
+ return TreeNode(eq.name, [limit1(child) for child in eq.children])
97
+ def fxinf(eq):
98
+ if eq is None:
99
+ return None
100
+ if eq.name == "f_add":
101
+ if tree_form("s_inf") in eq.children and -tree_form("s_inf") in eq.children:
102
+ return None
103
+ if tree_form("s_inf") in eq.children:
104
+ return tree_form("s_inf")
105
+ if -tree_form("s_inf") in eq.children:
106
+ return -tree_form("s_inf")
107
+ if eq.name == "f_mul":
108
+ lst = factor_generation(eq)
109
+ if tree_form("s_inf") in lst:
110
+ eq = TreeNode(eq.name, [dowhile(child, fxinf) for child in eq.children])
111
+ if None in eq.children:
112
+ return None
113
+ lst = factor_generation(eq)
114
+ if tree_form("d_0") in lst:
115
+ return tree_form("d_0")
116
+ lst2 = [item for item in lst if "v_" in str_form(item)]
117
+ sign = True
118
+ if len([item for item in lst if "v_" not in str_form(item) and not contain(item, tree_form("s_inf")) and compute(item)<0]) % 2==1:
119
+ sign = False
120
+ if lst2 == []:
121
+ if sign:
122
+ return tree_form("s_inf")
123
+ else:
124
+ return -tree_form("s_inf")
125
+ if eq.name == "f_pow":
126
+ if "v_" not in str_form(eq.children[0]) and not contain(eq.children[0], tree_form("s_inf")) and compute(eq.children[0])>0:
127
+ if eq.children[1] == -tree_form("s_inf"):
128
+ return tree_form("d_0")
129
+
130
+ eq = TreeNode(eq.name, [fxinf(child) for child in eq.children])
131
+ if None in eq.children:
132
+ return None
133
+ return eq
134
+ def limit3(eq):
135
+
136
+ if eq.name == "f_limitpinf":
137
+ if not contain(eq, eq.children[1]):
138
+ return eq.children[0]
139
+ eq2 = replace(eq.children[0], eq.children[1], tree_form("s_inf"))
140
+ eq2 = dowhile(eq2, fxinf)
141
+ if not contain(eq2, tree_form("s_inf")) and not contain(eq2, eq.children[1]):
142
+ return simplify(eq2)
143
+ return TreeNode(eq.name, [limit3(child) for child in eq.children])
144
+
145
+ def limit(equation, var="v_0"):
146
+
147
+ eq2 = dowhile(replace(equation, tree_form(var), tree_form("d_0")), lambda x: trig0(simplify(x)))
148
+ if eq2 is not None and not contain(equation, tree_form(var)):
149
+ return eq2, True
150
+
151
+ equation = lhospital2(equation, var)
152
+ equation = simplify(expand(simplify(equation)))
153
+ if not contain(equation, tree_form(var)):
154
+ return equation, True
155
+
156
+ return equation, False