mathai 0.7.8__tar.gz → 0.7.9__tar.gz

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.
Files changed (36) hide show
  1. {mathai-0.7.8 → mathai-0.7.9}/PKG-INFO +1 -1
  2. mathai-0.7.9/mathai/fraction.py +106 -0
  3. {mathai-0.7.8 → mathai-0.7.9}/mathai/integrate.py +10 -4
  4. {mathai-0.7.8 → mathai-0.7.9}/mathai/ode.py +164 -104
  5. {mathai-0.7.8 → mathai-0.7.9}/mathai/pde.py +5 -10
  6. {mathai-0.7.8 → mathai-0.7.9}/mathai/structure.py +3 -3
  7. {mathai-0.7.8 → mathai-0.7.9}/mathai.egg-info/PKG-INFO +1 -1
  8. {mathai-0.7.8 → mathai-0.7.9}/setup.py +1 -1
  9. mathai-0.7.8/mathai/fraction.py +0 -103
  10. {mathai-0.7.8 → mathai-0.7.9}/README.md +0 -0
  11. {mathai-0.7.8 → mathai-0.7.9}/mathai/__init__.py +0 -0
  12. {mathai-0.7.8 → mathai-0.7.9}/mathai/apart.py +0 -0
  13. {mathai-0.7.8 → mathai-0.7.9}/mathai/base.py +0 -0
  14. {mathai-0.7.8 → mathai-0.7.9}/mathai/bivariate_inequality.py +0 -0
  15. {mathai-0.7.8 → mathai-0.7.9}/mathai/console.py +0 -0
  16. {mathai-0.7.8 → mathai-0.7.9}/mathai/diff.py +0 -0
  17. {mathai-0.7.8 → mathai-0.7.9}/mathai/expand.py +0 -0
  18. {mathai-0.7.8 → mathai-0.7.9}/mathai/factor.py +0 -0
  19. {mathai-0.7.8 → mathai-0.7.9}/mathai/inverse.py +0 -0
  20. {mathai-0.7.8 → mathai-0.7.9}/mathai/limit.py +0 -0
  21. {mathai-0.7.8 → mathai-0.7.9}/mathai/linear.py +0 -0
  22. {mathai-0.7.8 → mathai-0.7.9}/mathai/logic.py +0 -0
  23. {mathai-0.7.8 → mathai-0.7.9}/mathai/matrix.py +0 -0
  24. {mathai-0.7.8 → mathai-0.7.9}/mathai/parser.py +0 -0
  25. {mathai-0.7.8 → mathai-0.7.9}/mathai/parsetab.py +0 -0
  26. {mathai-0.7.8 → mathai-0.7.9}/mathai/printeq.py +0 -0
  27. {mathai-0.7.8 → mathai-0.7.9}/mathai/simplify.py +0 -0
  28. {mathai-0.7.8 → mathai-0.7.9}/mathai/statistics.py +0 -0
  29. {mathai-0.7.8 → mathai-0.7.9}/mathai/tool.py +0 -0
  30. {mathai-0.7.8 → mathai-0.7.9}/mathai/trig.py +0 -0
  31. {mathai-0.7.8 → mathai-0.7.9}/mathai/univariate_inequality.py +0 -0
  32. {mathai-0.7.8 → mathai-0.7.9}/mathai.egg-info/SOURCES.txt +0 -0
  33. {mathai-0.7.8 → mathai-0.7.9}/mathai.egg-info/dependency_links.txt +0 -0
  34. {mathai-0.7.8 → mathai-0.7.9}/mathai.egg-info/requires.txt +0 -0
  35. {mathai-0.7.8 → mathai-0.7.9}/mathai.egg-info/top_level.txt +0 -0
  36. {mathai-0.7.8 → mathai-0.7.9}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mathai
3
- Version: 0.7.8
3
+ Version: 0.7.9
4
4
  Summary: Mathematics solving Ai tailored to NCERT
