tpapp / SpectralKit.jl

@@ -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%
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.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading