[julia-users] Re: Passing Array{Array{T,N},1} to a function

2015-09-29 Thread Tomas Lycken


If you’re trying this out in the REPL, you might have stumbled on the fact 
that list comprehensions currently aren’t type stable, unless you tell 
Julia the type of the elements. So instead of Xinput = 
[Array{Float64}(InnerArrayPts) for r in 1:OuterArrayPts] in your setup, do 
Xinput 
= Vector{Float64}[Array(Float64, InnerArrayPts) for r in 1:OuterArrayPts] 
(I also switched which array constructor you use, but that shouldn’t matter 
- it’s just a question of style, which is subjective :) ).

Note that Vector{Float64} is just a type alias for Array{Float64, 1}.

// T

On Tuesday, September 29, 2015 at 1:20:02 PM UTC+2, Alan Crawford wrote:


>
> I would like to preallocate memory of an array of arrays and pass it to a 
> function to be filled in. I have created an example below that illustrates 
> my question(s).
>
> Based on my (probably incorrect) understanding that it would be desirable 
> to fix the type in my function, I would like to be able to pass my array of 
> arrays, X, in a type stable way.  However, I can't seem to pass 
> Array{Array{Float64,N},1}. If, however, i do not attempt to impose the type 
> on the function, it works. 
>
> Is there a way to pass Array{Array{Float64,N},1 to my function? Do I even 
> need to fix the type in the function to get good performance?
>
> # version of Julia: 0.4.0-rc3
>
> @generated function 
> testfun1!{N}(X::Array{Array{Float64,1},1},Y::NTuple{N,Float64})
> quote
> for j in 1:$N, i in eachindex(X)
> X[i][j] = Y[j]
> end
> return X
> end
> end
>
> @generated function testfun2!{N}(X,Y::NTuple{N,Float64})
> quote
> for j in 1:$N, i in eachindex(X)
> X[i][j] = Y[j]
> end
> return X
> end
> end
>
> # Setup for function call
> InnerArrayPts = 3
> OuterArrayPts = 10
> Xinput = [Array{Float64}(InnerArrayPts) for r in 1:OuterArrayPts]
> Yinput = rand(InnerArrayPts)
>
> # Method Error Problem
> testfun1!(Xinput,tuple(Yinput...))
>
> # This works
> testfun2!(Xinput,tuple(Yinput...))
>
> I also tried with the following version of testfun1!() and again got a 
> method error.
>
> @generated function 
> testfun1!{N}(X::Array{Array{Float64,N},1},Y::NTuple{N,Float64})
> quote
> for j in 1:$N, i in eachindex(X)
> X[i][j] = Y[j]
> end
> return X
> end
> end
>
>
> I am sure i am misunderstanding something quite fundamental and/or missing 
> something straightforward...
>
> Thanks,
> Alan
>
>
>
> ​


Re: [julia-users] Re: Passing Array{Array{T,N},1} to a function

2015-09-29 Thread Alan Crawford
Many thanks!
alan
On 29 Sep 2015, at 13:04, Tomas Lycken  wrote:

> makes a difference in this specific case is a little beyond me, but an 
> educated guess says that with that guarantee, it is possible to know what 
> type Array(Float64, InnerArrayPts) will return, making it possible to also 
> type the comprehension tightly



[julia-users] Re: Passing Array{Array{T,N},1} to a function

2015-09-29 Thread Tomas Lycken


Type-inference in the REPL usually doesn’t give you as tight types as you’d 
like, mainly because it has to give room for what you *might* do in the 
future. Declaring variables const in the REPL (i.e. in global scope) helps 
with that, since it gives type-inference some guarantees that the variable 
won’t change its type.

Exactly why that makes a difference in this specific case is a little 
beyond me, but an educated guess says that with that guarantee, it is 
possible to know what type Array(Float64, InnerArrayPts) will return, 
making it possible to also type the comprehension tightly.

// T

On Tuesday, September 29, 2015 at 1:58:24 PM UTC+2, Alan Crawford wrote:

Thanks Tomas, works perfectly.
>
> I was testing out some code in the REPL... Relatedly and without abusing 
> the thread too much, I wondered if you might be able to help me understand 
> why the setting InnerArrayPts as const created the desired type stable 
> array comprehension? Namely,
>
> const InnerArrayPts1 = 3 
> OuterArrayPts = 10
> Xinput1 = [Array(Float64,InnerArrayPts1) for r in 1:OuterArrayPts]
>
> Cheers
> Alan
>
>
>
> On Tuesday, 29 September 2015 12:28:36 UTC+1, Tomas Lycken wrote:
>>
>> If you’re trying this out in the REPL, you might have stumbled on the 
>> fact that list comprehensions currently aren’t type stable, unless you tell 
>> Julia the type of the elements. So instead of Xinput = 
>> [Array{Float64}(InnerArrayPts) for r in 1:OuterArrayPts] in your setup, 
>> do Xinput = Vector{Float64}[Array(Float64, InnerArrayPts) for r in 
>> 1:OuterArrayPts] (I also switched which array constructor you use, but 
>> that shouldn’t matter - it’s just a question of style, which is subjective 
>> :) ).
>>
>> Note that Vector{Float64} is just a type alias for Array{Float64, 1}.
>>
>> // T
>>
>> On Tuesday, September 29, 2015 at 1:20:02 PM UTC+2, Alan Crawford wrote:
>>
>>
>>>
>>> I would like to preallocate memory of an array of arrays and pass it to 
>>> a function to be filled in. I have created an example below that 
>>> illustrates my question(s).
>>>
>>> Based on my (probably incorrect) understanding that it would be 
>>> desirable to fix the type in my function, I would like to be able to pass 
>>> my array of arrays, X, in a type stable way.  However, I can't seem to pass 
>>> Array{Array{Float64,N},1}. If, however, i do not attempt to impose the type 
>>> on the function, it works. 
>>>
>>> Is there a way to pass Array{Array{Float64,N},1 to my function? Do I 
>>> even need to fix the type in the function to get good performance?
>>>
>>> # version of Julia: 0.4.0-rc3
>>>
>>> @generated function 
>>> testfun1!{N}(X::Array{Array{Float64,1},1},Y::NTuple{N,Float64})
>>> quote
>>> for j in 1:$N, i in eachindex(X)
>>> X[i][j] = Y[j]
>>> end
>>> return X
>>> end
>>> end
>>>
>>> @generated function testfun2!{N}(X,Y::NTuple{N,Float64})
>>> quote
>>> for j in 1:$N, i in eachindex(X)
>>> X[i][j] = Y[j]
>>> end
>>> return X
>>> end
>>> end
>>>
>>> # Setup for function call
>>> InnerArrayPts = 3
>>> OuterArrayPts = 10
>>> Xinput = [Array{Float64}(InnerArrayPts) for r in 1:OuterArrayPts]
>>> Yinput = rand(InnerArrayPts)
>>>
>>> # Method Error Problem
>>> testfun1!(Xinput,tuple(Yinput...))
>>>
>>> # This works
>>> testfun2!(Xinput,tuple(Yinput...))
>>>
>>> I also tried with the following version of testfun1!() and again got a 
>>> method error.
>>>
>>> @generated function 
>>> testfun1!{N}(X::Array{Array{Float64,N},1},Y::NTuple{N,Float64})
>>> quote
>>> for j in 1:$N, i in eachindex(X)
>>> X[i][j] = Y[j]
>>> end
>>> return X
>>> end
>>> end
>>>
>>>
>>> I am sure i am misunderstanding something quite fundamental and/or 
>>> missing something straightforward...
>>>
>>> Thanks,
>>> Alan
>>>
>>>
>>>
>>> ​
>>
> ​


[julia-users] Re: Passing Array{Array{T,N},1} to a function

2015-09-29 Thread Alan Crawford
Thanks Tomas, works perfectly.

I was testing out some code in the REPL... Relatedly and without abusing 
the thread too much, I wondered if you might be able to help me understand 
why the setting InnerArrayPts as const created the desired type stable 
array comprehension? Namely,

const InnerArrayPts1 = 3 
OuterArrayPts = 10
Xinput1 = [Array(Float64,InnerArrayPts1) for r in 1:OuterArrayPts]

Cheers
Alan



On Tuesday, 29 September 2015 12:28:36 UTC+1, Tomas Lycken wrote:
>
> If you’re trying this out in the REPL, you might have stumbled on the fact 
> that list comprehensions currently aren’t type stable, unless you tell 
> Julia the type of the elements. So instead of Xinput = 
> [Array{Float64}(InnerArrayPts) for r in 1:OuterArrayPts] in your setup, 
> do Xinput = Vector{Float64}[Array(Float64, InnerArrayPts) for r in 
> 1:OuterArrayPts] (I also switched which array constructor you use, but 
> that shouldn’t matter - it’s just a question of style, which is subjective 
> :) ).
>
> Note that Vector{Float64} is just a type alias for Array{Float64, 1}.
>
> // T
>
> On Tuesday, September 29, 2015 at 1:20:02 PM UTC+2, Alan Crawford wrote:
>
>
>>
>> I would like to preallocate memory of an array of arrays and pass it to a 
>> function to be filled in. I have created an example below that illustrates 
>> my question(s).
>>
>> Based on my (probably incorrect) understanding that it would be desirable 
>> to fix the type in my function, I would like to be able to pass my array of 
>> arrays, X, in a type stable way.  However, I can't seem to pass 
>> Array{Array{Float64,N},1}. If, however, i do not attempt to impose the type 
>> on the function, it works. 
>>
>> Is there a way to pass Array{Array{Float64,N},1 to my function? Do I 
>> even need to fix the type in the function to get good performance?
>>
>> # version of Julia: 0.4.0-rc3
>>
>> @generated function 
>> testfun1!{N}(X::Array{Array{Float64,1},1},Y::NTuple{N,Float64})
>> quote
>> for j in 1:$N, i in eachindex(X)
>> X[i][j] = Y[j]
>> end
>> return X
>> end
>> end
>>
>> @generated function testfun2!{N}(X,Y::NTuple{N,Float64})
>> quote
>> for j in 1:$N, i in eachindex(X)
>> X[i][j] = Y[j]
>> end
>> return X
>> end
>> end
>>
>> # Setup for function call
>> InnerArrayPts = 3
>> OuterArrayPts = 10
>> Xinput = [Array{Float64}(InnerArrayPts) for r in 1:OuterArrayPts]
>> Yinput = rand(InnerArrayPts)
>>
>> # Method Error Problem
>> testfun1!(Xinput,tuple(Yinput...))
>>
>> # This works
>> testfun2!(Xinput,tuple(Yinput...))
>>
>> I also tried with the following version of testfun1!() and again got a 
>> method error.
>>
>> @generated function 
>> testfun1!{N}(X::Array{Array{Float64,N},1},Y::NTuple{N,Float64})
>> quote
>> for j in 1:$N, i in eachindex(X)
>> X[i][j] = Y[j]
>> end
>> return X
>> end
>> end
>>
>>
>> I am sure i am misunderstanding something quite fundamental and/or 
>> missing something straightforward...
>>
>> Thanks,
>> Alan
>>
>>
>>
>> ​
>