executable-engineering 0.1.31__tar.gz → 0.1.32__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 (20) hide show
  1. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/PKG-INFO +2 -2
  2. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/executable_engineering/__init__.py +2 -1
  3. executable_engineering-0.1.32/executable_engineering/linearsystems_module.py +95 -0
  4. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/executable_engineering.egg-info/PKG-INFO +2 -2
  5. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/executable_engineering.egg-info/SOURCES.txt +1 -0
  6. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/setup.py +2 -2
  7. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/LICENSE +0 -0
  8. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/README.md +0 -0
  9. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/executable_engineering/closedoptimization_module.py +0 -0
  10. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/executable_engineering/closedrootfinder_module.py +0 -0
  11. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/executable_engineering/gradientoptimization_module.py +0 -0
  12. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/executable_engineering/neuralnet_module.py +0 -0
  13. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/executable_engineering/numerical_error_module.py +0 -0
  14. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/executable_engineering/openoptimization_module.py +0 -0
  15. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/executable_engineering/openrootfinder_module.py +0 -0
  16. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/executable_engineering.egg-info/dependency_links.txt +0 -0
  17. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/executable_engineering.egg-info/requires.txt +0 -0
  18. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/executable_engineering.egg-info/top_level.txt +0 -0
  19. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/pyproject.toml +0 -0
  20. {executable_engineering-0.1.31 → executable_engineering-0.1.32}/setup.cfg +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: executable_engineering
3
- Version: 0.1.31
4
- Summary: Tools for ENGPHYS 3NM4
3
+ Version: 0.1.32
4
+ Summary: Demonstrative tools for the Executable Engineering textbook
5
5
  Home-page: https://github.com/themintlab/ExecutableEngineering/tree/main/executable_engineering
6
6
  Author: Michael Welland
7
7
  License: MIT
@@ -5,9 +5,10 @@ from .closedoptimization_module import OptimizerClosed
5
5
  from .openoptimization_module import OptimizerOpen
6
6
  from .gradientoptimization_module import OptimizerGrad
7
7
  from .numerical_error_module import python_internal_binary, decimal_to_binary
8
-
8
+ from .linearsystems_module import visual_solve_2d
9
9
 
