Initialize an Empty Array of Tuples in Julia - julia

I can't figure out how to initialize an empty array of tuples. The manual says:
The type of a tuple of values is the tuple of types of values... Accordingly, a tuple of types can be used anywhere a type is expected.
Yet this does not work:
myarray = (Int64,Int64)[]
But this does:
Int64[]
It would seem a type is expected in front of the empty square brackets, but the tuple type doesn't work. This <type>[] syntax is the only way I can find to get an empty typed Array (other methods seem to produce a bunch of #undef values). Is the only way to do it, and if it is, how can I type the Array with tuples?
BTW, my use case is creating an array of initially indeterminate length and pushing tuples onto it in a loop.

For people who look for the latest solution,
Tuple{Int, Int}[] works in v0.4
Also the verbose way Array{Tuple{Int, Int}}(0) works in v0.4 as well.
It creates a 0-element Array{Tuple{Int64,Int64},1}
Note that in v1.0 you'd need to write
Array{Tuple{Int, Int}}(undef, 0)

You can do Array((Int,Int),0) for this. It is probably feasible to add methods to getindex to make (Int,Int)[] work, but I'm not sure it's worth it. Feel free to open an issue.

Related

How to clear an array in Julia

I have an array representing image metadata that I want to clear out. Currently, I use the empty!() function but it is throwing an error because I think it needs to be a dictionary and I have an array so I am looking for an alternate way to clear the Array.
For reference, here is the type I am working with:
Array{ImageMetadata.ImageMeta{ColorTypes.Gray{FixedPointNumbers.Normed{UInt8,8}},2,Array{ColorTypes.Gray{FixedPointNumbers.Normed{UInt8,8}},2},P} where P<:AbstractDict{Symbol,Any},1}
empty! shouldn't be throwing an error:
julia> x = rand(10);
julia> empty!(x)
0-element Array{Float64,1}
Would be useful to know what error you're actually seeing.
I am not sure what you mean by "clear", but in general you can use fill! to fill the array with a value of your choice.
However, if your question is to make an array filled with some values to be set to have #undef in its entries (if its eltype allows for it), then I do not know of a method to make this. You can use similar to create a new array that will have the same shape and be uninitialized.

Reshaping 1d array to 2D pointer array Fortran

I have a pointer uvw(:,:) which is two-dimensional, and I got a 1d buffer array x(:).
Now I need to point uvw(1,:)=>x(1:ncell) and uvw(2,:)=>x(ncell+1:ncell*2) etc.
I made a very simple example. I know that array of pointers does not work, but does anybody have an idea how this can be worked around?
PS: For a pragmatic reason I do not want to wrap my uvw with a declared type. ( i am changing some bit of code, and need uvw as 2D pointer. Currently is an array, and my idea is to avoid changing the way uvw is being used as it being used thousands of times)
program test
real, allocatable,target :: x(:)
real, pointer :: ptr(:,:)
allocate(x(100) )
x = 1.
ptr(1,:) => x(1:10)
end program
The error message says:
`error #8524: The syntax of this data pointer assignment is incorrect:
either 'bound spec' or 'bound remapping' is expected in this context.
[1]
ptr(1,:) => x(1:10)
----^`
You are trying to perform pointer bounds remapping, but you have the incorrect syntax and approach.
Pointer bounds remapping is a way to have the shape of the pointer different from that of the target. In particular, the rank of the pointer and target may differ. However, in such an assignment it is necessary to explicitly specify the lower and upper bounds of the remapping; it isn't sufficient to use : by itself.
Also, you'll need to assign the whole pointer in one go. That is, you can't have "the first ten elements point to this slice, the next ten to this slice" and so on in multiple statements.
The assignment statement would be
ptr(1:10,1:10) => x
Note, that this also means that you can't actually have what you want. You are asking for the elements ptr(1,1:10) to correspond to x(1:10) and ptr(2,2:10) to correspond to x(11:20). That isn't possible: the array elements must match in order: ptr(1:10,1) being the first ten elements of ptr must instead be associated with the first ten elements x(1:10). The corrected pointer assignment above has this.
If you prefer avoiding a pointer, then the UNION/MAP is an option depending on compiler. It was added to gfortran a while ago... then you can think of the array as a rank=2 but also use the vector (Rank=1) for SIMD operations.
All this assumes that one wants to avoid pointers...

Why are immutable types passed by copying?

