How to select odd numbers from a matrix? - julia

How do you select odd numbers from a matrix larger than 29?

You can use filter:
filter(x->isodd(x)&&x>29, M)
Here, x->isodd(x)&&x>29 is an anonymous function, specifying your filter criterium, and M is your matrix.
Example:
julia> M = rand(1:50, 3,3)
3×3 Array{Int64,2}:
20 42 35
23 6 31
28 4 4
julia> filter(x->isodd(x)&&x>29, M)
2-element Array{Int64,1}:
35
31
Alternatively, you can use array comprehensions:
julia> [x for x in M if isodd(x) && x>29]
2-element Array{Int64,1}:
35
31

You can also use this:
using Statistics;
A = round.(rand(5,5)*10)
odd = A[(rem.(A,2).>0) .& (A.>29)]

Related

How can I determine if an array contains some element?

How can I tell if an array contains some element?
I have been manually checking with a loop:
for x in xs
if x == a
return true
end
end
return false
Is there a more idiomatic way?
The in operator will iterate over an array and check if some element exists:
julia> xs = [5, 9, 2, 3, 3, 8, 7]
julia> 8 in xs
true
julia> 1 in xs
false
It is important to remember that missing values can alter the behavior you might otherwise expect:
julia> 2 in [1, missing]
missing
in can be used on general collections. In particular, matrices:
julia> A = [1 4 7
2 5 8
3 6 9]
3×3 Array{Int64,2}:
1 4 7
2 5 8
3 6 9
julia> 7 in A
true
julia> 10 in A
false

newline sensitive interpretation of Arrays

When I add a newline to my array definition, the type of my array changes.
julia> a = [[1]]
1-element Array{Array{Int64,1},1}:
[1]
julia> a = [[1]
]
1-element Array{Int64,1}:
1
I thought they both should return the same result i.e. of type Array{Array{Int64,1},1}
In order to understand this see the following:
julia> :([[1]
])
:([[1];])
And you see that adding a newline is rewritten as vcat operation.
The reason for this is to allow writing something like this:
julia> x = [1 2
3 4]
2×2 Array{Int64,2}:
1 2
3 4
and your example is hitting a corner case of this syntax.
Note, however, that without an extra empty line vcat is not called:
julia> :([[1]
])
:([[1]])
Another use-case that is worth to know is:
julia> [[1, 2]
[3, 4]]
4-element Array{Int64,1}:
1
2
3
4
and the same with variables (can improve code readability in some cases):
julia> a = [1,2]
2-element Array{Int64,1}:
1
2
julia> b = [3, 4]
2-element Array{Int64,1}:
3
4
julia> [a
b]
4-element Array{Int64,1}:
1
2
3
4

Find the tail of array except first element

Is there a method to get the tail of a collection(e.g. vector) i.e. the array except the first element. Currently, I have
tail(arr) = selectdim(arr, 1, 2:length(arr))
julia> c
3-element Array{Int64,1}:
1
2
3
julia> tail(c)
2-element view(::Array{Int64,1}, 2:3) with eltype Int64:
2
3
Simply use the end keyword:
julia> c = [11,12,13]
3-element Array{Int64,1}:
11
12
13
julia> c[2:end]
2-element Array{Int64,1}:
12
13

How to apply one argument to Array{Function, 1} element-wise smartly in Julia?

I understand Julia can apply element-wise argument to a function by f.(x)
in v0.6
x = [1, 2, 3]
f = x->3x
#assert f.(x) = [3, 6, 9]
Now, I define f as Array{Function, 1}.
f1(x) = 3x
f2(x) = 4x
f = [f1, f2]
x = 2
#assert isa(f, Array{Function,1}) == true
# f.(x) is unavailable
I want to apply arguments to element-wise function like above syntax, not using map, [_f(x) for _f in f]
Can someone be familiar with this issue?
You can broadcast the pipe operator (|>), e.g.
x .|> f
You have to take care how to define x and f, in some cases you will fail. Your first x applied on your last f will fail.
julia> 5 .|> [x->2x, x->7x]
2-element Array{Int64,1}:
10
35
julia> [2, 5] .|> [x->2x, x->7x]
2-element Array{Int64,1}:
4
35
julia> [2 5] .|> [x->2x, x->7x]
2-element Array{Int64,2}:
4 10
14 35
julia> [2 5] .|> [x->2x x->7x]
1×2 Array{Int64,2}:
4 35
julia> [2, 5] .|> [x->2x x->7x]
2×2 Array{Int64,2}:
4 14
10 35
julia> [2 3 5] .|> [x->2x x->7x]
ERROR: DimensionMismatch("arrays could not be broadcast to a common")
julia> [2, 3, 5] .|> [x->2x, x->7x]
ERROR: DimensionMismatch("arrays could not be broadcast to a common")
julia> x = [1, 2, 3]; f = [x->2x, x->3x]; x .|> f
ERROR: DimensionMismatch("arrays could not be broadcast to a common")
Here's another possibility:
((f, x)->f(x)).([f1, f2], x)

Declare and initialise 3-dimensional array

I want to initialise a 3-dimensional array in Julia with constant entries. For the 2d case I can use
A = [1 2; 3 4]
Is there a similar short syntax for 3d arrays?
Not at this time, although something like the following isn't too bad
A = zeros(2,2,2)
A[:,:,1] = [1 2; 3 4]
A[:,:,2] = [10 20; 30 40]
One can use either the cat or the reshape functions to accomplish the task: (tested with Julia-1.0.0):
julia> cat([1 2; 3 4], [5 6; 7 8], dims=3)
2×2×2 Array{Int64,3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
5 6
7 8
For higher Array dimensions, the cat calls must be nested: cat(cat(..., dims=3), cat(..., dims=3), dims=4).
The reshape function allows building higher dimension Arrays "at once", i.e., without nested calls:
julia> reshape([(1:16)...], 2, 2, 2, 2)
2×2×2×2 Array{Int64,4}:
[:, :, 1, 1] =
1 3
2 4
[:, :, 2, 1] =
5 7
6 8
[:, :, 1, 2] =
9 11
10 12
[:, :, 2, 2] =
13 15
14 16
It is actually possible to declare a multidimensional array in julia using only list comprehension
julia> a = [x + y + z for x in 1:2, y ∈ 2:3, z = 3:4]
2×2×2 Array{Int64,3}:
[:, :, 1] =
6 7
7 8
[:, :, 2] =
7 8
8 9
julia> size(a)
(2, 2, 2)
julia> ndims(a)
3
Julia documentation about Multi-dimensional Arrays is a good place to learn more about array creation.
For a 3-dimensional array, you can do the following:
julia> [1; 2;; 3; 4;; 5; 6;;;
7; 8;; 9; 10;; 11; 12]
2×3×2 Array{Int64, 3}:
[:, :, 1] =
1 3 5
2 4 6
[:, :, 2] =
7 9 11
8 10 12
From the documentation, "... ; and ;; concatenate in the first and second dimension, using more semicolons extends this same general scheme. The number of semicolons in the separator specifies the particular dimension, so ;;; concatenates in the third dimension, ;;;; in the 4th, and so on."

Resources