LinearMaps.jl

Is it possible to use Linearmaps on custom data types? I have a struct data type v and wish to construct a function wrapped linear map A that can act on v like A*v. Would love to know how I could do this! Thanks in advance

I believe I somewhat understand how LinearMaps is working, but Iā€™m not sure if I understand your question correctly. Therefore let us start with a simple example

using LinearMaps

A = rand(2, 2)
fA!(y, x) = y .= A * x
LA = LinearMap{Float64}(fA!, 2, 2)
v = rand(2)
@assert LA * v ā‰ˆ A * v

Is that similar to what you are looking for?

Edit: if v is a struct of your own making, you could either

  • support converting it to a vector
  • or add a Base.*(LinearMap, YourStruct) method
1 Like

You can also make the struct a subtype of AbstractVector and implement the interface for Arrays. But probably adding Base.*(LinearMap, YourStruct) is easier/better.

2 Likes

Correct, this would most probably be the way to go if OP 's struct is part of a public API.

1 Like

Maybe using ComponentArrays is faster than implementing the AbstractVector yourself?

1 Like

Thanks, yes that is what I am looking for. Are you suggesting that I define the action of the linearmap inside Base.*(LinearMap, struct)? I already have a function based linearmap(like the fA!+LA in your example) that takes in the struct and defines the action of the function/linearmap. Since I have already defined the action of the linearmap / * here I am not exactly sure what to define under Base. *(). Thoughts?

Iā€™m still not sure;) But then the natural continuation is something like

using LinearMaps
using StaticArrays

A = rand(2, 2)
fA!(y, x) = y .= A * x
LA = LinearMap{Float64}(fA!, 2, 2)
v = rand(2)
@assert LA * v ā‰ˆ A * v

struct SpecialVector
    v1::Float64
    v2::Float64
end

import Base.*
function *(l::LinearMap{Float64}, v::SpecialVector)
    l * [v.v1, v.v2]
end

v = rand(2)
sv = SpecialVector(v...)
@assert LA * sv ā‰ˆ A * v

Does this help?

1 Like

Yeah I now get it, thanks a lot!