I need to create a tuple with the value r
repeated N
times. Creating an array would be easy, as I could just do fill(r, N)
. How can I do this, but creating a tuple instead?
ntuple
is probably what you are looking for.
julia> ntuple(i->1, 4)
(1, 1, 1, 1)
julia> typeof(ans)
NTuple{4, Int64}
Thank you. This works, but I am having a problem with type stability (I am obtaining N
as the length of a vector).
function test(x::AbstractArray{T}, R) where{T<:Real}
n = length(v)
r = ntuple(i -> R, n)
end
Running @code_warntype
@code_warntype test(x, 2)
MethodInstance for test(::Vector{Float64}, ::Int64)
from test(x::AbstractArray{T}, R) where T<:Real in Main at ...
Static Parameters
T = Float64
Arguments
#self#::Core.Const(test)
x::Vector{Float64}
R::Int64
Locals
#53::var"#53#54"{Int64}
r::Any
n::Any
Body::Any
1 ─ (n = Main.length(Main.v))
│ %2 = Main.:(var"#53#54")::Core.Const(var"#53#54")
│ %3 = Core.typeof(R)::Core.Const(Int64)
│ %4 = Core.apply_type(%2, %3)::Core.Const(var"#53#54"{Int64})
│ (#53 = %new(%4, R))
│ %6 = #53::var"#53#54"{Int64}
│ %7 = Main.ntuple(%6, n)::Any
│ (r = %7)
└── return %7
(If N
were a compile time constant, then there is no problem.)
Did you mean to define test(v)
, not test(x)
? Because if v
is a non-const global, length
is not inferred.
Further, because n
is known at runtime only, you won’t get better inference than Tuple{Vararg{Int64}}
Yes, sorry, I mixed up x
and v
. I was using tuples with Iterators to implement a variable nested level loop. Let me think if there is an alternative way to do this. Thanks for your help here.
Every length tuple is a different type in Julia. This is why you shouldn’t over use ...
splat either (it makes an arbitrary length tuple that the compiler can’t predict).
Are you sure you need a Tuple? Could you use an array?
i -> R
Note that, as of Julia 1.7, you can replace constant-valued functions like this with
Returns(R)
which might be a little more pleasant to work with.