5
5
  Home-page: https://github.com/infinity390/mathai4
6
6
  Requires-Python: >=3.7
@@ -0,0 +1,106 @@
1
+ from .base import *
2
+ from .simplify import simplify
3
+ from .expand import expand
4
+
5
+
6
+ def fraction(expr):
7
+ if expr is None:
8
+ return None
9
+
10
+ expr = simplify(expr)
11
+
12
+ # -----------------------------
13
+ # leaf
14
+ # -----------------------------
15
+ if expr.children == []:
16
+ return expr
17
+
18
+ # recurse first (inner-most first)
19
+ children = [fraction(c) for c in expr.children]
20
+
21
+ # -----------------------------
22
+ # ADDITION: collect denominators
23
+ # -----------------------------
24
+ if expr.name == "f_add":
25
+ terms = []
26
+
27
+ for c in children:
28
+ # term is a multiplication
29
+ if c.name == "f_mul":
30
+ num = []
31
+ den = []
32
+ for f in c.children:
33
+ if (
34
+ f.name == "f_pow"
35
+ and f.children[1].name.startswith("d_")
36
+ and int(f.children[1].name[2:]) < 0
37
+ ):
38
+ n = int(f.children[1].name[2:])
39
+ den.append(
40
+ f.children[0]
41
+ if n == -1
42
+ else TreeNode("f_pow", [f.children[0], tree_form(f"d_{-n}")])
43
+ )
44
+ else:
45
+ num.append(f)
46
+ terms.append((num, den))
47
+
48
+ # pure reciprocal
49
+ elif (
50
+ c.name == "f_pow"
51
+ and c.children[1].name.startswith("d_")
52
+ and int(c.children[1].name[2:]) < 0
53
+ ):
54
+ n = int(c.children[1].name[2:])
55
+ terms.append(([], [
56
+ c.children[0]
57
+ if n == -1
58
+ else TreeNode("f_pow", [c.children[0], tree_form(f"d_{-n}")])
59
+ ]))
60
+
61
+ # normal term
62
+ else:
63
+ terms.append(([c], []))
64
+
65
+ # if no denominators → rebuild normally
66
+ if not any(den for _, den in terms):
67
+ return TreeNode("f_add", children)
68
+
69
+ # -----------------------------
70
+ # build numerator
71
+ # -----------------------------
72
+ num_terms = []
73
+ for i, (num_i, _) in enumerate(terms):
74
+ acc = list(num_i)
75
+ for j, (_, den_j) in enumerate(terms):
76
+ if i != j:
77
+ acc += den_j
78
+ if not acc:
79
+ acc = [tree_form("d_1")]
80
+ num_terms.append(
81
+ acc[0] if len(acc) == 1 else TreeNode("f_mul", acc)
82
+ )
83
+
84
+ numerator = TreeNode("f_add", num_terms)
85
+
86
+ # -----------------------------
87
+ # build denominator
88
+ # -----------------------------
89
+ den_all = []
90
+ for _, den in terms:
91
+ den_all += den
92
+
93
+ denom = den_all[0] if len(den_all) == 1 else TreeNode("f_mul", den_all)
94
+ denom = TreeNode("f_pow", [denom, tree_form("d_-1")])
95
+
96
+ return simplify(
97
+ TreeNode(
98
+ "f_mul",
99
+ [simplify(expand(numerator)), denom],
100
+ )
101
+ )
102
+
103
+ # -----------------------------
104
+ # default reconstruction
105
+ # -----------------------------
106
+ return TreeNode(expr.name, children)
@@ -97,6 +97,8 @@ def place_try2(eq):
97
97
  return eq.children[try_lst.pop(0)]
98
98
  return TreeNode(eq.name, [place_try2(child) for child in eq.children])
99
99
  def _solve_integrate(eq):
100
+ if eq is None:
101
+ return None
100
102
  if eq.name == "f_ref":
101
103
  return eq
102
104
  if eq.name == "f_subs":
@@ -153,6 +155,8 @@ def inteq(eq):
153
155
  else:
154
156
  return TreeNode(eq.name, [inteq(child) for child in eq.children])
155
157
  def rm(eq):
158
+ if eq is None:
159
+ return None
156
160
  if eq.name == "f_try":
157
161
  eq = TreeNode(eq.name, list(set(eq.children)))
158
162
  return TreeNode(eq.name, [rm(child) for child in eq.children if child is not None])
@@ -161,6 +165,8 @@ def solve_integrate(eq):
161
165
  eq2 = dowhile(eq, _solve_integrate)
162
166
  #eq2 = dowhile(eq2, handle_try)
163
167
  eq2 = rm(eq2)
168
+ if eq2 is None:
169
+ return None
164
170
  if eq2.name == "f_try":
165
171
  eq2.children = list(set(eq2.children))
166
172
  return eq2
@@ -409,8 +415,8 @@ def integration_formula_ex():
409
415
 
410
416
  formula_gen11 = integration_formula_ex()
411
417
  def rm_const(equation):
412
- if equation.name == "f_ref":
413
- return equation
418
+ if equation is None:
419
+ return None
414
420
  eq2 = equation
415
421
  if eq2.name == "f_integrate" and contain(eq2.children[0], eq2.children[1]):
416
422
  equation = eq2.children[0]
@@ -436,8 +442,8 @@ def shorten(eq):
436
442
  return tree_form("d_0")
437
443
  return TreeNode(eq.name, [shorten(child) for child in eq.children])
438
444
  def integrate_formula(equation):
439
- if equation.name == "f_ref":
440
- return equation.copy_tree()
445
+ if equation is None:
446
+ return None
441
447
  eq2 = equation.copy_tree()
442
448
  if eq2.name == "f_integrate":
443
449
  integrand = eq2.children[0]
@@ -1,6 +1,7 @@
1
+ import itertools
1
2
  from collections import Counter
2
- from .diff import diff
3
- from .factor import factor, factor2
3
+ from .diff import diff, diff2
4
+ from .factor import factor, factor2, term_common2
4
5
  from .expand import expand
5
6
  from .base import *
6
7
  from .fraction import fraction
@@ -9,71 +10,110 @@ import copy
9
10
  from .inverse import inverse
10
11
  from .parser import parse
11
12
 
12
-
13
- def jjj(lhs, rhs):
14
- lst = [lhs, rhs]
15
- for i in range(2):
16
- if lst[i].name in ["f_mul", "f_add"]:
17
-
18
- out = []
19
- for child in lst[i].children:
20
-
21
- if not contain(child, tree_form(f"v_{i}")):
22
- out.append(child)
23
- if out == []:
24
- continue
25
- out = TreeNode(lst[i].name, out)
26
-
27
- if len(out.children) == 1:
28
- out = out.children[0]
29
- out = out.copy_tree()
30
- if lst[i].name == "f_add":
31
- lst[i] = lst[i] - out
32
- lst[1-i] = lst[1-i] - out
33
- else:
34
- lst[i] = lst[i] / out
35
- lst[1-i] = lst[1-i] / out
36
-
37
- lst = [simplify(expand(simplify(item))) for item in lst]
38
- return lst
39
-
40
- def kkk(lhs, rhs, depth=3):
41
-
42
- lst = jjj(lhs, rhs)
43
-
44
- if depth < 0:
45
- return lst, False
13
+ def rev(eq):
14
+ tmp = factor_generation(eq)
15
+ if tree_form("v_0").fx("dif")**-1 in tmp or tree_form("v_1").fx("dif")**-1 in tmp:
16
+ return False
17
+ for child in eq.children:
18
+ if not rev(child):
19
+ return False
20
+ return True
21
+ node_count = 100
22
+ def kkk(lhs, rhs, depth=5):
23
+ global node_count
24
+ lst = [simplify(lhs), simplify(rhs)]
25
+ orig = copy.deepcopy(lst)
46
26
  if not contain(lst[0], tree_form("v_1")) and not contain(lst[1], tree_form("v_0")):
27
+ if not contain(lst[0], tree_form("v_0")) and not contain(lst[1], tree_form("v_1")):
28
+ return lst, False
47
29
  return lst, True
48
- orig = copy.deepcopy(lst)
49
- for i in range(2):
50
- if lst[i].name in ["f_mul", "f_add"]:
51
- for child in lst[i].children:
52
-
53
- out = child
54
- if lst[i].name == "f_add":
55
- lst[i] = lst[i] - out
56
- lst[1-i] = lst[1-i] - out
57
- else:
58
- lst[i] = lst[i] / out
59
- lst[1-i] = lst[1-i] / out
60
- lst = [simplify(item) for item in lst]
30
+ node_count -= 1
31
+
32
+ if depth < 0 or node_count < 0:
33
+ return lst, False
34
+ for j in range(2):
35
+ for i in range(2):
36
+ if lst[i].name in ["f_mul", "f_add"]:
37
+ for child in lst[i].children:
38
+ out = child
39
+ if j == 0:
40
+ if contain(out, tree_form(f"v_{i}")) or not contain(out, tree_form(f"v_{1-i}")):
41
+ continue
42
+ if contain(out, tree_form(f"v_{i}")) and not contain(out, tree_form(f"v_{1-i}")):
43
+ continue
44
+
45
+ if lst[i].name == "f_add":
46
+ lst[i] = lst[i] - out
47
+ lst[1-i] = lst[1-i] - out
48
+ elif lst[i].name == "f_mul":
49
+ lst[i] = lst[i] / out
50
+ lst[1-i] = lst[1-i] / out
51
+ else:
52
+ continue
53
+
54
+ output = kkk(lst[0], lst[1], depth-1)
55
+ lst = orig
56
+
57
+ if output[1]:
58
+ return output
61
59
 
62
- output = kkk(lst[0], lst[1], depth-1)
63
- lst = orig
64
- if output[1]:
65
- return output
66
60
  return lst, False
67
-
61
+ def clr(eq):
62
+ return simplify(product([item for item in factor_generation(eq) if "f_add" in str_form(item)]))
68
63
  def inversediff(lhs, rhs):
69
- out = [[tree_form("d_0"), lhs-rhs], False]
70
- while True:
71
- out = list(kkk(out[0][0], out[0][1]))
72
- if out[1]:
73
- break
74
- out[0] = [simplify(item) for item in out[0]]
64
+ global node_count
65
+ eq = simplify(fraction(TreeNode("f_eq", [lhs-rhs, tree_form("d_0")]))).children[0]
66
+ eq = simplify(term_common2(eq))
67
+ eq = clr(eq)
68
+
69
+ out= None
70
+ if eq.name == "f_add":
71
+ h = {}
72
+ n = [eq]
73
+ for i in range(len(eq.children)-2,1,-1):
74
+ for item in itertools.combinations(list(range(len(eq.children))), i):
75
+ item = tuple(sorted(list(item)))
76
+ tmp = simplify(term_common2(simplify(summation([eq.children[x] for x in item]))))
77
+ if tmp.name == "f_mul":
78
+ h[item] = tmp
79
+
80
+ for item in itertools.combinations(list(h.keys()),2):
81
+
82
+ g = []
83
+ for x in item:
84
+ g += x
85
+ if sum([len(x) for x in item]) == len(set(g)):
86
+ pass
87
+ else:
88
+ continue
89
+
90
+ item2 = summation([eq.children[x] for x in list(set(range(len(eq.children)))-set(g))])
91
+ n.append(simplify(term_common2(simplify(h[item[0]] + h[item[1]]))+item2))
92
+
93
+
94
+ for item in list(set(n)):
95
+
96
+ item = clr(item)
97
+ node_count = 100
98
+
99
+ tmp = kkk(item, tree_form("d_0"))
100
+
101
+ if tmp[1]:
102
+ out = tmp[0]
103
+ break
104
+ else:
105
+ node_count = 100
106
+ tmp = kkk(eq, tree_form("d_0"))
107
+ if tmp[1]:
108
+ out = tmp[0]
109
+ if out is None:
110
+ return None
111
+ out = [simplify(fraction(item)) for item in out]
112
+
113
+ if not rev(out[0]) and not rev(out[1]):
75
114
 
