mathai 0.3.7__py3-none-any.whl → 0.3.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 CHANGED
@@ -36,8 +36,6 @@ from .console import console
36
36
 
37
37
  from .limit import limit
38
38
 
39
- from .search import dfs_simplify as search0
40
-
41
39
  from .univariate_inequality import wavycurvy, absolute, domain, handle_sqrt
42
40
 
43
41
  from .base import *
mathai/apart.py CHANGED
@@ -1,14 +1,18 @@
1
1
  from .linear import linear_solve
2
2
  from .expand import expand
3
3
  from .simplify import simplify
4
+
4
5
  from .diff import diff
5
6
  from .inverse import inverse
6
7
  from .base import *
7
8
  import math
8
9
  from .tool import poly, enclose_const
9
10
 
10
- def _apart(eq, v="v_0"):
11
-
11
+ def _apart(eq, v=None):
12
+ if v is None:
13
+ if len(vlist(eq)) == 0:
14
+ return eq
15
+ v = vlist(eq)[0]
12
16
  origv = vlist(eq)
13
17
  eq = simplify(eq)
14
18
  if eq.name != "f_mul":
@@ -42,8 +46,9 @@ def _apart(eq, v="v_0"):
42
46
  s = []
43
47
  facd = [simplify(x) for x in factor_generation(simplify(d))]
44
48
 
45
-
46
- facd2 = remove_duplicates_custom(facd, lambda m, n: simplify(m-n) == tree_form("d_0"))
49
+
50
+ facd2 = remove_duplicates_custom(facd, lambda m, n: simplify(expand(simplify(m-n))) == tree_form("d_0"))
51
+
47
52
  if len(facd2) == 1:
48
53
  return eq
49
54
  x = tree_form(v)
@@ -58,6 +63,7 @@ def _apart(eq, v="v_0"):
58
63
  if n > 2:
59
64
  return eq
60
65
  n = tree_form("d_"+str(n))
66
+
61
67
  l = len(poly(item, v))
62
68
  if l == 3:
63
69
  a = alloclst.pop(0)
@@ -93,14 +99,15 @@ def _apart(eq, v="v_0"):
93
99
  final = summation(final2)
94
100
 
95
101
  s = simplify(TreeNode("f_eq", [final-eq2, tree_form("d_0")]))
96
-
102
+
97
103
  lst = poly(s.children[0], v)
98
-
104
+
99
105
  lst = [TreeNode("f_eq", [item, tree_form("d_0")]) for item in lst if "v_" in str_form(item)]
100
106
  lst2 = []
101
107
  for item in lst:
102
108
  lst2+=vlist(item)
103
109
  origv = list(set(lst2)-set(origv))
110
+
104
111
  out = linear_solve(TreeNode("f_and", lst), [tree_form(item) for item in origv])
105
112
  for item in out.children:
106
113
 
@@ -108,6 +115,9 @@ def _apart(eq, v="v_0"):
108
115
  return simplify(final3)
109
116
  def apart(eq):
110
117
  eq, fx = enclose_const(eq)
111
-
112
- eq = _apart(eq)
113
- return fx(eq)
118
+ def helper(eq):
119
+ eq2 = _apart(eq)
120
+ if eq != eq2:
121
+ return eq2
122
+ return TreeNode(eq.name, [helper(child) for child in eq.children])
123
+ return fx(helper(eq))
mathai/base.py CHANGED
@@ -131,6 +131,8 @@ def frac(eq):
131
131
  return Fraction(int(eq.name[2:]))
132
132
  if eq.name == "f_add":
133
133
  p = frac(eq.children[0])
134
+ if p is None:
135
+ return None
134
136
  for child in eq.children[1:]:
135
137
  tmp = frac(child)
136
138
  if isinstance(tmp, Fraction):
@@ -140,6 +142,8 @@ def frac(eq):
140
142
  return p
141
143
  if eq.name == "f_mul":
142
144
  p = frac(eq.children[0])
145
+ if p is None:
146
+ return None
143
147
  for child in eq.children[1:]:
144
148
  tmp = frac(child)
145
149
  if isinstance(tmp, Fraction):
mathai/integrate.py CHANGED
@@ -170,7 +170,7 @@ def integrate_subs(equation, term, v1, v2):
170
170
 