In the documentation on types, it says:
An object with an immutable type is passed around (both in assignment statements and in function calls) by copying, whereas a mutable type is passed around by reference.
What's the purpose of copying an entire object when the object can't be changed? Why not just copy the reference?
Also, when I try to test this with
struct Foo
bar::Int
end
x = Foo(10)
y = x
pointer_from_objref(x) # Ptr{Void} #0x00000001141ea760
pointer_from_objref(y) # Ptr{Void} #0x00000001141ea760
it suggest that the objects are the same. Am I misunderstanding this?
Thanks for the help!
pointer_from_objref does not work as you think on immutable types. The results depends on the context you call it from.
Try something like
function test(x) return pointer_from_objref(x) end
println(test(x))
println(test(y))
I'm actually quite surprised that it even worked, considering that the source tries to trow an error for immutable arguments.
For your really small immutable, a copy (or just keeping the value in a registrer) is actually much cheaper than going the detour of a pointer (A pointer is the same size as an int and obviously also needs to be copied to a function call).

Integer matrix in stan getting flattened

I'm trying to pass a three-dimensional data structure to Stan (in RStan) where the entries must be integers, because a function down-stream requires that. However I'm having trouble declaring it.
I tried the straight-forward approach:
int x[n,n,k];
But that gave me the error
mismatch in number dimensions declared and found in context; ... dims declared=(n,n,k); dims found=(n*n*k)
meaning, clearly, the input array is getting flattened, for some reason (that I don't understand). I'm giving it a simple 3d array, no NAs, the dimensions look right before I pass it. And in fact, the same things is happening for 2d arrays, as well, meaning I can't even declare a set of 2d matrices, as a workaround.
Then I tried
row_vector[K] x[N,N];
but that gives back real, not int. And when I do something like
int row_vector[K] x[N,N];
that's just not proper syntax.
I also tried passing logical values, hoping they'd be re-cast as ints, but no. I passed arrays, I passed them cast with as.matrix, I checked their dimension both before and after being put into the data list.
This is with R version 3.4.1 on OSX 10.11.6, using the most recent version of stan, that was just compiled from source, today.
What am I missing? OR, how might I cast a single real to an integer, so that the integer-requiring function doesn't break?
(And, WHERE is the documentation? The best I can find is long-dead comment threads.)

How to use a vector as a type parameter in Julia

This is similar to my previous question, but a bit more complicated.
Before I was defining a type with an associated integer as a parameter, Intp{p}. Now I would like to define a type using a vector as a parameter.
The following is the closest I can write to what I want:
type Extp{g::Vector{T}}
c::Vector{T}
end
In other words, Extp should be defined with respect to a Vector, g, and I want the contents, c, to be another Vector, whose entries should be the of the same type as the entries of g.
Well, this does not work.
Problem 1: I don't think I can use :: in the type parameter.
Problem 2: I could work around that by making the types of g and c arbitary and just making sure the types in the vectors match up in the constructor. But, even if I completely take everything out and use
type Extp{g}
c
end
it still doesn't seem to like this. When I try to use it the way I want to,
julia> Extp{[1,1,1]}([0,0,1])
ERROR: type: apply_type: in Extp, expected Type{T<:Top}, got Array{Int64,1}
So, does Julia just not like particular Vectors being associated with types? Does what I'm trying to do only work with integers, like in my Intp question?
EDIT: In the documentation I see that type parameters "can be any type at all (or an integer, actually, although here it’s clearly used as a type)." Does that mean that what I'm asking is impossible, and that that only types and integers work for Type parameters? If so, why? (what makes integers special over other types in Julia in this way?)
In Julia 0.4, you can use any "bitstype" as a parameter of a type. However, a vector is not a bitstype, so this is not going to work. The closest analog is to use a tuple: for example, (3.2, 1.5) is a perfectly valid type parameter.
In a sense vectors (or any mutable object) are antithetical to types, which cannot change at runtime.
Here is the relevant quote:
Both abstract and concrete types can be parameterized by other types
and by certain other values (currently integers, symbols, bools, and
tuples thereof).
So, your EDIT is correct. Widening this has come up on the Julia issues page (e.g., #5102 and #6081 were two related issues I found with some discussion), so this may change in the future - I'm guessing not in v0.4 though. It'd have to be an immutable type really to make any sense, so not Vector. I'm not sure I understand your application, but would a Tuple work?

Resources