76
- out = out[0]
115
+ out[0] = fraction(1/out[0])
116
+ out[1] = fraction(1/out[1])
77
117
  return simplify(e0(out[0]-out[1]))
78
118
 
79
119
  def allocvar():
@@ -88,38 +128,28 @@ def esolve(s):
88
128
  return product([tree_form("s_e")**child for child in s.children]) - tree_form("d_1")
89
129
  return TreeNode(s.name, [esolve(child) for child in s.children])
90
130
  def diffsolve_sep2(eq):
91
- global tab
92
-
93
- s = []
94
- eq = simplify(expand(eq))
95
- eq = e1(eq)
96
-
97
- def vlor1(eq):
98
- if contain(eq, tree_form("v_0")) and not contain(eq, tree_form("v_1")):
99
- return True
100
- if contain(eq, tree_form("v_1")) and not contain(eq, tree_form("v_0")):
101
- return True
102
- return False
103
- if eq.name == "f_add" and all(vlor1(child) and [str_form(x) for x in factor_generation(copy.deepcopy(child))].count(str_form(tree_form(vlist(child)[0]).fx("dif")))==1 for child in eq.children):
104
- for child in eq.children:
105
- v = vlist(child)[0]
106
- v2 = tree_form(v).fx("dif")
107
- child = replace(child, v2, tree_form("d_1"))
108
- child = simplify(child)
109
-
110
-
111
- tmp6 = TreeNode("f_integrate", [child, tree_form(v)])
112
- s.append(tmp6)
113
-
114
- if s[-1] is None:
115
- return None
116
- s.append(allocvar())
117
- else:
131
+ lst = None
132
+ if eq is None:
118
133
  return None
119
- s = summation(s)
120
- s = simplify(e0(s))
134
+ eq = eq.children[0]
135
+ if eq.name == "f_add":
136
+ lst = list(eq.children)
137
+ else:
138
+ lst = [eq]
139
+ s = [allocvar()]
140
+
141
+ for item in lst:
142
+ item = simplify(item)
143
+ tmp = factor_generation(item)
144
+
145
+ tmp2 = product([k for k in tmp if k.name != "f_dif"])
146
+
147
+ if tree_form("v_0").fx("dif") in tmp:
148
+ s.append(TreeNode("f_integrate", [tmp2, tree_form("v_0")]))
149
+ elif tree_form("v_1").fx("dif") in tmp:
150
+ s.append(TreeNode("f_integrate", [tmp2, tree_form("v_1")]))
121
151
 
122
- return groupe(s)
152
+ return TreeNode("f_eq", [summation(s), tree_form("d_0")])
123
153
  def e0(eq):
124
154
  return TreeNode("f_eq", [eq, tree_form("d_0")])
125
155
  def e1(eq):
@@ -136,11 +166,17 @@ def groupe(eq):
136
166
 
137
167
  def diffsolve_sep(eq):
138
168
  eq = epowersplit(eq)
169
+
139
170
  eq = inversediff(tree_form("d_0"), eq.children[0].copy_tree())
171
+
140
172
  return eq
141
173
 
142
174
  def diffsolve(eq):
143
175
  orig = eq.copy_tree()
176
+ eq = diff2(eq)
177
+ eq = subs2(eq, order(eq))
178
+ eq = fraction(simplify(fraction(eq)))
179
+
144
180
  if order(eq) == 2:
145
181
  for i in range(2):
