Vectors and matrices in Julia

Square brackets are used to enclose elements of a matrix or vector. Use spaces for horizontal concatenation, and semicolons or new lines to indicate vertical concatenation.

A = [ 1 2 3 4 5; 50 40 30 20 10
    pi sqrt(2) exp(1) (1+sqrt(5))/2 log(3) ]
3×5 Array{Float64,2}:
  1.0       2.0       3.0       4.0       5.0
 50.0      40.0      30.0      20.0      10.0
  3.14159   1.41421   2.71828   1.61803   1.09861
m,n = size(A)
(3, 5)

A vector is not quite the same thing as a matrix. It has only one dimension, not two. Separate its elements by commas.

x = [ 3, 3, 0, 1, 0 ]
size(x)
(5,)

For many purposes, though, an \(n\)-vector in Julia is a lot like an \(n\times 1\) column vector.

size( [3;3;0;1;0] )
(5,)

Concatenated elements within brackets may be matrices for a block representation, as long as all the block sizes are compatible.

AA = [ A; A ]
6×5 Array{Float64,2}:
  1.0       2.0       3.0       4.0       5.0
 50.0      40.0      30.0      20.0      10.0
  3.14159   1.41421   2.71828   1.61803   1.09861
  1.0       2.0       3.0       4.0       5.0
 50.0      40.0      30.0      20.0      10.0
  3.14159   1.41421   2.71828   1.61803   1.09861
B = [ zeros(3,2) ones(3,1) ]
3×3 Array{Float64,2}:
 0.0  0.0  1.0
 0.0  0.0  1.0
 0.0  0.0  1.0

The dot-quote .' transposes a matrix. A single quote ' on its own performs the hermitian (transpose and complex conjugation). For a real matrix, the two operations are the same.

A'
5×3 LinearAlgebra.Adjoint{Float64,Array{Float64,2}}:
 1.0  50.0  3.14159
 2.0  40.0  1.41421
 3.0  30.0  2.71828
 4.0  20.0  1.61803
 5.0  10.0  1.09861

If x is simply a vector, then its transpose has a row shape.

x'
1×5 LinearAlgebra.Adjoint{Int64,Array{Int64,1}}:
 3  3  0  1  0

There are many convenient shorthand ways of building vectors and matrices other than entering all of their entries directly or in a loop. To get a vector with evenly spaced entries between two endpoints, you have two options.

y = 1:4              # start:stop
1:4
z = ( 0:3:12 )'     # start:step:stop
1×5 LinearAlgebra.Adjoint{Int64,StepRange{Int64,Int64}}:
 0  3  6  9  12

(Technically, y above is not a vector but a range. It behaves identically in most circumstances.)

s = range(-1,stop=1,length=5)
-1.0:0.5:1.0

Accessing an element is done by giving one (for a vector) or two index values in square brackets. The keyword end as an index refers to the last position in the corresponding dimension.

a = A[2,end-1]
20.0
x[2]
3

The indices can be vectors or ranges, in which case a block of the matrix is accessed.

A[1:2,end-2:end]    # first two rows, last three columns
2×3 Array{Float64,2}:
  3.0   4.0   5.0
 30.0  20.0  10.0

If a dimension has only the index : (a colon), then it refers to all the entries in that dimension of the matrix.

A[:,1:2:end]        # all of the odd columns
3×3 Array{Float64,2}:
  1.0       3.0       5.0
 50.0      30.0      10.0
  3.14159   2.71828   1.09861

The matrix and vector senses of addition, subtraction, scalar multiplication, multiplication, and power are all handled by the usual symbols. If matrix sizes are such that the operation is not defined, an error message will result.

using LinearAlgebra
B = diagm( 0=>[-1,0,-5] )     # create a diagonal matrix
3×3 Array{Int64,2}:
 -1  0   0
  0  0   0
  0  0  -5
BA = B*A     # matrix product
3×5 Array{Float64,2}:
  -1.0    -2.0       -3.0     -4.0      -5.0
   0.0     0.0        0.0      0.0       0.0
 -15.708  -7.07107  -13.5914  -8.09017  -5.49306

A*B causes an error, so it is commented out here.

# A*B  # throws an error

A square matrix raised to an integer power is the same as repeated matrix multiplication.

B^3    # same as B*B*B
3×3 Array{Int64,2}:
 -1  0     0
  0  0     0
  0  0  -125

In many cases, one instead wants to treat a matrix or vector as a mere array and simply apply a single operation to each element of it. For multiplication, division, and power, the corresponding operators start with a dot.

C = -A;

A*C would be an error.

elementwise = A.*C
3×5 Array{Float64,2}:
    -1.0        -4.0    -9.0       -16.0       -25.0
 -2500.0     -1600.0  -900.0      -400.0      -100.0
    -9.8696     -2.0    -7.38906    -2.61803    -1.20695

The two operands of a dot operator have to have the same size—unless one is a scalar, in which case it is expanded or “broadcast” to be the same size as the other operand.

xtotwo = x.^2
5-element Array{Int64,1}:
 9
 9
 0
 1
 0
twotox = 2 .^ x
5-element Array{Int64,1}:
 8
 8
 1
 2
 1

Most of the mathematical functions, such as cos, sin, log, exp and sqrt, expect scalars as operands. However, you can broadcast any function across a vector or array by using a special dot syntax.

@show cos.(pi*x);      # vectorize a single function
@show @. cos(pi*x);    # vectorize an entire expression
cos.(pi * x) = [-1.0, -1.0, 1.0, -1.0, 1.0]
#= In[24]:2 =# @__dot__(cos(pi * x)) = [-1.0, -1.0, 1.0, -1.0, 1.0]