- Julia 1.0 Programming Complete Reference Guide
- Ivo Balbaert Adrian Salceanu
- 1472字
- 2021-06-24 14:21:47
Matrices
We know that the notation [1, 2, 3] is used to create an array. In fact, this notation denotes a special type of array, called a (column) vector in Julia, as shown in the following screenshot:

To create this as a row vector (1 2 3), use the notation [1 2 3] with spaces instead of commas. This array is of type 1 x 3 Array{Int64,2}, so it has two dimensions. (The spaces used in [1, 2, 3] are for readability only, we could have written this as [1,2,3]).
A matrix is a two- or multidimensional array (in fact, a matrix is an alias for the two-dimensional case). We can write this as follows:
Array{Int64, 1} == Vector{Int64} #> true Array{Int64, 2} == Matrix{Int64} #> true
As matrices are so prevalent in data science and numerical programming, Julia has an amazing range of functionalities for them.
To create a matrix, use space-separated values for the columns and semicolon-separated for the rows:
// code in Chapter 5\matrices.jl: matrix = [1 2; 3 4] 2x2 Array{Int64,2}: 1 2 3 4
So, the column vector from the beginning can also be written as [1; 2; 3]. However, you cannot use commas and semicolons together.
To get the value from a specific element in the matrix, you need to index it by row and then by column, for example, matrix[2, 1] returns the value 3 (second row, first column).
Using the same notation, one can calculate products of matrices such as [1 2] * [3 ; 4]; this is calculated as [1 2] * [3 4], which returns the value 11 (which is equal to 1*3 + 2*4). In contrast to this, conventional matrix multiplication is defined with the operator .*:
[1 2] .* [3 ; 4] # 2 Array{Int64,2}: # 3 6 # 4 8
To create a matrix from random numbers between 0 and 1, with three rows and five columns, use ma1 = rand(3, 5), which shows the following results:
3x5 Array{Float64,2}: 0.0626778 0.616528 0.60699 0.709196 0.900165 0.511043 0.830033 0.671381 0.425688 0.0437949 0.0863619 0.621321 0.78343 0.908102 0.940307
The ndims function can be used to obtain the number of dimensions of a matrix. Consider the following example:
julia> ndims(ma1) #> 2 julia> size(ma1) #> a tuple with the dimensions (3, 5)
To get the number of rows (3), run the following command:
julia> size(ma1,1) #> 3
The number of columns (5) is given by:
julia> size(ma1,2) #> 5 julia> length(ma1) #> 15, the number of elements
That's why you will often see this: nrows, ncols = size(ma), where ma is a matrix, nrows is the number of rows, and ncols is the number of columns.
If you need an identity matrix, where all the elements are zero, except for the elements on the diagonal that are 1.0, use the I function (from the LinearAlgebra package) with the argument 3 for a 3 x 3 matrix:
using LinearAlgebra idm = Matrix(1.0*I, 3, 3) #> 3x3 Array{Float64,2}: 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0
You can easily work with parts of a matrix, known as slices; these are similar to those used in Python and NumPy as follows:
- idm[1:end, 2] or shorter idm[:, 2] returns the entire second column
- idm[2, :] returns the entire second row
- idmc = idm[2:end, 2:end] returns the output as follows:
2x2 Array{Float64,2} 1.0 0.0 0.0 1.0
- idm[2, :] .= 0 sets the entire second row to 0
- idm[2:end, 2:end] = [ 5 7 ; 9 11 ] will change the matrix as follows:
1.0 0.0 0.0 0.0 5.0 7.0 0.0 9.0 11.0
Slicing operations create views into the original array rather than copying the data, so a change in the slice changes the original array or matrix.
Any multidimensional matrix can also be seen as a one-dimensional vector in column order, as follows:
a = [1 2;3 4] 2 Array{Int64,2}: 1 2 3 4 a[:] 4-element Array{Int64,1}: 1 3 2 4
To make an array of arrays (a jagged array), use an Array initialization, and then push! each array in its place, for example:
jarr = (Array{Int64, 1})[] push!(jarr, [1,2]) push!(jarr, [1,2,3,4]) push!(jarr, [1,2,3]) #=> 3-element Array{Array{Int64,1},1}: [1,2] [1,2,3,4] [1,2,3]
If ma is a matrix, say [1 2; 3 4], then ma' is the transpose matrix, that is [1 3; 2 4]:
ma: 1 2 ma' 1 3 3 4 2 4
Multiplication is defined between matrices, as in mathematics, so ma * ma' returns the 2 x 2 matrix or type Array{Int64,2} as follows:
5 11 11 25
If you need element-wise multiplication, use ma .* ma', which returns 2 x 2 Array{Int64,2}:
1 6 6 16
The inverse of a matrix ma (if it exists) is given by the inv(ma) function. The inv(ma) function returns 2 x 2 Array{Float64,2}:
-2.0 1.0 1.5 -0.5
The inverse means that ma * inv(ma) produces the identity matrix:
1.0 0.0 0.0 1.0
If v = [1.,2.,3.] and w = [2.,4.,6.], and you want to form a 3 x 2 matrix with these two column vectors, then use hcat(v, w) (for horizontal concatenation) to produce the following output:
1.0 2.0 2.0 4.0 3.0 6.0
vcat(v,w) (for vertical concatenation) results in a one-dimensional array with all the six elements with the same result as append!(v, w).
Thus, hcat concatenates vectors or matrices along the second dimension (columns), while vcat concatenates along the first dimension (rows). The more general cat can be used to concatenate multidimensional arrays along arbitrary dimensions.
There is an even simpler literal notation: to concatenate two matrices a and b with the same number of rows to a matrix c, just execute c = [a b]. now b is appended to the right of a. To put b beneath c, use c = [a; b]. The following is a concrete example, a = [1 2; 3 4]and b = [5 6; 7 8]:

