Skip to content
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

Solving Lyapunov equation for matrices given in Adjoint form #38177

Closed
wants to merge 1 commit into from
Closed

Solving Lyapunov equation for matrices given in Adjoint form #38177

wants to merge 1 commit into from

Conversation

guberger
Copy link
Contributor

There seems to be no consensus about what should be the Lyapunov equation: A'P+PA+Q=0 or AP+PA'+Q=0. For instance, Wikipedia says differently than the doc of lyap. For this reason, I think it would be nice to have an easy interface to switch between both definitions by allowing to put A' directly in the arguments of lyap.

There seems to be no consensus about what should be the Lyapunov equation: A'P+PA+Q=0 or AP+PA'+Q=0. For instance, Wikipedia says differently than the doc of `lyap`. For this reason, I think it would be nice to have an easy interface to switch between both definitions by allowing to put `A'` directly in the arguments of `lyap`.
@simonbyrne
Copy link
Contributor

Is it possible to compute it without first explicitly computing the adjoint?

@simonbyrne
Copy link
Contributor

In any case, this should have a test.

@simonbyrne simonbyrne added linear algebra Linear algebra needs tests Unit tests are required for this change labels Oct 30, 2020
@imciner2
Copy link
Contributor

imciner2 commented Nov 6, 2020

We always need to form the full matrices to pass into A and C for the lyap function to work, since it is only defined for StridedArray. This behavior seems similar to how other methods such as schur implement their dispatching on the more generic arrays.

@@ -1567,4 +1567,5 @@ function lyap(A::StridedMatrix{T}, C::StridedMatrix{T}) where {T<:BlasFloat}
rmul!(Q*(Y * adjoint(Q)), inv(scale))
end
lyap(A::StridedMatrix{T}, C::StridedMatrix{T}) where {T<:Integer} = lyap(float(A), float(C))
lyap(A::Adjoint{T,Matrix{T}}, C::Adjoint{T,Matrix{T}}) where T = lyap(Matrix(A), Matrix(C))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not generalize this to be an AbstractMatrix for both A and C:

lyap(A::AbstractMatrix{T}, C::AbstractMatrix{T}) where T = lyap(Matrix(A), Matrix(C))

That will allow for the adjoints to be passed in, as well as other matrix types to also be used (such as Tridiagonal, etc.) and make this bare-bones example code work (it will not currently work because it doesn't allow the Tridiagonal dispatch on the second argument).

A = randn(5,5)
B = randn(5,5)

lyap( A, Tridiagonal( B'*B ) )

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be

function lyap(A::AbstractMatrix, C::AbstractMatrix)
    T = promote_type(float(eltype(A)), float(eltype(C)))
    return lyap(copy_to_array(A, T), copy_to_array(C, T))
end

This will make sure that the matrices are strided and have float eltype, in one go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
linear algebra Linear algebra needs tests Unit tests are required for this change
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants