import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
import pandas as pd
# Test cases for energy comparison
test_cases = [
(2, 16, "Square root of 16"), (3, 27, "Cube root of 27"),
(4, 81, "Fourth root of 81"), (5, 32, "Fifth root of 32"),
(6, 64, "Sixth root of 64"), (8, 256, "Eighth root of 256"),
(10, 1024, "Tenth root of 1024"),
]
# Collect data for plotting
data = []
for n, value, description in test_cases:
result, iterations, time_taken, operations = newtons_nth_root(n, value, verbose=False)
ops_per_iter = operations / iterations
data.append({
'root_degree': n,
'value': value,
'description': description,
'iterations': iterations,
'operations': operations,
'ops_per_iter': ops_per_iter,
'time_seconds': time_taken,
'result': result
})
df = pd.DataFrame(data)
# Create interactive subplots
fig = make_subplots(
rows=2, cols=2,
subplot_titles=('Total Operations vs Root Degree', 'Iterations vs Root Degree',
'Operations per Iteration vs Root Degree', 'Computation Time vs Root Degree'),
specs=[[{"secondary_y": False}, {"secondary_y": False}],
[{"secondary_y": False}, {"secondary_y": False}]]
)
# Plot 1: Total Operations vs Root Degree
fig.add_trace(
go.Scatter(x=df['root_degree'], y=df['operations'],
mode='markers+lines',
name='Total Operations',
text=df['description'],
marker=dict(size=10, color='blue'),
line=dict(color='blue', width=3),
hovertemplate='<b>%{text}</b><br>Root Degree: %{x}<br>Operations: %{y}<extra></extra>'),
row=1, col=1
)
# Plot 2: Iterations vs Root Degree
fig.add_trace(
go.Scatter(x=df['root_degree'], y=df['iterations'],
mode='markers+lines',
name='Iterations',
text=df['description'],
marker=dict(size=10, color='red'),
line=dict(color='red', width=3),
hovertemplate='<b>%{text}</b><br>Root Degree: %{x}<br>Iterations: %{y}<extra></extra>'),
row=1, col=2
)
# Plot 3: Operations per Iteration vs Root Degree
fig.add_trace(
go.Scatter(x=df['root_degree'], y=df['ops_per_iter'],
mode='markers+lines',
name='Ops/Iteration',
text=df['description'],
marker=dict(size=10, color='green'),
line=dict(color='green', width=3),
hovertemplate='<b>%{text}</b><br>Root Degree: %{x}<br>Ops/Iter: %{y:.1f}<extra></extra>'),
row=2, col=1
)
# Plot 4: Computation Time vs Root Degree
fig.add_trace(
go.Scatter(x=df['root_degree'], y=df['time_seconds']*1000, # Convert to milliseconds
mode='markers+lines',
name='Time (ms)',
text=df['description'],
marker=dict(size=10, color='purple'),
line=dict(color='purple', width=3),
hovertemplate='<b>%{text}</b><br>Root Degree: %{x}<br>Time: %{y:.3f} ms<extra></extra>'),
row=2, col=2
)
# Update layout
fig.update_layout(
title=dict(
text="<b>Newton's Method: Energy Scaling Analysis</b>",
x=0.5,
font=dict(size=18)
),
showlegend=False,
height=600,
font=dict(size=12)
)
# Update axes labels
fig.update_xaxes(title_text="Root Degree (n)", row=1, col=1)
fig.update_xaxes(title_text="Root Degree (n)", row=1, col=2)
fig.update_xaxes(title_text="Root Degree (n)", row=2, col=1)
fig.update_xaxes(title_text="Root Degree (n)", row=2, col=2)
fig.update_yaxes(title_text="Total Operations", row=1, col=1)
fig.update_yaxes(title_text="Iterations", row=1, col=2)
fig.update_yaxes(title_text="Operations per Iteration", row=2, col=1)
fig.update_yaxes(title_text="Time (milliseconds)", row=2, col=2)
fig.show()