|
40 | 40 | return Expr(:tuple, [:(single_seed(Partials{N,V}, Val{$i}())) for i in 1:N]...) |
41 | 41 | end |
42 | 42 |
|
43 | | -function seed!(duals::AbstractArray{Dual{T,V,N}}, x, |
44 | | - seed::Partials{N,V} = zero(Partials{N,V})) where {T,V,N} |
45 | | - duals .= Dual{T,V,N}.(x, Ref(seed)) |
46 | | - return duals |
47 | | -end |
48 | | - |
49 | | -function seed!(duals::AbstractArray{Dual{T,V,N}}, x, |
50 | | - seeds::NTuple{N,Partials{N,V}}) where {T,V,N} |
51 | | - dual_inds = 1:N |
52 | | - duals[dual_inds] .= Dual{T,V,N}.(view(x,dual_inds), seeds) |
53 | | - return duals |
54 | | -end |
55 | | - |
56 | | -# Triangular matrices |
57 | | -function _nonzero_indices(x::UpperTriangular) |
| 43 | +# Only seed indices that are structurally non-zero |
| 44 | +_structural_nonzero_indices(x::AbstractArray) = eachindex(x) |
| 45 | +function _structural_nonzero_indices(x::UpperTriangular) |
58 | 46 | n = size(x, 1) |
59 | 47 | return (CartesianIndex(i, j) for j in 1:n for i in 1:j) |
60 | 48 | end |
61 | | -function _nonzero_indices(x::LowerTriangular) |
| 49 | +function _structural_nonzero_indices(x::LowerTriangular) |
62 | 50 | n = size(x, 1) |
63 | 51 | return (CartesianIndex(i, j) for j in 1:n for i in j:n) |
64 | 52 | end |
65 | | -function seed!(duals::Union{LowerTriangular{Dual{T,V,N}},UpperTriangular{Dual{T,V,N}}}, x, seeds::NTuple{N,Partials{N,V}}) where {T,V,N} |
66 | | - for (idx, seed) in zip(_nonzero_indices(duals), seeds) |
| 53 | +_structural_nonzero_indices(x::Diagonal) = diagind(x) |
| 54 | + |
| 55 | +function seed!(duals::AbstractArray{Dual{T,V,N}}, x, |
| 56 | + seed::Partials{N,V} = zero(Partials{N,V})) where {T,V,N} |
| 57 | + if eachindex(duals) != eachindex(x) |
| 58 | + throw(ArgumentError("indices of input array and array of duals are not identical")) |
| 59 | + end |
| 60 | + for idx in _structural_nonzero_indices(duals) |
67 | 61 | duals[idx] = Dual{T,V,N}(x[idx], seed) |
68 | 62 | end |
69 | 63 | return duals |
70 | 64 | end |
71 | 65 |
|
| 66 | +function seed!(duals::AbstractArray{Dual{T,V,N}}, x, |
| 67 | + seeds::NTuple{N,Partials{N,V}}) where {T,V,N} |
| 68 | + if eachindex(duals) != eachindex(x) |
| 69 | + throw(ArgumentError("indices of input array and array of duals are not identical")) |
| 70 | + end |
| 71 | + for (i, idx) in enumerate(_structural_nonzero_indices(duals)) |
| 72 | + duals[idx] = Dual{T,V,N}(x[idx], seeds[i]) |
| 73 | + end |
| 74 | + return duals |
| 75 | +end |
| 76 | + |
72 | 77 | function seed!(duals::AbstractArray{Dual{T,V,N}}, x, index, |
73 | 78 | seed::Partials{N,V} = zero(Partials{N,V})) where {T,V,N} |
| 79 | + if eachindex(duals) != eachindex(x) |
| 80 | + throw(ArgumentError("indices of input array and array of duals are not identical")) |
| 81 | + end |
74 | 82 | offset = index - 1 |
75 | | - dual_inds = (1:N) .+ offset |
76 | | - duals[dual_inds] .= Dual{T,V,N}.(view(x, dual_inds), Ref(seed)) |
| 83 | + idxs = Iterators.drop(_structural_nonzero_indices(duals), offset) |
| 84 | + for idx in idxs |
| 85 | + duals[idx] = Dual{T,V,N}(x[idx], seed) |
| 86 | + end |
77 | 87 | return duals |
78 | 88 | end |
79 | 89 |
|
80 | 90 | function seed!(duals::AbstractArray{Dual{T,V,N}}, x, index, |
81 | 91 | seeds::NTuple{N,Partials{N,V}}, chunksize = N) where {T,V,N} |
| 92 | + if eachindex(duals) != eachindex(x) |
| 93 | + throw(ArgumentError("indices of input array and array of duals are not identical")) |
| 94 | + end |
82 | 95 | offset = index - 1 |
83 | | - seed_inds = 1:chunksize |
84 | | - dual_inds = seed_inds .+ offset |
85 | | - duals[dual_inds] .= Dual{T,V,N}.(view(x, dual_inds), getindex.(Ref(seeds), seed_inds)) |
| 96 | + idxs = Iterators.drop(_structural_nonzero_indices(duals), offset) |
| 97 | + for (i, idx) in enumerate(idxs) |
| 98 | + i > chunksize && break |
| 99 | + duals[idx] = Dual{T,V,N}(x[idx], seeds[i]) |
| 100 | + end |
86 | 101 | return duals |
87 | 102 | end |
0 commit comments