Make grids iterable, fix types, incidental changes.
Showing 4 of 11 files from the diff.
src/generic_api.jl
changed.
src/transformations.jl
changed.
src/chebyshev.jl
changed.
src/smolyak_api.jl
changed.
Other files ignored by Codecov
test/test_chebyshev.jl
has changed.
docs/src/index.md
has changed.
test/test_smolyak.jl
has changed.
test/test_transformations.jl
has changed.
Project.toml
has changed.
test/test_generic_api.jl
has changed.
test/utilities.jl
has changed.
@@ -64,8 +64,8 @@
Loading
64 | 64 | Return an iterable with known element type and length (`Base.HasEltype()`, |
|
65 | 65 | `Base.HasLength()`) of basis functions in `basis` evaluated at `x`. |
|
66 | 66 | ||
67 | - | Univariate bases operate on real numbers, while for multivariate bases, |
|
68 | - | `StaticArrays.SVector` is preferred for performance, though all `<:AbstractVector` types |
|
67 | + | Univariate bases operate on real numbers, while for multivariate bases, `Tuple`s or |
|
68 | + | `StaticArrays.SVector` are preferred for performance, though all `<:AbstractVector` types |
|
69 | 69 | should work. |
|
70 | 70 | ||
71 | 71 | Methods are type stable. |
@@ -141,34 +141,19 @@
Loading
141 | 141 | """ |
|
142 | 142 | struct InteriorGrid2 <: AbstractGrid end |
|
143 | 143 | ||
144 | - | """ |
|
145 | - | $(SIGNATURES) |
|
146 | - | ||
147 | - | Return a gridpoint for collocation, with `1 ≤ i ≤ dimension(basis)`. |
|
148 | - | ||
149 | - | `T` is used *as a hint* for the element type of grid coordinates, and defaults to `Float64`. |
|
150 | - | The actual type can be broadened as required. Methods are type stable. |
|
151 | - | ||
152 | - | !!! note |
|
153 | - | Not all grids have this method defined, especially if it is impractical. See |
|
154 | - | [`grid`](@ref), which is part of the API, this function isn't. |
|
155 | - | """ |
|
156 | 144 | gridpoint(basis, i) = gridpoint(Float64, basis, i) |
|
157 | 145 | ||
158 | 146 | """ |
|
159 | 147 | `$(FUNCTIONNAME)([T], basis)` |
|
160 | 148 | ||
161 | - | Return a grid recommended for collocation, with `dimension(basis)` elements. |
|
149 | + | Return an iterator for the grid recommended for collocation, with `dimension(basis)` |
|
150 | + | elements. |
|
162 | 151 | ||
163 | - | `T` is used *as a hint* for the element type of grid coordinates, and defaults to `Float64`. |
|
164 | - | The actual type can be broadened as required. Methods are type stable. |
|
152 | + | `T` for the element type of grid coordinates, and defaults to `Float64`. |
|
153 | + | Methods are type stable. |
|
165 | 154 | """ |
|
166 | 155 | grid(basis) = grid(Float64, basis) |
|
167 | 156 | ||
168 | - | function grid(::Type{T}, basis) where {T<:Real} |
|
169 | - | map(i -> gridpoint(T, basis, i), 1:dimension(basis)) |
|
170 | - | end |
|
171 | - | ||
172 | 157 | """ |
|
173 | 158 | $(SIGNATURES) |
|
174 | 159 |
@@ -91,15 +91,11 @@
Loading
91 | 91 | (0.0,2.0) ↔ (-1, 1) [linear transformation] |
|
92 | 92 | (2,∞) ↔ (-1, 1) [rational transformation with scale 3] |
|
93 | 93 | ||
94 | - | julia> x = from_pm1(ct, SVector(0.4, 0.5)) |
|
95 | - | 2-element SVector{2, Float64} with indices SOneTo(2): |
|
96 | - | 1.4 |
|
97 | - | 11.0 |
|
94 | + | julia> x = from_pm1(ct, (0.4, 0.5)) |
|
95 | + | (1.4, 11.0) |
|
98 | 96 | ||
99 | 97 | julia> y = to_pm1(ct, x) |
|
100 | - | 2-element SVector{2, Float64} with indices SOneTo(2): |
|
101 | - | 0.3999999999999999 |
|
102 | - | 0.5 |
|
98 | + | (0.3999999999999999, 0.5) |
|
103 | 99 | ``` |
|
104 | 100 | """ |
|
105 | 101 | function coordinate_transformations(transformations::Tuple) |
@@ -108,20 +104,22 @@
Loading
108 | 104 | ||
109 | 105 | coordinate_transformations(transformations...) = coordinate_transformations(transformations) |
|
110 | 106 | ||
111 | - | function to_pm1(ct::CoordinateTransformations, x::SVector{N}) where N |
|
112 | - | SVector{N}(map((t, x) -> to_pm1(t, x), ct.transformations, Tuple(x))) |
|
107 | + | function to_pm1(ct::CoordinateTransformations, x::Tuple) |
|
108 | + | @argcheck length(ct.transformations) == length(x) |
|
109 | + | map((t, x) -> to_pm1(t, x), ct.transformations, x) |
|
113 | 110 | end |
|
114 | 111 | ||
115 | 112 | function to_pm1(ct::CoordinateTransformations, x::AbstractVector) |
|
116 | - | to_pm1(ct, SVector{length(ct.transformations)}(x)) |
|
113 | + | to_pm1(ct, Tuple(x)) |
|
117 | 114 | end |
|
118 | 115 | ||
119 | - | function from_pm1(ct::CoordinateTransformations, x::SVector{N}) where N |
|
120 | - | SVector{N}(map((t, x) -> from_pm1(t, x), ct.transformations, Tuple(x))) |
|
116 | + | function from_pm1(ct::CoordinateTransformations, x::Tuple) |
|
117 | + | @argcheck length(ct.transformations) == length(x) |
|
118 | + | map((t, x) -> from_pm1(t, x), ct.transformations, x) |
|
121 | 119 | end |
|
122 | 120 | ||
123 | 121 | function from_pm1(ct::CoordinateTransformations, x::AbstractVector) |
|
124 | - | from_pm1(ct, SVector{length(ct.transformations)}(x)) |
|
122 | + | from_pm1(ct, Tuple(x)) |
|
125 | 123 | end |
|
126 | 124 | ||
127 | 125 | #### |
@@ -73,28 +73,58 @@
Loading
73 | 73 | #### grids |
|
74 | 74 | #### |
|
75 | 75 | ||
76 | + | """ |
|
77 | + | $(SIGNATURES) |
|
78 | + | ||
79 | + | Return a gridpoint for collocation, with `1 ≤ i ≤ dimension(basis)`. |
|
80 | + | ||
81 | + | `T` is used *as a hint* for the element type of grid coordinates, and defaults to `Float64`. |
|
82 | + | The actual type can be broadened as required. Methods are type stable. |
|
83 | + | ||
84 | + | !!! note |
|
85 | + | Not all grids have this method defined, especially if it is impractical. See |
|
86 | + | [`grid`](@ref), which is part of the API, this function isn't. |
|
87 | + | """ |
|
76 | 88 | function gridpoint(::Type{T}, basis::Chebyshev{InteriorGrid}, i::Integer) where {T <: Real} |
|
77 | 89 | @unpack N = basis |
|
78 | - | @argcheck 1 ≤ i ≤ N # FIXME use boundscheck |
|
79 | - | sinpi((N - 2 * i + 1) / T(2 * N)) # use formula Xu (2016) |
|
90 | + | @argcheck 1 ≤ i ≤ N # FIXME use boundscheck |
|
91 | + | sinpi((N - 2 * i + 1) / T(2 * N))::T # use formula Xu (2016) |
|
80 | 92 | end |
|
81 | 93 | ||
82 | 94 | function gridpoint(::Type{T}, basis::Chebyshev{EndpointGrid}, i::Integer) where {T <: Real} |
|
83 | 95 | @unpack N = basis |
|
84 | 96 | @argcheck 1 ≤ i ≤ N # FIXME use boundscheck |
|
85 | 97 | if N == 1 |
|
86 | - | cospi(1/T(2)) # 0.0 as a fallback, even though it does not have endpoints |
|
98 | + | cospi(1/T(2))::T # 0.0 as a fallback, even though it does not have endpoints |
|
87 | 99 | else |
|
88 | - | cospi((N - i) ./ T(N - 1)) |
|
100 | + | cospi((N - i) ./ T(N - 1))::T |
|
89 | 101 | end |
|
90 | 102 | end |
|
91 | 103 | ||
92 | 104 | function gridpoint(::Type{T}, basis::Chebyshev{InteriorGrid2}, i::Integer) where {T <: Real} |
|
93 | 105 | @unpack N = basis |
|
94 | 106 | @argcheck 1 ≤ i ≤ N # FIXME use boundscheck |
|
95 | - | cospi(((N - i + 1) ./ T(N + 1))) |
|
107 | + | cospi(((N - i + 1) ./ T(N + 1)))::T |
|
108 | + | end |
|
109 | + | ||
110 | + | struct ChebyshevGridIterator{T,B} |
|
111 | + | basis::B |
|
112 | + | end |
|
113 | + | ||
114 | + | Base.eltype(::Type{<:ChebyshevGridIterator{T}}) where {T} = T |
|
115 | + | ||
116 | + | Base.length(itr::ChebyshevGridIterator) = dimension(itr.basis) |
|
117 | + | ||
118 | + | function Base.iterate(itr::ChebyshevGridIterator{T}, i = 1) where {T} |
|
119 | + | @unpack basis = itr |
|
120 | + | if i ≤ dimension(basis) |
|
121 | + | gridpoint(T, basis, i), i + 1 |
|
122 | + | else |
|
123 | + | nothing |
|
124 | + | end |
|
96 | 125 | end |
|
97 | 126 | ||
127 | + | grid(::Type{T}, basis::B) where {T<:Real,B<:Chebyshev} = ChebyshevGridIterator{T,B}(basis) |
|
98 | 128 | ||
99 | 129 | #### |
|
100 | 130 | #### augmenting |
@@ -237,12 +237,29 @@
Loading
237 | 237 | SmolyakProduct(smolyak_indices, univariate_bases_at) |
|
238 | 238 | end |
|
239 | 239 | ||
240 | + | struct SmolyakGridIterator{T,I,S} |
|
241 | + | smolyak_indices::I |
|
242 | + | sources::S |
|
243 | + | end |
|
244 | + | ||
245 | + | Base.eltype(::Type{<:SmolyakGridIterator{T}}) where {T} = T |
|
246 | + | ||
247 | + | Base.length(itr::SmolyakGridIterator) = length(itr.smolyak_indices) |
|
248 | + | ||
240 | 249 | function grid(::Type{T}, |
|
241 | 250 | smolyak_basis::SmolyakBasis{<:SmolyakIndices{N,H}}) where {T<:Real,N,H} |
|
242 | 251 | @unpack smolyak_indices, univariate_parent = smolyak_basis |
|
243 | - | x = sacollect(SVector{H}, gridpoint(T, univariate_parent, i) |
|
244 | - | for i in SmolyakGridShuffle(univariate_parent.grid_kind, H)) |
|
245 | - | [SVector{N}(map(i -> x[i], ι)) for ι in smolyak_indices] |
|
252 | + | sources = sacollect(SVector{H}, gridpoint(T, univariate_parent, i) |
|
253 | + | for i in SmolyakGridShuffle(univariate_parent.grid_kind, H)) |
|
254 | + | SmolyakGridIterator{NTuple{N,T},typeof(smolyak_indices),typeof(sources)}(smolyak_indices, sources) |
|
255 | + | end |
|
256 | + | ||
257 | + | function Base.iterate(itr::SmolyakGridIterator, state...) |
|
258 | + | @unpack smolyak_indices, sources = itr |
|
259 | + | result = iterate(smolyak_indices, state...) |
|
260 | + | result ≡ nothing && return nothing |
|
261 | + | ι, state′ = result |
|
262 | + | map(i -> sources[i], ι), state′ |
|
246 | 263 | end |
|
247 | 264 | ||
248 | 265 | """ |
Files | Coverage |
---|---|
src | 86.21% |
Project Totals (7 files) | 86.21% |
3091051201
3091051201
3091173169
3091051201
3091173169
3091173169
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file.
The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files.
The size and color of each slice is representing the number of statements and the coverage, respectively.