mathai 0.4.0__py3-none-any.whl → 0.6.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/limit.py CHANGED
@@ -1,12 +1,12 @@
1
1
  from .structure import structure
2
2
  from .base import *
3
3
  from .parser import parse
4
- from .simplify import simplify, solve
4
+ from .simplify import simplify
5
5
  from .expand import expand
6
6
  from .diff import diff
7
7
  from .trig import trig0
8
8
  from .fraction import fraction
9
- from .printeq import printeq_str
9
+ from .printeq import printeq
10
10
  tab=0
11
11
  def substitute_val(eq, val, var="v_0"):
12
12
  eq = replace(eq, tree_form(var), tree_form("d_"+str(val)))
@@ -14,6 +14,7 @@ def substitute_val(eq, val, var="v_0"):
14
14
 
15
15
  def subslimit(equation, var):
16
16
  equation2 = trig0(replace(equation, var, tree_form("d_0")))
17
+
17
18
  try:
18
19
  tmp = simplify(equation2)
19
20
  return simplify(expand(tmp))
@@ -32,99 +33,124 @@ def check(num, den, var):
32
33
  return simplify(n/d)
33
34
  return False
34
35
  def lhospital(num, den, steps,var):
35
- logs = []
36
36
 
37
37
  out = check(num, den, var)
38
+
38
39
  if isinstance(out, TreeNode):
39
- return out,[]
40
+ return out
40
41
  for _ in range(steps):
41
42
  num2, den2 = map(lambda e: simplify(diff(e, var)), (num, den))
42
43
  out = check(num2, den2, var)
43
44
  if out is True:
44
45
  num, den = num2, den2
45
- logs += [(0,"lim x->0 "+printeq_str(simplify(num/den)))]
46
46
  continue
47
47
  if out is False:
48
48
  eq2 = simplify(fraction(simplify(num/den)))
49
- return eq2,logs
50
- return out,logs
49
+ return eq2
50
+ return out
51
51
  def lhospital2(eq, var):
52
52
  eq= simplify(eq)
53
53
  if eq is None:
54
54
  return None
55
55
  if not contain(eq, tree_form(var)):
56
- return eq,[]
56
+ return eq
57
57
  num, dem = [simplify(item) for item in num_dem(eq)]
58
58
  if num is None or dem is None:
59
- return eq,[]
59
+ return eq
60
60
 
61
61
  return lhospital(num, dem, 10,var)
62
- ls = [parse("sin(A)"), parse("A^B-1"),parse("log(1+A)"), parse("cos(A)")]
63
- ls= [simplify(item) for item in ls]
64
-
65
- def approx(eq, var):
66
- n, d= num_dem(eq)
67
- n, d = solve(n), solve(d)
68
- n, d = expand(n), expand(d)
69
- out = []
70
- for equation in [n, d]:
71
- for item in factor_generation(equation):
72
- tmp = structure(item, ls[0])
73
- if tmp is not None and contain(tmp["v_-1"], var):
74
- item2 = substitute_val(tmp["v_-1"], 0, var.name)
75
- if tree_form("d_0") == expand(simplify(item2)):
76
- equation = equation/item
77
- equation = equation*tmp["v_-1"]
78
- break
79
- elif tree_form("d_0") == expand(simplify(tree_form("s_pi") - item2)):
80
- equation = equation/item
81
- equation = equation*(tree_form("s_pi") - tmp["v_-1"])
82
- break
83
- tmp = structure(item, ls[1])
84
- if tmp is not None and contain(tmp["v_-1"], var) and not contain(tmp["v_-2"], var):
85
- item2 = substitute_val(tmp["v_-1"], 0, var.name)
86
- item2 = expand(solve(item2))
87
- if tree_form("d_0") == item2:
88
- equation = equation/item
89
- equation = solve(equation*tmp["v_-1"]*tmp["v_-2"].fx("log"))
90
- break
91
- tmp = structure(item, ls[2])
92
- if tmp is not None and contain(tmp["v_-1"], var):
93
-
94
- item2 = substitute_val(tmp["v_-1"], 0, var.name)
95
- item2 = expand(solve(item2))
96
- if tree_form("d_0") == item2:
97
- equation = equation/item
98
- equation = solve(equation*tmp["v_-1"])
99
- break
100
- tmp = structure(item, ls[3])
101
- if tmp is not None and contain(tmp["v_-1"], var):
102
- item2 = substitute_val(item, 0, var.name)
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")):
103
80
 
104
- if tree_form("d_0") == expand(solve(item2)):
105
-
106
- equation = equation/item
107
- equation = equation*(tree_form("d_1") - tmp["v_-1"]**tree_form("d_2"))
108
- break
109
-
110
- equation = solve(equation)
111
- out.append(equation)
112
- return simplify(out[0]/out[1])
113
- def approx_limit(equation, var):
114
- return dowhile(equation, lambda x: approx(x, var))
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])
115
144
 
116
145
  def limit(equation, var="v_0"):
117
- logs = [(0,"lim x->0 "+printeq_str(simplify(equation)))]
146
+
118
147
  eq2 = dowhile(replace(equation, tree_form(var), tree_form("d_0")), lambda x: trig0(simplify(x)))
119
148
  if eq2 is not None and not contain(equation, tree_form(var)):
120
- return eq2,logs
149
+ return eq2, True
121
150
 
122
- equation, tmp = lhospital2(equation, var)
151
+ equation = lhospital2(equation, var)
123
152
  equation = simplify(expand(simplify(equation)))
124
153
  if not contain(equation, tree_form(var)):
125
- return equation,logs+tmp
126
- '''
127
- if equation.name == "f_add":
128
- return simplify(summation([limit(child, var) for child in equation.children]))
129
- '''
130
- return equation,logs+tmp
154
+ return equation, True
155
+
156
+ return equation, False
mathai/linear.py CHANGED
@@ -1,8 +1,14 @@
1
+ from .inverse import inverse
2
+ import itertools
1
3
  from .diff import diff
2
- from .simplify import simplify, solve
4
+ from .simplify import simplify
3
5
  from .fraction import fraction
4
6
  from .expand import expand
5
7
  from .base import *
8
+ from .factor import factorconst
9
+ from .tool import poly
10
+ def ss(eq):
11
+ return dowhile(eq, lambda x: fraction(expand(simplify(x))))
6
12
  def rref(matrix):
7
13
  rows, cols = len(matrix), len(matrix[0])
8
14
  lead = 0
@@ -10,7 +16,7 @@ def rref(matrix):
10
16
  if lead >= cols:
11
17
  return matrix
12
18
  i = r
13
- while fraction(simplify(matrix[i][lead])) == tree_form("d_0"):
19
+ while ss(matrix[i][lead]) == tree_form("d_0"):
14
20
  i += 1
15
21
  if i == rows:
16
22
  i = r
@@ -19,47 +25,25 @@ def rref(matrix):
19
25
  return matrix
20
26
  matrix[i], matrix[r] = matrix[r], matrix[i]
21
27
  lv = matrix[r][lead]
22
- matrix[r] = [fraction(simplify(m / lv)) for m in matrix[r]]
28
+ matrix[r] = [ss(m / lv) for m in matrix[r]]
23
29
  for i in range(rows):
24
30
  if i != r:
25
31
  lv = matrix[i][lead]
26
- matrix[i] = [fraction(simplify(m - lv * n)) for m, n in zip(matrix[i], matrix[r])]
32
+ matrix[i] = [ss(m - lv * n) for m, n in zip(matrix[i], matrix[r])]
27
33
  lead += 1
28
34
  return matrix
29
35
  def islinear(eq, fxconst):
30
36
  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
37
+ if all(fxconst(tree_form(item)) and poly(eq, item) is not None and len(poly(eq, item)) <= 2 for item in vlist(eq)):
38
+ return True
39
+ return False
38
40
  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)
