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()