mathai 0.4.5__tar.gz → 0.4.7__tar.gz
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-0.4.5 → mathai-0.4.7}/PKG-INFO +1 -1
- {mathai-0.4.5 → mathai-0.4.7}/mathai/__init__.py +7 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/base.py +1 -0
- mathai-0.4.7/mathai/factor.py +275 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/integrate.py +1 -2
- mathai-0.4.7/mathai/ode.py +124 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/simplify.py +4 -1
- {mathai-0.4.5 → mathai-0.4.7}/mathai/tool.py +7 -2
- {mathai-0.4.5 → mathai-0.4.7}/mathai/trig.py +56 -46
- {mathai-0.4.5 → mathai-0.4.7}/mathai.egg-info/PKG-INFO +1 -1
- {mathai-0.4.5 → mathai-0.4.7}/mathai.egg-info/SOURCES.txt +1 -0
- {mathai-0.4.5 → mathai-0.4.7}/setup.py +1 -1
- mathai-0.4.5/mathai/factor.py +0 -133
- {mathai-0.4.5 → mathai-0.4.7}/README.md +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/apart.py +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/console.py +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/diff.py +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/expand.py +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/fraction.py +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/inverse.py +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/limit.py +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/linear.py +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/logic.py +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/parser.py +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/printeq.py +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/structure.py +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai/univariate_inequality.py +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai.egg-info/dependency_links.txt +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai.egg-info/requires.txt +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/mathai.egg-info/top_level.txt +0 -0
- {mathai-0.4.5 → mathai-0.4.7}/setup.cfg +0 -0
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
from .ode import diffsolve as ode_solve
|
|
2
|
+
from .ode import diffsolve_sep as ode_shift_term
|
|
3
|
+
|
|
4
|
+
from .linear import linear_solve
|
|
5
|
+
|
|
1
6
|
from .expand import expand
|
|
2
7
|
|
|
3
8
|
from .parser import parse
|
|
@@ -20,6 +25,8 @@ from .diff import diff
|
|
|
20
25
|
|
|
21
26
|
from .factor import factor as factor1
|
|
22
27
|
from .factor import factor2
|
|
28
|
+
from .factor import rationalize_sqrt as rationalize
|
|
29
|
+
from .factor import merge_sqrt
|
|
23
30
|
from .factor import factorconst as factor0
|
|
24
31
|
|
|
25
32
|
from .fraction import fraction
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import itertools
|
|
2
|
+
from .parser import parse
|
|
3
|
+
from .structure import transform_formula
|
|
4
|
+
from .base import *
|
|
5
|
+
from .simplify import simplify,solve
|
|
6
|
+
from .expand import expand
|
|
7
|
+
import math
|
|
8
|
+
from .tool import poly
|
|
9
|
+
|
|
10
|
+
from collections import Counter
|
|
11
|
+
def multiset_intersection(*lists):
|
|
12
|
+
counters = list(map(Counter, lists))
|
|
13
|
+
common = counters[0]
|
|
14
|
+
for c in counters[1:]:
|
|
15
|
+
common = common & c
|
|
16
|
+
return list(common.elements())
|
|
17
|
+
def subtract_sublist(full_list, sublist):
|
|
18
|
+
c_full = Counter(full_list)
|
|
19
|
+
c_sub = Counter(sublist)
|
|
20
|
+
result = c_full - c_sub
|
|
21
|
+
tmp = list(result.elements())
|
|
22
|
+
if tmp == []:
|
|
23
|
+
return [tree_form("d_1")]
|
|
24
|
+
return tmp
|
|
25
|
+
def term_common2(eq):
|
|
26
|
+
if eq.name != "f_add":
|
|
27
|
+
return eq
|
|
28
|
+
s = []
|
|
29
|
+
arr = [factor_generation(child) for child in eq.children]
|
|
30
|
+
s = multiset_intersection(*arr)
|
|
31
|
+
return product(s)*summation([product(subtract_sublist(factor_generation(child), s)) for child in eq.children])
|
|
32
|
+
def term_common(eq):
|
|
33
|
+
if eq.name == "f_add":
|
|
34
|
+
return solve(term_common2(eq))
|
|
35
|
+
return solve(product([term_common2(item) for item in factor_generation(eq)]))
|
|
36
|
+
def take_common(eq):
|
|
37
|
+
if eq.name == "f_add":
|
|
38
|
+
eq = term_common(eq)
|
|
39
|
+
if eq.name == "f_add":
|
|
40
|
+
for i in range(len(eq.children)-1,1,-1):
|
|
41
|
+
for item in itertools.combinations(range(len(eq.children)), i):
|
|
42
|
+
eq2 = summation([item2 for index, item2 in enumerate(eq.children) if index in item])
|
|
43
|
+
eq2 = term_common(eq2)
|
|
44
|
+
if eq2.name == "f_mul":
|
|
45
|
+
return take_common(solve(summation([item2 for index, item2 in enumerate(eq.children) if index not in item]) + eq2))
|
|
46
|
+
return eq
|
|
47
|
+
return term_common(eq)
|
|
48
|
+
def take_common2(eq):
|
|
49
|
+
eq = take_common(eq)
|
|
50
|
+
return TreeNode(eq.name, [take_common2(child) for child in eq.children])
|
|
51
|
+
|
|
52
|
+
def _factorconst(eq):
|
|
53
|
+
def hcf_list(numbers):
|
|
54
|
+
if not numbers:
|
|
55
|
+
return None # empty list
|
|
56
|
+
hcf = numbers[0]
|
|
57
|
+
for num in numbers[1:]:
|
|
58
|
+
hcf = math.gcd(hcf, num)
|
|
59
|
+
return hcf
|
|
60
|
+
def extractnum(eq):
|
|
61
|
+
lst = factor_generation(eq)
|
|
62
|
+
for item in lst:
|
|
63
|
+
if item.name[:2] == "d_":
|
|
64
|
+
return int(item.name[2:])
|
|
65
|
+
return 1
|
|
66
|
+
n = 1
|
|
67
|
+
if eq.name == "f_add":
|
|
68
|
+
n = hcf_list([extractnum(child) for child in eq.children])
|
|
69
|
+
eq = TreeNode(eq.name, [child/tree_form("d_"+str(n)) for child in eq.children])
|
|
70
|
+
if n != 1:
|
|
71
|
+
return tree_form("d_"+str(n))*eq
|
|
72
|
+
return TreeNode(eq.name, [factorconst(child) for child in eq.children])
|
|
73
|
+
|
|
74
|
+
def _merge_sqrt(eq):
|
|
75
|
+
lst= []
|
|
76
|
+
eq2 = []
|
|
77
|
+
for child in factor_generation(eq):
|
|
78
|
+
if frac(child) is not None and frac(child).denominator==1:
|
|
79
|
+
if frac(child)>0:
|
|
80
|
+
eq2.append(child**2)
|
|
81
|
+
elif frac(child)!=-1:
|
|
82
|
+
eq2.append((-child)**2)
|
|
83
|
+
lst.append(tree_form("d_-1"))
|
|
84
|
+
else:
|
|
85
|
+
lst.append(tree_form("d_-1"))
|
|
86
|
+
elif child.name == "f_pow" and frac(child.children[1]) == Fraction(1,2):
|
|
87
|
+
eq2.append(child.children[0])
|
|
88
|
+
else:
|
|
89
|
+
lst.append(child)
|
|
90
|
+
|
|
91
|
+
if len(eq2)>1:
|
|
92
|
+
if lst == []:
|
|
93
|
+
lst= [tree_form("d_1")]
|
|
94
|
+
return simplify(product(eq2)**(tree_form("d_2")**-1)*product(lst))
|
|
95
|
+
return TreeNode(eq.name, [_merge_sqrt(child) for child in eq.children])
|
|
96
|
+
def sqrt_to_a_sqrt_b(n):
|
|
97
|
+
if n == 0:
|
|
98
|
+
return 0, 0
|
|
99
|
+
sign = 1
|
|
100
|
+
if n < 0:
|
|
101
|
+
sign = -1
|
|
102
|
+
m = -n
|
|
103
|
+
else:
|
|
104
|
+
m = n
|
|
105
|
+
|
|
106
|
+
a = 1
|
|
107
|
+
b = 1
|
|
108
|
+
p = 2
|
|
109
|
+
while p * p <= m:
|
|
110
|
+
exp = 0
|
|
111
|
+
while m % p == 0:
|
|
112
|
+
m //= p
|
|
113
|
+
exp += 1
|
|
114
|
+
if exp:
|
|
115
|
+
a *= p ** (exp // 2)
|
|
116
|
+
if exp % 2 == 1:
|
|
117
|
+
b *= p
|
|
118
|
+
p += 1 if p == 2 else 2
|
|
119
|
+
|
|
120
|
+
if m > 1:
|
|
121
|
+
b *= m
|
|
122
|
+
|
|
123
|
+
return sign * a, b
|
|
124
|
+
def merge_sqrt(eq):
|
|
125
|
+
def helper(eq):
|
|
126
|
+
if eq.name == "f_pow" and frac(eq.children[1]) == Fraction(1,2):
|
|
127
|
+
if eq.children[0].name[:2] == "d_":
|
|
128
|
+
n = int(eq.children[0].name[2:])
|
|
129
|
+
a, b =sqrt_to_a_sqrt_b(n)
|
|
130
|
+
return tree_form("d_"+str(b))**(tree_form("d_2")**-1)*tree_form("d_"+str(a))
|
|
131
|
+
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
|
132
|
+
return helper(_merge_sqrt(eq))
|
|
133
|
+
def rationalize_sqrt(eq):
|
|
134
|
+
if eq.name== "f_pow" and frac(eq.children[1]) == Fraction(-1,2):
|
|
135
|
+
eq = eq.children[0]**(tree_form("d_2")**-1)/eq.children[0]
|
|
136
|
+
def term(eq):
|
|
137
|
+
if eq.name == "f_add":
|
|
138
|
+
output = []
|
|
139
|
+
for child in eq.children:
|
|
140
|
+
if any(child2.name == "f_pow" and frac(child2.children[1]) == Fraction(1,2) for child2 in factor_generation(child)):
|
|
141
|
+
output.append(simplify(-child))
|
|
142
|
+
else:
|
|
143
|
+
output.append(child)
|
|
144
|
+
return summation(output)
|
|
145
|
+
return None
|
|
146
|
+
n, d=num_dem(eq)
|
|
147
|
+
n,d=simplify(n), simplify(d)
|
|
148
|
+
|
|
149
|
+
if d != 1:
|
|
150
|
+
t = term(d)
|
|
151
|
+
if t is not None and t!=1:
|
|
152
|
+
|
|
153
|
+
n,d=simplify(expand(simplify(n*t))),simplify(expand(simplify(d*t)))
|
|
154
|
+
tmp= simplify(n/d)
|
|
155
|
+
|
|
156
|
+
tmp = _merge_sqrt(tmp)
|
|
157
|
+
|
|
158
|
+
return tmp
|
|
159
|
+
return TreeNode(eq.name, [rationalize_sqrt(child) for child in eq.children])
|
|
160
|
+
def factorconst(eq):
|
|
161
|
+
return simplify(_factorconst(eq))
|
|
162
|
+
|
|
163
|
+
def factor_quar_formula_init():
|
|
164
|
+
var = ""
|
|
165
|
+
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))")]
|
|
166
|
+
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
|
167
|
+
expr = [[parse("A")], [parse("B"), parse("0"), parse("1")], [parse("C"), parse("0")]]
|
|
168
|
+
return [formula_list, var, expr]
|
|
169
|
+
|
|
170
|
+
formula_gen9 = factor_quar_formula_init()
|
|
171
|
+
def factor_helper(equation, complexnum, power=2):
|
|
172
|
+
global formula_gen9
|
|
173
|
+
|
|
174
|
+
maxnum=1
|
|
175
|
+
alloclst = []
|
|
176
|
+
for i in range(0,26):
|
|
177
|
+
if "v_"+str(i) not in vlist(equation):
|
|
178
|
+
alloclst.append("v_"+str(i))
|
|
179
|
+
r = alloclst.pop(0)
|
|
180
|
+
fx = None
|
|
181
|
+
curr = None
|
|
182
|
+
def high(eq):
|
|
183
|
+
nonlocal maxnum
|
|
184
|
+
if eq.name == "f_pow" and eq.children[1].name[:2] == "d_":
|
|
185
|
+
n = int(eq.children[1].name[2:])
|
|
186
|
+
if abs(n)>power and abs(n) % power == 0:
|
|
187
|
+
if abs(n)>abs(maxnum):
|
|
188
|
+
maxnum = n
|
|
189
|
+
for child in eq.children:
|
|
190
|
+
high(child)
|
|
191
|
+
def helper(eq):
|
|
192
|
+
nonlocal maxnum, fx, r
|
|
193
|
+
if eq.name == "f_pow" and eq.children[1].name[:2] == "d_":
|
|
194
|
+
n = int(eq.children[1].name[2:])
|
|
195
|
+
if maxnum !=1 and n % maxnum == 0:
|
|
196
|
+
fx = lambda x: replace(x, tree_form(r), curr**tree_form("d_"+str(maxnum)))
|
|
197
|
+
out= tree_form(r)**tree_form("d_"+str(int(n/maxnum)))
|
|
198
|
+
return out
|
|
199
|
+
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
|
200
|
+
out = None
|
|
201
|
+
for i in range(2,4):
|
|
202
|
+
if power == i:
|
|
203
|
+
for curr in vlist(equation):
|
|
204
|
+
curr = tree_form(curr)
|
|
205
|
+
fx = None
|
|
206
|
+
maxnum = 1
|
|
207
|
+
high(equation)
|
|
208
|
+
|
|
209
|
+
if maxnum != 1:
|
|
210
|
+
maxnum= maxnum/power
|
|
211
|
+
maxnum = round(maxnum)
|
|
212
|
+
eq2 = helper(equation)
|
|
213
|
+
if not contain(eq2, tree_form(r)) or (contain(eq2, tree_form(r)) and not contain(eq2,curr)):
|
|
214
|
+
if not contain(eq2, tree_form(r)):
|
|
215
|
+
r = curr.name
|
|
216
|
+
fx = lambda x: x
|
|
217
|
+
|
|
218
|
+
lst = poly(eq2.copy_tree(), r)
|
|
219
|
+
if lst is not None and len(lst)==i+1:
|
|
220
|
+
|
|
221
|
+
success = True
|
|
222
|
+
if i == 2:
|
|
223
|
+
a, b, c = lst
|
|
224
|
+
x1 = (-b+(b**2 - 4*a*c)**(tree_form("d_2")**-1))/(2*a)
|
|
225
|
+
x2 = (-b-(b**2 - 4*a*c)**(tree_form("d_2")**-1))/(2*a)
|
|
226
|
+
x1 = simplify(x1)
|
|
227
|
+
x2 = simplify(x2)
|
|
228
|
+
eq2 = a*(tree_form(r)-x1)*(tree_form(r)-x2)
|
|
229
|
+
if not complexnum and (contain(x1, tree_form("s_i")) or contain(x2, tree_form("s_i"))):
|
|
230
|
+
success = False
|
|
231
|
+
else:
|
|
232
|
+
a, b, c, d = lst
|
|
233
|
+
B, C, D = b/a, c/a, d/a
|
|
234
|
+
p = C-(B**2)/3
|
|
235
|
+
q = 2*B**3/27-B*C/3+D
|
|
236
|
+
t = q**2/4+ p**3/27
|
|
237
|
+
u = (-q/2+t**(tree_form("d_2")**-1))**(tree_form("d_3")**-1)
|
|
238
|
+
v = (-q/2-t**(tree_form("d_2")**-1))**(tree_form("d_3")**-1)
|
|
239
|
+
y1 = u+v
|
|
240
|
+
three = 3**(tree_form("d_2")**-1)
|
|
241
|
+
y2 = -(u+v)/2+tree_form("s_i")*three*(u-v)/2
|
|
242
|
+
y3 = -(u+v)/2-tree_form("s_i")*three*(u-v)/2
|
|
243
|
+
x1,x2,x3 = y1-B/3 , y2-B/3, y3-B/3
|
|
244
|
+
x1,x2, x3 = simplify(x1), simplify(x2), simplify(x3)
|
|
245
|
+
out2 = None
|
|
246
|
+
if not complexnum:
|
|
247
|
+
for item in itertools.combinations([x1,x2,x3],2):
|
|
248
|
+
if all(contain(item2,tree_form("s_i")) for item2 in list(item)):
|
|
249
|
+
out2 = (tree_form(r)-item[0])*(tree_form(r)-item[1])
|
|
250
|
+
break
|
|
251
|
+
if out2 is not None:
|
|
252
|
+
out2 = simplify(expand(simplify(out2)))
|
|
253
|
+
out3 = None
|
|
254
|
+
for item in [x1, x2, x3]:
|
|
255
|
+
if not contain(item,tree_form("s_i")):
|
|
256
|
+
out3 = item
|
|
257
|
+
break
|
|
258
|
+
eq2 = a*(tree_form(r)-out3)*out2
|
|
259
|
+
|
|
260
|
+
else:
|
|
261
|
+
eq2 = a*(tree_form(r)-x1)*(tree_form(r)-x2)*(tree_form(r)-x3)
|
|
262
|
+
if success:
|
|
263
|
+
equation = fx(eq2)
|
|
264
|
+
break
|
|
265
|
+
if power == 4:
|
|
266
|
+
out = transform_formula(helper(equation), "v_0", formula_gen9[0], formula_gen9[1], formula_gen9[2])
|
|
267
|
+
if out is not None:
|
|
268
|
+
out = simplify(solve(out))
|
|
269
|
+
if out is not None and (complexnum or (not complexnum and not contain(out, tree_form("s_i")))):
|
|
270
|
+
return out
|
|
271
|
+
return TreeNode(equation.name, [factor_helper(child, complexnum, power) for child in equation.children])
|
|
272
|
+
def factor(equation, complexnum=False):
|
|
273
|
+
return solve(take_common2(simplify(factor_helper(simplify(equation), complexnum, 2))))
|
|
274
|
+
def factor2(equation, complexnum=False):
|
|
275
|
+
return solve(factor_helper(solve(factor_helper(simplify(factor_helper(simplify(equation), complexnum, 2)), complexnum, 3)), complexnum, 4))
|
|
@@ -367,7 +367,7 @@ def rm_const(equation):
|
|
|
367
367
|
if equation.name == "f_ref":
|
|
368
368
|
return equation
|
|
369
369
|
eq2 = equation
|
|
370
|
-
if eq2.name == "f_integrate":
|
|
370
|
+
if eq2.name == "f_integrate" and contain(eq2.children[0], eq2.children[1]):
|
|
371
371
|
equation = eq2.children[0]
|
|
372
372
|
wrt = eq2.children[1]
|
|
373
373
|
lst = factor_generation(equation)
|
|
@@ -407,4 +407,3 @@ def integrate_formula(equation):
|
|
|
407
407
|
|
|
408
408
|
return out
|
|
409
409
|
return TreeNode(eq2.name, [integrate_formula(child) for child in eq2.children])
|
|
410
|
-
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
from .factor import factor
|
|
2
|
+
from .expand import expand
|
|
3
|
+
from .base import *
|
|
4
|
+
from .fraction import fraction
|
|
5
|
+
from .simplify import simplify
|
|
6
|
+
import copy
|
|
7
|
+
|
|
8
|
+
def inversediff(lhs, rhs):
|
|
9
|
+
count = 4
|
|
10
|
+
while contain(rhs, tree_form("v_1")) or contain(lhs, tree_form("v_0")):
|
|
11
|
+
success = False
|
|
12
|
+
if rhs.name == "f_add":
|
|
13
|
+
for i in range(len(rhs.children)-1,-1,-1):
|
|
14
|
+
if not contain(rhs.children[i], tree_form("v_0")) or str_form(tree_form("v_1").fx("dif")) in [str_form(x) for x in factor_generation(rhs.children[i])]:
|
|
15
|
+
if contain(rhs.children[i], tree_form("v_0")) or contain(rhs.children[i], tree_form("v_1")):
|
|
16
|
+
success = True
|
|
17
|
+
lhs = lhs - rhs.children[i]
|
|
18
|
+
rhs.children.pop(i)
|
|
19
|
+
elif rhs.name == "f_mul":
|
|
20
|
+
for i in range(len(rhs.children)-1,-1,-1):
|
|
21
|
+
if not contain(rhs.children[i], tree_form("v_0")):
|
|
22
|
+
if contain(rhs.children[i], tree_form("v_0")) or contain(rhs.children[i], tree_form("v_1")):
|
|
23
|
+
success = True
|
|
24
|
+
lhs = lhs / rhs.children[i]
|
|
25
|
+
rhs.children.pop(i)
|
|
26
|
+
if len(rhs.children) == 1:
|
|
27
|
+
rhs = rhs.children[0]
|
|
28
|
+
rhs, lhs = copy.deepcopy([simplify(lhs), simplify(rhs)])
|
|
29
|
+
if rhs.name == "f_add":
|
|
30
|
+
for i in range(len(rhs.children)-1,-1,-1):
|
|
31
|
+
if not contain(rhs.children[i], tree_form("v_1")) or str_form(tree_form("v_0").fx("dif")) in [str_form(x) for x in factor_generation(rhs.children[i])]:
|
|
32
|
+
if contain(rhs.children[i], tree_form("v_0")) or contain(rhs.children[i], tree_form("v_1")):
|
|
33
|
+
success = True
|
|
34
|
+
lhs = lhs - rhs.children[i]
|
|
35
|
+
rhs.children.pop(i)
|
|
36
|
+
elif rhs.name == "f_mul":
|
|
37
|
+
for i in range(len(rhs.children)-1,-1,-1):
|
|
38
|
+
if not contain(rhs.children[i], tree_form("v_1")):
|
|
39
|
+
if contain(rhs.children[i], tree_form("v_0")) or contain(rhs.children[i], tree_form("v_1")):
|
|
40
|
+
success = True
|
|
41
|
+
lhs = lhs / rhs.children[i]
|
|
42
|
+
rhs.children.pop(i)
|
|
43
|
+
rhs, lhs = copy.deepcopy([simplify(lhs), simplify(rhs)])
|
|
44
|
+
if not success:
|
|
45
|
+
lhs, rhs = factor(lhs),factor(rhs)
|
|
46
|
+
count -= 1
|
|
47
|
+
if count == 0:
|
|
48
|
+
return simplify(e0(lhs-rhs))
|
|
49
|
+
return simplify(e0(lhs-rhs))
|
|
50
|
+
|
|
51
|
+
intconst = ["v_"+str(i) for i in range(101,150)]
|
|
52
|
+
def allocvar():
|
|
53
|
+
global intconst
|
|
54
|
+
return tree_form(intconst.pop(0))
|
|
55
|
+
|
|
56
|
+
def epowersplit(eq):
|
|
57
|
+
if eq.name == "f_pow" and eq.children[1].name == "f_add":
|
|
58
|
+
return product([eq.children[0]**child for child in eq.children[1].children])
|
|
59
|
+
return TreeNode(eq.name, [epowersplit(child) for child in eq.children])
|
|
60
|
+
def esolve(s):
|
|
61
|
+
if s.name == "f_add" and "f_log" in str_form(s):
|
|
62
|
+
return product([tree_form("s_e")**child for child in s.children]) - tree_form("d_1")
|
|
63
|
+
return TreeNode(s.name, [esolve(child) for child in s.children])
|
|
64
|
+
def diffsolve_sep2(eq):
|
|
65
|
+
global tab
|
|
66
|
+
|
|
67
|
+
s = []
|
|
68
|
+
eq = simplify(expand(eq))
|
|
69
|
+
eq = e1(eq)
|
|
70
|
+
|
|
71
|
+
def vlor1(eq):
|
|
72
|
+
if contain(eq, tree_form("v_0")) and not contain(eq, tree_form("v_1")):
|
|
73
|
+
return True
|
|
74
|
+
if contain(eq, tree_form("v_1")) and not contain(eq, tree_form("v_0")):
|
|
75
|
+
return True
|
|
76
|
+
return False
|
|
77
|
+
if eq.name == "f_add" and all(vlor1(child) and [str_form(x) for x in factor_generation(copy.deepcopy(child))].count(str_form(tree_form(vlist(child)[0]).fx("dif")))==1 for child in eq.children):
|
|
78
|
+
for child in eq.children:
|
|
79
|
+
v = vlist(child)[0]
|
|
80
|
+
v2 = tree_form(v).fx("dif")
|
|
81
|
+
child = replace(child, v2, tree_form("d_1"))
|
|
82
|
+
child = simplify(child)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
tmp6 = TreeNode("f_integrate", [child, tree_form(v)])
|
|
86
|
+
s.append(tmp6)
|
|
87
|
+
|
|
88
|
+
if s[-1] is None:
|
|
89
|
+
return None
|
|
90
|
+
s.append(allocvar())
|
|
91
|
+
else:
|
|
92
|
+
return None
|
|
93
|
+
s = summation(s)
|
|
94
|
+
s = simplify(e0(s))
|
|
95
|
+
|
|
96
|
+
return groupe(s)
|
|
97
|
+
def e0(eq):
|
|
98
|
+
return TreeNode("f_eq", [eq, tree_form("d_0")])
|
|
99
|
+
def e1(eq):
|
|
100
|
+
if eq.name == "f_eq":
|
|
101
|
+
eq = eq.children[0]
|
|
102
|
+
return eq
|
|
103
|
+
def groupe(eq):
|
|
104
|
+
eq = esolve(eq)
|
|
105
|
+
eq = simplify(eq)
|
|
106
|
+
eq = fraction(eq)
|
|
107
|
+
eq = simplify(eq)
|
|
108
|
+
eq = epowersplit(eq)
|
|
109
|
+
return eq
|
|
110
|
+
|
|
111
|
+
def diffsolve_sep(eq):
|
|
112
|
+
eq = epowersplit(eq)
|
|
113
|
+
|
|
114
|
+
eq = inversediff(tree_form("d_0"), eq.children[0].copy_tree())
|
|
115
|
+
return eq
|
|
116
|
+
|
|
117
|
+
def diffsolve(eq):
|
|
118
|
+
orig = eq.copy_tree()
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
eq = diffsolve_sep2(eq)
|
|
122
|
+
if eq is None:
|
|
123
|
+
return orig
|
|
124
|
+
return eq
|
|
@@ -287,7 +287,9 @@ def simplify(eq):
|
|
|
287
287
|
error = True
|
|
288
288
|
else:
|
|
289
289
|
eq = tree_form("d_0")
|
|
290
|
-
|
|
290
|
+
if eq.name =="f_pow" and eq.children[0] == tree_form("s_i") and frac(eq.children[1])is not None and frac(eq.children[1]).denominator == 1:
|
|
291
|
+
n = frac(eq.children[1]).numerator
|
|
292
|
+
eq = {0:tree_form("d_1"), 1:tree_form("s_i"), 2:tree_form("d_-1"), 3:-tree_form("s_i")}[n%4]
|
|
291
293
|
if eq.name == "f_mul":
|
|
292
294
|
dic = {}
|
|
293
295
|
for child in eq.children:
|
|
@@ -384,3 +386,4 @@ def simplify(eq):
|
|
|
384
386
|
if error:
|
|
385
387
|
return None
|
|
386
388
|
return solve(eq)
|
|
389
|
+
|
|
@@ -36,7 +36,12 @@ def poly(eq, to_compute):
|
|
|
36
36
|
eq = replace(eq, tree_form(var), tree_form("d_"+str(val)))
|
|
37
37
|
return eq
|
|
38
38
|
def inv(eq):
|
|
39
|
-
if eq.name ==
|
|
39
|
+
if eq.name =="f_eq":
|
|
40
|
+
return False
|
|
41
|
+
if eq.name[2:] in ["sin", "cos", "log"] and contain(eq.children[0], tree_form(to_compute)):
|
|
42
|
+
return False
|
|
43
|
+
if eq.name == "f_pow" and contain(eq.children[0], tree_form(to_compute)) and\
|
|
44
|
+
(frac(eq.children[1]) is None or frac(eq.children[1]) < 0 or frac(eq.children[1]).denominator != 1):
|
|
40
45
|
return False
|
|
41
46
|
if eq.name == "f_abs":
|
|
42
47
|
return False
|
|
@@ -47,7 +52,7 @@ def poly(eq, to_compute):
|
|
|
47
52
|
return None
|
|
48
53
|
out = []
|
|
49
54
|
eq2 = eq
|
|
50
|
-
for i in range(
|
|
55
|
+
for i in range(8):
|
|
51
56
|
out.append(expand(simplify(eq2)))
|
|
52
57
|
eq2 = diff(eq2, to_compute)
|
|
53
58
|
for i in range(len(out)-1,-1,-1):
|
|
@@ -58,6 +58,9 @@ def trig0(eq):
|
|
|
58
58
|
if a > b:
|
|
59
59
|
a = 2*b - a
|
|
60
60
|
return a, b
|
|
61
|
+
if eq.name == "f_arccosec":
|
|
62
|
+
return (1/eq.children[0]).fx("arcsin")
|
|
63
|
+
|
|
61
64
|
if eq.name == "f_arctan":
|
|
62
65
|
if eq.children[0].name == "d_0":
|
|
63
66
|
return tree_form("d_0")
|
|
@@ -164,52 +167,59 @@ def _trig1(equation):
|
|
|
164
167
|
return TreeNode(equation.name, [_trig1(child) for child in equation.children])
|
|
165
168
|
def trig1(eq):
|
|
166
169
|
return simplify(_trig1(noneg_pow(eq)))
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if len(
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
170
|
+
def trig4(eq):
|
|
171
|
+
done = False
|
|
172
|
+
def _trig4(eq, numer=True, chance="sin"):
|
|
173
|
+
nonlocal done
|
|
174
|
+
if eq.name == "f_sin":
|
|
175
|
+
if eq.children[0].name == "f_add" and len(eq.children[0].children)>=2:
|
|
176
|
+
r = len(eq.children[0].children)%2
|
|
177
|
+
a, b = TreeNode("f_add", eq.children[0].children[:round((len(eq.children[0].children)-r)/2)]),\
|
|
178
|
+
TreeNode("f_add", eq.children[0].children[round((len(eq.children[0].children)-r)/2):])
|
|
179
|
+
if len(a.children)==1:
|
|
180
|
+
a=a.children[0]
|
|
181
|
+
if len(b.children)==1:
|
|
182
|
+
b=b.children[0]
|
|
183
|
+
return a.fx("sin")*b.fx("cos") + a.fx("cos")*b.fx("sin")
|
|
184
|
+
if eq.children[0].name == "f_arccos":
|
|
185
|
+
a = eq.children[0].children[0]
|
|
186
|
+
return (1-a**2)**(tree_form("d_2")**-1)
|
|
187
|
+
if eq.children[0].name == "f_arctan":
|
|
188
|
+
a = eq.children[0].children[0]
|
|
189
|
+
return a/(1+a**2)**(tree_form("d_2")**-1)
|
|
190
|
+
if eq.name == "f_pow" and numer:
|
|
191
|
+
if eq.children[0].name == "f_cos" and chance == "cos":
|
|
192
|
+
a = eq.children[0].children[0]
|
|
193
|
+
if frac(eq.children[1]) == 2:
|
|
194
|
+
done = True
|
|
195
|
+
return 1 - a.fx("sin")**2
|
|
196
|
+
if eq.children[0].name == "f_sin" and chance == "cos":
|
|
197
|
+
a = eq.children[0].children[0]
|
|
198
|
+
if frac(eq.children[1]) == 2:
|
|
199
|
+
done = True
|
|
200
|
+
return 1 - a.fx("cos")**2
|
|
201
|
+
if eq.name == "f_cos":
|
|
202
|
+
if eq.children[0].name == "f_add" and len(eq.children[0].children)>=2:
|
|
203
|
+
r = len(eq.children[0].children)%2
|
|
204
|
+
a, b = TreeNode("f_add", eq.children[0].children[:round((len(eq.children[0].children)-r)/2)]),\
|
|
205
|
+
TreeNode("f_add", eq.children[0].children[round((len(eq.children[0].children)-r)/2):])
|
|
206
|
+
if len(a.children)==1:
|
|
207
|
+
a=a.children[0]
|
|
208
|
+
if len(b.children)==1:
|
|
209
|
+
b=b.children[0]
|
|
210
|
+
return a.fx("cos")*b.fx("cos") - a.fx("sin")*b.fx("sin")
|
|
211
|
+
if eq.children[0].name == "f_arcsin":
|
|
212
|
+
a = eq.children[0].children[0]
|
|
213
|
+
return (1-a**2)**(tree_form("d_2")**-1)
|
|
214
|
+
if eq.children[0].name == "f_arctan":
|
|
215
|
+
a = eq.children[0].children[0]
|
|
216
|
+
return tree_form("d_1")/(1+a**2)**(tree_form("d_2")**-1)
|
|
217
|
+
|
|
218
|
+
return TreeNode(eq.name, [_trig4(child, False, chance) if not numer or (eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]) < 0) else _trig4(child, True, chance) for child in eq.children])
|
|
219
|
+
eq= _trig4(eq)
|
|
220
|
+
if not done:
|
|
221
|
+
eq = _trig4(eq,"cos")
|
|
222
|
+
return eq
|
|
213
223
|
def trig2(eq):
|
|
214
224
|
# Base case: if not an addition, recurse into children
|
|
215
225
|
if eq.name != "f_add":
|
mathai-0.4.5/mathai/factor.py
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import itertools
|
|
2
|
-
from .parser import parse
|
|
3
|
-
from .structure import transform_formula
|
|
4
|
-
from .base import *
|
|
5
|
-
from .simplify import simplify,solve
|
|
6
|
-
from .expand import expand
|
|
7
|
-
import math
|
|
8
|
-
|
|
9
|
-
from collections import Counter
|
|
10
|
-
def multiset_intersection(*lists):
|
|
11
|
-
counters = list(map(Counter, lists))
|
|
12
|
-
common = counters[0]
|
|
13
|
-
for c in counters[1:]:
|
|
14
|
-
common = common & c
|
|
15
|
-
return list(common.elements())
|
|
16
|
-
def subtract_sublist(full_list, sublist):
|
|
17
|
-
c_full = Counter(full_list)
|
|
18
|
-
c_sub = Counter(sublist)
|
|
19
|
-
result = c_full - c_sub
|
|
20
|
-
tmp = list(result.elements())
|
|
21
|
-
if tmp == []:
|
|
22
|
-
return [tree_form("d_1")]
|
|
23
|
-
return tmp
|
|
24
|
-
def term_common2(eq):
|
|
25
|
-
if eq.name != "f_add":
|
|
26
|
-
return eq
|
|
27
|
-
s = []
|
|
28
|
-
arr = [factor_generation(child) for child in eq.children]
|
|
29
|
-
s = multiset_intersection(*arr)
|
|
30
|
-
return product(s)*summation([product(subtract_sublist(factor_generation(child), s)) for child in eq.children])
|
|
31
|
-
def term_common(eq):
|
|
32
|
-
if eq.name == "f_add":
|
|
33
|
-
return solve(term_common2(eq))
|
|
34
|
-
return solve(product([term_common2(item) for item in factor_generation(eq)]))
|
|
35
|
-
def take_common(eq):
|
|
36
|
-
if eq.name == "f_add":
|
|
37
|
-
eq = term_common(eq)
|
|
38
|
-
if eq.name == "f_add":
|
|
39
|
-
for i in range(len(eq.children)-1,1,-1):
|
|
40
|
-
for item in itertools.combinations(range(len(eq.children)), i):
|
|
41
|
-
eq2 = summation([item2 for index, item2 in enumerate(eq.children) if index in item])
|
|
42
|
-
eq2 = term_common(eq2)
|
|
43
|
-
if eq2.name == "f_mul":
|
|
44
|
-
return take_common(solve(summation([item2 for index, item2 in enumerate(eq.children) if index not in item]) + eq2))
|
|
45
|
-
return eq
|
|
46
|
-
return term_common(eq)
|
|
47
|
-
def take_common2(eq):
|
|
48
|
-
eq = take_common(eq)
|
|
49
|
-
return TreeNode(eq.name, [take_common2(child) for child in eq.children])
|
|
50
|
-
|
|
51
|
-
def _factorconst(eq):
|
|
52
|
-
def hcf_list(numbers):
|
|
53
|
-
if not numbers:
|
|
54
|
-
return None # empty list
|
|
55
|
-
hcf = numbers[0]
|
|
56
|
-
for num in numbers[1:]:
|
|
57
|
-
hcf = math.gcd(hcf, num)
|
|
58
|
-
return hcf
|
|
59
|
-
def extractnum(eq):
|
|
60
|
-
lst = factor_generation(eq)
|
|
61
|
-
for item in lst:
|
|
62
|
-
if item.name[:2] == "d_":
|
|
63
|
-
return int(item.name[2:])
|
|
64
|
-
return 1
|
|
65
|
-
n = 1
|
|
66
|
-
if eq.name == "f_add":
|
|
67
|
-
n = hcf_list([extractnum(child) for child in eq.children])
|
|
68
|
-
eq = TreeNode(eq.name, [child/tree_form("d_"+str(n)) for child in eq.children])
|
|
69
|
-
if n != 1:
|
|
70
|
-
return tree_form("d_"+str(n))*eq
|
|
71
|
-
return TreeNode(eq.name, [factorconst(child) for child in eq.children])
|
|
72
|
-
def factorconst(eq):
|
|
73
|
-
return simplify(_factorconst(eq))
|
|
74
|
-
def factor_quad_formula_init():
|
|
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]
|
|
80
|
-
def factor_quar_formula_init():
|
|
81
|
-
var = ""
|
|
82
|
-
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
|
-
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
|
84
|
-
expr = [[parse("A")], [parse("B"), parse("0"), parse("1")], [parse("C"), parse("0")]]
|
|
85
|
-
return [formula_list, var, expr]
|
|
86
|
-
def factor_cube_formula_init():
|
|
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()
|
|
95
|
-
formula_gen9 = factor_quar_formula_init()
|
|
96
|
-
def factor_helper(equation, complexnum, power=2):
|
|
97
|
-
global formula_gen2, formula_gen3, formula_gen9
|
|
98
|
-
maxnum = 1
|
|
99
|
-
def high(eq):
|
|
100
|
-
nonlocal maxnum
|
|
101
|
-
if eq.name == "f_pow" and eq.children[1].name[:2] == "d_":
|
|
102
|
-
n = int(eq.children[1].name[2:])
|
|
103
|
-
if n>power and n % power == 0:
|
|
104
|
-
maxnum = max(maxnum, n)
|
|
105
|
-
for child in eq.children:
|
|
106
|
-
high(child)
|
|
107
|
-
def helper(eq):
|
|
108
|
-
nonlocal maxnum
|
|
109
|
-
if eq.name == "f_pow" and eq.children[1].name[:2] == "d_":
|
|
110
|
-
n = int(eq.children[1].name[2:])
|
|
111
|
-
sgn = round(abs(n)/n)
|
|
112
|
-
n = abs(n)
|
|
113
|
-
if n>power and n % power == 0 and maxnum==n:
|
|
114
|
-
out= (eq.children[0]**tree_form("d_"+str(sgn*int(n/power))))**power
|
|
115
|
-
return out
|
|
116
|
-
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
|
117
|
-
high(equation)
|
|
118
|
-
out = None
|
|
119
|
-
if power == 2:
|
|
120
|
-
out = transform_formula(helper(equation), "v_0", formula_gen2[0], formula_gen2[1], formula_gen2[2])
|
|
121
|
-
elif power == 3:
|
|
122
|
-
out = transform_formula(helper(equation), "v_0", formula_gen3[0], formula_gen3[1], formula_gen3[2])
|
|
123
|
-
elif power == 4:
|
|
124
|
-
out = transform_formula(helper(equation), "v_0", formula_gen9[0], formula_gen9[1], formula_gen9[2])
|
|
125
|
-
if out is not None:
|
|
126
|
-
out = simplify(solve(out))
|
|
127
|
-
if out is not None and (complexnum or (not complexnum and not contain(out, tree_form("s_i")))):
|
|
128
|
-
return out
|
|
129
|
-
return TreeNode(equation.name, [factor_helper(child, complexnum, power) for child in equation.children])
|
|
130
|
-
def factor(equation, complexnum=False):
|
|
131
|
-
return solve(take_common2(simplify(factor_helper(simplify(equation), complexnum, 2))))
|
|
132
|
-
def factor2(equation, complexnum=False):
|
|
133
|
-
return solve(factor_helper(solve(factor_helper(simplify(factor_helper(simplify(equation), complexnum, 2)), complexnum, 3)), complexnum, 4))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|