171
171
  return none
172
172
 
173
- return TreeNode("f_subs", [TreeNode("f_integrate", [simplify(expand(simplify(equation))), tree_form(origv2)]),tree_form(origv2) ,g])
173
+ return TreeNode("f_subs", [TreeNode("f_integrate", [simplify(fraction(expand(simplify(equation)))), tree_form(origv2)]),tree_form(origv2) ,g])
174
174
 
175
175
  def integrate_subs_main(equation):
176
176
  if equation.name == "f_ref":
mathai/linear.py CHANGED
@@ -3,6 +3,9 @@ from .simplify import simplify, solve
3
3
  from .fraction import fraction
4
4
  from .expand import expand
5
5
  from .base import *
6
+ from .factor import factorconst
7
+ def ss(eq):
8
+ return dowhile(eq, lambda x: fraction(expand(simplify(x))))
6
9
  def rref(matrix):
7
10
  rows, cols = len(matrix), len(matrix[0])
8
11
  lead = 0
@@ -10,7 +13,7 @@ def rref(matrix):
10
13
  if lead >= cols:
11
14
  return matrix
12
15
  i = r
13
- while fraction(simplify(matrix[i][lead])) == tree_form("d_0"):
16
+ while ss(matrix[i][lead]) == tree_form("d_0"):
14
17
  i += 1
15
18
  if i == rows:
16
19
  i = r
@@ -19,11 +22,11 @@ def rref(matrix):
19
22
  return matrix
20
23
  matrix[i], matrix[r] = matrix[r], matrix[i]
21
24
  lv = matrix[r][lead]
22
- matrix[r] = [fraction(simplify(m / lv)) for m in matrix[r]]
25
+ matrix[r] = [ss(m / lv) for m in matrix[r]]
23
26
  for i in range(rows):
24
27
  if i != r:
25
28
  lv = matrix[i][lead]
26
- matrix[i] = [fraction(simplify(m - lv * n)) for m, n in zip(matrix[i], matrix[r])]
29
+ matrix[i] = [ss(m - lv * n) for m, n in zip(matrix[i], matrix[r])]
27
30
  lead += 1
28
31
  return matrix
29
32
  def islinear(eq, fxconst):
@@ -91,7 +94,7 @@ def linear(eqlist, fxconst):
91
94
  for i in range(len(m)):
92
95
  for j in range(len(m[i])):
93
96
  m[i][j] = fraction(m[i][j])
94
- #print(m)
97
+
95
98
  for item in m:
96
99
  if all(item2==tree_form("d_0") for item2 in item[:-1]) and item[-1] != tree_form("d_0"):
97
100
  return tree_form("s_false")
mathai/simplify.py CHANGED
@@ -286,6 +286,23 @@ def simplify(eq):
286
286
  error = True
287
287
  else:
288
288
  eq = tree_form("d_0")
289
+
290
+ if eq.name == "f_mul" and str_form(eq).count("f_pow")>1:
291
+ dic = {}
292
+ for child in eq.children:
293
+ head = child
294
+ tail = None
295
+ if child.name == "f_pow":
296
+ head = child.children[0]
297
+ tail = child.children[1]
298
+ if tail is None:
299
+ tail = tree_form("d_1")
300
+ if head not in dic.keys():
301
+ dic[head] = tail
302
+ else:
303
+ dic[head] += tail
304
+ if len(eq.children) != len(dic.keys()):
305
+ eq = product([key if dic[key] == 1 else key**dic[key] for key in dic.keys()])
289
306
  if eq.name == "f_pow" and eq.children[0].name == "f_pow" and eq.children[0].children[1] == tree_form("d_2")**-1 and eq.children[1] == tree_form("d_2"):
290
307
  eq = eq.children[0].children[0]
291
308
  if (eq.name == "f_sin" and eq.children[0].name == "f_arcsin") or (eq.name == "f_cos" and eq.children[0].name == "f_arccos") or (eq.name == "f_tan" and eq.children[0].name == "f_arctan"):
mathai/trig.py CHANGED
@@ -199,16 +199,37 @@ def trig4(eq, numer=True):
199
199
  return tree_form("d_1")/(1+a**2)**(tree_form("d_2")**-1)
200
200
 
