6.1. Constructing Arrays#

6.1.1. Constructing Arrays using Comprehensions#

Comprehension syntax is a a more general way to create arrays based on expressions. It has the following form:

A = [ F(x,y,...) for x=rx, y=ry, ... ]

The function F(x,y,...) will be evaluated with the values x, y, etc, taking on each value in their given lists. The resulting values are put in a multi-dimensional array, of the size given by the variable ranges rx, ry, etc.

x = [ x^2 for x = 1:5 ]                # Square of the numbers 1 to 5
5-element Vector{Int64}:
  1
  4
  9
 16
 25
A = [ x+y for x = 1:3, y = 1:5 ]       # 3x5 matrix with entries A_ij = i + j
3×5 Matrix{Int64}:
 2  3  4  5  6
 3  4  5  6  7
 4  5  6  7  8
B = [ x^y for x = 1:3, y = 1:5 ]       # 3x5 matrix with entries A_ij = i^j
3×5 Matrix{Int64}:
 1  1   1   1    1
 2  4   8  16   32
 3  9  27  81  243

The generated values can also be filtered using the if keyword, that is, the value will only be included in the array if the condition after if is true:

x = [ x^2 for x = 1:10 if x%3 == 0]    # Only for x that are multiples of 3
3-element Vector{Int64}:
  9
 36
 81

Like before, the data type of the elements in the array will be determined based on the values, but can also be enforced by putting the type name before the brackets:

y = Float64[ rand(-5:5) for i = 1:2, j = 1:10 ]
2×10 Matrix{Float64}:
 4.0  -1.0  -1.0  -3.0  -5.0  3.0  -4.0  1.0  4.0  -1.0
 2.0  -3.0   1.0   3.0  -1.0  0.0   5.0  5.0  0.0  -3.0

6.1.2. Generator expressions#

If you remove the brackets from a comprehension, you create a generator expression. It can be seen as a rule that produces the requested values on demand, without allocating an array to store them. Parentheses are needed to separate the generator from other elements:

gen = (i*(i-1) for i = 1:10)        # A generator expression
Base.Generator{UnitRange{Int64}, var"#13#14"}(var"#13#14"(), 1:10)
for x in gen                        # Loop over all the values in the generator expression
    print(x, " ")
end
0 2 6 12 20 30 42 56 72 90 

6.1.3. More on creating arrays#

Some other useful functions for creating arrays include the reshape function, which takes the data from one array and rearranges it into new dimensions:

reshape(1:15, 3, 5)
3×5 reshape(::UnitRange{Int64}, 3, 5) with eltype Int64:
 1  4  7  10  13
 2  5  8  11  14
 3  6  9  12  15

Note how the elements are assigned column-wise, that is, first into column 1, then column 2, etc. If you want to assign by rows, you can use the permutedims function (which is strongly related to the transpose of a matrix in linear algebra, more on this later):

permutedims(reshape(1:15, 5, 3))
3×5 Matrix{Int64}:
  1   2   3   4   5
  6   7   8   9  10
 11  12  13  14  15

Note how the inner matrix is of dimensions 5x3, so that after permutation the size is 3x5 just like before.

The repeat function repeats the entries of a given matrix according to a specified pattern. In its simplest form, it just copies the array:

repeat(1:2, 3)
6-element Vector{Int64}:
 1
 2
 1
 2
 1
 2

but it also works for multi-dimensional arrays:

repeat(1:2, 3, 4)
6×4 Matrix{Int64}:
 1  1  1  1
 2  2  2  2
 1  1  1  1
 2  2  2  2
 1  1  1  1
 2  2  2  2
repeat([1 2; 3 4], 1, 2)
2×4 Matrix{Int64}:
 1  2  1  2
 3  4  3  4