-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Develop code review #1
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
""" Module to implement L1 and/or L2 regularization with | ||
SciPy linear_models module | ||
""" | ||
|
||
def L1L2(t, F, bound, Nz, alpha1, alpha2, iterations = 10000): | ||
""" | ||
Returns solution using mixed L1 and/or L2 regularization | ||
with simple gradient descent | ||
|
||
F(t) = ∫f(s)*exp(-s*t)ds | ||
|
||
or | ||
|
||
min = ||C*f - F||2 + alpha1*||I*f||1 + alpha2*||I*f||2 | ||
|
||
Parameters: | ||
------------ | ||
t : array | ||
Time domain data from experiment | ||
F : array, | ||
Transient data from experiment F(t) | ||
bound : list | ||
[lowerbound, upperbound] of s domain points | ||
Nz : int | ||
Number of points z to compute, must be smaller than len(F) | ||
alpha1, alpha 2 : floats | ||
Regularization parameters for L1 and L2 regularizers | ||
iterations : int | ||
Maximum number of iterations. Optional | ||
|
||
|
||
Returns: | ||
------------ | ||
s : array | ||
Emission rates domain points (evenly spaced on log scale) | ||
f : array | ||
Inverse Laplace transform f(s) | ||
F_restored : array | ||
Reconstructed transient from C@f + intercept | ||
""" | ||
|
||
import numpy as np | ||
from scipy.sparse import diags | ||
from sklearn.linear_model import ElasticNet | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. импорты в начало |
||
|
||
# set up grid points (# = Nz) | ||
h = np.log(bound[1]/bound[0])/(Nz - 1) # equally spaced on logscale | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. пробелы |
||
s = bound[0]*np.exp(np.arange(Nz)*h) # z (Nz by 1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. можно переменные обозвать терминами, чтобы более читабельно было |
||
|
||
# construct C matrix from [1] | ||
s_mesh, t_mesh = np.meshgrid(s, t) | ||
C = np.exp(-t_mesh*s_mesh) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. пробелы |
||
C[:, 0] /= 2. | ||
C[:, -1] /= 2. | ||
C *= h | ||
|
||
alpha = alpha1 + alpha2 | ||
l1_ratio = alpha1/alpha | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. пробелы |
||
|
||
model = ElasticNet(alpha=alpha, l1_ratio=l1_ratio, tol = 1e-12, | ||
fit_intercept = True, max_iter = iterations) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. либо в одну строчку, либо так:
|
||
model.fit(C, F) | ||
|
||
f = model.coef_ | ||
|
||
F_restored = C@f + model.intercept_ | ||
return s, f, F_restored |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from fista import Fista | ||
import numpy as np | ||
|
||
def l1_fista(t, F, bound, Nz, alpha, iterations = 50000, penalty = 'l11'): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. здесь тоже |
||
|
||
"Function to implement FISTA algorithm" | ||
|
||
h = np.log(bound[1]/bound[0])/(Nz - 1) # equally spaced on logscale | ||
z = bound[0]*np.exp(np.arange(Nz)*h) # z (Nz by 1) | ||
|
||
z_mesh, t_mesh = np.meshgrid(z, t) | ||
C = np.exp(-t_mesh*z_mesh) # specify integral kernel | ||
C[:, 0] /= 2. | ||
C[:, -1] /= 2. | ||
C *= h | ||
|
||
fista = Fista(loss='least-square', penalty = penalty, lambda_=alpha, n_iter = iterations) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
fista.fit(C, F) | ||
|
||
|
||
return z, fista.coefs_, fista.predict(C) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
"""Module to implement routines of numerical inverse | ||
Laplace tranform using L2 regularization algorithm | ||
""" | ||
|
||
import numpy as np | ||
from scipy.sparse import diags | ||
|
||
def L2(t, F, bound, Nz, alpha): | ||
""" | ||
Returns solution for problem imposing L2 regularization | ||
|
||
F(t) = ∫f(s)*exp(-s*t)ds | ||
|
||
or | ||
|
||
min = ||C*f - F||2 + alpha*||I*f||2 | ||
|
||
|
||
Parameters: | ||
------------ | ||
t : array | ||
Time domain data from experiment | ||
F : array, | ||
Transient data from experiment F(t) | ||
bound : list | ||
[lowerbound, upperbound] of s domain points | ||
Nz : int | ||
Number of points z to compute, must be smaller than len(F) | ||
alpha : float | ||
Regularization parameters for L2 regularizers | ||
iterations : int | ||
Maximum number of iterations. Optional | ||
|
||
|
||
Returns: | ||
------------ | ||
s : array | ||
Emission rates domain points (evenly spaced on log scale) | ||
f : array | ||
Inverse Laplace transform f(s) | ||
F_restored : array | ||
Reconstructed transient from C@f + intercept | ||
""" | ||
|
||
# set up grid points (# = Nz) | ||
h = np.log(bound[1]/bound[0])/(Nz - 1) # equally spaced on logscale | ||
s = bound[0]*np.exp(np.arange(Nz)*h) # z (Nz by 1) | ||
|
||
# construct C matrix from [1] | ||
s_mesh, t_mesh = np.meshgrid(s, t) | ||
C = np.exp(-t_mesh*s_mesh) | ||
C[:, 0] /= 2. | ||
C[:, -1] /= 2. | ||
C *= h | ||
|
||
l2 = alpha | ||
|
||
data = [-2*np.ones(Nz), 1*np.ones(Nz), 1*np.ones(Nz)] | ||
positions = [-1, -2, 0] | ||
I = diags(data, positions, (Nz+2, Nz)).toarray() | ||
#I = np.identity(Nz) | ||
|
||
f = np.linalg.solve(l2*np.dot(I.T,I) + np.dot(C.T,C), np.dot(C.T,F)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. много пробелов перед равно |
||
|
||
F_restored = C@f | ||
|
||
return s, f, F_restored#, res_norm, sol_norm | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. перед комментарием два пробела, после решетки - один |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
"""Module to implement routines of numerical inverse | ||
Laplace tranform using Contin algorithm [1] | ||
|
||
[1] Provencher, S. (1982) | ||
""" | ||
|
||
from __future__ import division | ||
import numpy as np | ||
|
||
def Contin(t, F, bound, Nz, alpha): | ||
""" | ||
Function returns processed data f(z) from the equation | ||
|
||
F(t) = ∫f(z)*exp(-z*t) | ||
|
||
Parameters: | ||
-------------- | ||
t : array | ||
Time domain data from experiment | ||
F : array, | ||
Transient data from experiment F(t) | ||
bound : list | ||
[lowerbound, upperbound] of z domain points | ||
Nz : int | ||
Number of points z to compute, must be smaller than len(F) | ||
alpha : float | ||
Regularization parameter | ||
|
||
Returns: | ||
-------------- | ||
z : array | ||
Emission rates domain points (evenly spaced on log scale) | ||
f : array | ||
Inverse Laplace transform f(z) | ||
F_restored : array | ||
Reconstructed transient from C@f(z) | ||
""" | ||
|
||
|
||
# set up grid points (# = Nz) | ||
h = np.log(bound[1]/bound[0])/(Nz - 1) # equally spaced on logscale | ||
z = bound[0]*np.exp(np.arange(Nz)*h) # z (Nz by 1) | ||
|
||
# construct C matrix from [1] | ||
z_mesh, t_mesh = np.meshgrid(z, t) | ||
C = np.exp(-t_mesh*z_mesh) | ||
C[:, 0] /= 2. | ||
C[:, -1] /= 2. | ||
C *= h | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
У тебя этот кусок используется много раз. Можно написать метод отдельный для него, чтобы не дублировать код |
||
|
||
# construct regularization matrix R to impose gaussian-like peaks in f(z) | ||
# R - tridiagonal matrix (1,-2,1) | ||
Nreg = Nz + 2 | ||
R = np.zeros([Nreg, Nz]) | ||
R[0, 0] = 1. | ||
R[-1, -1] = 1. | ||
R[1:-1, :] = -2*np.diag(np.ones(Nz)) + np.diag(np.ones(Nz-1), 1) \ | ||
+ np.diag(np.ones(Nz-1), -1) | ||
|
||
#R = U*H*Z^T | ||
U, H, Z = np.linalg.svd(R, full_matrices=False) # H diagonal | ||
Z = Z.T | ||
H = np.diag(H) | ||
|
||
#C*Z*inv(H) = Q*S*W^T | ||
Hinv = np.diag(1.0/np.diag(H)) | ||
Q, S, W = np.linalg.svd(C.dot(Z).dot(Hinv), full_matrices=False) # S diag | ||
W = W.T | ||
S = np.diag(S) | ||
|
||
# construct GammaTilde & Stilde | ||
# ||GammaTilde - Stilde*f5||^2 = ||Xi||^2 | ||
Gamma = np.dot(Q.T, F) | ||
Sdiag = np.diag(S) | ||
Salpha = np.sqrt(Sdiag**2 + alpha**2) | ||
GammaTilde = Gamma*Sdiag/Salpha | ||
Stilde = np.diag(Salpha) | ||
|
||
# construct LDP matrices G = Z*inv(H)*W*inv(Stilde), B = -G*GammaTilde | ||
# LDP: ||Xi||^2 = min, with constraint G*Xi >= B | ||
Stilde_inv = np.diag(1.0/np.diag(Stilde)) | ||
G = Z @ Hinv @ W @ Stilde_inv | ||
B = -G @ GammaTilde | ||
|
||
# call LDP solver | ||
Xi = ldp(G, B) | ||
|
||
# final solution | ||
zf = np.dot(G, Xi + GammaTilde) | ||
f = zf/z | ||
|
||
F_restored = C@zf | ||
|
||
return z, f, F_restored | ||
|
||
|
||
def ldp(G, h): | ||
""" | ||
Helper for Contin() for solving NNLS [1] | ||
|
||
[1] - Lawson and Hanson’s (1974) | ||
Parameters: | ||
------------- | ||
G : matrix | ||
Z*inv(H)*W*inv(Stilde) | ||
h : array | ||
-G*GammaTilde | ||
|
||
Returns: | ||
------------- | ||
x : array | ||
Solution of argmin_x || Ax - b ||_2 | ||
""" | ||
|
||
from scipy.optimize import nnls | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. импорт в начало |
||
|
||
m, n = G.shape | ||
A = np.concatenate((G.T, h.reshape(1, m))) | ||
b = np.zeros(n+1) | ||
b[n] = 1. | ||
|
||
# Solving for argmin_x || Ax - b ||_2 | ||
x, resnorm = nnls(A, b) | ||
|
||
r = A@x - b | ||
|
||
if np.linalg.norm(r) == 0: | ||
print('\n No solution found, try different input!') | ||
else: | ||
x = -r[0:-1]/r[-1] | ||
return x |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
def demo(Index, Nz, Reg_L1, Reg_L2, Reg_C, Reg_S, Bounds, dt, Methods, Plot, Residuals, LCurve, Arrhenius, Heatplot): | ||
"""Gets data from widgets initialized with interface(), | ||
calls laplace() to process data and calls plot_data(), hp() | ||
to plot results | ||
|
||
Parameters: | ||
------------- | ||
Index : int | ||
Index of transient in dataset | ||
Nz : int | ||
Value which is length of calculated vector | ||
Reg_L1, Reg_L2 : floats | ||
Reg. parameters for FISTA(L1) and L2 regularization | ||
Reg_C, Reg_S : floats | ||
Reg. parameters for CONTIN and reSpect algorithms | ||
Bounds : list | ||
[lowerbound, upperbound ] bounds of emission rates domain points | ||
dt : int | ||
Time step of transient data points in ms | ||
Methods : list | ||
Methods to process data | ||
Plot : boolean | ||
Calls plot_data() if True | ||
Residuals : boolean | ||
Calls regopt() and plots L-curve to control | ||
regularization if True | ||
LCurve : boolean, | ||
Automatically picks optimal reg. parameter from | ||
L-curve if True | ||
Heatplot : boolean | ||
Plots heatplot for all dataset and saves data | ||
in .LDLTS if True | ||
""" | ||
|
||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
|
||
from read_file import read_file | ||
from laplace import laplace | ||
from plot_data import plot_data | ||
from hp import hp | ||
from read_file import read_file | ||
from regopt import regopt | ||
from interface import interface | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. в начало |
||
|
||
Bounds = 10.0**np.asarray(Bounds) | ||
|
||
t, C, T = read_file(interface.path, dt, proc = True)# time, transients, temperatures | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. коммент и пробелы убрать для proc |
||
|
||
data = laplace(t, C[Index], Nz, Reg_L1, Reg_L2, Reg_C, Reg_S, Bounds, Methods) | ||
#print(data) | ||
|
||
if Plot: | ||
ay, aph = plot_data(t, C[Index], data, T, Index) | ||
|
||
if Heatplot: | ||
hp(t, C, T, aph, Methods, Index, Reg_L1, Reg_L2, Reg_C, Reg_S, Bounds, Nz, LCurve, Arrhenius) | ||
|
||
if Residuals: | ||
regopt(t, C[Index], ay, Methods, Reg_L1, Reg_L2, Reg_C, Reg_S, Bounds, Nz) | ||
|
||
plt.show() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Название функции, типы, аннотации, не забывай убирать типы из докстринга