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/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])