10
10
  __all__ = [
11
+ "visual_solve_2d",
11
12
  "init_weights",
12
13
  "tanh",
13
14
  "tanh_derivative",
@@ -0,0 +1,95 @@
1
+ import numpy as np
2
+ import plotly.graph_objects as go
3
+ import plotly.colors as pcolors
4
+
5
+ def visual_solve_2d(A, b, x_range=None, title="Linear System", labels=None):
6
+ """
7
+ Solves and visualizes a 2D linear system Ax = b.
8
+ Plots the lines represented by the rows of A and b, and the solution point.
9
+ Falls back to the pseudoinverse for singular or non-square systems.
10
+
11
+ Args:
12
+ A: (N, 2) array-like of coefficients.
13
+ b: (N,) array-like of constants.
14
+ x_range: Tuple of (xmin, xmax) for plotting. If None, auto-calculated.
15
+ title: Plot title.
16
+ labels: Tuple of (x_label, y_label) for axes.
17
+ """
18
+ if labels is None:
19
+ labels = ("x", "y")
20
+
21
+ A = np.array(A, dtype=float)
22
+ b = np.array(b, dtype=float).flatten()
23
+
24
+ if A.shape[1] != 2:
25
+ raise ValueError("visual_solve_2d only supports 2D systems (A must have 2 columns).")
26
+
27
+ # 1. Solve the system using the pseudoinverse
28
+ # For a square, full-rank matrix, pinv is mathematically identical to the standard inverse.
29
+ # For singular or non-square matrices, it finds the least-squares/minimum-norm solution.
30
+ sol = np.linalg.pinv(A) @ b
31
+
32
+ # Check if the solution is exact AND unique.
33
+ # It is exact if A*x = b. It is unique if the rank of A equals the number of variables (columns).
34
+ is_exact = np.allclose(A @ sol, b)
35
+ is_unique = np.linalg.matrix_rank(A) == A.shape[1]
36
+ is_exact_unique = is_exact and is_unique
37
+
38
+ # 2. Determine plotting range
39
+ if x_range is None:
40
+ center_x = sol[0]
41
+ x_range = (center_x - 10, center_x + 10)
42
+
43
+ x_vals = np.linspace(x_range[0], x_range[1], 100)
44
+
45
+ fig = go.Figure()
46
+
47
+ colors = pcolors.qualitative.Plotly
48
+
49
+ # 3. Plot each line
50
+ for i in range(A.shape[0]):
51
+ a1, a2 = A[i]
52
+ bi = b[i]
53
+
54
+ if np.abs(a2) > 1e-10:
55
+ # y = (bi - a1*x) / a2
56
+ y_vals = (bi - a1 * x_vals) / a2
57
+ line_name = f"{a1:g}{labels[0]} + {a2:g}{labels[1]} = {bi:g}"
58
+ fig.add_trace(go.Scatter(x=x_vals, y=y_vals, mode='lines', name=line_name, line=dict(color=colors[i % len(colors)])))
59
+ else:
60
+ # Vertical line: x = bi / a1
61
+ if np.abs(a1) > 1e-10:
62
+ x_val = bi / a1
63
+ line_name = f"{a1:g}{labels[0]} = {bi:g}"
64
+ fig.add_trace(go.Scatter(x=[x_val, x_val], y=[-100, 100], mode='lines', name=line_name, line=dict(color=colors[i % len(colors)])))
65
+
66
+ # 4. Plot solution point
67
+ if is_unique:
68
+ if is_exact:
69
+ sol_label = "Exact Solution"
70
+ else:
71
+ sol_label = "Best Fit Solution"
72
+
73
+ hover_text = f"{labels[0]}={sol[0]:.4g}, {labels[1]}={sol[1]:.4g}"
74
+ fig.add_trace(go.Scatter(
75
+ x=[sol[0]],
76
+ y=[sol[1]],
77
+ mode='markers',
78
+ marker=dict(color='black', size=12, symbol='star'),
79
+ name=sol_label,
80
+ hoverinfo='text',
81
+ hovertext=hover_text
82
+ ))
83
+
84
+ # Auto-adjust y-range nicely around the solution if not a vertical-only mess
85
+ y_margin = (x_range[1] - x_range[0]) / 2.0
86
+
87
+ fig.update_layout(
88
+ title=title,
89
+ xaxis_title=labels[0],
90
+ yaxis_title=labels[1],
91
+ yaxis=dict(range=[sol[1] - y_margin, sol[1] + y_margin]),
92
+ template="plotly_white"
93
+ )
94
+
95
+ return fig
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: executable_engineering
3
- Version: 0.1.31
4
- Summary: Tools for ENGPHYS 3NM4
3
+ Version: 0.1.32
4
+ Summary: Demonstrative tools for the Executable Engineering textbook
5
5
  Home-page: https://github.com/themintlab/ExecutableEngineering/tree/main/executable_engineering
6
6
  Author: Michael Welland
7
7
  License: MIT
@@ -6,6 +6,7 @@ executable_engineering/__init__.py
6
6
  executable_engineering/closedoptimization_module.py
7
7
  executable_engineering/closedrootfinder_module.py
8
8
  executable_engineering/gradientoptimization_module.py
9
+ executable_engineering/linearsystems_module.py
9
10
  executable_engineering/neuralnet_module.py
10
11
  executable_engineering/numerical_error_module.py
11
12
  executable_engineering/openoptimization_module.py
@@ -6,8 +6,8 @@ long_description = (this_directory / "README.md").read_text(encoding="utf-8")
6
6
 
7
7
  setup(
8
8
  name="executable_engineering",
9
- version="0.1.31",
10
- description="Tools for ENGPHYS 3NM4",
9
+ version="0.1.32",
10
+ description="Demonstrative tools for the Executable Engineering textbook",
11
11
  long_description=long_description,
12
12
  long_description_content_type="text/markdown",
13
13
  url="https://github.com/themintlab/ExecutableEngineering/tree/main/executable_engineering",