Just wanted to announce AffineMaps.
AffineMaps is a very lightweight package to express affine transforms (A * x + b, and variants). It provides function objects for add, mul, muladd and addmul. These support InverseFunctions.inverse
as well as ChangesOfVariables.logabsdetjacobian
and the Functors API.
Example:
using AffineMaps
using LinearAlgebra, InverseFunctions, ChangesOfVariables
A = rand(5, 5)
b = rand(5)
x = rand(5)
f = MulAdd(A, b)
y = f(x)
y ≈ A * x + b
inverse(f)(y) ≈ x
y, ladj = with_logabsdet_jacobian(f, x)
y ≈ A * x + b && ladj ≈ logabsdet(A)[1]
We have similar functionality in many packages of course, AffineMaps is mainly about offering this as very lightweight dependency.
8 Likes
Does/can it provide traits like islinear(f)
and isaffine(f)
for arbitrary functions?
These are occasionally useful, eg in FlexiMaps to determine when mapview(f, range)
can return a range vs array.
1 Like
Oh, I wasn’t aware of FlexiMaps (nice package!) but I’m happy to support it via an AffineMaps Pkg extension. Are islinear
and isaffine
originally defined in FlexiMaps, or are they owned by another package?
I can also add islinear
and isaffine
propagation to FunctionChains (need to properly announce that package sometime ).
1 Like
@aplavin AffineMaps and FunctionChains support FlexiMaps.islinear and FlexiMaps.isaffine now.
Great!
I was also looking for a more natural way to put those islinear
/isaffine
traits, FlexiMaps
seems very adhoc for this…
Can you comment on how the packages compares with the AffineMap from CoordinateTransformations.jl?
2 Likes
@evetion: Can you comment on how the packages compares with the AffineMap from CoordinateTransformations.jl?
I would say it’s more fully featured, regarding to the affine maps itself - AffineMaps offers both rotate-then-translate (MulAdd
) and translate-then-rotate (AddMul
), it also supports InverseFunctions, ChangesOfVariables, FlexiMaps and Functors (so it cal also be used as ML layers). On the other hand the scope of CoordinateTransformations as a whole is wider, and there’s probably also some things in CoordinateTransformations.AffineMap
that AffineMaps.jl lacks.
Ideally, one could see if AffineMaps.jl does lack anything that CoordinateTransformations.jl needs (which is likely), add it, and then have CoordinateTransformations.jl depend on AffineMaps.jl and get it’s maps from there. The problem is that CoordinateTransformations.AffineMap
is a subtype of CoordinateTransformations.Transformation
, so that won’t work. We’d need a AbstractCoordinateTransformations.jl package or so …
Currently CoordinateTransformations is also a much heavier dependency than AffineMaps, due to StaticArrays, but I think CoordinateTransformations could move the StaticArrays code into a Pkg extension. CoordinateTransformations itself shouldn’t be that heavy.
There’s also some discussion here: Comparison to CoordinateTransformations.jl? · Issue #1 · oschulz/AffineMaps.jl · GitHub
3 Likes