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/structure.py
CHANGED
@@ -1,103 +1,103 @@
|
|
1
|
-
import itertools
|
2
|
-
from .simplify import solve, simplify
|
3
|
-
from .base import *
|
4
|
-
|
5
|
-
def structure(equation, formula, formula_out=None, only_const=False):
|
6
|
-
varlist = {}
|
7
|
-
def helper(equation, formula):
|
8
|
-
nonlocal varlist
|
9
|
-
if formula.name[:2] == "v_" and int(formula.name[2:])< 0:
|
10
|
-
if formula.name in varlist.keys():
|
11
|
-
return varlist[formula.name] == equation
|
12
|
-
else:
|
13
|
-
varlist[formula.name] = equation
|
14
|
-
return True
|
15
|
-
if equation.name != formula.name:
|
16
|
-
return False
|
17
|
-
if len(equation.children) != len(formula.children):
|
18
|
-
return False
|
19
|
-
return all(helper(equation.children[i], formula.children[i]) for i in range(len(equation.children)))
|
20
|
-
def lst(formula):
|
21
|
-
out = set()
|
22
|
-
|
23
|
-
formula = conversion(formula)
|
24
|
-
def helper(node):
|
25
|
-
if not node.children:
|
26
|
-
return [node]
|
27
|
-
child_groups = [tuple(node.children)]
|
28
|
-
if node.name in ["f_addw", "f_mulw"]:
|
29
|
-
child_groups = list(itertools.permutations(node.children))
|
30
|
-
results = []
|
31
|
-
for children in child_groups:
|
32
|
-
child_perms = [helper(child) for child in children]
|
33
|
-
for combo in itertools.product(*child_perms):
|
34
|
-
results.append(TreeNode(node.name, list(combo)))
|
35
|
-
return results
|
36
|
-
def conversionrev(node):
|
37
|
-
if node.name == "f_addw":
|
38
|
-
node.name = "f_add"
|
39
|
-
elif node.name == "f_mulw":
|
40
|
-
node.name = "f_mul"
|
41
|
-
return TreeNode(node.name, [conversionrev(child) for child in node.children])
|
42
|
-
for tree in helper(formula):
|
43
|
-
out.add(tree)
|
44
|
-
return list(out)
|
45
|
-
def conversion(node):
|
46
|
-
if node.name == "f_add":
|
47
|
-
node.name = "f_addw"
|
48
|
-
elif node.name == "f_mul":
|
49
|
-
node.name = "f_mulw"
|
50
|
-
return TreeNode(node.name, [conversion(child) for child in node.children])
|
51
|
-
def conversionrev(node):
|
52
|
-
if node.name == "f_addw":
|
53
|
-
node.name = "f_add"
|
54
|
-
elif node.name == "f_mulw":
|
55
|
-
node.name = "f_mul"
|
56
|
-
return TreeNode(node.name, [conversionrev(child) for child in node.children])
|
57
|
-
equation = conversion(equation)
|
58
|
-
if formula_out is not None:
|
59
|
-
formula_out = conversion(formula_out)
|
60
|
-
for item in lst(formula):
|
61
|
-
varlist = {}
|
62
|
-
if helper(equation, item):
|
63
|
-
if only_const and any("v_" in str_form(varlist[key]) for key in varlist.keys()):
|
64
|
-
continue
|
65
|
-
if formula_out is None:
|
66
|
-
return varlist
|
67
|
-
for key in varlist.keys():
|
68
|
-
formula_out = replace(formula_out, tree_form(key), varlist[key])
|
69
|
-
|
70
|
-
return conversionrev(formula_out)
|
71
|
-
return None
|
72
|
-
|
73
|
-
def transform_formula(equation, wrt, formula_list, var, expr):
|
74
|
-
|
75
|
-
var2 = str(tree_form(wrt))
|
76
|
-
if var != var2:
|
77
|
-
formula_list = [[replace(y, tree_form("v_0"), tree_form(wrt)) for y in x] for x in formula_list]
|
78
|
-
expr = [[replace(item, tree_form("v_0"), tree_form(wrt)) for item in item2] for item2 in expr]
|
79
|
-
for item in formula_list:
|
80
|
-
item = list(item)
|
81
|
-
orig = copy.deepcopy(item)
|
82
|
-
for item2 in itertools.product(*expr):
|
83
|
-
for i in range(2):
|
84
|
-
for j in range(len(expr)):
|
85
|
-
item[i] = replace(item[i], expr[j][0], item2[j])
|
86
|
-
for i in range(2):
|
87
|
-
item[i] = solve(item[i])
|
88
|
-
out = None
|
89
|
-
p = False
|
90
|
-
if var != "":
|
91
|
-
p = True
|
92
|
-
try:
|
93
|
-
out = structure(copy.deepcopy(equation), copy.deepcopy(item[0]), copy.deepcopy(item[1]), p)
|
94
|
-
if out is not None:
|
95
|
-
out = simplify(out)
|
96
|
-
|
97
|
-
except:
|
98
|
-
out = None
|
99
|
-
|
100
|
-
if out is not None:
|
101
|
-
return out
|
102
|
-
item = copy.deepcopy(orig)
|
103
|
-
return None
|
1
|
+
import itertools
|
2
|
+
from .simplify import solve, simplify
|
3
|
+
from .base import *
|
4
|
+
|
5
|
+
def structure(equation, formula, formula_out=None, only_const=False):
|
6
|
+
varlist = {}
|
7
|
+
def helper(equation, formula):
|
8
|
+
nonlocal varlist
|
9
|
+
if formula.name[:2] == "v_" and int(formula.name[2:])< 0:
|
10
|
+
if formula.name in varlist.keys():
|
11
|
+
return varlist[formula.name] == equation
|
12
|
+
else:
|
13
|
+
varlist[formula.name] = equation
|
14
|
+
return True
|
15
|
+
if equation.name != formula.name:
|
16
|
+
return False
|
17
|
+
if len(equation.children) != len(formula.children):
|
18
|
+
return False
|
19
|
+
return all(helper(equation.children[i], formula.children[i]) for i in range(len(equation.children)))
|
20
|
+
def lst(formula):
|
21
|
+
out = set()
|
22
|
+
|
23
|
+
formula = conversion(formula)
|
24
|
+
def helper(node):
|
25
|
+
if not node.children:
|
26
|
+
return [node]
|
27
|
+
child_groups = [tuple(node.children)]
|
28
|
+
if node.name in ["f_addw", "f_mulw"]:
|
29
|
+
child_groups = list(itertools.permutations(node.children))
|
30
|
+
results = []
|
31
|
+
for children in child_groups:
|
32
|
+
child_perms = [helper(child) for child in children]
|
33
|
+
for combo in itertools.product(*child_perms):
|
34
|
+
results.append(TreeNode(node.name, list(combo)))
|
35
|
+
return results
|
36
|
+
def conversionrev(node):
|
37
|
+
if node.name == "f_addw":
|
38
|
+
node.name = "f_add"
|
39
|
+
elif node.name == "f_mulw":
|
40
|
+
node.name = "f_mul"
|
41
|
+
return TreeNode(node.name, [conversionrev(child) for child in node.children])
|
42
|
+
for tree in helper(formula):
|
43
|
+
out.add(tree)
|
44
|
+
return list(out)
|
45
|
+
def conversion(node):
|
46
|
+
if node.name == "f_add":
|
47
|
+
node.name = "f_addw"
|
48
|
+
elif node.name == "f_mul":
|
49
|
+
node.name = "f_mulw"
|
50
|
+
return TreeNode(node.name, [conversion(child) for child in node.children])
|
51
|
+
def conversionrev(node):
|
52
|
+
if node.name == "f_addw":
|
53
|
+
node.name = "f_add"
|
54
|
+
elif node.name == "f_mulw":
|
55
|
+
node.name = "f_mul"
|
56
|
+
return TreeNode(node.name, [conversionrev(child) for child in node.children])
|
57
|
+
equation = conversion(equation)
|
58
|
+
if formula_out is not None:
|
59
|
+
formula_out = conversion(formula_out)
|
60
|
+
for item in lst(formula):
|
61
|
+
varlist = {}
|
62
|
+
if helper(equation, item):
|
63
|
+
if only_const and any("v_" in str_form(varlist[key]) for key in varlist.keys()):
|
64
|
+
continue
|
65
|
+
if formula_out is None:
|
66
|
+
return varlist
|
67
|
+
for key in varlist.keys():
|
68
|
+
formula_out = replace(formula_out, tree_form(key), varlist[key])
|
69
|
+
|
70
|
+
return conversionrev(formula_out)
|
71
|
+
return None
|
72
|
+
|
73
|
+
def transform_formula(equation, wrt, formula_list, var, expr):
|
74
|
+
|
75
|
+
var2 = str(tree_form(wrt))
|
76
|
+
if var != var2:
|
77
|
+
formula_list = [[replace(y, tree_form("v_0"), tree_form(wrt)) for y in x] for x in formula_list]
|
78
|
+
expr = [[replace(item, tree_form("v_0"), tree_form(wrt)) for item in item2] for item2 in expr]
|
79
|
+
for item in formula_list:
|
80
|
+
item = list(item)
|
81
|
+
orig = copy.deepcopy(item)
|
82
|
+
for item2 in itertools.product(*expr):
|
83
|
+
for i in range(2):
|
84
|
+
for j in range(len(expr)):
|
85
|
+
item[i] = replace(item[i], expr[j][0], item2[j])
|
86
|
+
for i in range(2):
|
87
|
+
item[i] = solve(item[i])
|
88
|
+
out = None
|
89
|
+
p = False
|
90
|
+
if var != "":
|
91
|
+
p = True
|
92
|
+
try:
|
93
|
+
out = structure(copy.deepcopy(equation), copy.deepcopy(item[0]), copy.deepcopy(item[1]), p)
|
94
|
+
if out is not None:
|
95
|
+
out = simplify(out)
|
96
|
+
|
97
|
+
except:
|
98
|
+
out = None
|
99
|
+
|
100
|
+
if out is not None:
|
101
|
+
return out
|
102
|
+
item = copy.deepcopy(orig)
|
103
|
+
return None
|
mathai/tool.py
CHANGED
@@ -1,35 +1,35 @@
|
|
1
|
-
from .diff import diff
|
2
|
-
from .expand import expand
|
3
|
-
from .simplify import simplify
|
4
|
-
from .base import *
|
5
|
-
import math
|
6
|
-
|
7
|
-
def poly(eq, to_compute):
|
8
|
-
def substitute_val(eq, val, var="v_0"):
|
9
|
-
eq = replace(eq, tree_form(var), tree_form("d_"+str(val)))
|
10
|
-
return eq
|
11
|
-
def inv(eq):
|
12
|
-
if eq.name == "f_pow" and eq.children[1] == tree_form("d_-1"):
|
13
|
-
return False
|
14
|
-
if eq.name == "f_abs":
|
15
|
-
return False
|
16
|
-
if any(not inv(child) for child in eq.children):
|
17
|
-
return False
|
18
|
-
return True
|
19
|
-
if not inv(eq):
|
20
|
-
return None
|
21
|
-
out = []
|
22
|
-
eq2 = eq
|
23
|
-
for i in range(10):
|
24
|
-
out.append(expand(simplify(eq2)))
|
25
|
-
eq2 = diff(eq2, to_compute)
|
26
|
-
for i in range(len(out)-1,-1,-1):
|
27
|
-
if out[i] == tree_form("d_0"):
|
28
|
-
out.pop(i)
|
29
|
-
else:
|
30
|
-
break
|
31
|
-
final = []
|
32
|
-
for index, item in enumerate(out):
|
33
|
-
final.append(substitute_val(item, 0, to_compute)/tree_form("d_"+str(math.factorial(index))))
|
34
|
-
|
35
|
-
return [expand(simplify(item)) for item in final][::-1]
|
1
|
+
from .diff import diff
|
2
|
+
from .expand import expand
|
3
|
+
from .simplify import simplify
|
4
|
+
from .base import *
|
5
|
+
import math
|
6
|
+
|
7
|
+
def poly(eq, to_compute):
|
8
|
+
def substitute_val(eq, val, var="v_0"):
|
9
|
+
eq = replace(eq, tree_form(var), tree_form("d_"+str(val)))
|
10
|
+
return eq
|
11
|
+
def inv(eq):
|
12
|
+
if eq.name == "f_pow" and eq.children[1] == tree_form("d_-1"):
|
13
|
+
return False
|
14
|
+
if eq.name == "f_abs":
|
15
|
+
return False
|
16
|
+
if any(not inv(child) for child in eq.children):
|
17
|
+
return False
|
18
|
+
return True
|
19
|
+
if not inv(eq):
|
20
|
+
return None
|
21
|
+
out = []
|
22
|
+
eq2 = eq
|
23
|
+
for i in range(10):
|
24
|
+
out.append(expand(simplify(eq2)))
|
25
|
+
eq2 = diff(eq2, to_compute)
|
26
|
+
for i in range(len(out)-1,-1,-1):
|
27
|
+
if out[i] == tree_form("d_0"):
|
28
|
+
out.pop(i)
|
29
|
+
else:
|
30
|
+
break
|
31
|
+
final = []
|
32
|
+
for index, item in enumerate(out):
|
33
|
+
final.append(substitute_val(item, 0, to_compute)/tree_form("d_"+str(math.factorial(index))))
|
34
|
+
|
35
|
+
return [expand(simplify(item)) for item in final][::-1]
|
mathai/trig.py
CHANGED
@@ -1,169 +1,169 @@
|
|
1
|
-
import itertools
|
2
|
-
from .simplify import solve, simplify
|
3
|
-
from .base import *
|
4
|
-
from .expand import expand
|
5
|
-
from .structure import transform_formula
|
6
|
-
from .parser import parse
|
7
|
-
trig_sin_table = {
|
8
|
-
(0,1): parse("0"),
|
9
|
-
(1,6): parse("1/2"),
|
10
|
-
(1,4): parse("2^(1/2)/2"), # π/4
|
11
|
-
(1,3): parse("3^(1/2)/2"), # π/3
|
12
|
-
(1,2): parse("1"), # π/2
|
13
|
-
(2,3): parse("3^(1/2)/2"), # 2π/3
|
14
|
-
(3,4): parse("2^(1/2)/2"), # 3π/4
|
15
|
-
(5,6): parse("1/2"), # 5π/6
|
16
|
-
(1,1): parse("0") # π
|
17
|
-
}
|
18
|
-
trig_cos_table = {
|
19
|
-
(0,1): parse("1"), # 0
|
20
|
-
(1,6): parse("3^(1/2)/2"), # π/6
|
21
|
-
(1,4): parse("2^(1/2)/2"), # π/4
|
22
|
-
(1,3): parse("1/2"), # π/3
|
23
|
-
(1,2): parse("0"), # π/2
|
24
|
-
(2,3): parse("-1/2"), # 2π/3
|
25
|
-
(3,4): parse("-2^(1/2)/2"), # 3π/4
|
26
|
-
(5,6): parse("-1/2"), # 5π/6
|
27
|
-
(1,1): parse("-1") # π
|
28
|
-
}
|
29
|
-
|
30
|
-
for key in trig_cos_table.keys():
|
31
|
-
trig_cos_table[key] = simplify(trig_cos_table[key])
|
32
|
-
for key in trig_sin_table.keys():
|
33
|
-
trig_sin_table[key] = simplify(trig_sin_table[key])
|
34
|
-
def trig0(eq):
|
35
|
-
if eq is None:
|
36
|
-
return None
|
37
|
-
def isneg(eq):
|
38
|
-
if eq.name[:2] != "d_":
|
39
|
-
return False
|
40
|
-
if int(eq.name[2:]) >= 0:
|
41
|
-
return False
|
42
|
-
return True
|
43
|
-
def single_pi(lst):
|
44
|
-
if tree_form("d_0") in lst:
|
45
|
-
return 0, 1
|
46
|
-
count = 0
|
47
|
-
for item in lst:
|
48
|
-
if item == tree_form("s_pi"):
|
49
|
-
count += 1
|
50
|
-
if count != 1:
|
51
|
-
return None
|
52
|
-
eq = solve(product(lst)/tree_form("s_pi"))
|
53
|
-
out = frac(eq)
|
54
|
-
if out is None or out < 0:
|
55
|
-
return None
|
56
|
-
a,b= out.numerator, out.denominator
|
57
|
-
a %= 2*b
|
58
|
-
if a > b:
|
59
|
-
a = 2*b - a
|
60
|
-
return a, b
|
61
|
-
if eq.name == "f_arctan":
|
62
|
-
if eq.children[0].name == "d_0":
|
63
|
-
return tree_form("d_0")
|
64
|
-
if eq.name == "f_log":
|
65
|
-
if eq.children[0].name == "d_1":
|
66
|
-
return tree_form("d_0")
|
67
|
-
if eq.name=="f_tan":
|
68
|
-
return eq.children[0].fx("sin")/eq.children[0].fx("cos")
|
69
|
-
if eq.name == "f_sec":
|
70
|
-
return eq.children[0].fx("cos")**-1
|
71
|
-
if eq.name == "f_cosec":
|
72
|
-
return eq.children[0].fx("sin")**-1
|
73
|
-
if eq.name == "f_cot":
|
74
|
-
return eq.children[0].fx("cos")/eq.children[0].fx("sin")
|
75
|
-
if eq.name == "f_sin":
|
76
|
-
lst = factor_generation(eq.children[0])
|
77
|
-
if any(isneg(item) for item in lst):
|
78
|
-
return -(eq.children[0]*-1).fx("sin")
|
79
|
-
out=single_pi(lst)
|
80
|
-
if out is not None:
|
81
|
-
return trig_sin_table[tuple(out)]
|
82
|
-
if eq.name == "f_cos":
|
83
|
-
lst = factor_generation(eq.children[0])
|
84
|
-
if any(isneg(item) for item in lst):
|
85
|
-
return (eq.children[0]*-1).fx("cos")
|
86
|
-
out=single_pi(lst)
|
87
|
-
if out is not None:
|
88
|
-
if tuple(out) in trig_cos_table.keys():
|
89
|
-
return trig_cos_table[tuple(out)]
|
90
|
-
return TreeNode(eq.name, [trig0(child) for child in eq.children])
|
91
|
-
|
92
|
-
def product_to_sum(eq):
|
93
|
-
lst = factor_generation(eq)
|
94
|
-
if len(lst) == 1:
|
95
|
-
return lst[0]
|
96
|
-
if len(lst) == 2:
|
97
|
-
a, b = lst
|
98
|
-
if a.name == "f_sin" and b.name == "f_sin":
|
99
|
-
return ((a.children[0] - b.children[0]).fx("cos") - (a.children[0] + b.children[0]).fx("cos")) / tree_form("d_2")
|
100
|
-
elif a.name == "f_cos" and b.name == "f_cos":
|
101
|
-
return ((a.children[0] - b.children[0]).fx("cos") + (a.children[0] + b.children[0]).fx("cos")) / tree_form("d_2")
|
102
|
-
elif a.name == "f_sin" and b.name == "f_cos":
|
103
|
-
return ((a.children[0] + b.children[0]).fx("sin") + (a.children[0] - b.children[0]).fx("sin")) / tree_form("d_2")
|
104
|
-
elif a.name == "f_cos" and b.name == "f_sin":
|
105
|
-
return ((a.children[0] + b.children[0]).fx("sin") - (a.children[0] - b.children[0]).fx("sin")) / tree_form("d_2")
|
106
|
-
first, rest = lst[0], lst[1:]
|
107
|
-
s = tree_form("d_0")
|
108
|
-
eq = expand(simplify(first * product_to_sum(solve(TreeNode("f_mul", rest)))))
|
109
|
-
if eq.name == "f_add":
|
110
|
-
for child in eq.children:
|
111
|
-
s += product_to_sum(child)
|
112
|
-
s = simplify(s)
|
113
|
-
else:
|
114
|
-
s = eq
|
115
|
-
return s
|
116
|
-
def trig_formula_init():
|
117
|
-
var = ""
|
118
|
-
formula_list = [(f"A*sin(B)+C*sin(B)", f"(A^2+C^2)^(1/2)*sin(B+arctan(C/A))"),\
|
119
|
-
(f"sin(B+D)", f"sin(B)*cos(D)+cos(B)*sin(D)"),\
|
120
|
-
(f"cos(B+D)", f"cos(B)*cos(D)-sin(B)*sin(D)"),\
|
121
|
-
(f"cos(B)^2", f"1-sin(B)^2"),\
|
122
|
-
(f"1/cos(B)^2", f"1/(1-sin(B)^2)"),\
|
123
|
-
(f"cos(arcsin(B))", f"sqrt(1-B^2)"),\
|
124
|
-
(f"sin(arccos(B))", f"sqrt(1-B^2)"),\
|
125
|
-
(f"arccos(B)", f"pi/2-arcsin(B)")]
|
126
|
-
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
127
|
-
expr = [[parse("A"), parse("1")], [parse("B")], [parse("C"), parse("1")], [parse("D")]]
|
128
|
-
return [formula_list, var, expr]
|
129
|
-
formula_gen4 = trig_formula_init()
|
130
|
-
def trig3(eq):
|
131
|
-
def iseven(eq):
|
132
|
-
if eq.name[:2] != "d_":
|
133
|
-
return False
|
134
|
-
if int(eq.name[2:]) < 2 or int(eq.name[2:]) % 2 != 0:
|
135
|
-
return False
|
136
|
-
return True
|
137
|
-
|
138
|
-
if eq.name == "f_sin":
|
139
|
-
lst = factor_generation(eq.children[0])
|
140
|
-
if any(iseven(item) for item in lst):
|
141
|
-
eq= 2*(eq.children[0]/2).fx("sin")*(eq.children[0]/2).fx("cos")
|
142
|
-
if eq.name == "f_cos":
|
143
|
-
lst = factor_generation(eq.children[0])
|
144
|
-
if any(iseven(item) for item in lst):
|
145
|
-
eq = (eq.children[0]/2).fx("cos")**2-(eq.children[0]/2).fx("sin")**2
|
146
|
-
eq = expand(simplify(eq))
|
147
|
-
return TreeNode(eq.name, [trig3(child) for child in eq.children])
|
148
|
-
def trig1(equation):
|
149
|
-
equation = product_to_sum(equation)
|
150
|
-
return TreeNode(equation.name, [trig1(child) for child in equation.children])
|
151
|
-
def trig4(eq):
|
152
|
-
out = transform_formula(eq, "v_0", formula_gen4[0], formula_gen4[1], formula_gen4[2])
|
153
|
-
if out is not None:
|
154
|
-
return trig4(out)
|
155
|
-
else:
|
156
|
-
return TreeNode(eq.name, [trig4(child) for child in eq.children])
|
157
|
-
def trig2(eq):
|
158
|
-
if eq.name == "f_add":
|
159
|
-
for item in itertools.combinations(range(len(eq.children)), 2):
|
160
|
-
if all(eq.children[item2].name == "f_sin" for item2 in item):
|
161
|
-
a, b = eq.children[item[0]].children[0], eq.children[item[1]].children[0]
|
162
|
-
rest = [item2 for index, item2 in enumerate(eq.children) if index not in item]
|
163
|
-
if len(rest)==0:
|
164
|
-
rest = tree_form("d_0")
|
165
|
-
else:
|
166
|
-
rest = summation(rest)
|
167
|
-
two = tree_form("d_2")
|
168
|
-
return rest + two*((a+b)/two).fx("sin")*((a-b)/two).fx("cos")
|
169
|
-
return TreeNode(eq.name, [trig2(child) for child in eq.children])
|
1
|
+
import itertools
|
2
|
+
from .simplify import solve, simplify
|
3
|
+
from .base import *
|
4
|
+
from .expand import expand
|
5
|
+
from .structure import transform_formula
|
6
|
+
from .parser import parse
|
7
|
+
trig_sin_table = {
|
8
|
+
(0,1): parse("0"),
|
9
|
+
(1,6): parse("1/2"),
|
10
|
+
(1,4): parse("2^(1/2)/2"), # π/4
|
11
|
+
(1,3): parse("3^(1/2)/2"), # π/3
|
12
|
+
(1,2): parse("1"), # π/2
|
13
|
+
(2,3): parse("3^(1/2)/2"), # 2π/3
|
14
|
+
(3,4): parse("2^(1/2)/2"), # 3π/4
|
15
|
+
(5,6): parse("1/2"), # 5π/6
|
16
|
+
(1,1): parse("0") # π
|
17
|
+
}
|
18
|
+
trig_cos_table = {
|
19
|
+
(0,1): parse("1"), # 0
|
20
|
+
(1,6): parse("3^(1/2)/2"), # π/6
|
21
|
+
(1,4): parse("2^(1/2)/2"), # π/4
|
22
|
+
(1,3): parse("1/2"), # π/3
|
23
|
+
(1,2): parse("0"), # π/2
|
24
|
+
(2,3): parse("-1/2"), # 2π/3
|
25
|
+
(3,4): parse("-2^(1/2)/2"), # 3π/4
|
26
|
+
(5,6): parse("-1/2"), # 5π/6
|
27
|
+
(1,1): parse("-1") # π
|
28
|
+
}
|
29
|
+
|
30
|
+
for key in trig_cos_table.keys():
|
31
|
+
trig_cos_table[key] = simplify(trig_cos_table[key])
|
32
|
+
for key in trig_sin_table.keys():
|
33
|
+
trig_sin_table[key] = simplify(trig_sin_table[key])
|
34
|
+
def trig0(eq):
|
35
|
+
if eq is None:
|
36
|
+
return None
|
37
|
+
def isneg(eq):
|
38
|
+
if eq.name[:2] != "d_":
|
39
|
+
return False
|
40
|
+
if int(eq.name[2:]) >= 0:
|
41
|
+
return False
|
42
|
+
return True
|
43
|
+
def single_pi(lst):
|
44
|
+
if tree_form("d_0") in lst:
|
45
|
+
return 0, 1
|
46
|
+
count = 0
|
47
|
+
for item in lst:
|
48
|
+
if item == tree_form("s_pi"):
|
49
|
+
count += 1
|
50
|
+
if count != 1:
|
51
|
+
return None
|
52
|
+
eq = solve(product(lst)/tree_form("s_pi"))
|
53
|
+
out = frac(eq)
|
54
|
+
if out is None or out < 0:
|
55
|
+
return None
|
56
|
+
a,b= out.numerator, out.denominator
|
57
|
+
a %= 2*b
|
58
|
+
if a > b:
|
59
|
+
a = 2*b - a
|
60
|
+
return a, b
|
61
|
+
if eq.name == "f_arctan":
|
62
|
+
if eq.children[0].name == "d_0":
|
63
|
+
return tree_form("d_0")
|
64
|
+
if eq.name == "f_log":
|
65
|
+
if eq.children[0].name == "d_1":
|
66
|
+
return tree_form("d_0")
|
67
|
+
if eq.name=="f_tan":
|
68
|
+
return eq.children[0].fx("sin")/eq.children[0].fx("cos")
|
69
|
+
if eq.name == "f_sec":
|
70
|
+
return eq.children[0].fx("cos")**-1
|
71
|
+
if eq.name == "f_cosec":
|
72
|
+
return eq.children[0].fx("sin")**-1
|
73
|
+
if eq.name == "f_cot":
|
74
|
+
return eq.children[0].fx("cos")/eq.children[0].fx("sin")
|
75
|
+
if eq.name == "f_sin":
|
76
|
+
lst = factor_generation(eq.children[0])
|
77
|
+
if any(isneg(item) for item in lst):
|
78
|
+
return -(eq.children[0]*-1).fx("sin")
|
79
|
+
out=single_pi(lst)
|
80
|
+
if out is not None:
|
81
|
+
return trig_sin_table[tuple(out)]
|
82
|
+
if eq.name == "f_cos":
|
83
|
+
lst = factor_generation(eq.children[0])
|
84
|
+
if any(isneg(item) for item in lst):
|
85
|
+
return (eq.children[0]*-1).fx("cos")
|
86
|
+
out=single_pi(lst)
|
87
|
+
if out is not None:
|
88
|
+
if tuple(out) in trig_cos_table.keys():
|
89
|
+
return trig_cos_table[tuple(out)]
|
90
|
+
return TreeNode(eq.name, [trig0(child) for child in eq.children])
|
91
|
+
|
92
|
+
def product_to_sum(eq):
|
93
|
+
lst = factor_generation(eq)
|
94
|
+
if len(lst) == 1:
|
95
|
+
return lst[0]
|
96
|
+
if len(lst) == 2:
|
97
|
+
a, b = lst
|
98
|
+
if a.name == "f_sin" and b.name == "f_sin":
|
99
|
+
return ((a.children[0] - b.children[0]).fx("cos") - (a.children[0] + b.children[0]).fx("cos")) / tree_form("d_2")
|
100
|
+
elif a.name == "f_cos" and b.name == "f_cos":
|
101
|
+
return ((a.children[0] - b.children[0]).fx("cos") + (a.children[0] + b.children[0]).fx("cos")) / tree_form("d_2")
|
102
|
+
elif a.name == "f_sin" and b.name == "f_cos":
|
103
|
+
return ((a.children[0] + b.children[0]).fx("sin") + (a.children[0] - b.children[0]).fx("sin")) / tree_form("d_2")
|
104
|
+
elif a.name == "f_cos" and b.name == "f_sin":
|
105
|
+
return ((a.children[0] + b.children[0]).fx("sin") - (a.children[0] - b.children[0]).fx("sin")) / tree_form("d_2")
|
106
|
+
first, rest = lst[0], lst[1:]
|
107
|
+
s = tree_form("d_0")
|
108
|
+
eq = expand(simplify(first * product_to_sum(solve(TreeNode("f_mul", rest)))))
|
109
|
+
if eq.name == "f_add":
|
110
|
+
for child in eq.children:
|
111
|
+
s += product_to_sum(child)
|
112
|
+
s = simplify(s)
|
113
|
+
else:
|
114
|
+
s = eq
|
115
|
+
return s
|
116
|
+
def trig_formula_init():
|
117
|
+
var = ""
|
118
|
+
formula_list = [(f"A*sin(B)+C*sin(B)", f"(A^2+C^2)^(1/2)*sin(B+arctan(C/A))"),\
|
119
|
+
(f"sin(B+D)", f"sin(B)*cos(D)+cos(B)*sin(D)"),\
|
120
|
+
(f"cos(B+D)", f"cos(B)*cos(D)-sin(B)*sin(D)"),\
|
121
|
+
(f"cos(B)^2", f"1-sin(B)^2"),\
|
122
|
+
(f"1/cos(B)^2", f"1/(1-sin(B)^2)"),\
|
123
|
+
(f"cos(arcsin(B))", f"sqrt(1-B^2)"),\
|
124
|
+
(f"sin(arccos(B))", f"sqrt(1-B^2)"),\
|
125
|
+
(f"arccos(B)", f"pi/2-arcsin(B)")]
|
126
|
+
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
127
|
+
expr = [[parse("A"), parse("1")], [parse("B")], [parse("C"), parse("1")], [parse("D")]]
|
128
|
+
return [formula_list, var, expr]
|
129
|
+
formula_gen4 = trig_formula_init()
|
130
|
+
def trig3(eq):
|
131
|
+
def iseven(eq):
|
132
|
+
if eq.name[:2] != "d_":
|
133
|
+
return False
|
134
|
+
if int(eq.name[2:]) < 2 or int(eq.name[2:]) % 2 != 0:
|
135
|
+
return False
|
136
|
+
return True
|
137
|
+
|
138
|
+
if eq.name == "f_sin":
|
139
|
+
lst = factor_generation(eq.children[0])
|
140
|
+
if any(iseven(item) for item in lst):
|
141
|
+
eq= 2*(eq.children[0]/2).fx("sin")*(eq.children[0]/2).fx("cos")
|
142
|
+
if eq.name == "f_cos":
|
143
|
+
lst = factor_generation(eq.children[0])
|
144
|
+
if any(iseven(item) for item in lst):
|
145
|
+
eq = (eq.children[0]/2).fx("cos")**2-(eq.children[0]/2).fx("sin")**2
|
146
|
+
eq = expand(simplify(eq))
|
147
|
+
return TreeNode(eq.name, [trig3(child) for child in eq.children])
|
148
|
+
def trig1(equation):
|
149
|
+
equation = product_to_sum(equation)
|
150
|
+
return TreeNode(equation.name, [trig1(child) for child in equation.children])
|
151
|
+
def trig4(eq):
|
152
|
+
out = transform_formula(eq, "v_0", formula_gen4[0], formula_gen4[1], formula_gen4[2])
|
153
|
+
if out is not None:
|
154
|
+
return trig4(out)
|
155
|
+
else:
|
156
|
+
return TreeNode(eq.name, [trig4(child) for child in eq.children])
|
157
|
+
def trig2(eq):
|
158
|
+
if eq.name == "f_add":
|
159
|
+
for item in itertools.combinations(range(len(eq.children)), 2):
|
160
|
+
if all(eq.children[item2].name == "f_sin" for item2 in item):
|
161
|
+
a, b = eq.children[item[0]].children[0], eq.children[item[1]].children[0]
|
162
|
+
rest = [item2 for index, item2 in enumerate(eq.children) if index not in item]
|
163
|
+
if len(rest)==0:
|
164
|
+
rest = tree_form("d_0")
|
165
|
+
else:
|
166
|
+
rest = summation(rest)
|
167
|
+
two = tree_form("d_2")
|
168
|
+
return rest + two*((a+b)/two).fx("sin")*((a-b)/two).fx("cos")
|
169
|
+
return TreeNode(eq.name, [trig2(child) for child in eq.children])
|