The reshape function changes the dimensions of a matrix to new values if this is possible, for example:
reshape(1:12, 3, 4) #> returns a 3x4 array with the values 1 to 12 3x4 Array{Int64,2}: 1 4 7 10 2 5 8 11 3 6 9 12 a = rand(3, 3) #> produces a 3x3 Array{Float64,2} 3x3 Array{Float64,2}: 0.332401 0.499608 0.355623 0.0933291 0.132798 0.967591 0.722452 0.932347 0.809577 reshape(a, (9,1)) #> produces a 9x1 Array{Float64,2}: 9x1 Array{Float64,2}: 0.332401 0.0933291 0.722452 0.499608 0.132798 0.932347 0.355623 0.967591 0.809577 reshape(a, (2,2)) #> does not succeed: ERROR: DimensionMismatch("new dimensions (2,2) must be consistent
with array size 9")
When working with arrays that contain arrays, it is important to realize that such an array contains references to the contained arrays, not their values. If you want to make a copy of an array, you can use the copy() function, but this produces only a shallow copy with references to the contained arrays. In order to make a complete copy of the values, we need to use the deepcopy() function.
The following example makes this clear:
x = Array{Any}(undef, 2) #> 2-element Array{Any,1}: #undef #undef x[1] = ones(2) #> 2-element Array{Float64} 1.0 1.0 x[2] = trues(3) #> 3-element BitArray{1}: true true true x #> 2-element Array{Any,1}: [1.0,1.0] Bool[true,true,true] a = x b = copy(x)
c = deepcopy(x) # Now if we change x: x[1] = "Julia" x[2][1] = false x #> 2-element Array{Any,1}: "Julia" Bool[false,true,true] a #> 2-element Array{Any,1}: "Julia" Bool[false,true,true] isequal(a, x) #> true, a is identical to x b #> 2-element Array{Any,1}: [1.0,1.0] Bool[false,true,true] isequal(b, x) #> false, b is a shallow copy of x c #> 2-element Array{Any,1}: [1.0,1.0] Bool[true,true,true] isequal(c, x) #> false
The value of a remains identical to x when this changes, because it points to the same object in the memory. The deep copy c function remains identical to the original x. The b value retains the changes in a contained array of x, but not if one of the contained arrays becomes another array.
To further increase performance, consider using the statically-sized and immutable vectors and matrices from the ImmutableArrays package, which is a lot faster, certainly for small matrices, and particularly for vectors.
- 云原生Spring實戰
- Easy Web Development with WaveMaker
- SQL Server 2016數據庫應用與開發習題解答與上機指導
- Apache Kafka Quick Start Guide
- Mastering Xamarin.Forms(Second Edition)
- INSTANT Yii 1.1 Application Development Starter
- Couchbase Essentials
- Spring Boot實戰
- Azure Serverless Computing Cookbook
- C語言程序設計與應用(第2版)
- Django 3.0應用開發詳解
- Android應用開發實戰
- Vue.js 3應用開發與核心源碼解析
- Java程序設計
- CryENGINE Game Programming with C++,C#,and Lua