201
201
  return TreeNode(eq.name, [trig4(child, False) 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) for child in eq.children])
202
+
202
203
  def trig2(eq):
203
204
  if eq.name == "f_add":
204
205
  for item in itertools.combinations(range(len(eq.children)), 2):
205
- if all(eq.children[item2].name == "f_sin" for item2 in item):
206
- a, b = eq.children[item[0]].children[0], eq.children[item[1]].children[0]
207
- rest = [item2 for index, item2 in enumerate(eq.children) if index not in item]
208
- if len(rest)==0:
209
- rest = tree_form("d_0")
206
+ child1, child2 = eq.children[item[0]], eq.children[item[1]]
207
+
208
+ # Check if both are sin or cos
209
+ if child1.name in ["f_sin", "f_cos"] and child2.name in ["f_sin", "f_cos"]:
210
+ a, b = child1.children[0], child2.children[0]
211
+
212
+ # Compute the rest of the sum
213
+ rest = [eq.children[i] for i in range(len(eq.children)) if i not in item]
214
+ if len(rest) == 0:
215
+ rest_tree = tree_form("d_0")
216
+ else:
217
+ rest_tree = summation(rest)
218
+
219
+ # Now handle the sin/cos combination formula
220
+ if child1.name == "f_sin" and child2.name == "f_sin":
221
+ # sin A + sin B = 2 sin((A+B)/2) cos((A-B)/2)
222
+ two = tree_form("d_2")
223
+ combined = two * ((a + b) / two).fx("sin") * ((a - b) / two).fx("cos")
224
+ elif child1.name == "f_cos" and child2.name == "f_cos":
225
+ # cos A + cos B = 2 cos((A+B)/2) cos((A-B)/2)
226
+ two = tree_form("d_2")
227
+ combined = two * ((a + b) / two).fx("cos") * ((a - b) / two).fx("cos")
210
228
  else:
211
- rest = summation(rest)
212
- two = tree_form("d_2")
213
- return rest + two*((a+b)/two).fx("sin")*((a-b)/two).fx("cos")
229
+ # sin A + cos B = sin A + cos B (leave unchanged, or implement formula if desired)
230
+ continue # skip for now, keep original
231
+
232
+ return rest_tree + combined
233
+
234
+ # Recurse for other nodes
214
235
  return TreeNode(eq.name, [trig2(child) for child in eq.children])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mathai
3
- Version: 0.3.7
3
+ Version: 0.3.9
4
4
  Summary: Mathematics solving Ai tailored to NCERT
5
5
  Home-page: https://github.com/infinity390/mathai4
6
6
  Author: educated indians are having a low iq and are good for nothing
@@ -1,25 +1,24 @@
1
- mathai/__init__.py,sha256=GsDxDy6iWjoJ7CJty2nzE4Jx03mZkHFQW6hkmPJHkPE,1217
2
- mathai/apart.py,sha256=Fhl-OHZzPGIOj8YFyGQddjuh-2HV7uVDhkIzQ-YoMO0,3492
3
- mathai/base.py,sha256=x4Rjgz5mVblclsycKtDJjSudFpyIBWSEUX83_120BZY,12587
1
+ mathai/__init__.py,sha256=hxMCrvwj98yE5ChWSzvkn0gMxqAQnh8oze3ZlImWyD0,1170
2
+ mathai/apart.py,sha256=8IlJ8X6SKAjPunUPHVLmgNB5GuEi4_XpY0oLkQqrHKc,3770
3
+ mathai/base.py,sha256=zJqozbSeesbxw8YJ_eNXmaoy8K5VmkPHECnuAFGRvW4,12683
4
4
  mathai/console.py,sha256=Sn58iwYE79MLEh67s8X3q6vZjw6g7f9XM1T8_dBBR2o,3048
5
5
  mathai/diff.py,sha256=YUBpRsz0qmBkq5vGxeGnvR4nMKjdOQiIXlNMxpij2ns,3051
6
6
  mathai/expand.py,sha256=SnBltkpIENMGkP0AYmbMlSc4H-CF5RslO2PcBEkn1BQ,3359
7
7
  mathai/factor.py,sha256=NPXxET52TacNExuvw6p1jbC6g3wY6_VOCdlGlexXZio,5916
