diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5131d8e --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +Manifest.toml +test/Manifest.toml +exmaples/Manifest.toml + +docs/build/ \ No newline at end of file diff --git a/Project.toml b/Project.toml index 1c400f1..2b1665a 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "NDTools" uuid = "98581153-e998-4eef-8d0d-5ec2c052313d" authors = ["Rainer Heintzmann ", "Felix Wechsler "] -version = "0.6.0" +version = "0.7.0" [deps] LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" diff --git a/src/type_tools.jl b/src/type_tools.jl index 1408d12..ee4cd2c 100644 --- a/src/type_tools.jl +++ b/src/type_tools.jl @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/test/type_tools.jl b/test/type_tools.jl index 0c2e514..56cd54b 100644 --- a/test/type_tools.jl +++ b/test/type_tools.jl @@ -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