Skip to content
Snippets Groups Projects
Commit 1c80d316 authored by Michel Juillard's avatar Michel Juillard
Browse files

initial files

parents
No related branches found
No related tags found
No related merge requests found
# This file is machine-generated - editing it directly is not advised
[[FastLapackInterface]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "a82ae140565456800a09c026f200e7046b247ac7"
repo-rev = "master"
repo-url = "https://git.dynare.org/julia-packages/fastlapackinterface.jl.git"
uuid = "29a986be-02c6-4525-aec4-84b980013641"
version = "0.1.0"
[[Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
[[LinearAlgebra]]
deps = ["Libdl"]
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
name = "PolynomialMatrixEquations"
uuid = "4f9d485d-518f-41ed-81c8-372cd804c93b"
authors = ["michel "]
version = "0.1.0"
[deps]
FastLapackInterface = "29a986be-02c6-4525-aec4-84b980013641"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
using FastLapackInterface.LinSolveAlgo: LinSolveWs, linsolve_core!
using LinearAlgebra
using LinearAlgebra.BLAS: gemm!
export CyclicReductionWs, cyclic_reduction!, cyclic_reduction_check
mutable struct CyclicReductionWs
linsolve_ws::LinSolveWs
ahat1::Matrix{Float64}
a1copy::Matrix{Float64}
m::Matrix{Float64,}
m00::SubArray{Float64}
m02::SubArray{Float64}
m20::SubArray{Float64}
m22::SubArray{Float64}
m1::Matrix{Float64}
m1_a0::SubArray{Float64}
m1_a2::SubArray{Float64}
m2::Matrix{Float64}
m2_a0::SubArray{Float64}
m2_a2::SubArray{Float64}
info::Int64
function CyclicReductionWs(n)
linsolve_ws = LinSolveWs(n)
ahat1 = Matrix{Float64}(undef, n,n)
a1copy = Matrix{Float64}(undef, n,n)
m = Matrix{Float64}(undef, 2*n,2*n)
m00 = view(m,1:n,1:n)
m02 = view(m,1:n,n .+ (1:n))
m20 = view(m,n .+ (1:n), 1:n)
m22 = view(m,n .+ (1:n),n .+(1:n))
m1 = Matrix{Float64}(undef, n, 2*n)
m1_a0 = view(m1,1:n,1:n)
m1_a2 = view(m1,1:n,n .+ (1:n))
m2 = Matrix{Float64}(undef, 2*n, n)
m2_a0 = view(m2, 1:n, 1:n)
m2_a2 = view(m2, n .+ (1:n), 1:n)
info = 0
new(linsolve_ws,ahat1,a1copy,m, m00, m02, m20, m22, m1, m1_a0, m1_a2, m2, m2_a0, m2_a2, info)
end
end
"""
cyclic_reduction!(x::Array{Float64},a0::Array{Float64},a1::Array{Float64},a2::Array{Float64},ws::CyclicReductionWs, cvg_tol::Float64, max_it::Int64)
Solve the quadratic matrix equation a0 + a1*x + a2*x*x = 0, using the cyclic reduction method from Bini et al. (???).
The solution is returned in matrix x. In case of nonconvergency, x is set to NaN and an error code is returned in ws.info
* info = 0: return OK
* info = 1: no stable solution (????)
* info = 2: multiple stable solutions (????)
# Example
```meta
DocTestSetup = quote
using CyclicReduction
n = 3
ws = CyclicReductionWs(n)
a0 = [0.5 0 0; 0 0.5 0; 0 0 0];
a1 = eye(n)
a2 = [0 0 0; 0 0 0; 0 0 0.8]
x = zeros(n,n)
end
```
```jldoctest
julia> display(names(CyclicReduction))
```
```jldoctest
julia> cyclic_reduction!(x,a0,a1,a2,ws,1e-8,50)
```
"""
function cyclic_reduction!(x::Array{Float64},a0::Array{Float64},a1::Array{Float64},a2::Array{Float64},ws::CyclicReductionWs, cvg_tol::Float64, max_it::Int64)
copyto!(x,a0)
copyto!(ws.ahat1,1,a1,1,length(a1))
@inbounds copyto!(ws.m1_a0, a0)
@inbounds copyto!(ws.m1_a2, a2)
@inbounds copyto!(ws.m2_a0, a0)
@inbounds copyto!(ws.m2_a2, a2)
it = 0
@inbounds while it < max_it
# ws.m = [a0; a2]*(a1\[a0 a2])
copyto!(ws.a1copy,a1)
linsolve_core!(ws.a1copy, ws.m1, ws.linsolve_ws)
gemm!('N','N',-1.0,ws.m2,ws.m1,0.0,ws.m)
@simd for i in eachindex(a1)
a1[i] += ws.m02[i] + ws.m20[i]
end
copyto!(ws.m1_a0, ws.m00)
copyto!(ws.m1_a2, ws.m22)
copyto!(ws.m2_a0, ws.m00)
copyto!(ws.m2_a2, ws.m22)
if any(isinf.(ws.m))
if norm(ws.m1_a0) < cvg_tol
ws.info = 2
else
ws.info = 1
end
fill!(x,NaN)
return
end
ws.ahat1 += ws.m20
crit = norm(ws.m1_a0,1)
if crit < cvg_tol
# keep iterating until condition on a2 is met
if norm(ws.m1_a2,1) < cvg_tol
break
end
end
it += 1
end
if it == max_it
if norm(ws.m1_a0) < cvg_tol
ws.info = 2
else
ws.info = 1
end
fill!(x,NaN)
return
else
linsolve_core!(ws.ahat1, x, ws.linsolve_ws)
@inbounds lmul!(-1.0,x)
ws.info = 0
end
end
function cyclic_reduction_check(x::Array{Float64,2},a0::Array{Float64,2}, a1::Array{Float64,2}, a2::Array{Float64,2},cvg_tol::Float64)
res = a0 + a1*x + a2*x*x
if (sum(sum(abs.(res))) > cvg_tol)
print("the norm of the residuals, ", res, ", compared to the tolerance criterion ",cvg_tol)
end
nothing
end
using FastLapackInterface.SchurAlgo: DggesWs, dgges!
using FastLapackInterface.LinSolveAlgo: LinSolveWs, linsolve_core!
using LinearAlgebra
using LinearAlgebra.BLAS
struct GsSolverWs
dgges_ws::DggesWs
linsolve_ws_11::LinSolveWs
linsolve_ws_22::LinSolveWs
D11::SubArray{Float64}
E11::SubArray{Float64}
vsr::Matrix{Float64}
Z11::SubArray{Float64}
Z12::SubArray{Float64}
Z21::SubArray{Float64}
Z22::SubArray{Float64}
tmp1::Matrix{Float64}
tmp2::Matrix{Float64}
tmp3::Matrix{Float64}
g1::Matrix{Float64}
g2::Matrix{Float64}
eigval::Vector{ComplexF64}
function GsSolverWs(d,e,n1)
dgges_ws = DggesWs(Ref{UInt8}('N'), Ref{UInt8}('N'), Ref{UInt8}('N'), e, d)
n = size(d,1)
n2 = n - n1
linsolve_ws_11 = LinSolveWs(n1)
linsolve_ws_22 = LinSolveWs(n2)
D11 = view(d,1:n1,1:n1)
E11 = view(e,1:n1,1:n1)
vsr = Matrix{Float64}(undef, n, n)
Z11 = view(vsr,1:n1,1:n1)
Z12 = view(vsr,1:n1,n1+1:n)
Z21 = view(vsr,n1+1:n,1:n1)
Z22 = view(vsr,n1+1:n,n1+1:n)
tmp1 = Matrix{Float64}(undef, n2, n1)
tmp2 = Matrix{Float64}(undef, n1, n1)
tmp3 = Matrix{Float64}(undef, n1, n1)
g1 = Matrix{Float64}(undef, n1, n1)
g2 = Matrix{Float64}(undef, n2, n1)
eigval = Vector{ComplexF64}(undef, n)
new(dgges_ws,linsolve_ws_11, linsolve_ws_22, D11,E11,vsr,Z11,Z12,Z21,Z22,tmp1,tmp2,tmp3,g1,g2, eigval)
end
end
struct UnstableSystemException <: Exception end
struct UndeterminateSystemException <: Exception end
#"""
# gs_solver!(ws::GsSolverWs,d::Matrix{Float64},e::Matrix{Float64},n1::Int64,qz_criterium)
#
#finds the unique stable solution for the following system:
#
#```
#d \left[\begin{array}{c}I\\g_2\end{array}\right]g_1 = e \left[\begin{array}{c}I\\g_2\end{array}\right]
#```
#The solution is returned in ``ws.g1`` and ``ws.g2``
#"""
function gs_solver!(ws::GsSolverWs,d::Matrix{Float64},e::Matrix{Float64},n1::Int64,qz_criterium::Float64)
dgges!('N', 'V', e, d, zeros(1,1), ws.vsr, ws.eigval, ws.dgges_ws)
nstable = ws.dgges_ws.sdim[]
if nstable < n1
throw(UnstableSystemException)
elseif nstable > n1
throw(UndeterminateSystemExcpetion)
end
ws.g2 .= ws.Z12'
linsolve_core!(ws.Z22', ws.g2, ws.linsolve_ws_22)
lmul!(-1.0,ws.g2)
ws.tmp2 .= ws.Z11'
ws.D11 .= view(d,1:nstable,1:nstable)
linsolve_core!(ws.D11', ws.tmp2, ws.linsolve_ws_11)
ws.E11 .= view(e,1:nstable,1:nstable)
ws.tmp3 .= ws.E11'
linsolve_core!(ws.Z11', ws.tmp3, ws.linsolve_ws_11)
gemm!('T','T',1.0,ws.tmp2,ws.tmp3,0.0,ws.g1)
end
module PolynomialMatrixEquations
include("CyclicReduction.jl")
export CyclicReductionWs, cyclic_reduction!, cyclic_reduction_check
include("GeneralizedSchurDecompositionSolver.jl")
export GsSolverWs, gs_solver!
end # module
using PolynomialMatrixEquations
using LinearAlgebra
using Test
n = 3
ws = CyclicReductionWs(n)
a0 = [0.5 0 0; 0 0.5 0; 0 0 0];
a1 = I(n) .+ zeros(n, n)
a2 = [0 0 0; 0 0 0; 0 0 0.8]
x = zeros(n,n)
cyclic_reduction!(x,a0,a1,a2,ws,1e-8,50)
@test ws.info == 0
@test a0 + a1*x + a2*x*x zeros(n, n)
display(x)
cyclic_reduction_check(x,a0,a1,a2,1e-8)
a0 = [0.5 0 0; 0 1.1 0; 0 0 0];
a1 .= I(n) .+ zeros(n, n)
a2 = [0 0 0; 0 0 0; 0 0 0.8]
cyclic_reduction!(x,a0,a1,a2,ws,1e-8,50)
@test ws.info == 1
a0 = [0.5 0 0; 0 0.5 0; 0 0 0];
a1 = I(n) .+ zeros(n, n)
a2 = [0 0 0; 0 0 0; 0 0 1.2]
cyclic_reduction!(x,a0,a1,a2,ws,1e-8,50)
@test ws.info == 2
using PolynomialMatrixEquations
using LinearAlgebra
using Random
using Test
Random.seed!(132)
n = 3
d_org = randn(n,n)
e_org = randn(n,n)
n1 = count(abs.(eigen(e, d).values) .< 1+1e-6)
ws = GsSolverWs(d, e, n1)
qz_criterium = 1.0 + 1e-6
d = copy(d_org)
e = copy(e_org)
gs_solver!(ws, d , e, n1 , qz_criterium)
#@test ws.info == 0
@test d_org*[I(n1); ws.g2]*ws.g1 e_org*[I(n1); ws.g2]
#=
cyclic_reduction_check(x,a0,a1,a2,1e-8)
a0 = [0.5 0 0; 0 1.1 0; 0 0 0];
a1 .= I(n) .+ zeros(n, n)
a2 = [0 0 0; 0 0 0; 0 0 0.8]
cyclic_reduction!(x,a0,a1,a2,ws,1e-8,50)
@test ws.info == 1
a0 = [0.5 0 0; 0 0.5 0; 0 0 0];
a1 = I(n) .+ zeros(n, n)
a2 = [0 0 0; 0 0 0; 0 0 1.2]
cyclic_reduction!(x,a0,a1,a2,ws,1e-8,50)
@test ws.info == 2
=#
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment