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