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
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.
Correct, this would most probably be the way to go if OP 's struct
is part of a public API.
Maybe using ComponentArrays is faster than implementing the AbstractVector yourself?
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?
Yeah I now get it, thanks a lot!