Initializing Jagged Array in Julia - julia

I am new to Julia. I am trying to initialize a jagged array of known size K in the first dimension, and unknown size in the second dimension.
The way I currently do this is
arr = Array{Array{Int}}(undef, K)
for i in 1:K
arr[i] = []
end
# and then push! elements to arr[k] if the element is in category k.
Can we do this in a better way?

The simplest to write is I think:
arr = [Int[] for _ in 1:K]
You could also write (I am showing these as an exercise as I would normally use a comprehension):
arr = map(_ -> Int[], 1:K)
or
arr = (_ -> Int[]).(1:K)
A common mistake that should be avoided is:
arr = fill(Int[], K)
as then each element of arr is exactly the same vector, which you do not want. E.g.
julia> arr = fill(Int[], K)
5-element Array{Array{Int64,1},1}:
[]
[]
[]
[]
[]
julia> push!(arr[1], 1)
1-element Array{Int64,1}:
1
julia> arr
5-element Array{Array{Int64,1},1}:
[1]
[1]
[1]
[1]
[1]

Related

Julia - Equivalent of python `pop`. Remove elements from array using boolean array and return them

Is there an equivalent to Python's pop? I have an array x and a boolean array flag of the same length. I would like to extract x[flag] and be able to store it in a variable x_flagged while at the same time remove them in place from x.
x = rand(1:5, 100)
flag = x .> 2
x_flagged = some_function!(x, flag) # Now x would be equal to x[x .<= 2]
Try this one using deleteat!
julia> function pop_r!(list, y) t = list[y]; deleteat!( list, y ); t end
julia> x = rand(1:5, 100)
100-element Vector{Int64}
julia> flag = x .> 2
100-element BitVector
julia> pop_r!( x, flag )
60-element Vector{Int64}
julia> x
40-element Vector{Int64}
You can use splice! with a bit of help from findall:
julia> x_flagged = splice!(x, findall(flag))
59-element Vector{Int64}:
...
julia> size(x)
(41,)
splice!(a::Vector, indices, [replacement]) -> items
Remove items at specified indices, and return a collection containing the removed items.

Filtering using conditional evaluation (&&)

I am having trouble filtering a simple array-based on two conditions. For example, to filter out values between 3 and 5, I tried the following but I get an ERROR: TypeError: non-boolean (BitArray{1}) used in boolean context error.
arr = Array{Int64}([1,2,3,4,5,6])
arr[(arr .> 3) && (arr.< 5)]
Any idea how to solve it?
Also on a side note, I am wondering if there is a function opposite to isless. Something to find a value greater than a certain value.
Here are two ways to do it:
julia> arr = [1,2,3,4,5,6]
6-element Array{Int64,1}:
1
2
3
4
5
6
julia> arr[(arr .> 3) .& (arr.< 5)]
1-element Array{Int64,1}:
4
julia> filter(v -> 3 < v < 5, arr)
1-element Array{Int64,1}:
4
(I personally prefer filter).
To get the opposite of isless just reverse its arguments, or if needed define a new function:
isgreater(x, y) = isless(y, x)
I prefer a set comparison approach because it's quite intuitive:
julia> arr = Array{Int64}([1,2,3,4,5,6])
julia> intersect( arr[ arr .> 1 ], arr[ arr .< 4 ] )
2-element Array{Int64,1}:
2
3
Or list comprehension:
[ x for x in arr if 3 < x < 5]
# or
[ x for x in arr if 3 < x && x < 5]
Also to define an array literal with specific type Int64, there is a dedicated syntax to make it simpler:
arr = Int64[1,2,3,4,5,6]

For Loop Over a Recursive Call Ocaml

I'm working on an implementation of prime decomposition in OCaml. I am not a functional programmer; Below is my code. The prime decomposition happens recursively in the prime_part function. primes is the list of primes from 0 to num. The goal here being that I could type prime_part into the OCaml interpreter and have it spit out when n = 20, k = 1.
2 + 3 + 7
5 + 7
I adapted is_prime and all_primes from an OCaml tutorial. all_primes will need to be called to generate a list of primes up to b prior to prime_part being called.
(* adapted from http://www.ocaml.org/learn/tutorials/99problems.html *)
let is_prime n =
let n = abs n in
let rec is_not_divisor d =
d * d > n || (n mod d <> 0 && is_not_divisor (d+1)) in
n <> 1 && is_not_divisor 2;;
let rec all_primes a b =
if a > b then [] else
let rest = all_primes (a + 1) b in
if is_prime a then a :: rest else rest;;
let f elem =
Printf.printf "%d + " elem
let rec prime_part n k lst primes =
let h elem =
if elem > k then
append_item lst elem;
prime_part (n-elem) elem lst primes in
if n == 0 then begin
List.iter f lst;
Printf.printf "\n";
()
end
else
if n <= k then
()
else
List.iter h primes;
();;
let main num =
prime_part num 1 [] (all_primes 2 num)
I'm largely confused with the reclusive nature with the for loop. I see that List.ittr is the OCaml way, but I lose access to my variables if I define another function for List.ittr. I need access to those variables to recursively call prime_part. What is a better way of doing this?
I can articulate in Ruby what I'm trying to accomplish with OCaml. n = any number, k = 1, lst = [], primes = a list of prime number 0 to n
def prime_part_constructive(n, k, lst, primes)
if n == 0
print(lst.join(' + '))
puts()
end
if n <= k
return
end
primes.each{ |i|
next if i <= k
prime_part_constructive(n - i, i, lst+[i], primes)
}
end
Here are a few comments on your code.
You can define nested functions in OCaml. Nested functions have access to all previously defined names. So you can use List.iter without losing access to your local variables.
I don't see any reason that your function prime_part_constructive returns an integer value. It would be more idiomatic in OCaml for it to return the value (), known as "unit". This is the value returned by functions that are called for their side effects (such as printing values).
The notation a.(i) is for accessing arrays, not lists. Lists and arrays are not the same in OCaml. If you replace your for with List.iter you won't have to worry about this.
To concatenate two lists, use the # operator. The notation lst.concat doesn't make sense in OCaml.
Update
Here's how it looks to have a nested function. This made up function takes a number n and a list of ints, then writes out the value of each element of the list multiplied by n.
let write_mults n lst =
let write1 m = Printf.printf " %d" (m * n) in
List.iter write1 lst
The write1 function is a nested function. Note that it has access to the value of n.
Update 2
Here's what I got when I wrote up the function:
let prime_part n primes =
let rec go residue k lst accum =
if residue < 0 then
accum
else if residue = 0 then
lst :: accum
else
let f a p =
if p <= k then a
else go (residue - p) p (p :: lst) a
in
List.fold_left f accum primes
in
go n 1 [] []
It works for your example:
val prime_part : int -> int list -> int list list = <fun>
# prime_part 12 [2;3;5;7;11];;
- : int list list = [[7; 5]; [7; 3; 2]]
Note that this function returns the list of partitions. This is much more useful (and functional) than writing them out (IMHO).

Vector of matrices in Julia

How can I make a vector of (non-sparse) matrices in Julia? Then I want to use push! to add elements to that.
So if the name of the vector is V, then V[1] will be a matrix or Array{Float64,2}.
I know this works if the elements of the vector are sparse:
V = Array(SparseMatrixCSC).
You can use the Matrix alias (Array{T, 2}):
julia> v = Matrix{Float64}[]
0-element Array{Array{Float64,2},1}
julia> x = rand(2, 2)
2×2 Array{Float64,2}:
0.0877254 0.256971
0.719441 0.653947
julia> push!(v, x)
1-element Array{Array{Float64,2},1}:
[0.0877254 0.256971; 0.719441 0.653947]
julia> v[1]
2×2 Array{Float64,2}:
0.0877254 0.256971
0.719441 0.653947
I just tried this and it worked:
V = Array(Array{Float64,2}, 0);
edit: As #pkofod suggested, this way is prefered:
T = Array{Float64,2};
V = Array{T}(0)
other options: V = Array{Float64,2}[ ] or V = Matrix{Float64}[ ]

How to find index of an Array element in OCaml

I am trying to find the index of an integer array element in ocaml. How to do this recursively.
Example code:let a = [|2; 3; 10|];;
suppose I want to return the index of 3 in the array a. Any help appreciated. I am new to OCaml programming
type opt = Some of int | None;;
let find a i =
let rec find a i n =
if a.(n)=i then Some n
else find a i (n+1)
in
try
find a i 0
with _ -> None
;;
Test
# find a 3;;
- : int option = Some 1
# find [||] 3;;
- : int option = None
# find a 12;;
- : int option = None
You check each of the elements recursively using an index
let rec find a x n =
if a.(n) = x then n
else find a x (n+1);;
find a x 0;;
that will raise an exception (when n is bigger than the length of the array) in case the element is not part of the array.
let f xs x =
let i = ref (-1) in
let () = Array.iteri (fun n elt -> if x = elt then i := n else ()) xs in
!i
The return value will be -1 if the element is not in the list.

Resources