Added Project and Report
This commit is contained in:
428
project/plotting/L-BFGS.py
Normal file
428
project/plotting/L-BFGS.py
Normal file
@ -0,0 +1,428 @@
|
||||
from config import (
|
||||
LBFGS_RESULTS,
|
||||
PLOTS_PATH,
|
||||
log_tick_formatter,
|
||||
nanoseconds_to_seconds,
|
||||
setup
|
||||
)
|
||||
|
||||
from scipy.interpolate import griddata
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from matplotlib import ticker, cm
|
||||
import seaborn as sns
|
||||
from scipy.interpolate import interp1d
|
||||
|
||||
metrics_map = {
|
||||
'error': ['relative', 'residual'],
|
||||
'time': ['meantime'],
|
||||
'iterations': ['iterations']
|
||||
}
|
||||
|
||||
|
||||
def plot_lambda_epsilon_3D(kind):
|
||||
if kind not in ['error', 'time', 'iterations']:
|
||||
raise ValueError("kind must be one of 'error', 'time', 'iterations'")
|
||||
|
||||
df = pd.read_csv(LBFGS_RESULTS.format("3D", "statisticsLBFGS-lambda-eps-m300n20--{}.csv".format(kind)))
|
||||
|
||||
metrics = metrics_map[kind]
|
||||
|
||||
for metric in metrics:
|
||||
|
||||
lambda_values = df['lambda']
|
||||
epsilon_values = df['epsilon']
|
||||
meantime_values = df[metric]
|
||||
|
||||
lambda_mesh, epsilon_mesh = np.meshgrid(np.unique(lambda_values), np.unique(epsilon_values))
|
||||
|
||||
# Cubic interpolation of the data to make it smooth
|
||||
meantime_interp = griddata((lambda_values, epsilon_values), meantime_values, (lambda_mesh, epsilon_mesh),
|
||||
method='cubic')
|
||||
|
||||
# Plot the 3D surface
|
||||
fig = plt.figure(figsize=(13, 9))
|
||||
ax = fig.add_subplot(111, projection='3d')
|
||||
|
||||
sns.set(style="white", context="paper")
|
||||
|
||||
surface = ax.plot_surface(np.log10(lambda_mesh), np.log10(epsilon_mesh), meantime_interp, edgecolor='none',
|
||||
cmap='viridis', alpha=0.9)
|
||||
|
||||
fig.colorbar(surface, ax=ax, shrink=0.5, aspect=5, pad=0.2)
|
||||
|
||||
# Set labels
|
||||
ax.set_xlabel('λ', labelpad=20, fontsize=15)
|
||||
ax.set_ylabel('ϵ', labelpad=20, fontsize=15)
|
||||
|
||||
if metric == 'meantime':
|
||||
metric = 'running time'
|
||||
ax.set_zlabel('time (s)', labelpad=10, fontsize=20)
|
||||
ax.zaxis.set_major_formatter(ticker.FuncFormatter(nanoseconds_to_seconds))
|
||||
title = 'L-BFGS ' + metric + ' with respect to λ and ϵ over 10000 runs'
|
||||
elif metric in ['relative', 'residual']:
|
||||
if metric == 'relative':
|
||||
metric = 'relative error'
|
||||
ax.set_zlabel(metric, labelpad=10, fontsize=20)
|
||||
title = 'L-BFGS ' + metric + ' with respect to λ and ϵ'
|
||||
else:
|
||||
ax.set_zlabel(metric, labelpad=10, fontsize=20)
|
||||
title = 'L-BFGS ' + metric + ' with respect to λ and ϵ'
|
||||
|
||||
plt.title(title, fontsize=20, pad=20, fontweight='bold', loc='center')
|
||||
|
||||
# Set logarithmic locator of ticks
|
||||
ax.xaxis.set_major_formatter(ticker.FuncFormatter(log_tick_formatter))
|
||||
ax.yaxis.set_major_formatter(ticker.FuncFormatter(log_tick_formatter))
|
||||
|
||||
ax.xaxis.set_tick_params(size=15)
|
||||
ax.yaxis.set_tick_params(size=15)
|
||||
ax.zaxis.set_tick_params(size=15)
|
||||
|
||||
metric = metric.replace(" ", "_")
|
||||
plt.savefig(PLOTS_PATH.format("LBFGS/3D", "LBFGS-lambda-eps--{}.png".format(metric)))
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_epsilon_memory_3D(kind):
|
||||
if kind not in ['error', 'iterations']:
|
||||
raise ValueError("kind must be one of 'error', 'iterations'")
|
||||
|
||||
df = pd.read_csv(LBFGS_RESULTS.format("3D", "statisticsLBFGS-eps-mem-m300n20--{}.csv".format(kind)))
|
||||
|
||||
metrics = metrics_map[kind]
|
||||
|
||||
for metric in metrics:
|
||||
|
||||
memory_values = df['memsize']
|
||||
epsilon_values = df['epsilon']
|
||||
meantime_values = df[metric]
|
||||
|
||||
memory_mesh, epsilon_mesh = np.meshgrid(np.unique(memory_values), np.unique(epsilon_values))
|
||||
|
||||
# Cubic interpolation of the data to make it smooth
|
||||
meantime_interp = griddata((memory_values, epsilon_values), meantime_values, (memory_mesh, epsilon_mesh),
|
||||
method='cubic')
|
||||
|
||||
# Plot the 3D surface
|
||||
fig = plt.figure(figsize=(13, 9))
|
||||
ax = fig.add_subplot(111, projection='3d')
|
||||
|
||||
sns.set(style="white")
|
||||
sns.set_context('paper')
|
||||
|
||||
surface = ax.plot_surface(memory_mesh, np.log10(epsilon_mesh), meantime_interp, edgecolor='none',
|
||||
cmap='viridis', alpha=0.9)
|
||||
|
||||
fig.colorbar(surface, ax=ax, shrink=0.5, aspect=5, pad=0.2)
|
||||
|
||||
# Set labels
|
||||
ax.set_xlabel('memory size', labelpad=20, fontsize=15)
|
||||
ax.set_ylabel('ϵ', labelpad=20, fontsize=15)
|
||||
ax.set_zlabel('iterations', labelpad=10, fontsize=20)
|
||||
|
||||
if metric in ['relative', 'residual']:
|
||||
if metric == 'relative':
|
||||
metric = 'relative error'
|
||||
ax.set_zlabel(metric, labelpad=10, fontsize=20)
|
||||
|
||||
plt.title('L-BFGS ' + metric + ' with respect to the memory size and ϵ', fontsize=20, pad=20,
|
||||
fontweight='bold',
|
||||
loc='center')
|
||||
|
||||
ax.yaxis.set_major_formatter(ticker.FuncFormatter(log_tick_formatter))
|
||||
|
||||
ax.xaxis.set_tick_params(size=15)
|
||||
ax.yaxis.set_tick_params(size=15)
|
||||
ax.zaxis.set_tick_params(size=15)
|
||||
plt.savefig(PLOTS_PATH.format("LBFGS/3D", "LBFGS-eps-mem--{}.png".format(metric)))
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_iterations_error_2D(conditioning="well"):
|
||||
if conditioning not in ["well", "ill"]:
|
||||
raise ValueError("conditioning must be one of 'well' or 'ill'")
|
||||
|
||||
setup(
|
||||
title=f'L-BFGS errors with respect to iterations on {conditioning}-conditioned matrix',
|
||||
x_label='Iterations',
|
||||
y_label='Error'
|
||||
)
|
||||
conditioning = conditioning + "_conditioned"
|
||||
|
||||
df = pd.read_csv(LBFGS_RESULTS.format(conditioning, "statisticsLBFGS-iterations-m1000n20--error.csv"))
|
||||
|
||||
maxiterations_values = df['maxiterations']
|
||||
relative_values = df['relative']
|
||||
residual_values = df['residual']
|
||||
|
||||
# since from a certain row the residual and the relative gap are the same as the previous row, we can all the
|
||||
# next rows and keep only the first row of each value
|
||||
relative_values = relative_values.drop_duplicates(keep='first')
|
||||
residual_values = residual_values.drop_duplicates(keep='first')
|
||||
|
||||
assert len(relative_values) == len(residual_values)
|
||||
|
||||
maxiterations_values = maxiterations_values[:len(relative_values)]
|
||||
|
||||
max_iter_interp = np.linspace(min(maxiterations_values), max(maxiterations_values), 100)
|
||||
|
||||
relative_interp = interp1d(maxiterations_values, relative_values, kind='cubic')(max_iter_interp)
|
||||
residual_interp = interp1d(maxiterations_values, residual_values, kind='cubic')(max_iter_interp)
|
||||
|
||||
data = pd.DataFrame({
|
||||
'maxiterations': max_iter_interp,
|
||||
'relative': relative_interp,
|
||||
'residual': residual_interp
|
||||
})
|
||||
|
||||
sns.lineplot(data=data, x='maxiterations', y='relative', label='Relative Error', color='blue')
|
||||
sns.lineplot(data=data, x='maxiterations', y='residual', label='Residual', color='red')
|
||||
|
||||
plt.legend(loc='upper right', fontsize=15)
|
||||
plt.ylim(0, None)
|
||||
|
||||
conditioning = "LBFGS/" + conditioning
|
||||
|
||||
plt.savefig(PLOTS_PATH.format(conditioning, "LBFGS-iterations-error.png"))
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_norm_gradient_2D(conditioning="well", smoothing_window=5):
|
||||
if conditioning not in ["well", "ill"]:
|
||||
raise ValueError("conditioning must be one of 'well' or 'ill'")
|
||||
cond = conditioning
|
||||
setup(
|
||||
title=f'L-BFGS convergence on {cond}-conditioned matrix',
|
||||
x_label='Iterations',
|
||||
y_label=' '
|
||||
)
|
||||
|
||||
conditioning = conditioning + "_conditioned"
|
||||
|
||||
df = pd.read_csv(LBFGS_RESULTS.format(conditioning, "statisticsLBFGS-iterations-m1000n20--error-norm.csv"))
|
||||
|
||||
gradnorm = df['mean_gradient'].unique()
|
||||
error = df['mean_relative'].unique()
|
||||
residual = df['mean_residual'].unique()
|
||||
|
||||
iterations = list(range(len(gradnorm)))
|
||||
|
||||
assert len(error) == len(residual) == len(gradnorm)
|
||||
|
||||
iterations_interp = np.linspace(min(iterations), max(iterations), len(residual))
|
||||
gradnorm = interp1d(iterations, gradnorm, kind='quadratic')(iterations_interp)
|
||||
error = interp1d(iterations, error, kind='quadratic')(iterations_interp)
|
||||
residual = interp1d(iterations, residual, kind='quadratic')(iterations_interp)
|
||||
|
||||
smoothed_gradnorm = np.convolve(gradnorm, np.ones(smoothing_window) / smoothing_window, mode='valid')
|
||||
smoothed_error = np.convolve(error, np.ones(smoothing_window) / smoothing_window, mode='valid')
|
||||
smoothed_residual = np.convolve(residual, np.ones(smoothing_window) / smoothing_window, mode='valid')
|
||||
|
||||
data = pd.DataFrame({
|
||||
'iterations': iterations[:len(smoothed_gradnorm)],
|
||||
'Gradient Norm': smoothed_gradnorm,
|
||||
'Relative Error': smoothed_error,
|
||||
'Residual': smoothed_residual
|
||||
})
|
||||
|
||||
sns.lineplot(data=data, x='iterations', y='Gradient Norm', label='Gradient Norm', color='green')
|
||||
sns.lineplot(data=data, x='iterations', y='Relative Error', label='Relative Error', color='blue')
|
||||
sns.lineplot(data=data, x='iterations', y='Residual', label='Residual', color='red')
|
||||
|
||||
plt.yscale('log')
|
||||
plt.legend(loc='upper right', fontsize=15)
|
||||
|
||||
conditioning = "LBFGS/" + conditioning
|
||||
plt.savefig(PLOTS_PATH.format(conditioning, f"LBFGS-iterations-gradient-{cond}.png"))
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_iteration_memory(conditioning="well", smoothing_window=3):
|
||||
if conditioning not in ["well", "ill"]:
|
||||
raise ValueError("conditioning must be one of 'well' or 'ill'")
|
||||
|
||||
cond = conditioning
|
||||
setup(title=f'L-BFGS relative error for different memory sizes on {cond}-conditioned matrix', x_label='Iterations', y_label='Relative Error')
|
||||
|
||||
conditioning = conditioning + "_conditioned"
|
||||
|
||||
df = pd.read_csv(
|
||||
LBFGS_RESULTS.format(conditioning, "statisticsLBFGS-iterations-m1000n20--memsize.csv"),
|
||||
)
|
||||
|
||||
unique_memsize = df['memsize'].unique()
|
||||
|
||||
for memsize in unique_memsize:
|
||||
data = df[df['memsize'] == memsize]
|
||||
data.reset_index(drop=True, inplace=True)
|
||||
|
||||
gradients_indices = data.index[data['gradient'].drop_duplicates(keep='first').index]
|
||||
relative_errors = data.loc[gradients_indices]['relative'].values
|
||||
|
||||
extension = np.full(smoothing_window, relative_errors[-1])
|
||||
relative_errors = np.concatenate((relative_errors, extension))
|
||||
|
||||
print(len(relative_errors))
|
||||
|
||||
iterations = list(range(len(relative_errors)))
|
||||
iterations_interp = np.linspace(min(iterations), max(iterations), len(relative_errors))
|
||||
relative_interp = interp1d(iterations, relative_errors, kind='cubic')(iterations_interp)
|
||||
|
||||
smoothed_relative = np.convolve(relative_interp, np.ones(smoothing_window) / smoothing_window, mode='valid')
|
||||
|
||||
data = pd.DataFrame({
|
||||
'iterations': iterations_interp[:len(smoothed_relative)],
|
||||
'relative': smoothed_relative
|
||||
})
|
||||
|
||||
sns.lineplot(data=data, x='iterations', y='relative', label='Memory Size = {}'.format(memsize))
|
||||
|
||||
plt.legend(loc='upper right', fontsize=15)
|
||||
plt.yscale('log')
|
||||
|
||||
conditioning = "LBFGS/" + conditioning
|
||||
plt.savefig(PLOTS_PATH.format(conditioning, f"LBFGS-iterations-memory-{cond}.png"))
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_awls_vs_exact_gradient_decrease_2D(smoothing_window=3):
|
||||
conditioning = "well_conditioned"
|
||||
df2_awls_quad = pd.read_csv(
|
||||
LBFGS_RESULTS.format(conditioning, "statisticsLBFGS-AWLS-quad-iterations-m1000n20--error-norm.csv"),
|
||||
)
|
||||
df3_exact = pd.read_csv(
|
||||
LBFGS_RESULTS.format(conditioning, "statisticsLBFGS-iterations-m1000n20--error-norm.csv"),
|
||||
)
|
||||
|
||||
setup(title='L-BFGS ExactLS vs AWLS gradient norm on well-conditioned matrix', x_label='Iterations', y_label='Gradient Norm')
|
||||
|
||||
gradnorm_awls_quad = df2_awls_quad['mean_gradient'].unique()
|
||||
gradnorm_exact = df3_exact['mean_gradient'].unique()
|
||||
|
||||
extension = np.full(len(gradnorm_awls_quad) - len(gradnorm_exact) + smoothing_window, gradnorm_exact[-1])
|
||||
gradnorm_exact = np.concatenate((gradnorm_exact, extension))
|
||||
|
||||
extension = np.full(smoothing_window, gradnorm_awls_quad[-1])
|
||||
gradnorm_awls_quad = np.concatenate((gradnorm_awls_quad, extension))
|
||||
|
||||
assert len(gradnorm_awls_quad) == len(gradnorm_exact)
|
||||
|
||||
iterations = list(range(len(gradnorm_awls_quad)))
|
||||
|
||||
iterations_interp = np.linspace(min(iterations), max(iterations), len(gradnorm_awls_quad))
|
||||
|
||||
gradnorm_awls_quad = interp1d(iterations, gradnorm_awls_quad, kind='cubic')(iterations_interp)
|
||||
gradnorm_exact = interp1d(iterations, gradnorm_exact, kind='cubic')(iterations_interp)
|
||||
|
||||
smoothed_gradnorm_awls_quad = np.convolve(gradnorm_awls_quad, np.ones(smoothing_window) / smoothing_window,
|
||||
mode='valid')
|
||||
smoothed_gradnorm_exact = np.convolve(gradnorm_exact, np.ones(smoothing_window) / smoothing_window, mode='valid')
|
||||
|
||||
data = pd.DataFrame({
|
||||
'iterations': iterations_interp[:len(smoothed_gradnorm_awls_quad)],
|
||||
'AWLS quadratic': smoothed_gradnorm_awls_quad,
|
||||
'ExactLS': smoothed_gradnorm_exact
|
||||
})
|
||||
|
||||
sns.lineplot(data=data, x='iterations', y='AWLS quadratic', label='AWLS', color='blue')
|
||||
sns.lineplot(data=data, x='iterations', y='ExactLS', label='ExactLS', color='green')
|
||||
|
||||
plt.yscale('log')
|
||||
plt.legend(loc='upper right', fontsize=15)
|
||||
|
||||
conditioning = "LBFGS/" + conditioning
|
||||
plt.savefig(PLOTS_PATH.format(conditioning, "LBFGS-LS-gradient-comparison.png"))
|
||||
plt.show()
|
||||
|
||||
|
||||
def BFGS_comparison():
|
||||
folder = "comparison_BFGS"
|
||||
df_BFGS = pd.read_csv(
|
||||
LBFGS_RESULTS.format(folder, "statisticsBFGS-iterations-m1000n20--error-norm.csv"),
|
||||
)
|
||||
df_LBFGS = pd.read_csv(
|
||||
LBFGS_RESULTS.format("well_conditioned", "statisticsLBFGS-iterations-m1000n20--error-norm.csv"),
|
||||
)
|
||||
|
||||
setup(title='BFGS vs L-BFGS gradient norm on well-conditioned matrix', x_label='Iterations', y_label=' ')
|
||||
|
||||
gradnorm_BFGS = df_BFGS['mean_gradient'][::2]
|
||||
gradnorm_LBFGS = df_LBFGS['mean_gradient'][::2]
|
||||
error_BFGS = df_BFGS['mean_relative'][::2]
|
||||
error_LBFGS = df_LBFGS['mean_relative'][::2]
|
||||
residual_BFGS = df_BFGS['mean_residual'][::2]
|
||||
residual_LBFGS = df_LBFGS['mean_residual'][::2]
|
||||
|
||||
min_len = 27
|
||||
|
||||
iterations = list(range(min_len))
|
||||
gradnorm_BFGS = gradnorm_BFGS[:min_len]
|
||||
gradnorm_LBFGS = gradnorm_LBFGS[:min_len]
|
||||
error_BFGS = error_BFGS[:min_len]
|
||||
error_LBFGS = error_LBFGS[:min_len]
|
||||
residual_BFGS = residual_BFGS[:min_len]
|
||||
residual_LBFGS = residual_LBFGS[:min_len]
|
||||
|
||||
iterations_interp = np.linspace(min(iterations), max(iterations), len(residual_BFGS))
|
||||
|
||||
gradnorm_BFGS = interp1d(iterations, gradnorm_BFGS, kind='cubic')(iterations_interp)
|
||||
gradnorm_LBFGS = interp1d(iterations, gradnorm_LBFGS, kind='cubic')(iterations_interp)
|
||||
error_BFGS = interp1d(iterations, error_BFGS, kind='cubic')(iterations_interp)
|
||||
error_LBFGS = interp1d(iterations, error_LBFGS, kind='cubic')(iterations_interp)
|
||||
residual_BFGS = interp1d(iterations, residual_BFGS, kind='cubic')(iterations_interp)
|
||||
residual_LBFGS = interp1d(iterations, residual_LBFGS, kind='cubic')(iterations_interp)
|
||||
|
||||
data = pd.DataFrame({
|
||||
'Iterations': iterations_interp,
|
||||
'BFGS Gradient': gradnorm_BFGS,
|
||||
'LBFGS Gradient': gradnorm_LBFGS,
|
||||
'BFGS Error': error_BFGS,
|
||||
'LBFGS Error': error_LBFGS,
|
||||
'BFGS Residual': residual_BFGS,
|
||||
'LBFGS Residual': residual_LBFGS
|
||||
})
|
||||
|
||||
data_long = pd.melt(data, id_vars=['Iterations'], var_name='algorithm', value_name='value')
|
||||
|
||||
# Define custom color palette
|
||||
custom_palette = {
|
||||
'BFGS Gradient': 'red',
|
||||
'BFGS Error': 'orange',
|
||||
'BFGS Residual': 'gold',
|
||||
'LBFGS Gradient': 'blue',
|
||||
'LBFGS Error': 'green',
|
||||
'LBFGS Residual': 'deepskyblue'
|
||||
}
|
||||
|
||||
# Create the plot
|
||||
sns.lineplot(data=data_long, x='Iterations', y='value', hue='algorithm', palette=custom_palette)
|
||||
|
||||
plt.yscale('log')
|
||||
|
||||
handles, labels = plt.gca().get_legend_handles_labels()
|
||||
labels, handles = zip(*sorted(zip(labels, handles), key=lambda t: t[0]))
|
||||
plt.legend(handles, labels, loc='upper right', fontsize=15)
|
||||
|
||||
conditioning = "LBFGS/" + folder
|
||||
plt.savefig(PLOTS_PATH.format(conditioning, "BFGS-LBFGS-gradient-comparison.png"))
|
||||
plt.show()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# plot all 3D plots
|
||||
"""
|
||||
plot_lambda_epsilon_3D('error')
|
||||
plot_lambda_epsilon_3D('time')
|
||||
plot_lambda_epsilon_3D('iterations')
|
||||
plot_epsilon_memory_3D('error')
|
||||
plot_epsilon_memory_3D('iterations')
|
||||
"""
|
||||
plot_norm_gradient_2D("well")
|
||||
plot_norm_gradient_2D("ill")
|
||||
# plot_awls_vs_exact_gradient_decrease_2D()
|
||||
# plot_iteration_memory("well")
|
||||
plot_iteration_memory("ill")
|
||||
BFGS_comparison()
|
||||
68
project/plotting/QR.py
Normal file
68
project/plotting/QR.py
Normal file
@ -0,0 +1,68 @@
|
||||
from config import QR_RESULTS, PLOTS_PATH, nanoseconds_to_seconds, setup
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.ticker as ticker
|
||||
import seaborn as sns
|
||||
import numpy as np
|
||||
|
||||
|
||||
def plot_lambda(kind, smoothing_window=2):
|
||||
if kind not in ['error', 'time']:
|
||||
raise ValueError("kind must be one of 'error', 'time'")
|
||||
|
||||
df = pd.read_csv(QR_RESULTS.format("statisticsQR-lambda-m300n20--{}.csv".format(kind)))
|
||||
lambda_values = df['lambda']
|
||||
|
||||
if kind == 'time':
|
||||
|
||||
setup(title='QR running time with respect to λ', y_label='Time (s)', x_label='λ')
|
||||
meantime_values = df['meantime']
|
||||
stdtime_values = df['stdtime']
|
||||
sns.lineplot(data=df, x='lambda', y='meantime', label='Mean Time', color='blue')
|
||||
plt.fill_between(
|
||||
lambda_values,
|
||||
meantime_values - stdtime_values,
|
||||
meantime_values + stdtime_values,
|
||||
alpha=0.3,
|
||||
label='Standard Deviation',
|
||||
color='lightblue'
|
||||
)
|
||||
plt.ylim(0, 3.5 * max(meantime_values + stdtime_values))
|
||||
plt.gca().yaxis.set_major_formatter(ticker.FuncFormatter(nanoseconds_to_seconds))
|
||||
else:
|
||||
setup(title='QR errors with respect to λ', y_label='Error', x_label='λ')
|
||||
|
||||
df['relative'] = np.convolve(df['relative'], np.ones(smoothing_window) / smoothing_window, mode='same')
|
||||
df['residual'] = np.convolve(df['residual'], np.ones(smoothing_window) / smoothing_window, mode='same')
|
||||
df['stability'] = np.convolve(df['stability'], np.ones(smoothing_window) / smoothing_window, mode='same')
|
||||
|
||||
sns.lineplot(data=df, x='lambda', y='relative', label='Relative Error', color='blue')
|
||||
sns.lineplot(data=df, x='lambda', y='residual', label='Residual', color='red')
|
||||
sns.lineplot(data=df, x='lambda', y='stability', label='Stability', color='green')
|
||||
plt.yscale('log')
|
||||
|
||||
plt.legend(loc='upper right', fontsize=15)
|
||||
plt.xscale('log', base=10)
|
||||
|
||||
plt.savefig(PLOTS_PATH.format('QR', "QR-lambda-{}.png".format(kind)))
|
||||
plt.show()
|
||||
|
||||
|
||||
def plot_forward_error(smoothing_window=5):
|
||||
df = pd.read_csv(QR_RESULTS.format("statisticsQR-forward-m300n20--error.csv"))
|
||||
setup(title='QR forward error with respect to λ', y_label='Error', x_label='λ')
|
||||
df['forwardQ'] = np.convolve(df['forwardQ'], np.ones(smoothing_window) / smoothing_window, mode='same')
|
||||
df['forwardR'] = np.convolve(df['forwardR'], np.ones(smoothing_window) / smoothing_window, mode='same')
|
||||
sns.lineplot(data=df, x='lambda', y='forwardQ', label='Forward Error on Q', color='blue')
|
||||
sns.lineplot(data=df, x='lambda', y='forwardR', label='Forward Error on R', color='red')
|
||||
plt.yscale('log')
|
||||
plt.xscale('log', base=10)
|
||||
plt.legend(loc='upper right', fontsize=15)
|
||||
plt.savefig(PLOTS_PATH.format('QR', "QR-forward_error.png"))
|
||||
plt.show()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
plot_lambda('error')
|
||||
plot_lambda('time')
|
||||
plot_forward_error()
|
||||
0
project/plotting/__init__.py
Normal file
0
project/plotting/__init__.py
Normal file
271
project/plotting/comparison.py
Normal file
271
project/plotting/comparison.py
Normal file
@ -0,0 +1,271 @@
|
||||
import pandas as pd
|
||||
from matplotlib import pyplot as plt, ticker
|
||||
import seaborn as sns
|
||||
from config import COMPARISON_RESULTS, PLOTS_PATH
|
||||
|
||||
|
||||
def nanoseconds_to_seconds_2f(x, pos):
|
||||
return f"{x / 10 ** 9:.2f}"
|
||||
|
||||
|
||||
def nanoseconds_to_seconds_3f(x, pos):
|
||||
return f"{x / 10 ** 9:.3f}"
|
||||
|
||||
|
||||
def bytes_to_gib(x, pos):
|
||||
return f"{x / 1024 ** 3:.2f}"
|
||||
|
||||
|
||||
def QR_vs_LBFGS_time(conditioning, dimension="n"):
|
||||
if conditioning not in ['ill', 'well']:
|
||||
raise ValueError("conditioning must be one of 'ill', 'well'")
|
||||
if dimension not in ['n', 'm']:
|
||||
raise ValueError("dimension must be one of 'n', 'm'")
|
||||
if dimension == 'n':
|
||||
df = pd.read_csv(COMPARISON_RESULTS.format("QRvsLBFGS-n-m200-" + conditioning + "cond--time.csv"))
|
||||
else:
|
||||
df = pd.read_csv(COMPARISON_RESULTS.format("QRvsLBFGS-m-n50-" + conditioning + "cond--time.csv"))
|
||||
sns.set(style="whitegrid")
|
||||
sns.set_context('paper')
|
||||
|
||||
fig, ax1 = plt.subplots(figsize=(11, 8))
|
||||
|
||||
sns.lineplot(data=df, x=dimension, y='meantimeQR', marker='o', label='Mean Time QR', color='blue', ax=ax1)
|
||||
ax1.fill_between(
|
||||
df[dimension],
|
||||
df['meantimeQR'] - df['stdtimeQR'],
|
||||
df['meantimeQR'] + df['stdtimeQR'],
|
||||
alpha=0.3,
|
||||
label='Standard Deviation QR',
|
||||
color='lightblue'
|
||||
)
|
||||
|
||||
sns.lineplot(data=df, x=dimension, y='meantimeLBFGS', marker='o', label='Mean Time L-BFGS', color='red', ax=ax1)
|
||||
ax1.fill_between(
|
||||
df[dimension],
|
||||
df['meantimeLBFGS'] - df['stdtimeLBFGS'],
|
||||
df['meantimeLBFGS'] + df['stdtimeLBFGS'],
|
||||
alpha=0.3,
|
||||
label='Standard Deviation L-BFGS',
|
||||
color='lightsalmon'
|
||||
)
|
||||
|
||||
ax1.set_title('QR vs LBFGS time and memory scalability on ' + conditioning + '-conditioned matrix', fontsize=20,
|
||||
pad=20,
|
||||
fontweight='bold')
|
||||
ax1.set_xlabel(dimension, fontsize=15, labelpad=20)
|
||||
ax1.set_ylabel('time (s)', fontsize=15, labelpad=20)
|
||||
ax1.set_ylim(0, None)
|
||||
|
||||
ax1.legend(loc='upper left', fontsize=15)
|
||||
ax1.tick_params(axis='both', which='major', labelsize=15)
|
||||
ax1.yaxis.set_major_formatter(ticker.FuncFormatter(nanoseconds_to_seconds_2f))
|
||||
|
||||
ax2 = ax1.twinx()
|
||||
sns.lineplot(data=df, x=dimension, y='meanallocsQR', marker='o', label='GiB Allocation QR', color='green', ax=ax2)
|
||||
sns.lineplot(data=df, x=dimension, y='meanallocsLBFGS', marker='o', label='GiB Allocation BFGS', color='purple',
|
||||
ax=ax2)
|
||||
ax2.set_ylabel('memory (GiB)', fontsize=15, labelpad=20)
|
||||
ax2.set_ylim(0, None)
|
||||
ax2.legend(loc='upper right', fontsize=15)
|
||||
ax2.tick_params(axis='y', labelsize=15)
|
||||
ax2.yaxis.set_major_formatter(ticker.FuncFormatter(bytes_to_gib))
|
||||
|
||||
plt.savefig(PLOTS_PATH.format("comparison", "QRvsLBFGS-scalability-time-" + conditioning + f"cond-{dimension}.png"))
|
||||
plt.show()
|
||||
|
||||
|
||||
def BFGSvsLBFGS_time(dimension="n"):
|
||||
if dimension not in ['n', 'm']:
|
||||
raise ValueError("dimension must be one of 'n', 'm'")
|
||||
|
||||
if dimension == 'n':
|
||||
df = pd.read_csv(COMPARISON_RESULTS.format("BFGSvsLBFGS-n-m200--time.csv"))
|
||||
else:
|
||||
df = pd.read_csv(COMPARISON_RESULTS.format("BFGSvsLBFGS-m-n50--time.csv"))
|
||||
sns.set(style="whitegrid")
|
||||
sns.set_context('paper')
|
||||
|
||||
fig, ax1 = plt.subplots(figsize=(11, 8))
|
||||
|
||||
sns.lineplot(data=df, x=dimension, y='meantimeBFGS', marker='o', label='Mean Time BFGS', color='blue', ax=ax1)
|
||||
ax1.fill_between(
|
||||
df[dimension],
|
||||
df['meantimeBFGS'] - df['stdtimeBFGS'],
|
||||
df['meantimeBFGS'] + df['stdtimeBFGS'],
|
||||
alpha=0.3,
|
||||
label='Standard Deviation BFGS',
|
||||
color='lightblue'
|
||||
)
|
||||
|
||||
sns.lineplot(data=df, x=dimension, y='meantimeLBFGS', marker='o', label='Mean Time L-BFGS', color='red', ax=ax1)
|
||||
ax1.fill_between(
|
||||
df[dimension],
|
||||
df['meantimeLBFGS'] - df['stdtimeLBFGS'],
|
||||
df['meantimeLBFGS'] + df['stdtimeLBFGS'],
|
||||
alpha=0.3,
|
||||
label='Standard Deviation L-BFGS',
|
||||
color='lightsalmon'
|
||||
)
|
||||
|
||||
ax1.set_title('BFGS vs L-BFGS time and memory scalability on well-conditioned matrix', fontsize=20, pad=20, fontweight='bold')
|
||||
ax1.set_xlabel(dimension, fontsize=15, labelpad=20)
|
||||
ax1.set_ylabel('time (s)', fontsize=15, labelpad=20)
|
||||
ax1.set_ylim(0, None)
|
||||
|
||||
if dimension == 'n':
|
||||
ax1.legend(loc='upper right', fontsize=15)
|
||||
else:
|
||||
ax1.legend(loc='upper left', fontsize=15)
|
||||
ax1.tick_params(axis='both', which='major', labelsize=15)
|
||||
ax1.yaxis.set_major_formatter(ticker.FuncFormatter(nanoseconds_to_seconds_3f))
|
||||
|
||||
ax2 = ax1.twinx()
|
||||
sns.lineplot(data=df, x=dimension, y='meanallocsBFGS', marker='o', label='Bytes Allocation BFGS', color='green',
|
||||
ax=ax2)
|
||||
sns.lineplot(data=df, x=dimension, y='meanallocsLBFGS', marker='o', label='Bytes Allocation L-BFGS', color='purple',
|
||||
ax=ax2)
|
||||
ax2.set_ylabel('memory (B)', fontsize=15, labelpad=20)
|
||||
ax2.set_ylim(0, None)
|
||||
ax2.legend(loc='lower right', fontsize=15)
|
||||
ax2.tick_params(axis='y', labelsize=15)
|
||||
ax2.yaxis.set_major_formatter(ticker.FuncFormatter(bytes_to_gib))
|
||||
|
||||
plt.savefig(PLOTS_PATH.format("comparison", f"BFGSvsLBFGS-time-{dimension}.png"))
|
||||
plt.show()
|
||||
|
||||
|
||||
def quasi_newton_time(conditioning="well", dogleg=False):
|
||||
df = pd.read_csv(COMPARISON_RESULTS.format(f"Quasi-Newton-Comparison-time-{conditioning}cond.csv"))
|
||||
sns.set(style="whitegrid")
|
||||
sns.set_context('paper')
|
||||
|
||||
plt.figure(figsize=(11, 8))
|
||||
|
||||
sns.lineplot(data=df, x='m', y='meantimeLBFGS', marker='o', label='L-BFGS', color='blue')
|
||||
plt.fill_between(
|
||||
df['m'],
|
||||
df['meantimeLBFGS'] - df['stdtimeLBFGS'],
|
||||
df['meantimeLBFGS'] + df['stdtimeLBFGS'],
|
||||
alpha=0.3,
|
||||
label='Standard Deviation L-BFGS',
|
||||
color='lightblue'
|
||||
)
|
||||
|
||||
sns.lineplot(data=df, x='m', y='meantimeBFGS', marker='o', label='BFGS', color='red')
|
||||
plt.fill_between(
|
||||
df['m'],
|
||||
df['meantimeBFGS'] - df['stdtimeBFGS'],
|
||||
df['meantimeBFGS'] + df['stdtimeBFGS'],
|
||||
alpha=0.3,
|
||||
label='Standard Deviation BFGS',
|
||||
color='lightsalmon'
|
||||
)
|
||||
|
||||
sns.lineplot(data=df, x='m', y='meantimeDFP', marker='o', label='DFP', color='purple')
|
||||
plt.fill_between(
|
||||
df['m'],
|
||||
df['meantimeDFP'] - df['stdtimeDFP'],
|
||||
df['meantimeDFP'] + df['stdtimeDFP'],
|
||||
alpha=0.3,
|
||||
label='Standard Deviation DFP',
|
||||
color='violet'
|
||||
)
|
||||
|
||||
sns.lineplot(data=df, x='m', y='meantimeSR1', marker='o', label='SR1', color='violet')
|
||||
plt.fill_between(
|
||||
df['m'],
|
||||
df['meantimeSR1'] - df['stdtimeSR1'],
|
||||
df['meantimeSR1'] + df['stdtimeSR1'],
|
||||
alpha=0.3,
|
||||
label='Standard Deviation SR1',
|
||||
color='lightsalmon'
|
||||
)
|
||||
|
||||
if dogleg:
|
||||
sns.lineplot(data=df, x='m', y='meantimeDFPDogleg', marker='o', label='DFP with Dogleg', color='orange')
|
||||
plt.fill_between(
|
||||
df['m'],
|
||||
df['meantimeDFPDogleg'] - df['stdtimeDFPDogleg'],
|
||||
df['meantimeDFPDogleg'] + df['stdtimeDFPDogleg'],
|
||||
alpha=0.3,
|
||||
label='Standard Deviation DFP with Dogleg',
|
||||
color='lightsalmon'
|
||||
)
|
||||
sns.lineplot(data=df, x='m', y='meantimeBFGSDogleg', marker='o', label='BFGS with Dogleg', color='green')
|
||||
plt.fill_between(
|
||||
df['m'],
|
||||
df['meantimeBFGSDogleg'] - df['stdtimeBFGSDogleg'],
|
||||
df['meantimeBFGSDogleg'] + df['stdtimeBFGSDogleg'],
|
||||
alpha=0.3,
|
||||
label='Standard Deviation BFGS with Dogleg',
|
||||
color='lightgreen'
|
||||
)
|
||||
|
||||
plt.title(f'Quasi-Newton methods running time on {conditioning}-conditioned matrix', fontsize=20, pad=20,
|
||||
fontweight='bold')
|
||||
plt.xlabel('m', fontsize=15, labelpad=20)
|
||||
plt.ylabel('time (s)', fontsize=15, labelpad=20)
|
||||
plt.ylim(0, None)
|
||||
|
||||
handles, labels = plt.gca().get_legend_handles_labels()
|
||||
|
||||
keyword = 'Standard Deviation'
|
||||
|
||||
filtered_handles = [handle for label, handle in zip(labels, handles) if keyword not in label]
|
||||
filtered_labels = [label for label in labels if keyword not in label]
|
||||
|
||||
plt.legend(filtered_handles, filtered_labels, fontsize=15, loc='upper left')
|
||||
plt.xticks(fontsize=15)
|
||||
plt.yticks(fontsize=15)
|
||||
|
||||
plt.gca().yaxis.set_major_formatter(ticker.FuncFormatter(nanoseconds_to_seconds_2f))
|
||||
|
||||
if dogleg:
|
||||
plt.savefig(PLOTS_PATH.format("comparison", f"Quasi-Newton-Comparison-time-{conditioning}cond-Dogleg.png"))
|
||||
else:
|
||||
plt.savefig(PLOTS_PATH.format("comparison", f"Quasi-Newton-Comparison-time-{conditioning}cond.png"))
|
||||
plt.show()
|
||||
|
||||
|
||||
def quasi_newton_memory(conditioning="well"):
|
||||
df = pd.read_csv(COMPARISON_RESULTS.format(f"Quasi-Newton-Comparison-time-{conditioning}cond.csv"))
|
||||
sns.set(style="whitegrid")
|
||||
sns.set_context('paper')
|
||||
|
||||
plt.figure(figsize=(11, 8))
|
||||
|
||||
sns.lineplot(data=df, x='m', y='meanallocsLBFGS', marker='o', label='L-BFGS', color='blue')
|
||||
sns.lineplot(data=df, x='m', y='meanallocsBFGS', marker='o', label='BFGS', color='red')
|
||||
sns.lineplot(data=df, x='m', y='meanallocsBFGSDogleg', marker='o', label='BFGS with Dogleg', color='green')
|
||||
sns.lineplot(data=df, x='m', y='meanallocsDFP', marker='o', label='DFP', color='purple')
|
||||
sns.lineplot(data=df, x='m', y='meanallocsDFPDogleg', marker='o', label='DFP with Dogleg', color='orange')
|
||||
sns.lineplot(data=df, x='m', y='meanallocsSR1', marker='o', label='SR1', color='violet')
|
||||
|
||||
plt.title(f'Quasi-Newton methods memory allocation on {conditioning}-conditioned matrix', fontsize=20, pad=20, fontweight='bold')
|
||||
plt.xlabel('m', fontsize=15, labelpad=20)
|
||||
plt.ylabel('bytes (GiB)', fontsize=15, labelpad=20)
|
||||
plt.ylim(-1, None)
|
||||
|
||||
plt.legend(loc='upper left', fontsize=15)
|
||||
plt.xticks(fontsize=15)
|
||||
plt.yticks(fontsize=15)
|
||||
|
||||
plt.gca().yaxis.set_major_formatter(ticker.FuncFormatter(bytes_to_gib))
|
||||
|
||||
plt.savefig(PLOTS_PATH.format("comparison", f"Quasi-Newton-Comparison-memory-{conditioning}cond.png"))
|
||||
plt.show()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
QR_vs_LBFGS_time("well", "m")
|
||||
QR_vs_LBFGS_time("well", "n")
|
||||
QR_vs_LBFGS_time("ill", "m")
|
||||
QR_vs_LBFGS_time("ill", "n")
|
||||
BFGSvsLBFGS_time("n")
|
||||
BFGSvsLBFGS_time("m")
|
||||
quasi_newton_time("ill")
|
||||
quasi_newton_time("well", dogleg=True)
|
||||
quasi_newton_time("well", dogleg=False)
|
||||
quasi_newton_memory("ill")
|
||||
quasi_newton_memory("well")
|
||||
32
project/plotting/conditioning.py
Normal file
32
project/plotting/conditioning.py
Normal file
@ -0,0 +1,32 @@
|
||||
# read a csv of two columns and plot them in 2d with seaborn
|
||||
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
import seaborn as sns
|
||||
from config import CONDITIONING_RESULTS, PLOTS_PATH
|
||||
|
||||
|
||||
def plot_conditioning():
|
||||
df = pd.read_csv(CONDITIONING_RESULTS.format('conditioning.csv'))
|
||||
sns.set(style="whitegrid")
|
||||
sns.set_context('paper')
|
||||
|
||||
plt.figure(figsize=(11, 8))
|
||||
sns.lineplot(data=df, x='lambda', y='condnum', marker='o')
|
||||
|
||||
plt.xticks(fontsize=15)
|
||||
plt.yticks(fontsize=15)
|
||||
|
||||
plt.xlabel('λ', fontsize=20)
|
||||
plt.ylabel('k(X^)', fontsize=20)
|
||||
plt.xscale('log')
|
||||
plt.yscale('log')
|
||||
|
||||
plt.title('Condition number of X^ with respect to λ', fontsize=25, pad=20, fontweight='bold')
|
||||
|
||||
plt.savefig(PLOTS_PATH.format('conditioning', 'conditioning.png'), bbox_inches='tight', dpi=100)
|
||||
plt.show()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
plot_conditioning()
|
||||
46
project/plotting/config.py
Normal file
46
project/plotting/config.py
Normal file
@ -0,0 +1,46 @@
|
||||
import os
|
||||
|
||||
LBFGS_RESULTS = "/testing/results/LBFGS/{}/{}"
|
||||
QR_RESULTS = "/testing/results/QR/{}"
|
||||
CONDITIONING_RESULTS = "/testing/results/conditioning/{}"
|
||||
COMPARISON_RESULTS = "/testing/results/comparison/{}"
|
||||
PLOTS_PATH = "/testing/plots/{}/{}"
|
||||
|
||||
# PROJECT FOLDER PATH
|
||||
PROJECT_FOLDER_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
LBFGS_RESULTS = PROJECT_FOLDER_PATH + LBFGS_RESULTS
|
||||
QR_RESULTS = PROJECT_FOLDER_PATH + QR_RESULTS
|
||||
CONDITIONING_RESULTS = PROJECT_FOLDER_PATH + CONDITIONING_RESULTS
|
||||
COMPARISON_RESULTS = PROJECT_FOLDER_PATH + COMPARISON_RESULTS
|
||||
PLOTS_PATH = PROJECT_FOLDER_PATH + PLOTS_PATH
|
||||
|
||||
# PLOTTING CONFIGURATIONS
|
||||
from matplotlib import pyplot as plt
|
||||
import seaborn as sns
|
||||
|
||||
|
||||
def setup(title=None, x_label=None, y_label=None):
|
||||
sns.set_style("whitegrid")
|
||||
sns.set_context('paper')
|
||||
plt.figure(figsize=(13, 9))
|
||||
plt.xticks(fontsize=15)
|
||||
plt.yticks(fontsize=15)
|
||||
plt.title(title, fontsize=20, pad=20, loc='center', fontweight='bold')
|
||||
plt.xlabel(x_label, fontsize=15, labelpad=20)
|
||||
plt.ylabel(y_label, fontsize=15, labelpad=20)
|
||||
|
||||
|
||||
def nanoseconds_to_seconds(x, pos=None):
|
||||
return f"{x / 10 ** 9:.4f}"
|
||||
|
||||
|
||||
def log_tick_formatter(val, pos=None):
|
||||
return f"$10^{{{int(val)}}}$"
|
||||
|
||||
|
||||
def nanoseconds_to_milliseconds(x, pos=None):
|
||||
return f"{x / 10 ** 6:.1f}"
|
||||
|
||||
def scientific_notation(x, pos):
|
||||
return '%1.1e' % x
|
||||
Reference in New Issue
Block a user