Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added new methods to similar_arr_type to deal with SubArray ReshapedA… #18

Merged
merged 8 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Manifest.toml
test/Manifest.toml
exmaples/Manifest.toml

docs/build/
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "NDTools"
uuid = "98581153-e998-4eef-8d0d-5ec2c052313d"
authors = ["Rainer Heintzmann <[email protected]>", "Felix Wechsler <[email protected]>"]
version = "0.6.0"
version = "0.7.0"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand Down
62 changes: 38 additions & 24 deletions src/type_tools.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export real_arr_type, complex_arr_type, similar_arr_type

"""
real_arr_type(::Type{TA}) where {TA<:AbstractArray}
real_arr_type(::Type{TA}, dims::Val = Val(N)) where {TA<:AbstractArray}

returns the same array type but using `(real(eltype()))` as the element type
# Arguments
+ `TA`: The array type to convert to an eltype of `real(eltype(TA))`
+ `dims`: The number of dimensions of the returned array type
+ `dims`: The (optional) number of dimensions of the returned array type, default is Val(N) or Val(1) depending on whether the dimensions of the array are inferrable

# Example
```jldoctest
Expand All @@ -16,26 +16,26 @@ Vector{Float64} (alias for Array{Float64, 1})
julia> real_arr_type(Array{ComplexF64,3})
Array{Float64, 3}

julia> real_arr_type(Array{ComplexF64,3}, dims=4)
julia> real_arr_type(Array{ComplexF64,3}, dims=Val(4))
Array{Float64, 4}
```
"""
function real_arr_type(::Type{TA}; dims=N) where {T,N, TA<:AbstractArray{T,N}}
similar_arr_type(TA, dtype=real(eltype(TA)), dims=dims)
function real_arr_type(::Type{TA}, dims::Val=Val(N)) where {T,N, TA<:AbstractArray{T,N}}
similar_arr_type(TA, real(eltype(TA)), dims)
end

function real_arr_type(::Type{TA}; dims=1) where {TA<:AbstractArray}
similar_arr_type(TA, dtype=real(eltype(TA)), dims=dims)
function real_arr_type(::Type{TA}, dims::Val=Val(1)) where {TA<:AbstractArray}
similar_arr_type(TA, real(eltype(TA)), dims)
end

"""
complex_arr_type(::Type{TA}) where {TA<:AbstractArray}
complex_arr_type(::Type{TA}, dims::Val = VLa(N)) where {TA<:AbstractArray}

returns the same array type but using `(complex(eltype()))` as the element type
returns the same array type but using `(complex(eltype()))` as the element type, default is Val(N) or Val(1) depending on whether the dimensions of the array are inferrable

# Arguments
+ `TA`: The array type to convert to an eltype of `complex(eltype(TA))`
+ `dims`: The number of dimensions of the returned array type
+ `dims`: The (optional) number of dimensions of the returned array type

# Example
```jldoctest
Expand All @@ -45,28 +45,28 @@ Vector{ComplexF32} (alias for Array{Complex{Float32}, 1})
julia> complex_arr_type(Array{Float32,3})
Array{ComplexF32, 3}

julia> complex_arr_type(Array{Float32,3},dims=1)
julia> complex_arr_type(Array{Float32,3}, Val(1))
Vector{ComplexF32} (alias for Array{Complex{Float32}, 1})
```
"""
function complex_arr_type(::Type{TA}; dims=N) where {T,N, TA<:AbstractArray{T,N}}
similar_arr_type(TA, dtype=complex(eltype(TA)), dims=dims)
function complex_arr_type(::Type{TA}, dims::Val=Val(N)) where {T,N, TA<:AbstractArray{T,N}}
similar_arr_type(TA, complex(eltype(TA)), dims)
end

function complex_arr_type(::Type{TA}; dims=1) where {TA<:AbstractArray}
similar_arr_type(TA, dtype=complex(eltype(TA)), dims=dims)
function complex_arr_type(::Type{TA}, dims::Val=Val(1)) where {TA<:AbstractArray}
similar_arr_type(TA, complex(eltype(TA)), dims)
end


