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.)
Related
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...
I'm Brand new in Julia. I've been looking around some documentation like [1], [2], [3]. Generally, I found it usefull, but I see some lack of organization in them. They all have the approach of "learning by examples" but any of them have a structured way to approach the remarkable features of the language.
Well, my problem is that I'm trying to build a defined type with some variables. Among them, at least one variable is an n-dimensional array where the dimensions are variables inside that defined type. To start, I cannot even define a fixed dimension tensor in the "struct".
Type Geometry
dimension::UInt
coordinates::Array{Float64}(10,2)
end
Says that:
expected Type, got Array.
and, for example:
Type Geometry
dimension::UInt
coordinates=Array{Float64}(10,2)
end
Says that:
"assignation" in Type definition is reserved.
Another approach would be define a "pointer" in the Type and then reshape that pointer, something like:
Type Geometry
dimension::UInt
coordinates::Float64
end
mesh=Geometry(10,0)
reshape(mesh.coordinates,(10,3))
Says that you cannot reshape an scalar.
So, my two questions are:
There's any way to build this dynamic dimension defined type in julia?
And even more important: do you have any recommended, organized and structured bibliography for julia like we've Metcalf. Fortran 95/2003 explained for fortran?
Thank you all.
You're looking at a very old version of Julia's documentation. Here is the documentation for the current stable version (0.6 right now).
The expression Array{Float64}(10,2) constructs a 10x2 array (a value). You define fields with types, not values. The corresponding type is Array{Float64, 2} — 2 for two dimensions. The exact number of elements isn't encoded into the array's type; that is part of the value. So you want:
type Geometry
coordinates::Array{Float64, 2}
end
Of course, this means that every Geometry object must only contain a two-dimensional array. You can make it "dynamic" by simply omitting the parameter for the number of dimensions in the array type (but the tradeoff is that this won't perform as well):
type Geometry
coordinates::Array{Float64}
end
Now you can construct Geometry objects with coordinate arrays of any dimensionality. A bit more advanced would be to use a parametric type, but I recommend getting the basics of the language down first.
Finally, note that reshape isn't an in-place operation. The returned array shares the data, but the first array retains its original shape.
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?
How can I convert a Julia Int/Bool Array/Vector to a Fortran LOGICAL array for use within Julia's ccall?
I tried passing it as Array{Bool} in https://gist.github.com/axsk/28f297e2207365a7f4e8/, but the code is not working correctly and I am quite confident the problem is the Bool-Logical conversion.
I don't know too much about calling Fortran code, but according to this
The Fortran standard does not specify how variables of LOGICAL type
are represented, beyond requiring that LOGICAL variables of default
kind have the same storage size as default INTEGER and REAL variables.
The GNU Fortran internal representation is as follows.
A LOGICAL(KIND=N) variable is represented as an INTEGER(KIND=N)
variable, however, with only two permissible values: 1 for .TRUE. and
0 for .FALSE.. Any other integer value results in undefined behavior.
So I'd do something like the following
julia_array = rand(Bool, 1:10)
fort_array = Int[x?1:0 for x in julia_array]
Then use fort_array as the input. Which Fortran compiler are you using?
EDIT: It turns out the Julia developers already define a type that will work with the linked BLAS/LAPACK, Base.BLAS.BlasInt, that will use the correct Int variant for the system.
As iaindunning posted before, Fortran represents Logical variables as Integers.
Unfortunately the representation of the type Integer varies from platform to platform.
While I had success using Int on Windows and Cint on Linux/MacOS, in the end I used BlasInt, which adopts depending on the platform.
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.