Description
The example below attempts to project a Unitful.Quantity
differential onto a sparse array of Float64
using SparseArrays
using ChainRulesCore
using Unitful
using UnitfulChainRules # defines projection of quantities onto Floats/Complex{<:Float}
A = sprandn(5,5, 0.5)
pA = ProjectTo(A)
dx = randn((5,5)) * u"m"
pA(dx)
# Unitful error:
# ERROR: DimensionError: and m are not dimensionally compatible.
The error occurs here because we pre-allocate the nzvals
vector using project_type(project.element)
. However, project_type
doesn't take into account the value we are projecting, which, in the case of a Unitful.Quantity
, can mean that project_type(ProjectTo(A)) != eltype(A)
.
In the case of SparseMatrixCSC
, we can rewrite the projection without preallocating nzvals
using mapreduce
to get a type-stable pullback that doesn't use project_type
. In general, would it be better to get away without project_type
and write projections which infer the type based on the input types?
E- On closer inspection the mapreduce
solution runs into issues if the differential isn't a homogeneous type, project_type
may be a necessary solution here