146
182
  out = second_order_dif(eq, tree_form(f"v_{i}"), tree_form(f"v_{1-i}"))
@@ -149,28 +185,38 @@ def diffsolve(eq):
149
185
  return orig
150
186
 
151
187
  eq = diffsolve_sep2(diffsolve_sep(eq))
188
+
152
189
  if eq is None:
153
190
  for i in range(2):
154
191
  a = tree_form(f"v_{i}")
155
192
  b = tree_form(f"v_{1-i}")
156
193
  c = tree_form("v_2")
157
- eq2 = replace(orig, b,b*a)
158
- eq2 = replace(eq2, (a*b).fx("dif"), a.fx("dif")*b + b.fx("dif")*a)
159
- eq2 = expand(simplify(fraction(simplify(eq2))))
194
+ eq2 = orig
195
+
196
+ eq2 = subs2(eq2, 1)
197
+ eq2 = replace(eq2, b, b*a)
198
+ eq2 = subs3(eq2)
199
+
200
+ eq2 = simplify(fraction(simplify(eq2)))
201
+
160
202
  eq2 = diffsolve_sep(eq2)
203
+
161
204
  eq2 = diffsolve_sep2(eq2)
162
205
  if eq2 is not None:
163
206
  return e0(TreeNode("f_subs", [replace(eq2.children[0],b,c), c,b/a]).fx("try"))
164
207
  eq = orig
165
-
166
- eq = fraction(eq)
167
- eq = simplify(eq)
168
- for i in range(2):
169
-
170
- out = linear_dif(eq, tree_form(f"v_{i}"), tree_form(f"v_{1-i}"))
171
- if out is not None:
172
- return out
173
- return eq
208
+ eq = simplify(eq)
209
+ eq = subs2(eq, 1)
210
+ eq = fraction(eq)
211
+ for i in range(2):
212
+
213
+ out = linear_dif(eq, tree_form(f"v_{i}"), tree_form(f"v_{1-i}"))
214
+ if out is not None:
215
+ return out
216
+ return orig
217
+ else:
218
+ return eq
219
+
174
220
  def clist(x):
175
221
  return list(x.elements())
176
222
  def collect_term(eq, term_lst):
@@ -219,6 +265,19 @@ def order(eq,m=0):
219
265
  out = order(child, m)
220
266
  best = max(out, best)
221
267
  return best
268
+ def subs2(eq, orde):
269
+ if eq.name in ["f_dif", "f_pdif"] and len(eq.children) == 2:
270
+ if orde == 1:
271
+ return eq.children[0].fx("dif")/eq.children[1].fx("dif")
272
+ else:
273
+ return subs2(TreeNode("f_dif", eq.children), orde)
274
+ return TreeNode(eq.name, [subs2(child, orde) for child in eq.children])
275
+ def subs3(eq):
276
+ if eq.name == "f_dif" and eq.children[0].name == "f_add":
277
+ return summation([subs3(child.fx("dif")) for child in eq.children[0].children])
278
+ if eq.name == "f_dif" and eq.children[0].name == "f_mul":
279
+ return summation([product([subs3(child.fx("dif")) if index==index2 else child for index2, child in enumerate(eq.children[0].children)]) for index in range(len(eq.children[0].children))])
280
+ return TreeNode(eq.name, [subs3(child) for child in eq.children])
222
281
  def second_order_dif(eq, a, b):
223
282
  eq = simplify(eq)
224
283
  nn = [TreeNode("f_dif", [TreeNode("f_dif", [b,a]),a]), TreeNode("f_dif", [b,a]), b]
@@ -260,7 +319,8 @@ def linear_dif(eq, a, b):
260
319
  for key in out[0].keys():
261
320
  out[0][key] = simplify(out[0][key]/tmp)
262
321
  p, q = out[0][b*a.fx("dif")], -out[0][a.fx("dif")]
263
-
322
+ if contain(p, b) or contain(q, b):
323
+ return None
264
324
  f = tree_form("s_e") ** TreeNode("f_integrate", [p, a])
265
325
  return simplify(TreeNode("f_eq", [b*f, TreeNode("f_integrate", [q*f, a])+allocvar()]))
266
326
  return None
@@ -1,5 +1,5 @@
1
1
  from .expand import expand
2
- from .ode import diffsolve, inversediff, order, groupe, epowersplit
2
+ from .ode import diffsolve, inversediff, order, groupe, epowersplit, subs2
3
3
  from .base import *
4
4
  from .simplify import simplify
5
5
  from .diff import diff2
@@ -16,13 +16,7 @@ def capital2(eq):
16
16
  if out is not None:
17
17
  return out
18
18
  return None
19
- def subs2(eq, orde):
20
- if eq.name == "f_pdif":
21
- if orde == 1:
22
- return eq.children[0].fx("dif")/eq.children[1].fx("dif")
23
- else:
24
- return subs2(TreeNode("f_dif", eq.children), orde)
25
- return TreeNode(eq.name, [subs2(child, orde) for child in eq.children])
19
+
26
20
  def capital(eq):
27
21
  if eq.name[:2] == "f_" and eq.name != eq.name.lower():
28
22
  return eq
@@ -36,6 +30,8 @@ def abs_const(eq):
36
30
  return tree_form("v_101")*eq.children[0]
37
31
  return TreeNode(eq.name, [abs_const(child) for child in eq.children])
38
32
  def want(eq):
33
+ if eq is None:
34
+ return None
39
35
  if eq.name == "f_want":
40
36
 
41
37
  eq2 = eq.children[0]
@@ -95,8 +91,7 @@ def pde_sep(eq):
95
91
  r = capital(out[i])
96
92
  lst.append(r)
97
93
  out[i] = replace(out[i], r, tree_form(f"v_{1-i}"))
98
- out[i] = subs2(out[i], order(out[i]))
99
-
94
+ out[i] = tree_form(str_form(out[i]).replace("f_pdif", "f_dif"))
100
95
  out[i] = diffsolve(out[i])
101
96
 
102
97
  out[i] = replace(out[i], tree_form(f"v_{1-i}"), r)
@@ -2,7 +2,7 @@ import itertools
2
2
  from .simplify import simplify
3
3
  from .base import *
4
4
 
5
- def structure(equation, formula, formula_out=None, only_const=False):
5
+ def structure(equation, formula, formula_out=None, only_const=False, wrt=None):
6
6
  varlist = {}
7
7
  def helper(equation, formula):
8
8
  nonlocal varlist
@@ -60,7 +60,7 @@ def structure(equation, formula, formula_out=None, only_const=False):
60
60
  for item in lst(formula):
61
61
  varlist = {}
62
62
  if helper(equation, item):
63
- if only_const and any("v_" in str_form(varlist[key]) for key in varlist.keys()):
63
+ if only_const and any(contain(varlist[key], tree_form(wrt)) for key in varlist.keys()):
64
64
  continue
65
65
  if formula_out is None:
66
66
  return varlist
@@ -90,7 +90,7 @@ def transform_formula(equation, wrt, formula_list, var, expr):
90
90
  if var != "":
91
91
  p = True
92
92
  try:
93
- out = structure(equation.copy_tree(), copy.deepcopy(item[0]), copy.deepcopy(item[1]), p)
93
+ out = structure(equation.copy_tree(), copy.deepcopy(item[0]), copy.deepcopy(item[1]), p, wrt)
94
94
  if out is not None:
95
95
  out = simplify(out)
96
96
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mathai
3
- Version: 0.7.8
3
+ Version: 0.7.9
4
4
  Summary: Mathematics solving Ai tailored to NCERT
5
5
  Home-page: https://github.com/infinity390/mathai4
6
6
  Requires-Python: >=3.7
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="mathai",
5
- version="0.7.8",
5
+ version="0.7.9",
6
6
  description="Mathematics solving Ai tailored to NCERT",
7
7
  long_description=open("README.md").read(),
8
8
  long_description_content_type="text/markdown",
@@ -1,103 +0,0 @@
1
- from .base import *
2
- from .simplify import simplify
3
- from .expand import expand
4
-
5
- def fraction(eq):
6
- stack = [(eq, None)] # (current_node, parent_processed_children)
7
- result_map = {} # Map original nodes to their processed TreeNode
8
-
9
- while stack:
10
- node, parent_info = stack.pop()
11
-
12
- # If node already processed, continue
13
- if node in result_map:
14
- continue
15
-
16
- # Base case: leaf node
17
- if not node.children:
18
- result_map[node] = TreeNode(node.name, [])
19
- continue
20
-
21
- # Check if all children are processed
22
- all_children_done = all(child in result_map for child in node.children)
23
- if not all_children_done:
24
- # Push current node back to stack after children
25
- stack.append((node, parent_info))
26
- for child in reversed(node.children):
27
- if child not in result_map:
28
- stack.append((child, (node, node.children)))
29
- continue
30
-
31
- # Now all children are processed, handle this node
32
- if node.name == "f_eq":
33
- left = result_map[node.children[0]]
34
- right = result_map[node.children[1]]
35
- result_map[node] = TreeNode("f_eq", [left, right])
36
- continue
37
-
38
- elif node.name == "f_add":
39
- con = []
40
- for child in node.children:
41
- child_processed = result_map[child]
42
- if child_processed.name == "f_pow" and child_processed.children[1].name[:2] == "d_" and int(child_processed.children[1].name[2:]) < 0:
43
- den = []
44
- n = int(child_processed.children[1].name[2:])
45
- if n == -1:
46
- den.append(child_processed.children[0])
47
- else:
48
- den.append(TreeNode("f_pow", [child_processed.children[0], tree_form("d_" + str(-n))]))
49
- con.append([[], den])
50
- elif child_processed.name == "f_mul":
51
- num = []
52
- den = []
53
- for child2 in child_processed.children:
54
- if child2.name == "f_pow" and child2.children[1].name[:2] == "d_" and int(child2.children[1].name[2:]) < 0:
55
- n = int(child2.children[1].name[2:])
56
- if n == -1:
57
- den.append(child2.children[0])
58
- else:
59
- den.append(TreeNode("f_pow", [child2.children[0], tree_form("d_" + str(-n))]))
60
- else:
61
- num.append(child2)
62
- con.append([num, den])
63
- else:
64
- con.append([[child_processed], []])
65
-
66
- if len(con) > 1 and any(x[1] != [] for x in con):
67
- # Construct numerator
68
- a_children = []
69
- for i in range(len(con)):
70
- b_children = con[i][0].copy()
71
- for j in range(len(con)):
72
- if i == j:
73
- continue
74
- b_children += con[j][1]
75
- if len(b_children) == 0:
76
- b_children = [tree_form("d_1")]
77
- elif len(b_children) == 1:
78
- b_children = b_children
79
- else:
80
- b_children = [TreeNode("f_mul", b_children)]
81
- a_children += b_children if isinstance(b_children, list) else [b_children]
82
-
83
- a = TreeNode("f_add", a_children)
84
-
85
- # Construct denominator
86
- c_children = []
87
- for i in range(len(con)):
88
- c_children += con[i][1]
89
- if len(c_children) == 1:
90
- c = c_children[0]
91
- else:
92
- c = TreeNode("f_mul", c_children)
93
- c = TreeNode("f_pow", [c, tree_form("d_-1")])
94
-
95
- result_map[node] = TreeNode("f_mul", [simplify(expand(simplify(a))), c])
96
- continue
97
-
98
- # Default: just reconstruct node
99
- children_processed = [result_map[child] for child in node.children]
100
- result_map[node] = TreeNode(node.name, children_processed)
101
-
102
- # Final return
103
- return simplify(result_map[eq])
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes