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/linear.py CHANGED
@@ -1,152 +1,152 @@
1
- from .diff import diff
2
- from .simplify import simplify, solve
3
- from .fraction import fraction
4
- from .expand import expand
5
- from .base import *
6
- def rref(matrix):
7
- rows, cols = len(matrix), len(matrix[0])
8
- lead = 0
9
- for r in range(rows):
10
- if lead >= cols:
11
- return matrix
12
- i = r
13
- while fraction(simplify(matrix[i][lead])) == tree_form("d_0"):
14
- i += 1
15
- if i == rows:
16
- i = r
17
- lead += 1
18
- if lead == cols:
19
- return matrix
20
- matrix[i], matrix[r] = matrix[r], matrix[i]
21
- lv = matrix[r][lead]
22
- matrix[r] = [fraction(simplify(m / lv)) for m in matrix[r]]
23
- for i in range(rows):
24
- if i != r:
25
- lv = matrix[i][lead]
26
- matrix[i] = [fraction(simplify(m - lv * n)) for m, n in zip(matrix[i], matrix[r])]
27
- lead += 1
28
- return matrix
29
- def islinear(eq, fxconst):
30
- eq =simplify(eq)
31
- if eq.name == "f_pow" and fxconst(eq):#"v_" in str_form(eq):
32
- return False
33
- for child in eq.children:
34
- out = islinear(child, fxconst)
35
- if not out:
36
- return out
37
- return True
38
- def linear(eqlist, fxconst):
39
- final = []
40
- extra = []
41
- for i in range(len(eqlist)-1,-1,-1):
42
- if eqlist[i].name == "f_mul" and not islinear(expand2(eqlist[i]), fxconst):
43
- if "v_" in str_form(eqlist[i]):
44
- eqlist[i] = TreeNode("f_mul", [child for child in eqlist[i].children if fxconst(child)])
45
- if all(islinear(child, fxconst) for child in eqlist[i].children):
46
- for child in eqlist[i].children:
47
- extra.append(TreeNode("f_eq", [child, tree_form("d_0")]))
48
- eqlist.pop(i)
49
- else:
50
- final.append(TreeNode("f_eq", [eqlist[i], tree_form("d_0")]))
51
- eqlist.pop(i)
52
-
53
- if extra != []:
54
- final.append(TreeNode("f_or", extra))
55
- if eqlist == []:
56
- if len(final)==1:
57
-
58
- return final[0]
59
- return TreeNode("f_and", final)
60
- eqlist = [eq for eq in eqlist if fxconst(eq)]
61
- if not all(islinear(eq, fxconst) for eq in eqlist):
62
- return TreeNode("f_and", copy.deepcopy(final+eqlist))
63
- vl = []
64
- def varlist(eq, fxconst):
65
- nonlocal vl
66
- if eq.name[:2] == "v_" and fxconst(eq):
67
- vl.append(eq.name)
68
- for child in eq.children:
69
- varlist(child, fxconst)
70
- for eq in eqlist:
71
- varlist(eq, fxconst)
72
- vl = list(set(vl))
73
- if len(vl) > len(eqlist):
74
- return TreeNode("f_and", final+[TreeNode("f_eq", [x, tree_form("d_0")]) for x in eqlist])
75
- m = []
76
- for eq in eqlist:
77
- s = copy.deepcopy(eq)
78
- row = []
79
- for v in vl:
80
- row.append(diff(eq, v))
81
- s = replace(s, tree_form(v), tree_form("d_0"))
82
- row.append(s)
83
- m.append(row)
84
- for i in range(len(m)):
85
- for j in range(len(m[i])):
86
- m[i][j] = simplify(expand(m[i][j]))
87
- #print(m)
88
- m = rref(m)
89
-
90
- for i in range(len(m)):
91
- for j in range(len(m[i])):
92
- m[i][j] = fraction(m[i][j])
93
- #print(m)
94
- for item in m:
95
- if all(item2==tree_form("d_0") for item2 in item[:-1]) and item[-1] != tree_form("d_0"):
96
- return tree_form("d_false")
97
-
98
- output = []
99
- for index, row in enumerate(m):
100
- count = 0
101
- for item in row[:-1]:
102
- if item == tree_form("d_1"):
103
- count += 1
104
- if count == 2:
105
- break
106
- elif item == tree_form("d_0") and count == 1:
107
- break
108
- if count == 0:
109
- continue
110
- output.append(tree_form(vl[index])+row[-1])
111
- if len(output) == 1 and len(final)==0:
112
- return TreeNode("f_eq", [output[0], tree_form("d_0")])
113
- return TreeNode("f_and", final+[TreeNode("f_eq", [x, tree_form("d_0")]) for x in output])
114
-
115
- def rmeq(eq):
116
- if eq.name == "f_eq":
117
- return rmeq(eq.children[0])
118
- return TreeNode(eq.name, [rmeq(child) for child in eq.children])
119
-
120
- def mat0(eq, lst=None):
121
- def findeq(eq):
122
- out = []
123
- if "f_list" not in str_form(eq) and "f_eq" not in str_form(eq):
124
- return [str_form(eq)]
125
- else:
126
- for child in eq.children:
127
- out += findeq(child)
128
- return out
129
- eqlist = findeq(eq)
130
- eqlist = [tree_form(x) for x in eqlist]
131
- eqlist = [rmeq(x) for x in eqlist]
132
- eqlist = [TreeNode("f_mul", factor_generation(x)) for x in eqlist if x != tree_form("d_0")]
133
- eqlist = [x.children[0] if len(x.children) == 1 else x for x in eqlist]
134
- out = None
135
-
136
- if lst is None:
137
- out = linear(copy.deepcopy(eqlist), lambda x: "v_" in str_form(x))
138
- else:
139
- out = linear(copy.deepcopy(eqlist), lambda x: any(contain(x, item) for item in lst))
140
- def rms(eq):
141
- if eq.name in ["f_and", "f_or"] and len(eq.children) == 1:
142
- return eq.children[0]
143
- return TreeNode(eq.name, [rms(child) for child in eq.children])
144
- return rms(out)
145
- def linear_solve(eq, lst=None):
146
- if eq.name == "f_and":
147
- eq2 = copy.deepcopy(eq)
148
- eq2.name = "f_list"
149
- return mat0(eq2, lst)
150
- elif eq.name == "f_eq":
151
- return mat0(eq, lst)
152
- return TreeNode(eq.name, [linear_solve(child, lst) for child in eq.children])
1
+ from .diff import diff
2
+ from .simplify import simplify, solve
3
+ from .fraction import fraction
4
+ from .expand import expand
5
+ from .base import *
6
+ def rref(matrix):
7
+ rows, cols = len(matrix), len(matrix[0])
8
+ lead = 0
9
+ for r in range(rows):
10
+ if lead >= cols:
11
+ return matrix
12
+ i = r
13
+ while fraction(simplify(matrix[i][lead])) == tree_form("d_0"):
14
+ i += 1
15
+ if i == rows:
16
+ i = r
17
+ lead += 1
18
+ if lead == cols:
19
+ return matrix
20
+ matrix[i], matrix[r] = matrix[r], matrix[i]
21
+ lv = matrix[r][lead]
22
+ matrix[r] = [fraction(simplify(m / lv)) for m in matrix[r]]
23
+ for i in range(rows):
24
+ if i != r:
25
+ lv = matrix[i][lead]
26
+ matrix[i] = [fraction(simplify(m - lv * n)) for m, n in zip(matrix[i], matrix[r])]
27
+ lead += 1
28
+ return matrix
29
+ def islinear(eq, fxconst):
30
+ eq =simplify(eq)
31
+ if eq.name == "f_pow" and fxconst(eq):#"v_" in str_form(eq):
32
+ return False
33
+ for child in eq.children:
34
+ out = islinear(child, fxconst)
35
+ if not out:
36
+ return out
37
+ return True
38
+ def linear(eqlist, fxconst):
39
+ final = []
40
+ extra = []
41
+ for i in range(len(eqlist)-1,-1,-1):
42
+ if eqlist[i].name == "f_mul" and not islinear(expand2(eqlist[i]), fxconst):
43
+ if "v_" in str_form(eqlist[i]):
44
+ eqlist[i] = TreeNode("f_mul", [child for child in eqlist[i].children if fxconst(child)])
45
+ if all(islinear(child, fxconst) for child in eqlist[i].children):
46
+ for child in eqlist[i].children:
47
+ extra.append(TreeNode("f_eq", [child, tree_form("d_0")]))
48
+ eqlist.pop(i)
49
+ else:
50
+ final.append(TreeNode("f_eq", [eqlist[i], tree_form("d_0")]))
51
+ eqlist.pop(i)
52
+
53
+ if extra != []:
54
+ final.append(TreeNode("f_or", extra))
55
+ if eqlist == []:
56
+ if len(final)==1:
57
+
58
+ return final[0]
59
+ return TreeNode("f_and", final)
60
+ eqlist = [eq for eq in eqlist if fxconst(eq)]
61
+ if not all(islinear(eq, fxconst) for eq in eqlist):
62
+ return TreeNode("f_and", copy.deepcopy(final+eqlist))
63
+ vl = []
64
+ def varlist(eq, fxconst):
65
+ nonlocal vl
66
+ if eq.name[:2] == "v_" and fxconst(eq):
67
+ vl.append(eq.name)
68
+ for child in eq.children:
69
+ varlist(child, fxconst)
70
+ for eq in eqlist:
71
+ varlist(eq, fxconst)
72
+ vl = list(set(vl))
73
+ if len(vl) > len(eqlist):
74
+ return TreeNode("f_and", final+[TreeNode("f_eq", [x, tree_form("d_0")]) for x in eqlist])
75
+ m = []
76
+ for eq in eqlist:
77
+ s = copy.deepcopy(eq)
78
+ row = []
79
+ for v in vl:
80
+ row.append(diff(eq, v))
81
+ s = replace(s, tree_form(v), tree_form("d_0"))
82
+ row.append(s)
83
+ m.append(row)
84
+ for i in range(len(m)):
85
+ for j in range(len(m[i])):
86
+ m[i][j] = simplify(expand(m[i][j]))
87
+ #print(m)
88
+ m = rref(m)
89
+
90
+ for i in range(len(m)):
91
+ for j in range(len(m[i])):
92
+ m[i][j] = fraction(m[i][j])
93
+ #print(m)
94
+ for item in m:
95
+ if all(item2==tree_form("d_0") for item2 in item[:-1]) and item[-1] != tree_form("d_0"):
96
+ return tree_form("d_false")
97
+
98
+ output = []
99
+ for index, row in enumerate(m):
100
+ count = 0
101
+ for item in row[:-1]:
102
+ if item == tree_form("d_1"):
103
+ count += 1
104
+ if count == 2:
105
+ break
106
+ elif item == tree_form("d_0") and count == 1:
107
+ break
108
+ if count == 0:
109
+ continue
110
+ output.append(tree_form(vl[index])+row[-1])
111
+ if len(output) == 1 and len(final)==0:
112
+ return TreeNode("f_eq", [output[0], tree_form("d_0")])
113
+ return TreeNode("f_and", final+[TreeNode("f_eq", [x, tree_form("d_0")]) for x in output])
114
+
115
+ def rmeq(eq):
116
+ if eq.name == "f_eq":
117
+ return rmeq(eq.children[0])
118
+ return TreeNode(eq.name, [rmeq(child) for child in eq.children])
119
+
120
+ def mat0(eq, lst=None):
121
+ def findeq(eq):
122
+ out = []
123
+ if "f_list" not in str_form(eq) and "f_eq" not in str_form(eq):
124
+ return [str_form(eq)]
125
+ else:
126
+ for child in eq.children:
127
+ out += findeq(child)
128
+ return out
129
+ eqlist = findeq(eq)
130
+ eqlist = [tree_form(x) for x in eqlist]
131
+ eqlist = [rmeq(x) for x in eqlist]
132
+ eqlist = [TreeNode("f_mul", factor_generation(x)) for x in eqlist if x != tree_form("d_0")]
133
+ eqlist = [x.children[0] if len(x.children) == 1 else x for x in eqlist]
134
+ out = None
135
+
136
+ if lst is None:
137
+ out = linear(copy.deepcopy(eqlist), lambda x: "v_" in str_form(x))
138
+ else:
139
+ out = linear(copy.deepcopy(eqlist), lambda x: any(contain(x, item) for item in lst))
140
+ def rms(eq):
141
+ if eq.name in ["f_and", "f_or"] and len(eq.children) == 1:
142
+ return eq.children[0]
143
+ return TreeNode(eq.name, [rms(child) for child in eq.children])
144
+ return rms(out)
145
+ def linear_solve(eq, lst=None):
146
+ if eq.name == "f_and":
147
+ eq2 = copy.deepcopy(eq)
148
+ eq2.name = "f_list"
149
+ return mat0(eq2, lst)
150
+ elif eq.name == "f_eq":
151
+ return mat0(eq, lst)
152
+ return TreeNode(eq.name, [linear_solve(child, lst) for child in eq.children])