8
8
  mathai/fraction.py,sha256=Q2ztsh5Bpz6YhML2QU0tfufbAs0Q6J319AhlzKephIY,4396
9
- mathai/integrate.py,sha256=8IPtDHCqoS0zIPT3ssOkcgoH54y2pnzMZUhjVFqYuW4,15024
9
+ mathai/integrate.py,sha256=OH_DqnbgoCx7e3gq4u1zEz9ABcaiUvH5t75ap67t4GI,15034
10
10
  mathai/inverse.py,sha256=QCvDrzKquWsZv-BDAzZd9HnU0c3gZvcc44UztHVO5LQ,2919
11
11
  mathai/limit.py,sha256=RA8YAehgYCGVWv9qBc8uQ34BQ9mFthWl2OrVTwcHl2g,4920
12
- mathai/linear.py,sha256=wyiLpIxRDmD96xXktkgvc5gegIB3zblLB1EuV3TFdmU,5474
12
+ mathai/linear.py,sha256=BzSnm941Zlod_l6hON4Rs6J4pdAA3MGpRVqr6-66ZBk,5524
13
13
  mathai/logic.py,sha256=UvHzRmKcO9AD51tRzHmpNSEhgW5gmaf4XPaQKFjGfC4,9653
14
14
  mathai/parser.py,sha256=f7bemieFmp0sbup1NlraMLvZDVFvqKGFknEVtlFRMVk,6979
15
15
  mathai/printeq.py,sha256=gIes-pstFOa6FcnpVIVvkjVKuWdsVdo11LlEnmHhakU,1303
16
- mathai/search.py,sha256=6S_V0PrC2ZnbhkWyT2ZTtExRD_mDlo-C3p0TDn6Dk3w,4743
17
- mathai/simplify.py,sha256=F37h-Z_rW35uVgx0G86vQErU2Ac6ZiTBN9KcC3RzDkg,15156
16
+ mathai/simplify.py,sha256=4gJgEh7fmwJ3aKMliB4d1NalGAx9duIYA7bGAIYUX2Y,15858
18
17
  mathai/structure.py,sha256=4Ww2IAx62RcQSO7_17TZES-DjMWBpcFQtL939FBIHwY,4103
19
18
  mathai/tool.py,sha256=UyccamiJy_CkFPakfufyPzdhtlEO6v2D7qwbXQ9V7Rg,2000
20
- mathai/trig.py,sha256=5P0RNS4eetNds2l-wyA4BAKqJdFIUws_8RGS_dH7gp8,9348
19
+ mathai/trig.py,sha256=Zadw-uTJaMfoXwxuiio7QYHWgPxezEP2xZ2fr__PFM0,10290
21
20
  mathai/univariate_inequality.py,sha256=_r-kkiS4Hr-jRN7f-EL_E4svAMFWJP1Ea50HJKKbjfk,14778
22
- mathai-0.3.7.dist-info/METADATA,sha256=FDULZSw1CmA66jzn0svcz_YlrQEk_yRV6uB4rGBB7kk,7021
23
- mathai-0.3.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
24
- mathai-0.3.7.dist-info/top_level.txt,sha256=ROP4l3OhGYw3ihkQGASr18xM9GsK4z3_6whV5AyXLwE,7
25
- mathai-0.3.7.dist-info/RECORD,,
21
+ mathai-0.3.9.dist-info/METADATA,sha256=sWapzjSv4xLp5xqwXkpt0_lqv32BcPNlQvpYmwi1tiU,7021
22
+ mathai-0.3.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
+ mathai-0.3.9.dist-info/top_level.txt,sha256=ROP4l3OhGYw3ihkQGASr18xM9GsK4z3_6whV5AyXLwE,7
24
+ mathai-0.3.9.dist-info/RECORD,,
mathai/search.py DELETED
@@ -1,117 +0,0 @@
1
- from mathai import *
2
- import copy
3
- from concurrent.futures import ThreadPoolExecutor, TimeoutError
4
-
5
- def dfs_simplify(equation, functions, true_expr, false_expr,
6
- max_timeout=25, max_small=4,
7
- base_timeout=1, time_per_char=0.1, timeout_increase=0.5):
8
- """
9
- Perform DFS simplification on a given equation using provided functions.
10
-
11
- Args:
12
- equation: The starting expression (TreeNode or parsed equation)
13
- functions: List of simplification functions
14
- true_expr: Expression representing True (immediate termination)
15
- false_expr: Expression representing False (immediate termination)
16
- max_timeout: Maximum timeout allowed for any function
17
- max_small: Number of smallest expressions to track
18
- base_timeout: Base timeout in seconds
19
- time_per_char: Additional timeout per character of expression
20
- timeout_increase: Factor to increase timeout for consecutive timeouts
21
-
22
- Returns:
23
- tuple(found_boolean, boolean_path, smallest_expressions)
24
- """
25
- original_eq = simplify(equation)
26
- smallest_four = []
27
-
28
- stack = [(copy.deepcopy(original_eq), [copy.deepcopy(original_eq)])]
29
- visited = set()
30
-
31
- found_boolean = False
32
- boolean_path = None
33
- boolean_expr = None
34
-
35
- executor = ThreadPoolExecutor(max_workers=3)
36
- consecutive_timeouts = 0
37
-
38
- while stack and not found_boolean:
39
- current_eq, path = stack.pop()
40
- expr_str = str(current_eq)
41
-
42
- if expr_str in visited:
43
- continue
44
- visited.add(expr_str)
45
-
46
- # Thinking message
47
- printeq(current_eq)
48
-
49
- # Immediate termination using predicate functions
50
- if true_expr(current_eq):
51
- found_boolean = True
52
- boolean_path = path
53
- boolean_expr = current_eq
54
- break
55
- if false_expr(current_eq):
56
- found_boolean = True
57
- boolean_path = path
58
- boolean_expr = current_eq
59
- break
60
-
61
-
62
- # Insert into smallest_four if qualifies
63
- inserted = False
64
- for j in range(len(smallest_four)):
65
- if len(expr_str) < len(str(smallest_four[j][0])):
66
- smallest_four.insert(j, (copy.deepcopy(current_eq), copy.deepcopy(path)))
67
- inserted = True
68
- break
69
- if not inserted and len(smallest_four) < max_small:
70
- smallest_four.append((copy.deepcopy(current_eq), copy.deepcopy(path)))
71
- if len(smallest_four) > max_small:
72
- smallest_four = smallest_four[:max_small]
73
-
74
- # Calculate adaptive timeout with cap
75
- timeout = (base_timeout + time_per_char * len(expr_str)) * (1 + timeout_increase * consecutive_timeouts)
76
- if timeout > max_timeout:
77
- timeout = max_timeout
78
-
79
- # Try functions that reduce length first
80
- reduced_any = False
81
- for fx in functions:
82
- print(f"[Thinking] Executing {fx.__name__} on current expression (timeout={timeout:.2f}s):")
83
- printeq(current_eq)
84
- future = executor.submit(fx, current_eq)
85
- try:
86
- new_expr = future.result(timeout=timeout)
87
- new_expr_str = str(new_expr)
88
- if len(new_expr_str) <= len(expr_str) and new_expr_str != expr_str:
89
- reduced_any = True
90
- stack.append((new_expr, path + [copy.deepcopy(new_expr)]))
91
- consecutive_timeouts = 0 # reset after success
92
- except TimeoutError:
93
- print(f"[Thinking] {fx.__name__} timed out, skipping.")
94
- consecutive_timeouts += 1
95
- continue
96
-
97
- # If no reducing function worked, try growing functions
98
- if not reduced_any:
99
- for fx in functions:
100
- print(f"[Thinking] Trying growing {fx.__name__} on current expression (timeout={timeout:.2f}s):")
101
- printeq(current_eq)
102
- future = executor.submit(fx, current_eq)
103
- try:
104
- new_expr = future.result(timeout=timeout)
105
- new_expr_str = str(new_expr)
106
- if new_expr_str != expr_str:
107
- stack.append((new_expr, path + [copy.deepcopy(new_expr)]))
108
- consecutive_timeouts = 0
109
- break # only take one growing function
110
- except TimeoutError:
111
- print(f"[Thinking] {fx.__name__} (growing) timed out, skipping.")
112
- consecutive_timeouts += 1
113
- continue
114
-
115
- executor.shutdown(wait=True)
116
-
117
- return found_boolean, boolean_path, smallest_four
File without changes