Commit 3254829a authored by Javier's avatar Javier

Merge branch 'rearrange-linalg'

parents 241323d9 c20a2ce7
...@@ -9,7 +9,7 @@ include("juobs_tools.jl") ...@@ -9,7 +9,7 @@ include("juobs_tools.jl")
include("juobs_obs.jl") include("juobs_obs.jl")
export read_mesons, read_ms1, read_ms, read_md, truncate_data! export read_mesons, read_ms1, read_ms, read_md, truncate_data!
export get_matrix, uwgevp_tot, energies, uwdot export get_matrix, energies, uwdot, uweigvals, uweigvecs, uweigen, invert, getall_eigvals, getall_eigvecs
export corr_obs, md_sea, plat_av, lin_fit, x_lin_fit, y_lin_fit, fit_routine export corr_obs, md_sea, plat_av, lin_fit, x_lin_fit, y_lin_fit, fit_routine
export meff, dec_const_pcvc, comp_t0 export meff, dec_const_pcvc, comp_t0
......
################################################################## #=
# Alessandro Conigli wrote this script. using ForwardDiff, LinearAlgebra
# It implements multiple linear algebra utilites optimised to work for op in (:eigvals, :eigvecs)
# with uwreal data types. @eval function LinearAlgebra.$op(a::Matrix{uwreal})
# The major features so fare implemented are:
# - matrix matrix and vector vector multiplication function fvec(x::Matrix)
# - norm of uwreal vectors return LinearAlgebra.$op(x)
# - copysign function for uwreal variables end
# - creation of identity matrix of uwreal return fvec(value.(a))
# - element wise multiplication between uwreal variables and matrix of uwreal #return uwreal(LinearAlgebra.$op(a.mean), a.prop, ForwardDiff.derivative($op, a.mean)*a.der)
# end
# end
################################################################## =#
@doc raw""" @doc raw"""
get_matrix(corr_diag::Vector{Array}, corr_upper::Vector{Array} ) get_matrix(corr_diag::Vector{Array}, corr_upper::Vector{Array} )
...@@ -62,7 +62,6 @@ function get_matrix(corr_diag::Vector{Vector{uwreal}}, corr_upper::Vector{Vector ...@@ -62,7 +62,6 @@ function get_matrix(corr_diag::Vector{Vector{uwreal}}, corr_upper::Vector{Vector
aux = Matrix{uwreal}(undef, n, n) aux = Matrix{uwreal}(undef, n, n)
for t in 1:time for t in 1:time
count=0 count=0
#testing = corr_upper[1][1]
for i in range(n-1,1, step=-1) for i in range(n-1,1, step=-1)
for j in range(n, i+1, step=-1) for j in range(n, i+1, step=-1)
aux[i,j] = corr_upper[d-count][t] aux[i,j] = corr_upper[d-count][t]
...@@ -84,103 +83,161 @@ Given a vector where each entry evals[t] is a uwreal array of eigenvalues, this ...@@ -84,103 +83,161 @@ Given a vector where each entry evals[t] is a uwreal array of eigenvalues, this
The index t here runs from 1:T=lenght(evals), while the index i stands for the number of energy levels computed: i = length(evals[t]) The index t here runs from 1:T=lenght(evals), while the index i stands for the number of energy levels computed: i = length(evals[t])
It returns a vector array eff_en where each entry eff_en[t] contains the first N states energies as uwreal objects It returns a vector array eff_en where each entry eff_en[t] contains the first N states energies as uwreal objects
""" """
function energies(evals::Union{Vector{Vector{uwreal}},Array{Array{uwreal}} }) function energies(evals::Union{Vector{Vector{uwreal}},Array{Array{uwreal}} }; wpm::Union{Dict{Int64,Vector{Float64}},Dict{String,Vector{Float64}}, Nothing}=nothing)
time = length(evals) time = length(evals)
n = length(evals[1]) n = length(evals[1])
eff_en = Array{Array{uwreal}}(undef, n) eff_en = Array{Array{uwreal}}(undef, n)
aux_en = Vector{uwreal}(undef, time-1) aux_en = Vector{uwreal}(undef, time-1)
for i in 1:n for i in 1:n
#aux_en = Vector{uwreal}(undef, time-1)
for t in 1:time-1 for t in 1:time-1
ratio = evals[t][i] / evals[t+1][i] ratio = evals[t][i] / evals[t+1][i]
aux_en[t] = 0.5*log(ratio * ratio) aux_en[t] = 0.5*log(ratio * ratio)
end end
uwerr.(aux_en) isnothing(wpm) ? uwerr.(aux_en) : uwerr.(aux_en, wpm)
eff_en[i] = copy(aux_en) eff_en[i] = copy(aux_en)
end end
return eff_en return eff_en
end end
@doc raw""" @doc raw"""
uwgevp_tot(mat_list::Vector{Array}, tnot::Int64; iter = 30, evec = false) getall_eigvals(a::Vector{Matrix}, t0; iter=30 )
Given a list of uwreal matrices and an integer value tnot, this method solves the generalised eigenvalue problem This function solves a GEVP problem, returning the eigenvalues, for a list of matrices, taking as generalised matrix the one
for all the matrices in the list, using the same auxiliary matrix mat_list[tnot]. at index t0, i.e:
C(t_i)v_i = λ_i C(t_0) v_i, with i=1:lenght(a)
It takes as input:
- a::Vector{Matrix} : a vector of matrices
- t0::Int64 : idex value at which the fixed matrix is taken
- iter=30 : the number of iterations of the qr algorithm used to extract the eigenvalues
It returns:
- res = Vector{Vector{uwreal}}
where res[i] are the generalised eigenvalues of the i-th matrix of the input array.
Examples:
'''@example
mat_array = get_matrix(diag, upper_diag)
evals = getall_eigvals(mat_array, 5)
'''
"""
function getall_eigvals(a::Vector{Matrix}, t0::Int64; iter=30 )
n = length(a)
res = Vector{Vector{uwreal}}(undef, n)
[res[i] = uweigvals(a[i], a[t0]) for i=1:n]
return res
end
By default, it returns a vector evals where each entry evals[i] is a vector of uwreal containing the @doc raw"""
generalised eigenvalues of the matrix mat_list[i]. uweigvals(a::Matrix{uwreal}; iter = 30)
uweigvals(a::Matrix{uwreal}, b::Matrix{uwreal}; iter = 30)
If evec is set to true, the methods returns also an array evecs where each entry evecs[i] is a matrix of uwreal. This function computes the eigenvalues of a matrix of uwreal objects.
The columns of such matrix are the eigenvectors associated with eigenvalues evals[i]. If a second matrix b is given as input, it returns the generalised eigenvalues instead.
It takes as input:
- a::Matrix{uwreal} : a matrix of uwreal
- b::Matrix{uwreal} : a matrix of uwreal, optional
It returns:
- res = Vector{uwreal}: a vector where each elements is an eigenvalue
The keyword iter, set by default to 30, selects the number of iterations of the qr algorithm before stopping.
""" """
function uwgevp_tot(mat_list::Vector{Matrix}, tnot::Int64; iter::Int64 = 30, evec::Bool = false) function uweigvals(a::Matrix{uwreal}; iter = 30)
n = length(mat_list) n = size(a,1)
evals = Array{Array{uwreal}}(undef, 0 ) for k in 1:iter
if !evec q_k, r_k = qr(a)
println(tnot) a = uwdot(r_k, q_k)
c_inv = invert(mat_list[tnot])
for i =1:n
aux_evals = uwgevp(mat_list[i], c_inv, iter = iter)
push!(evals , get_diag(aux_evals))
end
return evals
else
evecs = Array{Matrix}(undef, 0)
for i = 2:n-4
c_inv = invert(mat_list[i])
aux_evals, aux_evec = uwgevp(mat_list[i+3], c_inv, evec=evec, iter=iter)
push!(evals, get_diag(aux_evals))
ptilda = norm_evec(aux_evec, mat_list[i])
m = uwdot(mat_list[i], ptilda)
push!(evecs, m)
println( "\n t is ", i+3, " tnot is ", i)
#if 2*tnot < i && i<n-5
# tnot+=5
#end
end
return evals, evecs
end end
return get_diag(a)
end
function uweigvals(a::Matrix{uwreal}, b::Matrix{uwreal}; iter = 30)
c = uwdot(invert(b),a)
for k in 1:iter
q_k, r_k = qr(c)
c = uwdot(r_k, q_k)
end
return get_diag(c)
end end
"""
uwgevp(c_t:: Matrix{uwreal}, c_tnot_inv::Matrix{uwreal}; iter = 30, evec = false)
Given two matrices of uwreal C(t) and C(t0), this method solves the generalized eigenvalue problem @doc raw"""
C(t)V = C(t_0)D V, where V is the eigenvector matrix and D is the diagonal matrix of eigenvalues. getall_eigvecs(a::Vector{Matrix}, delta_t; iter=30 )
This function solves a GEVP problem, returning the eigenvectors, for a list of matrices.
C(t_i)v_i = λ_i C(t_i-delta_t) v_i, with i=1:lenght(a)
Here delta_t is the time shift within the two matrices of the problem, and is kept fixed.
It takes as input:
- a::Vector{Matrix} : a vector of matrices
- delta_t::Int64 : the fixed time shift t-t_0
- iter=30 : the number of iterations of the qr algorithm used to extract the eigenvalues
It returns:
- res = Vector{Matrix{uwreal}}
where each res[i] is a matrix with the eigenvectors as columns
Examples:
'''@example
mat_array = get_matrix(diag, upper_diag)
evecs = getall_eigvecs(mat_array, 5)
'''
"""
function getall_eigvecs(a::Vector{Matrix}, delta_t; iter=30)
n = length(a)-delta_t
res = Vector{Matrix{uwreal}}(undef, n)
[res[i] = uweigvecs(a[i+delta_t], a[i]) for i=1:n]
return res
If evec = true also the eigenvectors are returned as columns of the orthogonal matrix u.
The keyword iter, set by default to 30, selects the number of iterations of the qr algorithm before stopping.
"""
function uwgevp(c_t:: Matrix{uwreal}, c_tnot_inv::Matrix{uwreal}; iter::Int64 = 30, evec::Bool = false)
c = uwdot(c_tnot_inv, c_t) #matrix to diagonalize
return uwevp(c, iter = iter, evec = evec)
end end
""" @doc raw"""
uwevp(a::Matrix{uwreal}; iter = 30, evec = false) uweigvecs(a::Matrix{uwreal}; iter = 30)
uweigvecs(a::Matrix{uwreal}, b::Matrix{uwreal}; iter = 30)
This function computes the eigenvectors of a matrix of uwreal objects.
If a second matrix b is given as input, it returns the generalised eigenvectors instead.
It takes as input:
- a::Matrix{uwreal} : a matrix of uwreal
- b::Matrix{uwreal} : a matrix of uwreal, optional
It returns:
- res = Matrix{uwreal}: a matrix where each column is an eigenvector
Return the eigenvalues of the uwreal matrix a.
If evec = true also the eigenvectors are returned as columns of the orthogonal matrix u.
The keyword iter, set by default to 30, selects the number of iterations of the qr algorithm before stopping.
""" """
function uwevp(a::Matrix{uwreal}; iter = 30, evec = false) function uweigvecs(a::Matrix{uwreal}; iter = 30)
n = size(a,1) n = size(a,1)
if evec u = idty(n)
u = idty(n) for k in 1:iter
for k in 1:iter q_k, r_k = qr(a)
q_k, r_k = qr(a) a = uwdot(r_k, q_k)
a = uwdot(r_k, q_k) u = uwdot(u, q_k)
u = uwdot(u, q_k) end
end return u
return a, u end
else function uweigvecs(a::Matrix{uwreal}, b::Matrix{uwreal}; iter = 30)
for k in 1:iter c = uwdot(invert(b), a)
q_k, r_k = qr(a) n = size(c,1)
a = uwdot(r_k, q_k) u = idty(n)
end for k in 1:iter
return a q_k, r_k = qr(c)
c = uwdot(r_k, q_k)
u = uwdot(u, q_k)
end end
return u
end
@doc raw"""
uweigen(a::Matrix{uwreal}; iter = 30)
uweigen(a::Matrix{uwreal}, b::Matrix{uwreal}; iter = 30)
This function computes the eigenvalues and the eigenvectors of a matrix of uwreal objects.
If a second matrix b is given as input, it returns the generalised eigenvalues and eigenvectors instead.
It takes as input:
- a::Matrix{uwreal} : a matrix of uwreal
- b::Matrix{uwreal} : a matrix of uwreal, optional
It returns:
- evals = Vector{uwreal}: a vector where each elements is an eigenvalue
-evecs = Matrix{uwreal}: a matrix where the i-th column is the eigenvector of the i-th eigenvalue
"""
function uweigen(a::Matrix{uwreal}; iter = 30)
return uweigvals(a, iter=iter), uweigvecs(a, iter=iter)
end
function uweigen(a::Matrix{uwreal}, b::Matrix{uwreal}; iter = 30)
return uweigvals(a, b, iter=iter), uweigvecs(a, b, iter=iter)
end end
function norm_evec(evec::Matrix{uwreal}, ctnot::Matrix{uwreal}) function norm_evec(evec::Matrix{uwreal}, ctnot::Matrix{uwreal})
...@@ -190,9 +247,6 @@ function norm_evec(evec::Matrix{uwreal}, ctnot::Matrix{uwreal}) ...@@ -190,9 +247,6 @@ function norm_evec(evec::Matrix{uwreal}, ctnot::Matrix{uwreal})
aux_norm = (uwdot(evec[:,i], uwdot(ctnot, evec[:,i])).^2).^0.25 aux_norm = (uwdot(evec[:,i], uwdot(ctnot, evec[:,i])).^2).^0.25
res_evec[:,i] = 1 ./aux_norm .* evec[:,i] res_evec[:,i] = 1 ./aux_norm .* evec[:,i]
end end
#println("res_evec is ", res_evec)
#println("evec is ", evec)
#println(res_evec)
return res_evec return res_evec
end end
function get_diag(a::Matrix{uwreal}) function get_diag(a::Matrix{uwreal})
...@@ -200,6 +254,14 @@ function get_diag(a::Matrix{uwreal}) ...@@ -200,6 +254,14 @@ function get_diag(a::Matrix{uwreal})
res = [a[k, k] for k = 1:n] res = [a[k, k] for k = 1:n]
return res return res
end end
function get_diag(v::Vector{uwreal})
n = length(v)
res = idty(n)
for i =1:n
res[i,i] = v[i]
end
return res
end
""" """
...@@ -269,12 +331,10 @@ function make_householder(a::Vector{uwreal}) ...@@ -269,12 +331,10 @@ function make_householder(a::Vector{uwreal})
v[1] = uwreal(1.0) v[1] = uwreal(1.0)
H = idty(n) H = idty(n)
H = H - (2.0 / uwdot(v,v)) * uwdot(reshape(v, :,1), transpose(v)) #this last term is a vector product H = H - (2.0 / uwdot(v,v)) * uwdot(reshape(v, :,1), transpose(v)) #this last term is a vector product
#H = H - (2.0 / dot(value.(v),value.(v))) * uwdot(reshape(v, :,1), reshape(v, 1 ,:))
for i in 1:n for i in 1:n
for j in 1:n for j in 1:n
#println(H[i,j].ids)
if H[i,j]!= 0 && H[i,j]!=1 if H[i,j]!= 0 && H[i,j]!=1
#uwerr(H[i,j])
end end
end end
end end
...@@ -347,7 +407,6 @@ function backward_sub(u::Matrix{uwreal}, y::Vector{uwreal}) ...@@ -347,7 +407,6 @@ function backward_sub(u::Matrix{uwreal}, y::Vector{uwreal})
end end
x[i] = (y[i] - temp) /u[i,i] x[i] = (y[i] - temp) /u[i,i]
if x[i] !=0 if x[i] !=0
#uwerr(x[i])
end end
end end
...@@ -402,10 +461,10 @@ uwnorm(a::Vector{uwreal}) ...@@ -402,10 +461,10 @@ uwnorm(a::Vector{uwreal})
It returns the norm of a vector of uwreal It returns the norm of a vector of uwreal
""" """
function uwnorm(a::Vector{uwreal}) function uwnorm(a::Vector{uwreal}; wpm::Union{Dict{Int64,Vector{Float64}},Dict{String,Vector{Float64}}, Nothing}=nothing)
norm = sqrt(uwdot(a,a)) norm = sqrt(uwdot(a,a))
uwerr(norm) isnothing(wpm) ? uwerr(norm) : uwerr(norm, wpm)
return norm return norm
end end
""" """
...@@ -476,7 +535,6 @@ function Base.:*(x::uwreal, y::Matrix{uwreal}) ...@@ -476,7 +535,6 @@ function Base.:*(x::uwreal, y::Matrix{uwreal})
for j in 1:m for j in 1:m
res[i,j] = x * y[i,j] res[i,j] = x * y[i,j]
if res[i,j] !=0 && res[i,j] !=1 if res[i,j] !=0 && res[i,j] !=1
#uwerr(res[i,j])
end end
end end
end end
......
...@@ -73,7 +73,7 @@ end ...@@ -73,7 +73,7 @@ end
read_mesons(path::String, g1::Union{String, Nothing}=nothing, g2::Union{String, Nothing}=nothing; id::Union{Int64, Nothing}=nothing) read_mesons(path::String, g1::Union{String, Nothing}=nothing, g2::Union{String, Nothing}=nothing; id::Union{Int64, Nothing}=nothing)
read_mesons(path::Vector{String}, g1::Union{String, Nothing}=nothing, g2::Union{String, Nothing}=nothing; id::Union{Int64, Nothing}=nothing) read_mesons(path::Vector{String}, g1::Union{String, Nothing}=nothing, g2::Union{String, Nothing}=nothing; id::Union{Int64, Nothing}=nothing)
This faction read a mesons dat file at a given path and returns a vector of CData structures for different masses and Dirac structures. This function read a mesons dat file at a given path and returns a vector of CData structures for different masses and Dirac structures.
Dirac structures g1 and/or g2 can be passed as string arguments in order to filter correaltors. Dirac structures g1 and/or g2 can be passed as string arguments in order to filter correaltors.
ADerrors id can be specified as argument. If is not specified, the id is fixed according to the ensemble name (example: "H400"-> id = 400) ADerrors id can be specified as argument. If is not specified, the id is fixed according to the ensemble name (example: "H400"-> id = 400)
......
...@@ -247,6 +247,14 @@ fit_routine(model::Function, xdata::Array{uwreal}, ydata::Array{uwreal}, param:: ...@@ -247,6 +247,14 @@ fit_routine(model::Function, xdata::Array{uwreal}, ydata::Array{uwreal}, param::
Given a model function with a number param of parameters and an array of uwreal, Given a model function with a number param of parameters and an array of uwreal,
this function fit ydata with the given model and print fit information this function fit ydata with the given model and print fit information
The method return an array upar with the best fit parameters with their errors. The method return an array upar with the best fit parameters with their errors.
The flag wpm is an optional array of Float64 of lenght 4. The first three paramenters specify the criteria to determine
the summation windows:
vp[1]: The autocorrelation function is summed up to t = round(vp[1]).
vp[2]: The sumation window is determined using U. Wolff poposal with S_\tau = wpm[2]
vp[3]: The autocorrelation function Γ(t) is summed up a point where its error δΓ(t) is a factor vp[3] times larger than the signal.
An additional fourth parameter vp[4], tells ADerrors to add a tail to the error with \tau_{exp} = wpm[4].
Negative values of wpm[1:4] are ignored and only one component of wpm[1:3] needs to be positive.
'''@example '''@example
@. model(x,p) = p[1] + p[2] * exp(-(p[3]-p[1])*x) @. model(x,p) = p[1] + p[2] * exp(-(p[3]-p[1])*x)
@. model2(x,p) = p[1] + p[2] * x[:, 1] + (p[3] + p[4] * x[:, 1]) * x[:, 2] @. model2(x,p) = p[1] + p[2] * x[:, 1] + (p[3] + p[4] * x[:, 1]) * x[:, 2]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment