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

transpose(::Basis) as opposed to adjoint(::Basis) #36

Open
jagot opened this issue Feb 19, 2021 · 3 comments
Open

transpose(::Basis) as opposed to adjoint(::Basis) #36

jagot opened this issue Feb 19, 2021 · 3 comments

Comments

@jagot
Copy link
Member

jagot commented Feb 19, 2021

For discretization of non-Hermitian operators in non-uniform finite-differences, it can be advantageous to work with separate left- and right-vectors, where the inner product is computed as transpose(left)*right (i.e. the first argument is not conjugated), instead of u'*S*u. The reason is that the metric S is dense, and it's more efficient to work with a biorthogonal set of vectors.

How should this be represented in the ContinuumArrays framework? I'm thinking something like this:

R = Basis(...)

u = ...
# The current way of computing the norm (inner product) would be
u'*R'*R*u
# or equivalently
dot(u, R'R, u) # R'R is dense

uc = (R'R)*u # Left vector
# The new way of computing norms/inner products
transpose(uc)*transpose(R)*R*u
# or equivalently
dotu(uc, u)

I am not entirely satisfied by this, ideally one would always write an inner product as dot(u, S, v), and this would figure out if u is a left-vector that should be transposed in the biorthogonal case or adjointed in the normal case.

@dlfivefifty
Copy link
Member

Why not just add dotu(u, A, v)?

@jagot
Copy link
Member Author

jagot commented Feb 19, 2021

Basically, I envision being able to run the same calculation in two "modes":

  • Hermitian mode where one pretends that left-vectors are simply the adjoints of right-vectors and the metric is dense (or some diagonal approximation; this will lower order of convergence), or
  • non-Hermitian mode where left-vectors are computed explicitly and the metric is the identity matrix by construction.
V = Matrix{ComplexF64}(...) # Right-vectors
# Right vectors and metric
U,S = if mode == :hermitian
    adjoint(V), R'R
else
    (R'R)*V, Diagonal(...)
end

for i = 1:steps
    propagate_right_vectors!(V)
    mode == :non_hermitian && propagate_left_vectors!(U)

    u = transpose(view(U, m, :)) # Some left-vector
    v = view(V, :, n) # Some right-vector
    uv = dot(u, S, v) # Correct inner product, regardless of propagation mode
end

@jagot
Copy link
Member Author

jagot commented Feb 19, 2021

Maybe this already works, as-is?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants