mathai 2.2.4__tar.gz → 2.2.6__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.
- {mathai-2.2.4 → mathai-2.2.6}/PKG-INFO +36 -16
- {mathai-2.2.4 → mathai-2.2.6}/README.md +35 -14
- {mathai-2.2.4 → mathai-2.2.6}/mathai/__init__.py +1 -1
- {mathai-2.2.4 → mathai-2.2.6}/mathai/electronic.py +27 -206
- {mathai-2.2.4 → mathai-2.2.6}/mathai/graphics.py +1 -19
- {mathai-2.2.4 → mathai-2.2.6}/mathai/inverse.py +24 -13
- {mathai-2.2.4 → mathai-2.2.6}/mathai/linear.py +27 -11
- {mathai-2.2.4 → mathai-2.2.6}/mathai.egg-info/PKG-INFO +36 -16
- {mathai-2.2.4 → mathai-2.2.6}/mathai.egg-info/requires.txt +0 -1
- {mathai-2.2.4 → mathai-2.2.6}/setup.py +2 -3
- {mathai-2.2.4 → mathai-2.2.6}/mathai/apart.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/base.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/decision.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/diff.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/expand.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/factor.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/differentiation.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/integration.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/integration_trig.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/is_integrate_subs.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/lambda_compress.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/lambda_expand.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/lambda_reduce.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/limit_infinity.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/matrix_vectorization_calculus.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/power_rule.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/quadratic.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/statistics_1.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/statistics_2.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/test.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula/trigonometry_misc.marshal +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula_compiler.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula_data.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/formula_interpretor.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/fraction.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/integrate.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/lambda_calculus.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/limit.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/logic.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/matrix.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/ml.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/mlscalar.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/ode.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/parser.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/pde.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/printeq.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/qm.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/simplify.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/statistics.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/test.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/tool.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/trig.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai/univariate_inequality.py +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai.egg-info/SOURCES.txt +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai.egg-info/dependency_links.txt +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/mathai.egg-info/top_level.txt +0 -0
- {mathai-2.2.4 → mathai-2.2.6}/setup.cfg +0 -0
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mathai
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.6
|
|
4
4
|
Summary: Mathematics solving Ai tailored to NCERT
|
|
5
5
|
Home-page: https://github.com/infinity390/mathai
|
|
6
6
|
Requires-Python: >=3.7
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
Requires-Dist: more_itertools
|
|
9
|
-
Requires-Dist: schemdraw
|
|
10
9
|
Dynamic: description
|
|
11
10
|
Dynamic: description-content-type
|
|
12
11
|
Dynamic: home-page
|
|
@@ -438,7 +437,6 @@ wire_4 = Edge((4, 9))
|
|
|
438
437
|
edge_list = [wire_1, wire_2, wire_3, wire_4,ohm_5, ohm_6, ohm_7, ohm_8, ohm_8_2, ohm_10, ohm_11, ohm_20]
|
|
439
438
|
graph = CircuitGraph(10, edge_list, {})
|
|
440
439
|
print(compute(find_resistance(graph, 0, 9)))
|
|
441
|
-
draw_circuit(graph, start=0, end=9, scale=3.0, grid_size=30)
|
|
442
440
|
```
|
|
443
441
|
|
|
444
442
|
#### Output
|
|
@@ -450,7 +448,29 @@ done
|
|
|
450
448
|
8.66474543707973
|
|
451
449
|
```
|
|
452
450
|
|
|
453
|
-
#### Example Demonstration 11 (
|
|
451
|
+
#### Example Demonstration 11 (resistors in parallel)
|
|
452
|
+
```python
|
|
453
|
+
from mathai import *
|
|
454
|
+
load_formula_from_file()
|
|
455
|
+
wire_1 = Edge((1, 3))
|
|
456
|
+
wire_2 = Edge((2, 3))
|
|
457
|
+
ohm_r1 = Edge((0, 1), "resistor", parse("x"))
|
|
458
|
+
ohm_r2 = Edge((0, 2), "resistor", parse("y"))
|
|
459
|
+
edge_list = [wire_1, ohm_r1, ohm_r2, wire_2]
|
|
460
|
+
graph = CircuitGraph(4, edge_list, {})
|
|
461
|
+
print(fraction(find_resistance(graph, 0, 3)))
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
#### Output
|
|
465
|
+
|
|
466
|
+
```
|
|
467
|
+
loading formulas from file...
|
|
468
|
+
done
|
|
469
|
+
|
|
470
|
+
(x*y)/(x+y)
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
#### Example Demonstration 12 (engineering graphics)
|
|
454
474
|
```python
|
|
455
475
|
from mathai import *
|
|
456
476
|
# (z,y) is dash, a'b' is front view
|
|
@@ -467,7 +487,7 @@ solve_graphics_string("15 25 0 None None None None None None 30*pi/180 0 50 None
|
|
|
467
487
|
print()
|
|
468
488
|
solve_graphics_string("0 -25 0 None None None None None None None 0 55 None 75") # 11.17
|
|
469
489
|
print()
|
|
470
|
-
solve_graphics_string("25 50 0 -30 None None None None None None 0
|
|
490
|
+
solve_graphics_string("25 50 0 -30 None None None None None None 0 None None 80") # 11.19
|
|
471
491
|
```
|
|
472
492
|
|
|
473
493
|
#### Output
|
|
@@ -477,14 +497,14 @@ Ay : 20
|
|
|
477
497
|
Az : 0
|
|
478
498
|
Bx : 30
|
|
479
499
|
By : 20+(60*sin(((2*pi)/9)))
|
|
480
|
-
Bz : 60*
|
|
500
|
+
Bz : 60*sqrt((1-(sin(((2*pi)/9))^2)))
|
|
481
501
|
Bx-Ax : 0
|
|
482
502
|
By-Ay : 60*sin(((2*pi)/9))
|
|
483
|
-
Bz-Az : 60*
|
|
503
|
+
Bz-Az : 60*sqrt((1-(sin(((2*pi)/9))^2)))
|
|
484
504
|
inclination_with_VP : 0
|
|
485
505
|
inclination_with_HP : (2*pi)/9
|
|
486
506
|
front_view_length : 60
|
|
487
|
-
top_view_length :
|
|
507
|
+
top_view_length : sqrt((3600-(3600*(sin(((2*pi)/9))^2))))
|
|
488
508
|
line_length : 60
|
|
489
509
|
|
|
490
510
|
Ax : 20
|
|
@@ -520,16 +540,16 @@ line_length : 100/(3^-(-1/2))
|
|
|
520
540
|
Ax : 0
|
|
521
541
|
Ay : -25
|
|
522
542
|
Az : 0
|
|
523
|
-
Bx :
|
|
543
|
+
Bx : 5*sqrt(104)
|
|
524
544
|
By : -25
|
|
525
545
|
Bz : 55
|
|
526
|
-
Bx-Ax :
|
|
546
|
+
Bx-Ax : 5*sqrt(104)
|
|
527
547
|
By-Ay : 0
|
|
528
548
|
Bz-Az : 55
|
|
529
|
-
inclination_with_VP :
|
|
549
|
+
inclination_with_VP : arcsin((sqrt(104)/15))
|
|
530
550
|
inclination_with_HP : 0
|
|
531
551
|
front_view_length : 55
|
|
532
|
-
top_view_length :
|
|
552
|
+
top_view_length : 75
|
|
533
553
|
line_length : 75
|
|
534
554
|
|
|
535
555
|
Ax : 25
|
|
@@ -537,14 +557,14 @@ Ay : 50
|
|
|
537
557
|
Az : 0
|
|
538
558
|
Bx : -30
|
|
539
559
|
By : 50
|
|
540
|
-
Bz :
|
|
560
|
+
Bz : 5*sqrt(135)
|
|
541
561
|
Bx-Ax : -55
|
|
542
562
|
By-Ay : 0
|
|
543
|
-
Bz-Az :
|
|
563
|
+
Bz-Az : 5*sqrt(135)
|
|
544
564
|
inclination_with_VP : arcsin((-11/16))
|
|
545
565
|
inclination_with_HP : 0
|
|
546
|
-
front_view_length :
|
|
547
|
-
top_view_length :
|
|
566
|
+
front_view_length : sqrt(3375)
|
|
567
|
+
top_view_length : 80
|
|
548
568
|
line_length : 80
|
|
549
569
|
```
|
|
550
570
|
|
|
@@ -422,7 +422,6 @@ wire_4 = Edge((4, 9))
|
|
|
422
422
|
edge_list = [wire_1, wire_2, wire_3, wire_4,ohm_5, ohm_6, ohm_7, ohm_8, ohm_8_2, ohm_10, ohm_11, ohm_20]
|
|
423
423
|
graph = CircuitGraph(10, edge_list, {})
|
|
424
424
|
print(compute(find_resistance(graph, 0, 9)))
|
|
425
|
-
draw_circuit(graph, start=0, end=9, scale=3.0, grid_size=30)
|
|
426
425
|
```
|
|
427
426
|
|
|
428
427
|
#### Output
|
|
@@ -434,7 +433,29 @@ done
|
|
|
434
433
|
8.66474543707973
|
|
435
434
|
```
|
|
436
435
|
|
|
437
|
-
#### Example Demonstration 11 (
|
|
436
|
+
#### Example Demonstration 11 (resistors in parallel)
|
|
437
|
+
```python
|
|
438
|
+
from mathai import *
|
|
439
|
+
load_formula_from_file()
|
|
440
|
+
wire_1 = Edge((1, 3))
|
|
441
|
+
wire_2 = Edge((2, 3))
|
|
442
|
+
ohm_r1 = Edge((0, 1), "resistor", parse("x"))
|
|
443
|
+
ohm_r2 = Edge((0, 2), "resistor", parse("y"))
|
|
444
|
+
edge_list = [wire_1, ohm_r1, ohm_r2, wire_2]
|
|
445
|
+
graph = CircuitGraph(4, edge_list, {})
|
|
446
|
+
print(fraction(find_resistance(graph, 0, 3)))
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
#### Output
|
|
450
|
+
|
|
451
|
+
```
|
|
452
|
+
loading formulas from file...
|
|
453
|
+
done
|
|
454
|
+
|
|
455
|
+
(x*y)/(x+y)
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
#### Example Demonstration 12 (engineering graphics)
|
|
438
459
|
```python
|
|
439
460
|
from mathai import *
|
|
440
461
|
# (z,y) is dash, a'b' is front view
|
|
@@ -451,7 +472,7 @@ solve_graphics_string("15 25 0 None None None None None None 30*pi/180 0 50 None
|
|
|
451
472
|
print()
|
|
452
473
|
solve_graphics_string("0 -25 0 None None None None None None None 0 55 None 75") # 11.17
|
|
453
474
|
print()
|
|
454
|
-
solve_graphics_string("25 50 0 -30 None None None None None None 0
|
|
475
|
+
solve_graphics_string("25 50 0 -30 None None None None None None 0 None None 80") # 11.19
|
|
455
476
|
```
|
|
456
477
|
|
|
457
478
|
#### Output
|
|
@@ -461,14 +482,14 @@ Ay : 20
|
|
|
461
482
|
Az : 0
|
|
462
483
|
Bx : 30
|
|
463
484
|
By : 20+(60*sin(((2*pi)/9)))
|
|
464
|
-
Bz : 60*
|
|
485
|
+
Bz : 60*sqrt((1-(sin(((2*pi)/9))^2)))
|
|
465
486
|
Bx-Ax : 0
|
|
466
487
|
By-Ay : 60*sin(((2*pi)/9))
|
|
467
|
-
Bz-Az : 60*
|
|
488
|
+
Bz-Az : 60*sqrt((1-(sin(((2*pi)/9))^2)))
|
|
468
489
|
inclination_with_VP : 0
|
|
469
490
|
inclination_with_HP : (2*pi)/9
|
|
470
491
|
front_view_length : 60
|
|
471
|
-
top_view_length :
|
|
492
|
+
top_view_length : sqrt((3600-(3600*(sin(((2*pi)/9))^2))))
|
|
472
493
|
line_length : 60
|
|
473
494
|
|
|
474
495
|
Ax : 20
|
|
@@ -504,16 +525,16 @@ line_length : 100/(3^-(-1/2))
|
|
|
504
525
|
Ax : 0
|
|
505
526
|
Ay : -25
|
|
506
527
|
Az : 0
|
|
507
|
-
Bx :
|
|
528
|
+
Bx : 5*sqrt(104)
|
|
508
529
|
By : -25
|
|
509
530
|
Bz : 55
|
|
510
|
-
Bx-Ax :
|
|
531
|
+
Bx-Ax : 5*sqrt(104)
|
|
511
532
|
By-Ay : 0
|
|
512
533
|
Bz-Az : 55
|
|
513
|
-
inclination_with_VP :
|
|
534
|
+
inclination_with_VP : arcsin((sqrt(104)/15))
|
|
514
535
|
inclination_with_HP : 0
|
|
515
536
|
front_view_length : 55
|
|
516
|
-
top_view_length :
|
|
537
|
+
top_view_length : 75
|
|
517
538
|
line_length : 75
|
|
518
539
|
|
|
519
540
|
Ax : 25
|
|
@@ -521,14 +542,14 @@ Ay : 50
|
|
|
521
542
|
Az : 0
|
|
522
543
|
Bx : -30
|
|
523
544
|
By : 50
|
|
524
|
-
Bz :
|
|
545
|
+
Bz : 5*sqrt(135)
|
|
525
546
|
Bx-Ax : -55
|
|
526
547
|
By-Ay : 0
|
|
527
|
-
Bz-Az :
|
|
548
|
+
Bz-Az : 5*sqrt(135)
|
|
528
549
|
inclination_with_VP : arcsin((-11/16))
|
|
529
550
|
inclination_with_HP : 0
|
|
530
|
-
front_view_length :
|
|
531
|
-
top_view_length :
|
|
551
|
+
front_view_length : sqrt(3375)
|
|
552
|
+
top_view_length : 80
|
|
532
553
|
line_length : 80
|
|
533
554
|
```
|
|
534
555
|
|
|
@@ -7,7 +7,7 @@ from .qm import hydrogen_gse, helium_gse, power_rule
|
|
|
7
7
|
|
|
8
8
|
from .lambda_calculus import lambda_expand, lambda_compress, lambda_reduce
|
|
9
9
|
|
|
10
|
-
from .electronic import Edge, CircuitGraph, find_resistance
|
|
10
|
+
from .electronic import Edge, CircuitGraph, find_resistance
|
|
11
11
|
|
|
12
12
|
from .linear import linear_solve
|
|
13
13
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import random
|
|
2
1
|
import copy
|
|
3
2
|
from .base import *
|
|
4
3
|
from .simplify import simplify
|
|
@@ -12,6 +11,7 @@ class Edge:
|
|
|
12
11
|
self.value = value
|
|
13
12
|
self.edge = tuple(edge) if edge else None
|
|
14
13
|
self.current = None
|
|
14
|
+
self.voltage = None
|
|
15
15
|
class CircuitGraph:
|
|
16
16
|
def __init__(self, node_count=0, edge_list=None, connection=None):
|
|
17
17
|
self.node_count = node_count
|
|
@@ -26,7 +26,7 @@ class CircuitGraph:
|
|
|
26
26
|
if edge.edge:
|
|
27
27
|
self.node_count = max(self.node_count, max(edge.edge) + 1)
|
|
28
28
|
self.connection = copy.deepcopy(connection) if connection else {}
|
|
29
|
-
self.variable_list = [TreeNode(f"v_{i}") for i in range(26)]
|
|
29
|
+
self.variable_list = [TreeNode(f"v_{i}") for i in range(6,26)]
|
|
30
30
|
self.complete_connection()
|
|
31
31
|
def complete_connection(self):
|
|
32
32
|
for i in range(self.node_count):
|
|
@@ -174,19 +174,21 @@ class CircuitGraph:
|
|
|
174
174
|
missing = [i for i, edge in enumerate(self.edge_list) if edge.current is None]
|
|
175
175
|
if missing:
|
|
176
176
|
raise ValueError(f"Could not determine currents: {missing}")
|
|
177
|
-
def find_resistance(circuit, start, end):
|
|
177
|
+
def find_resistance(circuit, start=None, end=None, compute_current_only=False):
|
|
178
178
|
circuit = copy.deepcopy(circuit)
|
|
179
|
-
if start == end:
|
|
179
|
+
if start == end and start is not None and end is not None:
|
|
180
180
|
return TreeNode("d_0")
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
181
|
+
cell_idx = None
|
|
182
|
+
if not compute_current_only:
|
|
183
|
+
new_node = circuit.node_count
|
|
184
|
+
circuit.node_count += 1
|
|
185
|
+
cell = Edge((end, new_node), "cell", TreeNode("d_1"))
|
|
186
|
+
wire = Edge((new_node, start), "wire")
|
|
187
|
+
circuit.edge_list.append(cell)
|
|
188
|
+
cell_idx = len(circuit.edge_list) - 1
|
|
189
|
+
circuit.edge_list.append(wire)
|
|
188
190
|
circuit.complete_connection()
|
|
189
|
-
circuit.assign_currents(
|
|
191
|
+
circuit.assign_currents()
|
|
190
192
|
cycles = circuit.all_simple_cycle()
|
|
191
193
|
equations = []
|
|
192
194
|
for cycle in cycles:
|
|
@@ -200,210 +202,29 @@ def find_resistance(circuit, start, end):
|
|
|
200
202
|
[TreeNode("f_eq", [equation, TreeNode("d_0")]) for equation in equations]
|
|
201
203
|
)
|
|
202
204
|
equations = simplify(fraction(simplify(equations)))
|
|
203
|
-
|
|
205
|
+
const_list = []
|
|
206
|
+
for item in circuit.edge_list:
|
|
207
|
+
if item.edge_type == "resistor":
|
|
208
|
+
const_list += [TreeNode(item) for item in vlist(item.value)]
|
|
209
|
+
equations = linear_solve(equations, const_list)
|
|
204
210
|
solutions = {}
|
|
205
211
|
equation_list = equations.children if equations.name == "f_and" else [equations]
|
|
206
212
|
for equation in equation_list:
|
|
207
|
-
variables = vlist(equation)
|
|
213
|
+
variables = list(set(vlist(equation))-set([item.name for item in const_list]))
|
|
208
214
|
if len(variables) != 1:
|
|
209
215
|
continue
|
|
210
216
|
variable = variables[0]
|
|
211
217
|
solutions[variable] = inverse(equation.children[0], variable)
|
|
218
|
+
for index, item in enumerate(circuit.edge_list):
|
|
219
|
+
for v in vlist(circuit.edge_list[index].current):
|
|
220
|
+
if TreeNode(v) in const_list:
|
|
221
|
+
continue
|
|
222
|
+
circuit.edge_list[index].current = simplify(replace(circuit.edge_list[index].current, TreeNode(v), solutions[v]))
|
|
223
|
+
if compute_current_only:
|
|
224
|
+
return circuit
|
|
212
225
|
current = circuit.edge_list[cell_idx].current
|
|
213
226
|
for variable, value in solutions.items():
|
|
214
227
|
if variable in vlist(current):
|
|
215
228
|
current = replace(current, tree_form(variable), value)
|
|
216
229
|
current = simplify(TreeNode("d_1")/current)
|
|
217
230
|
return current
|
|
218
|
-
import random
|
|
219
|
-
import schemdraw
|
|
220
|
-
import schemdraw.elements as elm
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
def on_segment(p, a, b):
|
|
224
|
-
"""Returns True if point p lies exactly on the line segment a-b."""
|
|
225
|
-
# Collinearity check (cross product == 0)
|
|
226
|
-
cross = (p[0] - a[0]) * (b[1] - a[1]) - (p[1] - a[1]) * (b[0] - a[0])
|
|
227
|
-
if abs(cross) > 1e-6:
|
|
228
|
-
return False
|
|
229
|
-
# Bounding box check
|
|
230
|
-
if min(a[0], b[0]) <= p[0] <= max(a[0], b[0]) and \
|
|
231
|
-
min(a[1], b[1]) <= p[1] <= max(a[1], b[1]):
|
|
232
|
-
return True
|
|
233
|
-
return False
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
def segments_conflict_exact(a, b, c, d):
|
|
237
|
-
"""
|
|
238
|
-
Checks if segment ab conflicts with cd (intersects or overlaps),
|
|
239
|
-
ignoring shared endpoints unless they perfectly overlap.
|
|
240
|
-
"""
|
|
241
|
-
def ccw(p, q, r):
|
|
242
|
-
return (q[0] - p[0]) * (r[1] - p[1]) - (q[1] - p[1]) * (r[0] - p[0])
|
|
243
|
-
|
|
244
|
-
c1, c2 = ccw(a, b, c), ccw(a, b, d)
|
|
245
|
-
c3, c4 = ccw(c, d, a), ccw(c, d, b)
|
|
246
|
-
|
|
247
|
-
# 1. True geometric intersection (lines cross)
|
|
248
|
-
if ((c1 > 0 and c2 < 0) or (c1 < 0 and c2 > 0)) and \
|
|
249
|
-
((c3 > 0 and c4 < 0) or (c3 < 0 and c4 > 0)):
|
|
250
|
-
return True
|
|
251
|
-
|
|
252
|
-
# 2. Collinear overlap (one point lies strictly inside the other segment)
|
|
253
|
-
if on_segment(c, a, b) and c != a and c != b: return True
|
|
254
|
-
if on_segment(d, a, b) and d != a and d != b: return True
|
|
255
|
-
if on_segment(a, c, d) and a != c and a != d: return True
|
|
256
|
-
if on_segment(b, c, d) and b != c and b != d: return True
|
|
257
|
-
|
|
258
|
-
# 3. Identical overlapping segments
|
|
259
|
-
if (a == c and b == d) or (a == d and b == c):
|
|
260
|
-
return True
|
|
261
|
-
|
|
262
|
-
return False
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
def get_all_candidate_routes(p1, p2):
|
|
266
|
-
"""Generates all valid orthogonal straight line and 1-bend L-routes."""
|
|
267
|
-
x1, y1 = p1
|
|
268
|
-
x2, y2 = p2
|
|
269
|
-
|
|
270
|
-
# Collinear (Straight line along single axis)
|
|
271
|
-
if x1 == x2 or y1 == y2:
|
|
272
|
-
return [[p1, p2]]
|
|
273
|
-
|
|
274
|
-
# Standard L-shapes (Horizontal-first or Vertical-first)
|
|
275
|
-
return [
|
|
276
|
-
[p1, (x1, y2), p2],
|
|
277
|
-
[p1, (x2, y1), p2]
|
|
278
|
-
]
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
def route_to_segments(route):
|
|
282
|
-
return [(route[i], route[i + 1]) for i in range(len(route) - 1)]
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
def check_route_conflict(route, placed_routes, node_positions, u, v):
|
|
286
|
-
"""Validates that a new route does not cross placed routes or run over unrelated nodes."""
|
|
287
|
-
segs = route_to_segments(route)
|
|
288
|
-
|
|
289
|
-
# 1. Check against already placed routes
|
|
290
|
-
for placed_route in placed_routes:
|
|
291
|
-
placed_segs = route_to_segments(placed_route)
|
|
292
|
-
for a, b in segs:
|
|
293
|
-
for c, d in placed_segs:
|
|
294
|
-
if segments_conflict_exact(a, b, c, d):
|
|
295
|
-
return True
|
|
296
|
-
|
|
297
|
-
# 2. Check against nodes (prevent line from running through an unrelated node)
|
|
298
|
-
for node, pos in node_positions.items():
|
|
299
|
-
if node == u or node == v:
|
|
300
|
-
continue # Permitted to touch its own endpoints
|
|
301
|
-
for a, b in segs:
|
|
302
|
-
if on_segment(pos, a, b):
|
|
303
|
-
return True
|
|
304
|
-
|
|
305
|
-
return False
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
def solve_routing(edges, node_positions):
|
|
309
|
-
"""DFS Backtracking to find a 100% collision-free route mapping for a given node layout."""
|
|
310
|
-
placed_routes = []
|
|
311
|
-
|
|
312
|
-
def backtrack(edge_idx):
|
|
313
|
-
if edge_idx == len(edges):
|
|
314
|
-
return True
|
|
315
|
-
|
|
316
|
-
edge = edges[edge_idx]
|
|
317
|
-
u, v = edge.edge
|
|
318
|
-
p1, p2 = node_positions[u], node_positions[v]
|
|
319
|
-
|
|
320
|
-
candidate_routes = get_all_candidate_routes(p1, p2)
|
|
321
|
-
random.shuffle(candidate_routes)
|
|
322
|
-
|
|
323
|
-
for route in candidate_routes:
|
|
324
|
-
if not check_route_conflict(route, placed_routes, node_positions, u, v):
|
|
325
|
-
placed_routes.append(route)
|
|
326
|
-
if backtrack(edge_idx + 1):
|
|
327
|
-
return True
|
|
328
|
-
placed_routes.pop()
|
|
329
|
-
return False
|
|
330
|
-
|
|
331
|
-
if backtrack(0):
|
|
332
|
-
return placed_routes
|
|
333
|
-
return None
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
def draw_circuit(graph, start=None, end=None, scale=3.0, grid_size=12, max_attempts=10000):
|
|
337
|
-
"""
|
|
338
|
-
Renders a circuit using randomized grid placement and exact geometric backtracking.
|
|
339
|
-
Guarantees strict L/straight paths without line intersections or bugs.
|
|
340
|
-
"""
|
|
341
|
-
edges = graph.edge_list
|
|
342
|
-
all_nodes = set()
|
|
343
|
-
for edge in edges:
|
|
344
|
-
all_nodes.add(edge.edge[0])
|
|
345
|
-
all_nodes.add(edge.edge[1])
|
|
346
|
-
|
|
347
|
-
nodes_list = sorted(list(all_nodes))
|
|
348
|
-
|
|
349
|
-
best_positions = None
|
|
350
|
-
best_routes = None
|
|
351
|
-
|
|
352
|
-
# Search for a node configuration that allows a perfect non-intersecting layout
|
|
353
|
-
for _ in range(max_attempts):
|
|
354
|
-
# Generate random available grid locations
|
|
355
|
-
available_cells = [
|
|
356
|
-
(col * scale, -row * scale)
|
|
357
|
-
for row in range(grid_size)
|
|
358
|
-
for col in range(grid_size)
|
|
359
|
-
]
|
|
360
|
-
random.shuffle(available_cells)
|
|
361
|
-
|
|
362
|
-
current_positions = {node: available_cells[i] for i, node in enumerate(nodes_list)}
|
|
363
|
-
|
|
364
|
-
# Attempt to perfectly route all edges
|
|
365
|
-
routes = solve_routing(edges, current_positions)
|
|
366
|
-
|
|
367
|
-
if routes is not None:
|
|
368
|
-
best_positions = current_positions
|
|
369
|
-
best_routes = routes
|
|
370
|
-
break # Perfect layout found!
|
|
371
|
-
|
|
372
|
-
if best_routes is None:
|
|
373
|
-
raise RuntimeError("Failed to find a non-intersecting layout. Try increasing grid_size or max_attempts.")
|
|
374
|
-
|
|
375
|
-
# Render Circuit Diagram with Schemdraw
|
|
376
|
-
d = schemdraw.Drawing()
|
|
377
|
-
|
|
378
|
-
for idx, edge in enumerate(edges):
|
|
379
|
-
route = best_routes[idx]
|
|
380
|
-
segs = route_to_segments(route)
|
|
381
|
-
resistor = getattr(edge, "edge_type", "") == "resistor"
|
|
382
|
-
value = getattr(edge, "value", "")
|
|
383
|
-
|
|
384
|
-
for i, (p1, p2) in enumerate(segs):
|
|
385
|
-
# Place resistor component on the last segment of the route
|
|
386
|
-
if resistor and i == len(segs) - 1:
|
|
387
|
-
lbl = f"{value} Ω" if value else ""
|
|
388
|
-
d.add(
|
|
389
|
-
elm.Resistor()
|
|
390
|
-
.at(p1)
|
|
391
|
-
.to(p2)
|
|
392
|
-
.label(lbl)
|
|
393
|
-
)
|
|
394
|
-
else:
|
|
395
|
-
d.add(elm.Line().at(p1).to(p2))
|
|
396
|
-
|
|
397
|
-
# Draw Nodes
|
|
398
|
-
for node, pos in best_positions.items():
|
|
399
|
-
d.add(elm.Dot().at(pos))
|
|
400
|
-
|
|
401
|
-
# Add Terminal Labels
|
|
402
|
-
if start is not None and start in best_positions:
|
|
403
|
-
d.add(elm.Label().at(best_positions[start]).label("Start", loc="left"))
|
|
404
|
-
|
|
405
|
-
if end is not None and end in best_positions:
|
|
406
|
-
d.add(elm.Label().at(best_positions[end]).label("End", loc="right"))
|
|
407
|
-
|
|
408
|
-
d.draw()
|
|
409
|
-
return d
|
|
@@ -4,10 +4,8 @@ from .simplify import simplify
|
|
|
4
4
|
from .trig import trig0
|
|
5
5
|
import itertools
|
|
6
6
|
from .inverse import inverse
|
|
7
|
-
from .formula_data import compile_formula
|
|
8
7
|
from .expand import expand
|
|
9
8
|
from .parser import parse
|
|
10
|
-
|
|
11
9
|
def solve_graphics(Ax, Ay, Az, Bx, By, Bz, BAx, BAy, BAz, phi, theta, fvl, tvl, length):
|
|
12
10
|
eq1 = TreeNode("f_eq", [TreeNode("v_6"), TreeNode("v_3") - TreeNode("v_0")])
|
|
13
11
|
eq2 = TreeNode("f_eq", [TreeNode("v_7"), TreeNode("v_4") - TreeNode("v_1")])
|
|
@@ -17,52 +15,36 @@ def solve_graphics(Ax, Ay, Az, Bx, By, Bz, BAx, BAy, BAz, phi, theta, fvl, tvl,
|
|
|
17
15
|
eq6 = TreeNode("f_eq", [TreeNode("v_8"), (TreeNode("d_1") - TreeNode("v_9").fx("sin")**2 - TreeNode("v_10").fx("sin")**2).fx("sqrt") * TreeNode("v_13")])
|
|
18
16
|
eq7 = TreeNode("f_eq", [TreeNode("v_12")**2, (TreeNode("v_3") - TreeNode("v_0"))**2 + (TreeNode("v_5") - TreeNode("v_2"))**2])
|
|
19
17
|
eq8 = TreeNode("f_eq", [TreeNode("v_11")**2, (TreeNode("v_4") - TreeNode("v_1"))**2 + (TreeNode("v_5") - TreeNode("v_2"))**2])
|
|
20
|
-
|
|
21
18
|
q = operation("f_and", [eq1, eq2, eq3, eq4, eq5, eq6, eq7, eq8])
|
|
22
19
|
lst = [Ax, Ay, Az, Bx, By, Bz, BAx, BAy, BAz, phi, theta, fvl, tvl, length]
|
|
23
20
|
name = "Ax Ay Az Bx By Bz Bx-Ax By-Ay Bz-Az inclination_with_VP inclination_with_HP front_view_length top_view_length line_length".split(" ")
|
|
24
|
-
|
|
25
21
|
solution = {}
|
|
26
22
|
for index, item in enumerate(lst):
|
|
27
23
|
if item is not None:
|
|
28
24
|
solution[f"v_{index}"] = item
|
|
29
|
-
|
|
30
|
-
fx = compile_formula("sin(x)^2 1-cos(x)^2 _ _ _ _ _ _ _ 2")
|
|
31
25
|
q = simplify(q)
|
|
32
|
-
|
|
33
26
|
done = True
|
|
34
27
|
while done:
|
|
35
28
|
done = False
|
|
36
29
|
for i in range(len(q.children)):
|
|
37
30
|
item = q.children[i]
|
|
38
|
-
# Replace known variables
|
|
39
31
|
for key, item2 in solution.items():
|
|
40
32
|
item = replace(item, TreeNode(key), item2)
|
|
41
|
-
|
|
42
|
-
# Apply trig identities during simplification
|
|
43
|
-
item = fraction(expand(trig0(fx(simplify(item)))))
|
|
33
|
+
item = fraction(expand(trig0(simplify(item))))
|
|
44
34
|
q.children[i] = item
|
|
45
|
-
|
|
46
|
-
# Solvable equation check
|
|
47
35
|
vars_in_item = vlist(item)
|
|
48
36
|
if len(vars_in_item) == 1:
|
|
49
37
|
target_var = vars_in_item[0]
|
|
50
|
-
# Pass the full equation node (or LHS - RHS) so inverse() has both sides
|
|
51
38
|
solution[target_var] = inverse(item.children[0], target_var)
|
|
52
39
|
done = True
|
|
53
40
|
break
|
|
54
|
-
|
|
55
|
-
# Map back to readable parameter names safely
|
|
56
41
|
final_solution = {}
|
|
57
42
|
for i, param_name in enumerate(name):
|
|
58
43
|
var_key = f"v_{i}"
|
|
59
44
|
if var_key in solution:
|
|
60
45
|
final_solution[param_name] = simplify(expand(solution[var_key]))
|
|
61
|
-
|
|
62
46
|
return final_solution
|
|
63
|
-
|
|
64
47
|
def solve_graphics_string(s):
|
|
65
|
-
# Use s.split() to handle arbitrary whitespace cleanly
|
|
66
48
|
s_parsed = [None if item == "None" else parse(item) for item in s.split()]
|
|
67
49
|
for key, item in solve_graphics(*s_parsed).items():
|
|
68
50
|
print(f"{key} : {item}")
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
from .base import *
|
|
2
2
|
from .simplify import simplify
|
|
3
3
|
from .expand import expand
|
|
4
|
-
|
|
4
|
+
import copy
|
|
5
|
+
def inverse(rhs, term, sign=None):
|
|
5
6
|
term = tree_form(term)
|
|
6
7
|
lhs = tree_form("d_0")
|
|
8
|
+
rhs = copy.deepcopy(rhs)
|
|
7
9
|
count = 15
|
|
8
|
-
while not rhs==term:
|
|
10
|
+
while not rhs == term:
|
|
9
11
|
if rhs.name == "f_add":
|
|
10
|
-
if all(term in factor_generation(child) for child in rhs.children):
|
|
11
|
-
newrhs = simplify(expand(rhs*term**-1))
|
|
12
|
+
if rhs.children and all(term in factor_generation(child) for child in rhs.children):
|
|
13
|
+
newrhs = simplify(expand(rhs * term**-1))
|
|
12
14
|
if not contain(newrhs, term):
|
|
13
15
|
rhs = term * newrhs
|
|
14
16
|
else:
|
|
15
|
-
for i in range(len(rhs.children)-1
|
|
17
|
+
for i in range(len(rhs.children) - 1, -1, -1):
|
|
16
18
|
if not contain(rhs.children[i], term):
|
|
17
19
|
lhs = lhs - rhs.children[i]
|
|
18
20
|
rhs.children.pop(i)
|
|
19
21
|
elif rhs.name == "f_mul":
|
|
20
|
-
for i in range(len(rhs.children)-1
|
|
22
|
+
for i in range(len(rhs.children) - 1, -1, -1):
|
|
21
23
|
if not contain(rhs.children[i], term):
|
|
22
24
|
lhs = lhs * rhs.children[i]**-1
|
|
23
25
|
if sign is not None:
|
|
@@ -26,11 +28,17 @@ def inverse(rhs,term, sign=None):
|
|
|
26
28
|
if compute(rhs.children[i]**-1) < 0:
|
|
27
29
|
sign = not sign
|
|
28
30
|
rhs.children.pop(i)
|
|
29
|
-
elif rhs.name == "f_pow" and contain(rhs.children[0], term):
|
|
30
|
-
lhs = lhs ** (tree_form("d_1")/rhs.children[1])
|
|
31
|
+
elif rhs.name == "f_pow" and contain(rhs.children[0], term) and not contain(rhs.children[1], term):
|
|
32
|
+
lhs = lhs ** (tree_form("d_1") / rhs.children[1])
|
|
33
|
+
if sign is not None:
|
|
34
|
+
if compute(rhs.children[1]) < 0:
|
|
35
|
+
sign = not sign
|
|
31
36
|
rhs = copy.deepcopy(rhs.children[0])
|
|
37
|
+
elif rhs.name == "f_pow" and rhs.children[0].name == "s_e" and contain(rhs.children[1], term):
|
|
38
|
+
lhs = lhs.fx("log")
|
|
39
|
+
rhs = copy.deepcopy(rhs.children[1])
|
|
32
40
|
elif rhs.name == "f_pow" and contain(rhs.children[1], term) and not contain(rhs.children[0], term):
|
|
33
|
-
lhs = lhs.fx("log")/rhs.children[0].fx("log")
|
|
41
|
+
lhs = lhs.fx("log") / rhs.children[0].fx("log")
|
|
34
42
|
rhs = copy.deepcopy(rhs.children[1])
|
|
35
43
|
elif rhs.name == "f_sin" and contain(rhs.children[0], term):
|
|
36
44
|
lhs = lhs.fx("arcsin")
|
|
@@ -40,27 +48,30 @@ def inverse(rhs,term, sign=None):
|
|
|
40
48
|
rhs = copy.deepcopy(rhs.children[0])
|
|
41
49
|
elif rhs.name == "f_arccos" and contain(rhs.children[0], term):
|
|
42
50
|
lhs = lhs.fx("cos")
|
|
51
|
+
if sign is not None:
|
|
52
|
+
sign = not sign
|
|
43
53
|
rhs = copy.deepcopy(rhs.children[0])
|
|
44
54
|
elif rhs.name == "f_cos" and contain(rhs.children[0], term):
|
|
45
55
|
lhs = lhs.fx("arccos")
|
|
56
|
+
if sign is not None:
|
|
57
|
+
sign = not sign
|
|
46
58
|
rhs = copy.deepcopy(rhs.children[0])
|
|
47
59
|
elif rhs.name == "f_log" and contain(rhs.children[0], term):
|
|
48
60
|
lhs = tree_form("s_e")**lhs
|
|
49
61
|
rhs = copy.deepcopy(rhs.children[0])
|
|
50
|
-
elif rhs.name == "f_pow" and rhs.children[0].name == "s_e" and contain(rhs.children[1], term):
|
|
51
|
-
lhs = lhs.fx("log")
|
|
52
|
-
rhs = copy.deepcopy(rhs.children[1].fx("log"))
|
|
53
62
|
elif rhs.name == "f_tan" and contain(rhs.children[0], term):
|
|
54
63
|
lhs = lhs.fx("arctan")
|
|
55
64
|
rhs = copy.deepcopy(rhs.children[0])
|
|
56
65
|
elif rhs.name == "f_arctan" and contain(rhs.children[0], term):
|
|
57
66
|
lhs = lhs.fx("tan")
|
|
58
67
|
rhs = copy.deepcopy(rhs.children[0])
|
|
59
|
-
if len(rhs.children) == 1:
|
|
68
|
+
if rhs.name in ["f_add", "f_mul"] and len(rhs.children) == 1:
|
|
60
69
|
rhs = rhs.children[0]
|
|
61
70
|
count -= 1
|
|
62
71
|
if count == 0:
|
|
63
72
|
return None
|
|
73
|
+
if contain(lhs, term):
|
|
74
|
+
return None
|
|
64
75
|
if sign is None:
|
|
65
76
|
return simplify(lhs)
|
|
66
77
|
return simplify(lhs), sign
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from .inverse import inverse
|
|
2
2
|
import itertools
|
|
3
|
+
import copy
|
|
3
4
|
from .diff import diff
|
|
4
5
|
from .simplify import simplify
|
|
5
6
|
from .fraction import fraction
|
|
@@ -7,8 +8,10 @@ from .expand import expand
|
|
|
7
8
|
from .base import *
|
|
8
9
|
from .factor import factorconst
|
|
9
10
|
from .tool import poly
|
|
11
|
+
|
|
10
12
|
def ss(eq):
|
|
11
13
|
return dowhile(eq, lambda x: fraction(simplify(x)))
|
|
14
|
+
|
|
12
15
|
def rref(matrix, fxconst):
|
|
13
16
|
rows, cols = len(matrix), len(matrix[0])
|
|
14
17
|
lead = 0
|
|
@@ -32,25 +35,28 @@ def rref(matrix, fxconst):
|
|
|
32
35
|
matrix[i] = [ss(m - lv * n) for m, n in zip(matrix[i], matrix[r])]
|
|
33
36
|
lead += 1
|
|
34
37
|
return matrix
|
|
38
|
+
|
|
35
39
|
def linear(eqlist, fxconst):
|
|
36
40
|
orig = [item.copy_tree() for item in eqlist]
|
|
37
|
-
v2 = []
|
|
38
41
|
vl = []
|
|
42
|
+
|
|
39
43
|
def varlist(eq, fxconst):
|
|
40
44
|
nonlocal vl
|
|
41
|
-
nonlocal v2
|
|
42
|
-
if eq.name[:2] == "v_" and fxconst(eq):
|
|
43
|
-
vl.append(eq.name)
|
|
44
45
|
if eq.name[:2] == "v_" and not fxconst(eq):
|
|
45
|
-
|
|
46
|
+
vl.append(eq.name)
|
|
46
47
|
for child in eq.children:
|
|
47
48
|
varlist(child, fxconst)
|
|
49
|
+
|
|
48
50
|
for eq in eqlist:
|
|
49
51
|
varlist(eq, fxconst)
|
|
50
|
-
|
|
51
|
-
vl = list(set(vl))
|
|
52
|
+
|
|
53
|
+
vl = sorted(list(set(vl)))
|
|
54
|
+
|
|
52
55
|
if len(vl) > len(eqlist):
|
|
56
|
+
if len(eqlist) == 1:
|
|
57
|
+
return TreeNode("f_eq", [eqlist[0], tree_form("d_0")])
|
|
53
58
|
return TreeNode("f_and", [TreeNode("f_eq", [x, tree_form("d_0")]) for x in eqlist])
|
|
59
|
+
|
|
54
60
|
m = []
|
|
55
61
|
for eq in eqlist:
|
|
56
62
|
s = copy.deepcopy(eq)
|
|
@@ -60,36 +66,46 @@ def linear(eqlist, fxconst):
|
|
|
60
66
|
s = replace(s, tree_form(v), tree_form("d_0"))
|
|
61
67
|
row.append(s)
|
|
62
68
|
m.append(row)
|
|
69
|
+
|
|
63
70
|
for i in range(len(m)):
|
|
64
71
|
for j in range(len(m[i])):
|
|
65
72
|
m[i][j] = simplify(expand(m[i][j]))
|
|
73
|
+
|
|
66
74
|
m = rref(m, fxconst)
|
|
75
|
+
|
|
67
76
|
for i in range(len(m)):
|
|
68
77
|
for j in range(len(m[i])):
|
|
69
78
|
m[i][j] = fraction(m[i][j])
|
|
79
|
+
|
|
70
80
|
output = []
|
|
71
81
|
for index, row in enumerate(m):
|
|
72
|
-
if not all(item ==
|
|
73
|
-
output.append(summation([tree_form(vl[index2])*coeff for index2, coeff in enumerate(row[:-1])])+row[-1])
|
|
74
|
-
elif row[-1] !=
|
|
82
|
+
if not all(item == tree_form("d_0") for item in row[:-1]):
|
|
83
|
+
output.append(summation([tree_form(vl[index2])*coeff for index2, coeff in enumerate(row[:-1])]) + row[-1])
|
|
84
|
+
elif row[-1] != tree_form("d_0"):
|
|
75
85
|
return tree_form("s_false")
|
|
86
|
+
|
|
76
87
|
if len(output) == 1:
|
|
77
88
|
return TreeNode("f_eq", [output[0], tree_form("d_0")])
|
|
78
89
|
if len(output) == 0:
|
|
79
90
|
return tree_form("s_false")
|
|
80
91
|
return TreeNode("f_and", [TreeNode("f_eq", [x, tree_form("d_0")]) for x in output])
|
|
92
|
+
|
|
81
93
|
def linear_solve(eq, lst=None):
|
|
82
94
|
eq = simplify(eq)
|
|
83
95
|
eqlist = []
|
|
84
|
-
if eq.name =="f_and" and all(child.name == "f_eq" and child.children[1] == tree_form("d_0") for child in eq.children):
|
|
96
|
+
if eq.name == "f_and" and all(child.name == "f_eq" and child.children[1] == tree_form("d_0") for child in eq.children):
|
|
85
97
|
eqlist = [child.children[0] for child in eq.children]
|
|
98
|
+
elif eq.name == "f_eq" and eq.children[1] == tree_form("d_0"):
|
|
99
|
+
eqlist = [eq.children[0]]
|
|
86
100
|
else:
|
|
87
101
|
return eq
|
|
102
|
+
|
|
88
103
|
out = None
|
|
89
104
|
if lst is None:
|
|
90
105
|
out = linear(copy.deepcopy(eqlist), lambda x: False)
|
|
91
106
|
else:
|
|
92
107
|
out = linear(copy.deepcopy(eqlist), lambda x: any(contain(x, item) for item in lst))
|
|
108
|
+
|
|
93
109
|
if out is None:
|
|
94
110
|
return None
|
|
95
111
|
return simplify(out)
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mathai
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.6
|
|
4
4
|
Summary: Mathematics solving Ai tailored to NCERT
|
|
5
5
|
Home-page: https://github.com/infinity390/mathai
|
|
6
6
|
Requires-Python: >=3.7
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
Requires-Dist: more_itertools
|
|
9
|
-
Requires-Dist: schemdraw
|
|
10
9
|
Dynamic: description
|
|
11
10
|
Dynamic: description-content-type
|
|
12
11
|
Dynamic: home-page
|
|
@@ -438,7 +437,6 @@ wire_4 = Edge((4, 9))
|
|
|
438
437
|
edge_list = [wire_1, wire_2, wire_3, wire_4,ohm_5, ohm_6, ohm_7, ohm_8, ohm_8_2, ohm_10, ohm_11, ohm_20]
|
|
439
438
|
graph = CircuitGraph(10, edge_list, {})
|
|
440
439
|
print(compute(find_resistance(graph, 0, 9)))
|
|
441
|
-
draw_circuit(graph, start=0, end=9, scale=3.0, grid_size=30)
|
|
442
440
|
```
|
|
443
441
|
|
|
444
442
|
#### Output
|
|
@@ -450,7 +448,29 @@ done
|
|
|
450
448
|
8.66474543707973
|
|
451
449
|
```
|
|
452
450
|
|
|
453
|
-
#### Example Demonstration 11 (
|
|
451
|
+
#### Example Demonstration 11 (resistors in parallel)
|
|
452
|
+
```python
|
|
453
|
+
from mathai import *
|
|
454
|
+
load_formula_from_file()
|
|
455
|
+
wire_1 = Edge((1, 3))
|
|
456
|
+
wire_2 = Edge((2, 3))
|
|
457
|
+
ohm_r1 = Edge((0, 1), "resistor", parse("x"))
|
|
458
|
+
ohm_r2 = Edge((0, 2), "resistor", parse("y"))
|
|
459
|
+
edge_list = [wire_1, ohm_r1, ohm_r2, wire_2]
|
|
460
|
+
graph = CircuitGraph(4, edge_list, {})
|
|
461
|
+
print(fraction(find_resistance(graph, 0, 3)))
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
#### Output
|
|
465
|
+
|
|
466
|
+
```
|
|
467
|
+
loading formulas from file...
|
|
468
|
+
done
|
|
469
|
+
|
|
470
|
+
(x*y)/(x+y)
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
#### Example Demonstration 12 (engineering graphics)
|
|
454
474
|
```python
|
|
455
475
|
from mathai import *
|
|
456
476
|
# (z,y) is dash, a'b' is front view
|
|
@@ -467,7 +487,7 @@ solve_graphics_string("15 25 0 None None None None None None 30*pi/180 0 50 None
|
|
|
467
487
|
print()
|
|
468
488
|
solve_graphics_string("0 -25 0 None None None None None None None 0 55 None 75") # 11.17
|
|
469
489
|
print()
|
|
470
|
-
solve_graphics_string("25 50 0 -30 None None None None None None 0
|
|
490
|
+
solve_graphics_string("25 50 0 -30 None None None None None None 0 None None 80") # 11.19
|
|
471
491
|
```
|
|
472
492
|
|
|
473
493
|
#### Output
|
|
@@ -477,14 +497,14 @@ Ay : 20
|
|
|
477
497
|
Az : 0
|
|
478
498
|
Bx : 30
|
|
479
499
|
By : 20+(60*sin(((2*pi)/9)))
|
|
480
|
-
Bz : 60*
|
|
500
|
+
Bz : 60*sqrt((1-(sin(((2*pi)/9))^2)))
|
|
481
501
|
Bx-Ax : 0
|
|
482
502
|
By-Ay : 60*sin(((2*pi)/9))
|
|
483
|
-
Bz-Az : 60*
|
|
503
|
+
Bz-Az : 60*sqrt((1-(sin(((2*pi)/9))^2)))
|
|
484
504
|
inclination_with_VP : 0
|
|
485
505
|
inclination_with_HP : (2*pi)/9
|
|
486
506
|
front_view_length : 60
|
|
487
|
-
top_view_length :
|
|
507
|
+
top_view_length : sqrt((3600-(3600*(sin(((2*pi)/9))^2))))
|
|
488
508
|
line_length : 60
|
|
489
509
|
|
|
490
510
|
Ax : 20
|
|
@@ -520,16 +540,16 @@ line_length : 100/(3^-(-1/2))
|
|
|
520
540
|
Ax : 0
|
|
521
541
|
Ay : -25
|
|
522
542
|
Az : 0
|
|
523
|
-
Bx :
|
|
543
|
+
Bx : 5*sqrt(104)
|
|
524
544
|
By : -25
|
|
525
545
|
Bz : 55
|
|
526
|
-
Bx-Ax :
|
|
546
|
+
Bx-Ax : 5*sqrt(104)
|
|
527
547
|
By-Ay : 0
|
|
528
548
|
Bz-Az : 55
|
|
529
|
-
inclination_with_VP :
|
|
549
|
+
inclination_with_VP : arcsin((sqrt(104)/15))
|
|
530
550
|
inclination_with_HP : 0
|
|
531
551
|
front_view_length : 55
|
|
532
|
-
top_view_length :
|
|
552
|
+
top_view_length : 75
|
|
533
553
|
line_length : 75
|
|
534
554
|
|
|
535
555
|
Ax : 25
|
|
@@ -537,14 +557,14 @@ Ay : 50
|
|
|
537
557
|
Az : 0
|
|
538
558
|
Bx : -30
|
|
539
559
|
By : 50
|
|
540
|
-
Bz :
|
|
560
|
+
Bz : 5*sqrt(135)
|
|
541
561
|
Bx-Ax : -55
|
|
542
562
|
By-Ay : 0
|
|
543
|
-
Bz-Az :
|
|
563
|
+
Bz-Az : 5*sqrt(135)
|
|
544
564
|
inclination_with_VP : arcsin((-11/16))
|
|
545
565
|
inclination_with_HP : 0
|
|
546
|
-
front_view_length :
|
|
547
|
-
top_view_length :
|
|
566
|
+
front_view_length : sqrt(3375)
|
|
567
|
+
top_view_length : 80
|
|
548
568
|
line_length : 80
|
|
549
569
|
```
|
|
550
570
|
|
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
setup(
|
|
4
4
|
name="mathai",
|
|
5
|
-
version="2.2.
|
|
5
|
+
version="2.2.6",
|
|
6
6
|
description="Mathematics solving Ai tailored to NCERT",
|
|
7
7
|
long_description=Path("README.md").read_text(encoding="utf-8"),
|
|
8
8
|
long_description_content_type="text/markdown",
|
|
@@ -13,7 +13,6 @@ setup(
|
|
|
13
13
|
},
|
|
14
14
|
python_requires=">=3.7",
|
|
15
15
|
install_requires=[
|
|
16
|
-
"more_itertools"
|
|
17
|
-
"schemdraw"
|
|
16
|
+
"more_itertools"
|
|
18
17
|
],
|
|
19
18
|
)
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|