How to store many variables of type AffineMap?

Dear community.

This is following up on an earlier question of me (here). I opened this thread, because my current question no longer fits the original one.

My problem is that I need to loop through a stack of a few hundred slices. I would like to store the AffineMap generated by RegisterQD.jl in such a way that I can address the according map with an index related to the image of the stack in a later part of my script. So I am basically looking for some kind of Array/Matrix/Collection-variable that holds my AffineMaps.

However, I am having trouble creating or using said array. I can create it, but cannot assign values to it.

julia> using CoordinateTransformations #necessary to get the AffineMap type in this sample
julia> tfm=AffineMap([0 0;0 0],[0,0]) #the values do not matter, it does not even work with others
AffineMap([0 0; 0 0], [0, 0])

julia> tfmarr=Array{AffineMap,1}

julia> tfmarr[1]=tfm #trying to assign a value to the array
ERROR: MethodError: no method matching setindex!(::Type{Array{AffineMap,1}}, ::AffineMap{Array{Int64,2},Array{Int64,1}}, ::Int64)
 [1] top-level scope at none:0

I usually generate arrays using the zeros() command. But this fails for AffineMaps:

julia> tfmarr=zeros(AffineMap,1500)
ERROR: MethodError: no method matching zero(::Type{AffineMap})
Closest candidates are:
  zero(::Type{LibGit2.GitHash}) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/LibGit2/src/oid.jl:220
  zero(::Type{Pkg.Resolve.VersionWeights.VersionWeight}) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/Pkg/src/resolve/VersionWeights.jl:19
  zero(::Type{Pkg.Resolve.MaxSum.FieldValues.FieldValue}) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/Pkg/src/resolve/FieldValues.jl:44
 [1] zeros(::Type{AffineMap}, ::Tuple{Int64}) at ./array.jl:467
 [2] zeros(::Type{AffineMap}, ::Int64) at ./array.jl:464
 [3] top-level scope at none:0

Where am I going wrong? Are arrays just not a way to store AffineMaps? If this is the case, how do I store them properly for later use in the script (and possible saving)?


julia> using CoordinateTransforms

julia> tfm_array = [AffineMap([0 0; 0 0], [0, 0]) for _ in 1:5]
5-element Array{AffineMap{Array{Int64,2},Array{Int64,1}},1}:
 AffineMap([0 0; 0 0], [0, 0])
 AffineMap([0 0; 0 0], [0, 0])
 AffineMap([0 0; 0 0], [0, 0])
 AffineMap([0 0; 0 0], [0, 0])
 AffineMap([0 0; 0 0], [0, 0])

julia> tfm_array[1] = AffineMap([1 2; 3 4], [3, 2])
AffineMap([1 2; 3 4], [3, 2])

julia> tfm_array
5-element Array{AffineMap{Array{Int64,2},Array{Int64,1}},1}:
 AffineMap([1 2; 3 4], [3, 2])
 AffineMap([0 0; 0 0], [0, 0])
 AffineMap([0 0; 0 0], [0, 0])
 AffineMap([0 0; 0 0], [0, 0])
 AffineMap([0 0; 0 0], [0, 0])


Thank you, that did the trick.
Interestingly, I now also see something similar in the updated version of “Julia by example”. Seems I have missed this before.

For others trying to replicate @nilshg’s solution: Make sure the first command is using CoordinateTransformations. CoordianteTransforms doesn’t seem to exist at all.


I meanwhile figured that there is a problem in this solution: The types are wrong.
The above solution generates an AffineMap with type Int64. However, we need
AffineMap{RotMatrix{2,Float64,4},StaticArrays.SArray{Tuple{2},Float64,1,2}}. If I want to assign a variable of this type to the Int64-type array, I get a “cannot convert”-error.

My current workaround is to call the registering command from my previous thread once, thereby generating the correct type for the AffineMap (stored in a variable called tfm). I then modified the above solution to this: tfm_array = [tfm for _ in 1:size(inputimg,3)]. This generates an array of the correct type. I then loop through my stack and fill the array.