How to clear an array in Julia - 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.

Related

Rust ndarray: Convert ArrayD to Array2

Got an ArrayD which always has 2 dimensions, but is an ArrayD due to a calculation, need to change this to Array2 for storage.
Been looking through documentation, can't seem to find a way.
Is there a function to do it?
If you have a variable of type ArrayD<f32>, you can do:
// convert n-dimensional array into 2d array
let arr2d: Array2<f32> = arr2d.into_dimensionality::<Ix2>()?;
to convert it into a variable of type Array2<f32>.
If the dimensions don't match, it will throw an ndarray::ShapeError error.
also see: ndarray documentation: into_dimensionality

Julia: What is undef in Array in Julia

This is a constructor for arrays:
Array{T}(undef, dims)
I am new to Julia, and don't have a good background in programming. In this syntax, why is undef used for creating the array?
What is a constructor in Julia, in what situation do we use a constructor?
If we don't type constructor, Julia will automatically create a constructor. Then, Why we use constructor?
First, you want to understand what is a constructor:
For that, I suggest you the Julia doc: Constructors in Julia
Now that you have the theory, let's break apart this expression:
a = Array{Int}(undef, (2, 2))
What this expression is saying is "I want a to be an Array of dimension (2, 2)". So Julia will ask for some memory space. When I write it on the Julia REPL:
julia> a = Array{Int}(undef, (2, 2))
2×2 Array{Int64,2}:
0 0
0 0
Now Array{T}(undef, dims) is the generalization of that. "Construct an array of a specific type T with a specific number of dimensions dims"
So far, I didn't explain what is undef. undef is a shortcut for UndefInitializer(). In this example, we wanted an uninitialized array. What does it mean? For that, you have to understand that variables are not created ex nihilo on your terminal. They are occupying a specific place in the memory of your computer. And sometimes, the same memory space was occupied by another variable. So the space my new variable can take might not be empty:
julia> a = Array{Float64}(undef, (2, 2))
2×2 Array{Float64,2}:
6.94339e-310 6.94339e-310
6.94339e-310 0.0
Here, I never asked for these values to be there. I could erase it to work with a clean variable. But that would mean to erase the value for each cell, and it's much more expensive for the computer to replace each value rather than declaring "here is the new variable".
So basically, undef and uninitialized arrays are used for performance purposes. If you want an array well initialized, you can use fill.

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).

Initialize an Empty Array of Tuples in 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.

Resources