"""
similar_arr_type(::Type{TA}) where {TA<:AbstractArray}
similar_arr_type(::Type{TA}, , T2::Type=Type{T}, N2::Val=Val(N)) where {TA<:AbstractArray}

returns a similar array type but using as TA, but eltype and ndims can be changed.

# Arguments
+ `TA`: The array type to convert to an eltype of `complex(eltype(TA))`
+ `dims`: The number of dimensions of the returned array type
+ `dtype`: The `eltype()` of the returned array type.
+ `T2`: The `eltype()` of the returned array type. Use `eltype(TA)` to keep the same type. Default is `eltype(TA)`.
+ `N2`: The number of dimensions of the returned array type. Please specify this as a ::Val type to be type-stable. Default is Val(1).

# Example

Expand All @@ -77,14 +77,28 @@ Vector{ComplexF64} (alias for Array{Complex{Float64}, 1})
julia> similar_arr_type(Array{ComplexF64,3})
Array{ComplexF64, 3}

julia> similar_arr_type(Array{ComplexF64,3}, dims=2, dtype=Int)
julia> similar_arr_type(Array{ComplexF64,3}, Int, Val(2))
Matrix{Int64} (alias for Array{Int64, 2})
```
"""
function similar_arr_type(::Type{TA}; dims=N, dtype=T) where {T,N, TA<:AbstractArray{T,N}}
typeof(similar(TA(undef, ntuple(x->0, N)), dtype, ntuple(x->0, dims)))
function similar_arr_type(::Type{TA}, T2::Type=Type{T}, N2::Val=Val(N)) where {T, N, TA<:AbstractArray{T,N}}
typeof(similar(TA(undef, ntuple(x->0, N)), T2, ntuple(x->0, N2)))
end

function similar_arr_type(::Type{TA}; dims=1, dtype=eltype(TA)) where {TA<:AbstractArray}
typeof(similar(TA(undef), dtype, ntuple(x->0, dims)))

function similar_arr_type(::Type{TA}, T2::Type=Type{T}, N2::Val=Val(N)) where {T, N, P, I, L, TA<:SubArray{T,N,P,I,L}}
similar_arr_type(P, T2, N2)
end

function similar_arr_type(::Type{TA}, T2::Type=Type{T}, N2::Val=Val(N)) where {T, N, P, MI, TA<:Base.ReshapedArray{T,N,P,MI}}
similar_arr_type(P, T2, N2)
end

# note that T refers to the new type (if not explicitely specified) and therefore replaces the eltype of the array as defined by P
function similar_arr_type(::Type{TA}, T2::Type=Type{T}, N2::Val=Val(N)) where {T, N, O, P, B, TA<:Base.ReinterpretArray{T,N,O,P,B}}
similar_arr_type(P, T2, N2)
end

# specifically for not fully specified arrays
function similar_arr_type(::Type{TA}, T2::Type=eltype(TA), N2::Val=Val(1)) where {TA<:AbstractArray}
typeof(similar(TA(undef), T2, ntuple(x->0, N2)))
end
16 changes: 10 additions & 6 deletions test/type_tools.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
@testset "Test Type Tools" begin
sz = (11,12)
@test real_arr_type(Array{Float32,2}) == Matrix{Float32}
@test complex_arr_type(Array{Float32,1}, dims=2) == Matrix{ComplexF32}
@test real_arr_type(Array{Float32}, dims=2) == Matrix{Float32}
@test complex_arr_type(Array{Float32}, dims=2) == Matrix{ComplexF32}
@test real_arr_type(Array{ComplexF64,2}, dims=1) == Vector{Float64}
@test complex_arr_type(Array{Float32,1}, Val(2)) == Matrix{ComplexF32}
@test real_arr_type(Array{Float32}, Val(2)) == Matrix{Float32}
@test complex_arr_type(Array{Float32}, Val(2)) == Matrix{ComplexF32}
@test real_arr_type(Array{ComplexF64,2}, Val(1)) == Vector{Float64}
@test complex_arr_type(Array{ComplexF64,1}) == Vector{ComplexF64}
@test similar_arr_type(Array{ComplexF64,1}, dims=2, dtype=Int) == Matrix{Int}
@test similar_arr_type(Array{ComplexF64}, dims=2, dtype=Int) == Matrix{Int}

@test similar_arr_type(Array{ComplexF64,1}, Int, Val(2)) == Matrix{Int}
@test similar_arr_type(Array{ComplexF64}, Float64, Val(2)) == Matrix{Float64}
@test similar_arr_type(typeof(view(ones(10,10),2:5,2:5)), Float64, Val(1)) == Vector{Float64}
@test similar_arr_type(typeof(reinterpret(Int, ones(10))), Float32, Val(2)) == Matrix{Float32}
@test similar_arr_type(typeof(reshape(view(ones(25),1:25), 5,5)), Int, Val(1)) == Vector{Int}
end
Loading