Files
FYS-STK4155/doc/Programs/VariousCodes/functions.py
T
2019-11-17 22:22:03 +01:00

189 lines
4.9 KiB
Python

import sys
import numpy as np
from matplotlib import cm
"""
A file for all common functions used in project 1
"""
def FrankeFunction(x,y):
term1 = 0.75*np.exp(-(0.25*(9*x-2)**2) - 0.25*((9*y-2)**2))
term2 = 0.75*np.exp(-((9*x+1)**2)/49.0 - 0.1*(9*y+1))
term3 = 0.5*np.exp(-(9*x-7)**2/4.0 - 0.25*((9*y-3)**2))
term4 = -0.2*np.exp(-(9*x-4)**2 - (9*y-7)**2)
return term1 + term2 + term3 + term4
def MSE(y, y_tilde):
"""
Function for computing mean squared error.
Input is y: analytical solution, y_tilde: computed solution.
"""
return np.sum((y-y_tilde)**2)/y.size
def R2_Score(y, y_tilde):
"""
Function for computing the R2 score.
Input is y: analytical solution, y_tilde: computed solution.
"""
return 1 - np.sum((y[:-2]-y_tilde[:-2])**2)/np.sum((y[:-2]-np.average(y))**2)
def create_X(x, y, n = 5):
"""
Function for creating a X-matrix with rows [1, x, y, x^2, xy, xy^2 , etc.]
Input is x and y mesh or raveled mesh, keyword agruments n is the degree of the polinomial you want to fit.
"""
if len(x.shape) > 1:
x = np.ravel(x)
y = np.ravel(y)
N = len(x)
l = int((n+1)*(n+2)/2) # Number of elements in beta
X = np.ones((N,l))
for i in range(1,n+1):
q = int((i)*(i+1)/2)
for k in range(i+1):
X[:,q+k] = (x**(i-k))*(y**k)
return X
def plot_surface(x, y, z, title = "", show = False, cmap=cm.coolwarm, figsize = None):
"""
Function to plot surfaces of z, given an x and y.
Input: x, y, z (NxN'Modeler' matrices), and a title (string)
"""
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib.ticker import LinearLocator, FormatStrFormatter
if figsize:
fig = plt.figure(figsize = figsize)
else:
fig = plt.figure()
ax = fig.gca(projection='3d')
# Plot the surface.of the best fit
surf = ax.plot_surface(x, y, z, cmap=cmap,
linewidth=0, antialiased=False)
# Customize the z axis automatically
z_min = np.min(z)
z_min = z_min*1.01 if z_min < 0 else z_min*.99
z_max = np.max(z)
z_max = z_max*1.01 if z_max > 0 else z_max*.99
ax.set_zlim(z_min, z_max)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
ax.view_init(azim=20,elev=45)
# Add a color bar which maps values to colors.
fig.colorbar(surf, shrink=0.5, aspect=5)
ax.set_title(title)
if show:
plt.show()
return fig, ax ,surf
def train_test_data(x_,y_,z_,i):
"""
Takes in x,y and z arrays, and a array with random indesies iself.
returns learning arrays for x, y and z with (N-len(i)) dimetions
and test data with length (len(i))
"""
x_learn=np.delete(x_,i)
y_learn=np.delete(y_,i)
z_learn=np.delete(z_,i)
x_test=np.take(x_,i)
y_test=np.take(y_,i)
z_test=np.take(z_,i)
return x_learn,y_learn,z_learn,x_test,y_test,z_test
def K_fold(x,y,z,k,alpha,model,m=5, ret_std = False):
"""Function to who calculate the average MSE and R2 using k-fold.
Takes in x,y and z varibles for a dataset, k number of folds, alpha and which method beta shall use. (OLS,Ridge or Lasso)
Returns average MSE and average R2"""
print(m)
if len(x.shape) > 1:
x = np.ravel(x)
y = np.ravel(y)
z = np.ravel(z)
n=len(x)
n_k=int(n/k)
if n_k*k!=n:
print("k needs to be a multiple of ", n,k)
i=np.arange(n)
np.random.shuffle(i)
MSE_=0
R2_=0
Variance_=0
Bias_=0
betas = np.zeros((k,int((m+1)*(m+2)/2)))
for t in range(k):
x_,y_,z_,x_test,y_test,z_test=train_test_data(x,y,z,i[t*n_k:(t+1)*n_k])
X= create_X(x_,y_,n=m)
X_test= create_X(x_test,y_test,n=m)
model.fit(X,z_)
betas[t] = model.beta
z_predict=model.predict(X_test)
MSE_+=MSE(z_test,z_predict)
R2_+=R2_Score(z_test,z_predict)
Bias_+=bias(z_test,z_predict)
Variance_+=variance(z_predict)
return (MSE_/k, R2_/k, Bias_/k, Variance_/k, np.std(betas, axis = 0), np.mean(betas, axis = 0))
def variance(y_tilde):
"""
Calculates the variance of the predicted values y_tilde.
"""
return np.sum((y_tilde - np.mean(y_tilde))**2)/np.size(y_tilde)
def bias(y, y_tilde):
"""
Calculates the bias of the predicted values y_tilde compared to
the actual data y.
"""
return np.sum((y - np.mean(y_tilde))**2)/np.size(y_tilde)
def update_progress(job_title, progress):
"""
Shows the progress of an for-loop.
"""
length = 20 # modify this to change the length
block = int(round(length*progress))
msg = "\r{0}: [{1}] {2}%".format(job_title, "#"*block + "-"*(length-block), round(progress*100, 2))
if progress >= 1: msg += " DONE\r\n"
sys.stdout.write(msg)
sys.stdout.flush()
def savefigure(name, figure = "gcf"):
"""
Function for saving figures as a .tex-file for easier integration with latex.
"""
try:
from matplotlib2tikz import save as tikz_save
tikz_save(name.replace(" ", "_") + ".tex", figure = figure, figureheight='\\figureheight', figurewidth='\\figurewidth')
except ImportError:
print("Please install matplotlib2tikz to save figure as a .tex-file.")
import matplotlib.pyplot as plt
if figure == "gcf":
plt.savefig(name+".pdf")
else:
fig.savefig(name+".pdf")