executable-engineering 0.1.42__py3-none-any.whl → 0.1.43__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.
- executable_engineering/__init__.py +4 -1
- executable_engineering/functions_module.py +127 -0
- {executable_engineering-0.1.42.dist-info → executable_engineering-0.1.43.dist-info}/METADATA +1 -1
- {executable_engineering-0.1.42.dist-info → executable_engineering-0.1.43.dist-info}/RECORD +7 -7
- {executable_engineering-0.1.42.dist-info → executable_engineering-0.1.43.dist-info}/WHEEL +0 -0
- {executable_engineering-0.1.42.dist-info → executable_engineering-0.1.43.dist-info}/licenses/LICENSE +0 -0
- {executable_engineering-0.1.42.dist-info → executable_engineering-0.1.43.dist-info}/top_level.txt +0 -0
|
@@ -6,7 +6,7 @@ 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, visualize_conditioning, visualize_matrix_norms, jacobi_step, gauss_seidel_step, sor_step, visualize_convergence_2d, create_diagonally_dominant_matrix, iter_solve, steepest_descent, conjugate_gradient, IterationTracker, discretise_poisson, spai
|
|
9
|
-
from .functions_module import weierstrass, plot_and_find_roots, complex_plot_with_shadow, plot_polynomial_roots_companion
|
|
9
|
+
from .functions_module import weierstrass, plot_and_find_roots, complex_plot_with_shadow, plot_polynomial_roots_companion, plot_secant, plot_newton_raphson, plot_basins_of_attraction
|
|
10
10
|
from .optimization_module import visual_golden_section, visual_powell_2d, newton_method
|
|
11
11
|
|
|
12
12
|
__all__ = [
|
|
@@ -14,6 +14,9 @@ __all__ = [
|
|
|
14
14
|
"visual_powell_2d",
|
|
15
15
|
"visual_golden_section",
|
|
16
16
|
"plot_polynomial_roots_companion",
|
|
17
|
+
"plot_secant",
|
|
18
|
+
"plot_newton_raphson",
|
|
19
|
+
"plot_basins_of_attraction",
|
|
17
20
|
"plot_and_find_roots",
|
|
18
21
|
"complex_plot_with_shadow",
|
|
19
22
|
"weierstrass",
|
|
@@ -149,3 +149,130 @@ def plot_polynomial_roots_companion(n):
|
|
|
149
149
|
title = f"Complex Space Plot: Roots of Order {n} Polynomial"
|
|
150
150
|
complex_plot_with_shadow(poly_func, title=title, roots=roots, plot_range=(-plot_limit, plot_limit))
|
|
151
151
|
|
|
152
|
+
|
|
153
|
+
def plot_secant(f, x0, x1, tolerance=1e-6, max_iterations=100, title='Secant Method'):
|
|
154
|
+
import plotly.graph_objects as go
|
|
155
|
+
import plotly.express as px
|
|
156
|
+
import numpy as np
|
|
157
|
+
|
|
158
|
+
x_values = [x0, x1]
|
|
159
|
+
for i in range(max_iterations):
|
|
160
|
+
denom = f(x1) - f(x0)
|
|
161
|
+
if denom == 0:
|
|
162
|
+
break
|
|
163
|
+
x_new = x1 - f(x1) * (x1 - x0) / denom
|
|
164
|
+
x_values.append(x_new)
|
|
165
|
+
if abs(f(x_new)) < tolerance:
|
|
166
|
+
break
|
|
167
|
+
x0 = x1
|
|
168
|
+
x1 = x_new
|
|
169
|
+
|
|
170
|
+
root = x_values[-1] if abs(f(x_values[-1])) < tolerance else None
|
|
171
|
+
|
|
172
|
+
# Determine plot bounds
|
|
173
|
+
min_x = min(x_values)
|
|
174
|
+
max_x = max(x_values)
|
|
175
|
+
padding = (max_x - min_x) * 0.2 if max_x > min_x else 0.5
|
|
176
|
+
x = np.linspace(min_x - padding, max_x + padding, 100)
|
|
177
|
+
|
|
178
|
+
fig = go.Figure()
|
|
179
|
+
fig.add_trace(go.Scatter(x=x, y=f(x), mode='lines', name='f(x)'))
|
|
180
|
+
fig.add_trace(go.Scatter(x=[x_values[0], x_values[1]], y=[f(x_values[0]), f(x_values[1])], mode='markers', name='Initial guesses'))
|
|
181
|
+
|
|
182
|
+
colors = px.colors.qualitative.Plotly
|
|
183
|
+
|
|
184
|
+
for i in range(1, len(x_values) - 1):
|
|
185
|
+
# Secant line intersecting x-axis
|
|
186
|
+
fig.add_trace(go.Scatter(x=[x_values[i-1], x_values[i], x_values[i+1]], y=[f(x_values[i-1]), f(x_values[i]), 0], mode='lines', line=dict(dash='dash', color='gray'), showlegend=False))
|
|
187
|
+
# Vertical dotted line to the curve
|
|
188
|
+
fig.add_trace(go.Scatter(x=[x_values[i+1], x_values[i+1]], y=[0, f(x_values[i+1])], mode='lines', line=dict(dash='dot', color='gray'), showlegend=False))
|
|
189
|
+
|
|
190
|
+
color = colors[(i-1) % len(colors)]
|
|
191
|
+
fig.add_trace(go.Scatter(x=[x_values[i+1]], y=[0], mode='markers', marker=dict(size=10, color=color), name=f'x_{i+1}'))
|
|
192
|
+
|
|
193
|
+
if root:
|
|
194
|
+
fig.add_trace(go.Scatter(x=[root], y=[0], mode='markers', marker=dict(color='green', size=10), name='Approximate root'))
|
|
195
|
+
|
|
196
|
+
fig.update_layout(title=title, xaxis_title='x', yaxis_title='f(x)')
|
|
197
|
+
fig.show()
|
|
198
|
+
return root, x_values
|
|
199
|
+
|
|
200
|
+
def plot_newton_raphson(f, df, x0, tolerance=1e-6, max_iterations=100, title='Newton-Raphson Method', xrange=None, yrange=None):
|
|
201
|
+
import plotly.graph_objects as go
|
|
202
|
+
import plotly.express as px
|
|
203
|
+
import numpy as np
|
|
204
|
+
|
|
205
|
+
x_values = [x0]
|
|
206
|
+
for i in range(max_iterations):
|
|
207
|
+
d = df(x0)
|
|
208
|
+
if d == 0:
|
|
209
|
+
break
|
|
210
|
+
x_new = x0 - f(x0) / d
|
|
211
|
+
x_values.append(x_new)
|
|
212
|
+
if abs(f(x_new)) < tolerance or abs(x_new - x0) < tolerance:
|
|
213
|
+
break
|
|
214
|
+
x0 = x_new
|
|
215
|
+
|
|
216
|
+
root = x_values[-1] if abs(f(x_values[-1])) < tolerance or abs(x_values[-1] - x_values[-2]) < tolerance else None
|
|
217
|
+
|
|
218
|
+
# Determine plot bounds
|
|
219
|
+
if xrange is None:
|
|
220
|
+
min_x = min(x_values)
|
|
221
|
+
max_x = max(x_values)
|
|
222
|
+
padding = (max_x - min_x) * 0.2 if max_x > min_x else 0.5
|
|
223
|
+
x = np.linspace(min_x - padding, max_x + padding, 100)
|
|
224
|
+
else:
|
|
225
|
+
x = np.linspace(xrange[0], xrange[1], 100)
|
|
226
|
+
|
|
227
|
+
fig = go.Figure()
|
|
228
|
+
fig.add_trace(go.Scatter(x=x, y=f(x), mode='lines', name='f(x)'))
|
|
229
|
+
fig.add_trace(go.Scatter(x=[x_values[0]], y=[f(x_values[0])], mode='markers', name='Initial guess'))
|
|
230
|
+
|
|
231
|
+
colors = px.colors.qualitative.Plotly
|
|
232
|
+
|
|
233
|
+
for i in range(len(x_values) - 1):
|
|
234
|
+
# Tangent line intersecting x-axis
|
|
235
|
+
fig.add_trace(go.Scatter(x=[x_values[i], x_values[i+1]], y=[f(x_values[i]), 0], mode='lines', line=dict(dash='dash', color='gray'), showlegend=False))
|
|
236
|
+
# Vertical dotted line to the curve
|
|
237
|
+
fig.add_trace(go.Scatter(x=[x_values[i+1], x_values[i+1]], y=[0, f(x_values[i+1])], mode='lines', line=dict(dash='dot', color='gray'), showlegend=False))
|
|
238
|
+
|
|
239
|
+
color = colors[i % len(colors)]
|
|
240
|
+
fig.add_trace(go.Scatter(x=[x_values[i+1]], y=[0], mode='markers', marker=dict(size=10, color=color), name=f'x_{i+1}'))
|
|
241
|
+
|
|
242
|
+
if root:
|
|
243
|
+
fig.add_trace(go.Scatter(x=[root], y=[0], mode='markers', marker=dict(color='green', size=10), name='Approximate root'))
|
|
244
|
+
|
|
245
|
+
fig.update_layout(title=title, xaxis_title='x', yaxis_title='f(x)')
|
|
246
|
+
if xrange:
|
|
247
|
+
fig.update_layout(xaxis_range=xrange)
|
|
248
|
+
if yrange:
|
|
249
|
+
fig.update_layout(yaxis_range=yrange)
|
|
250
|
+
|
|
251
|
+
fig.show()
|
|
252
|
+
return root, x_values
|
|
253
|
+
|
|
254
|
+
def plot_basins_of_attraction(f, df, known_roots, title, real_range=(-2, 2), imag_range=(-2, 2), grid_size=500, th=1e-3):
|
|
255
|
+
import numpy as np
|
|
256
|
+
import plotly.graph_objects as go
|
|
257
|
+
from scipy.optimize import newton
|
|
258
|
+
|
|
259
|
+
real_values = np.linspace(real_range[0], real_range[1], grid_size)
|
|
260
|
+
imag_values = np.linspace(imag_range[0], imag_range[1], grid_size)
|
|
261
|
+
z_grid = np.array([[complex(r, i) for r in real_values] for i in imag_values])
|
|
262
|
+
|
|
263
|
+
roots = newton(f, z_grid, fprime=df)
|
|
264
|
+
|
|
265
|
+
colors = np.zeros((grid_size, grid_size))
|
|
266
|
+
for i in range(grid_size):
|
|
267
|
+
for j in range(grid_size):
|
|
268
|
+
if roots[i, j] is None:
|
|
269
|
+
colors[i, j] = 0
|
|
270
|
+
else:
|
|
271
|
+
for idx, r in enumerate(known_roots):
|
|
272
|
+
if abs(roots[i, j] - r) < th:
|
|
273
|
+
colors[i, j] = idx + 1
|
|
274
|
+
break
|
|
275
|
+
|
|
276
|
+
fig = go.Figure(data=go.Heatmap(z=colors, x=real_values, y=imag_values, colorscale='Viridis', showscale=False))
|
|
277
|
+
fig.update_layout(title=title, xaxis_title='Real', yaxis_title='Imaginary', width=600, height=600)
|
|
278
|
+
fig.show()
|
{executable_engineering-0.1.42.dist-info → executable_engineering-0.1.43.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: executable_engineering
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.43
|
|
4
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
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
executable_engineering/__init__.py,sha256=
|
|
1
|
+
executable_engineering/__init__.py,sha256=p_BjWnXnCdd_g2SUfgn5L9xSEBCjSLDrZV0inHka1Sc,2177
|
|
2
2
|
executable_engineering/closedoptimization_module.py,sha256=i9KkdulyCZmriYKlx0CuUetjoMmxJm9ADWgStU3w85w,9273
|
|
3
3
|
executable_engineering/closedrootfinder_module.py,sha256=hQ6iWNi16RkZTaE_WPUEwkohmrYrAyU8WWSXO2EPLJY,6000
|
|
4
|
-
executable_engineering/functions_module.py,sha256=
|
|
4
|
+
executable_engineering/functions_module.py,sha256=HmZacKzSpUtjM1BLzAoXAgnARhQXizJcWeL7zZnO5zM,10473
|
|
5
5
|
executable_engineering/gradientoptimization_module.py,sha256=-2fErE9cemSEPeV9PlWOf4cF7Tr6DjilEw_NxvE-JYw,6601
|
|
6
6
|
executable_engineering/linearsystems_module.py,sha256=w6UkwZu80gUz5bAIWY47xJbwaEVzR9tCcIBkMsKjIRk,18356
|
|
7
7
|
executable_engineering/neuralnet_module.py,sha256=Hu9QFoMyODg4RCEpHmT9zTwzjcVFYM8ZLYtbB3CbrsA,10102
|
|
@@ -9,8 +9,8 @@ executable_engineering/numerical_error_module.py,sha256=wxfYP8u29c19I2D6MxpQV3zD
|
|
|
9
9
|
executable_engineering/openoptimization_module.py,sha256=OCPyrynkTo1It50RoT7irnL72aQn6FexE_R1SfFYxlg,8590
|
|
10
10
|
executable_engineering/openrootfinder_module.py,sha256=R_lPtCQsIGLXV-j_uDpQepImOOgtgA7I6qnhUPwWLLc,5944
|
|
11
11
|
executable_engineering/optimization_module.py,sha256=qFKdksJxeU4WZ9CDKs9lF-kn-FIHUx9DhifRprlATHo,12315
|
|
12
|
-
executable_engineering-0.1.
|
|
13
|
-
executable_engineering-0.1.
|
|
14
|
-
executable_engineering-0.1.
|
|
15
|
-
executable_engineering-0.1.
|
|
16
|
-
executable_engineering-0.1.
|
|
12
|
+
executable_engineering-0.1.43.dist-info/licenses/LICENSE,sha256=Tg4nrt8rFhgpkPbIA8SWoCR3MlGLw0NufB8AE6-TH_o,1074
|
|
13
|
+
executable_engineering-0.1.43.dist-info/METADATA,sha256=OEali3wRbahuFRUapelVMCs-TLz2p36HbsV_5QNbBYg,1648
|
|
14
|
+
executable_engineering-0.1.43.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
15
|
+
executable_engineering-0.1.43.dist-info/top_level.txt,sha256=0U5ATV5WGTLvN9rRSjQ54TyL-ztTyXaN3FzZ_QMq4HM,23
|
|
16
|
+
executable_engineering-0.1.43.dist-info/RECORD,,
|
|
File without changes
|
{executable_engineering-0.1.42.dist-info → executable_engineering-0.1.43.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{executable_engineering-0.1.42.dist-info → executable_engineering-0.1.43.dist-info}/top_level.txt
RENAMED
|
File without changes
|