41
+ orig = [item.copy_tree() for item in eqlist]
42
+ #eqlist = [eq for eq in eqlist if fxconst(eq)]
52
43
 
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))
44
+ if eqlist == [] or not all(islinear(eq, fxconst) for eq in eqlist):
45
+ return None
46
+ #return TreeNode("f_and", [TreeNode("f_eq", [x, tree_form("d_0")]) for x in orig])
63
47
  vl = []
64
48
  def varlist(eq, fxconst):
65
49
  nonlocal vl
@@ -72,7 +56,7 @@ def linear(eqlist, fxconst):
72
56
  vl = list(set(vl))
73
57
 
74
58
  if len(vl) > len(eqlist):
75
- return TreeNode("f_and", final+[TreeNode("f_eq", [x, tree_form("d_0")]) for x in eqlist])
59
+ return TreeNode("f_and", [TreeNode("f_eq", [x, tree_form("d_0")]) for x in eqlist])
76
60
  m = []
77
61
  for eq in eqlist:
78
62
  s = copy.deepcopy(eq)
@@ -91,63 +75,91 @@ def linear(eqlist, fxconst):
91
75
  for i in range(len(m)):
92
76
  for j in range(len(m[i])):
93
77
  m[i][j] = fraction(m[i][j])
94
- #print(m)
95
- for item in m:
96
- if all(item2==tree_form("d_0") for item2 in item[:-1]) and item[-1] != tree_form("d_0"):
97
- return tree_form("s_false")
98
78
 
99
79
  output = []
100
80
  for index, row in enumerate(m):
101
- count = 0
102
- for item in row[:-1]:
103
- if item == tree_form("d_1"):
104
- count += 1
105
- if count == 2:
106
- break
107
- elif item == tree_form("d_0") and count == 1:
108
- break
109
- if count == 0:
110
- continue
111
- output.append(tree_form(vl[index])+row[-1])
112
- if len(output) == 1 and len(final)==0:
81
+ if not all(item == 0 for item in row[:-1]):
82
+ output.append(summation([tree_form(vl[index2])*coeff for index2, coeff in enumerate(row[:-1])])+row[-1])
83
+ elif row[-1] != 0:
84
+ return tree_form("s_false")
85
+ if len(output) == 1:
113
86
  return TreeNode("f_eq", [output[0], tree_form("d_0")])
114
- return TreeNode("f_and", final+[TreeNode("f_eq", [x, tree_form("d_0")]) for x in output])
87
+ if len(output) == 0:
88
+ return tree_form("s_false")
89
+ return TreeNode("f_and", [TreeNode("f_eq", [x, tree_form("d_0")]) for x in output])
90
+ def order_collinear_indices(points, idx):
91
+ """
92
+ Arrange a subset of collinear points (given by indices) along their line.
93
+
94
+ points: list of (x, y) tuples
95
+ idx: list of indices referring to points
96
+ Returns: list of indices sorted along the line
97
+ """
98
+ if len(idx) <= 1:
99
+ return idx[:]
100
+
101
+ # Take first two points from the subset to define the line
102
+ p0, p1 = points[idx[0]], points[idx[1]]
103
+ dx, dy = p1[0] - p0[0], p1[1] - p0[1]
104
+
105
+ # Projection factor for sorting
106
+ def projection_factor(i):
107
+ vx, vy = points[i][0] - p0[0], points[i][1] - p0[1]
108
+ return compute((vx * dx + vy * dy) / (dx**2 + dy**2))
109
+
110
+ # Sort indices by projection
111
+ sorted_idx = sorted(idx, key=projection_factor)
112
+ return list(sorted_idx)
113
+ def linear_or(eq):
114
+ eqlst =[]
115
+ if eq.name != "f_or":
116
+ eqlst = [eq]
117
+ else:
118
+ eqlst = eq.children
119
+ v = vlist(eq)
120
+ p = []
121
+ line = {}
122
+ for i in range(len(eqlst)):
123
+ line[i] = []
124
+ for item in itertools.combinations(enumerate(eqlst), 2):
125
+ x, y = item[0][0], item[1][0]
126
+ item = [item[0][1], item[1][1]]
127
+
128
+ out = linear_solve(TreeNode("f_and", list(item)))
115
129
 
116
- def rmeq(eq):
117
- if eq.name == "f_eq":
118
- return rmeq(eq.children[0])
119
- return TreeNode(eq.name, [rmeq(child) for child in eq.children])
130
+ if out is None:
131
+ return None
132
+
133
+ if out.name == "f_and" and all(len(vlist(child)) == 1 for child in out.children) and set(vlist(out)) == set(v) and all(len(vlist(simplify(child))) >0 for child in out.children):
134
+ t = {}
135
+ for child in out.children:
136
+ t[v.index(vlist(child)[0])] = simplify(inverse(child.children[0], vlist(child)[0]))
137
+ t2 = []
138
+ for key in sorted(t.keys()):
139
+ t2.append(t[key])
140
+ t2 = tuple(t2)
141
+ if t2 not in p:
142
+ p.append(t2)
143
+ line[x] += [p.index(t2)]
144
+ line[y] += [p.index(t2)]
145
+ line2 = []
146
+ for key in sorted(line.keys()):
147
+ line2.append(order_collinear_indices(p, list(set(line[key]))))
120
148
 
121
- def mat0(eq, lst=None):
122
- def findeq(eq):
123
- out = []
124
- if "f_list" not in str_form(eq) and "f_eq" not in str_form(eq):
125
- return [str_form(eq)]
126
- else:
127
- for child in eq.children:
128
- out += findeq(child)
129
- return out
130
- eqlist = findeq(eq)
131
- eqlist = [tree_form(x) for x in eqlist]
132
- eqlist = [rmeq(x) for x in eqlist]
133
- eqlist = [TreeNode("f_mul", factor_generation(x)) for x in eqlist if x != tree_form("d_0")]
134
- eqlist = [x.children[0] if len(x.children) == 1 else x for x in eqlist]
149
+ return v, p, line2, eqlst
150
+ def linear_solve(eq, lst=None):
151
+ eq = simplify(eq)
152
+ eqlist = []
153
+ if eq.name =="f_and" and all(child.name == "f_eq" and child.children[1] == 0 for child in eq.children):
154
+
155
+ eqlist = [child.children[0] for child in eq.children]
156
+ else:
157
+ return eq
135
158
  out = None
136
-
137
159
  if lst is None:
138
160
  out = linear(copy.deepcopy(eqlist), lambda x: "v_" in str_form(x))
139
161
  else:
140
162
  out = linear(copy.deepcopy(eqlist), lambda x: any(contain(x, item) for item in lst))
141
- def rms(eq):
142
- if eq.name in ["f_and", "f_or"] and len(eq.children) == 1:
143
- return eq.children[0]
144
- return TreeNode(eq.name, [rms(child) for child in eq.children])
145
- return rms(out)
146
- def linear_solve(eq, lst=None):
147
- if eq.name == "f_and":
148
- eq2 = copy.deepcopy(eq)
149
- eq2.name = "f_list"
150
- return mat0(eq2, lst)
151
- elif eq.name == "f_eq":
152
- return mat0(eq, lst)
153
- return TreeNode(eq.name, [linear_solve(child, lst) for child in eq.children])
163
+ if out is None:
164
+ return None
165
+ return simplify(out)
mathai/logic.py CHANGED
@@ -1,6 +1,12 @@
1
1
  import itertools
2
2
  from .base import *
3
-
3
+ def c(eq):
4
+ eq = logic1(eq)
5
+ eq = dowhile(eq, logic0)
6
+ eq = dowhile(eq, logic2)
7
+ return eq
8
+ def logic_n(eq):
9
+ return dowhile(eq, c)
4
10
  def logic0(eq):
5
11
  if eq.children is None or len(eq.children)==0:
6
12
  return eq