In general, unlike many other technical computing languages, Julia does not expect programs to be written in a vectorized style for performance. Julia’s compiler uses type inference and generates optimized code for scalar array indexing, allowing programs to be written in a style that is convenient and readable, without sacrificing performance, and using less memory at times.[1]
The above quote, taken directly from Julia documentation is the feature that got me into Julia in the first place. It might seem trivial at first, but this is the same level of paradigm-shift as PyTorch caused after Tensorflow. When the compiler isn’t responsible for vectorization, everyone else is! Let’s see how many people that is. The user must keep track of the best-practices, which must be maintained by the community. Moreover, packages need to be written to allow idiomatic vectorization. All this takes a lot of time and effort by way too many people. When the compiler is responsible instead, vectorization is a concern only for core developers.
Manually defining an array in Julia takes much less effort and keystrokes than most other languages.
Defining vectors is particularly pleasant, you can specify ranges (or elements) separated by a semicolon to concatenate all of them into a column vector:
julia> [1:3;4:6]
6-element Array{Int64,1}:
1
2
3
4
5
6
If instead of the semicolon, you use spaces, the concatenation is horizontal:
julia> [1:3 4:6]
3×2 Array{Int64,2}:
1 4
2 5
3 6
You can then combine the two types of concatenation to define matrices:
julia> A=[[1,2,3] [4,5,6] [7,8,9]]
3×3 Array{Int64,2}:
1 4 7
2 5 8
3 6 9
julia> A=[[1 2 3];[4 5 6];[7 8 9]]
3×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
You can force the ‘type’ of an array by prefixing with it:
julia> Real[[1 2 3];[4 5 6];[7 8 9]]
3×3 Array{Real,2}:
1 2 3
4 5 6
7 8 9
As must be familiar to you, arrays have many helper methods:
julia> eltype(A) #Element type of A
Int64
julia> ndims(A) #Number of dimensions of A
2
julia> size(A) #Shape of A
(3, 3)
Syntax for comprehension is as natural as could be, let’s see how you’d populate a matrix with the values of a polynomial in two variables at various points of the Argand plane:
julia> poly=[42x^3+3y^2+9x*y+1 for x=-3:3,y=3:9] #That's it! One line only!!
7×7 Array{Int64,2}:
-1187 -1193 -1193 -1187 -1175 -1157 -1133
-362 -359 -350 -335 -314 -287 -254
-41 -29 -11 13 43 79 121
28 49 76 109 148 193 244
97 127 163 205 253 307 367
418 457 502 553 610 673 742
1243 1291 1345 1405 1471 1543 1621
In general, the syntax is [ expression for var1=rangeVar1,var2=rangeVar2,...]
. Now, we showcase reshape
to define a higher dimensional matrix:
julia> A=reshape(1:64,(4,4,4))
4×4×4 reshape(::UnitRange{Int64}, 4, 4, 4) with eltype Int64:
[:, :, 1] =
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
[:, :, 2] =
17 21 25 29
18 22 26 30
19 23 27 31
20 24 28 32
[:, :, 3] =
33 37 41 45
34 38 42 46
35 39 43 47
36 40 44 48
[:, :, 4] =
49 53 57 61
50 54 58 62
51 55 59 63
52 56 60 64
Then, you’d index the matrix as per usual:
julia> poly[3,5]
43
julia> A[3,4,4]
63
You can also use this indexing to change a matrix:
julia> poly[end,end]=345678909876543 #change the bottom-right value
345678909876543
julia> poly
7×7 Array{Int64,2}:
-1187 -1193 -1193 -1187 -1175 -1157 -1133
-362 -359 -350 -335 -314 -287 -254
-41 -29 -11 13 43 79 121
28 49 76 109 148 193 244
97 127 163 205 253 307 367
418 457 502 553 610 673 742
1243 1291 1345 1405 1471 1543 345678909876543
You can also use ranges as indices:
julia> poly[1:2,:]
2×7 Array{Int64,2}:
-1187 -1193 -1193 -1187 -1175 -1157 -1133
-362 -359 -350 -335 -314 -287 -254
Remember that in Julia, ranges are inclusive, and indices start at 1, always.
Now, broadcasting, in Julia can be done explicitly:
julia> poly[1:2,:]=broadcast(+,1000000,poly[1:2,:])
2×7 Array{Int64,2}:
998813 998807 998807 998813 998825 998843 998867
999638 999641 999650 999665 999686 999713 999746
julia> poly
7×7 Array{Int64,2}:
998813 998807 998807 998813 998825 998843 998867
999638 999641 999650 999665 999686 999713 999746
-41 -29 -11 13 43 79 121
28 49 76 109 148 193 244
97 127 163 205 253 307 367
418 457 502 553 610 673 742
1243 1291 1345 1405 1471 1543 345678909876543
Or it can be done implicitly:
julia> poly[3:4,:] .+ -10000 #This doesn't change the matrix poly
2×7 Array{Int64,2}:
-10041 -10029 -10011 -9987 -9957 -9921 -9879
-9972 -9951 -9924 -9891 -9852 -9807 -9756
As homework, I suggest you play with the .*
operator on matrices with at least 4 dimensions. In the next article, we’ll be looking at Tuples in Julia.
In this tutorial, we will focus on MapReduce Algorithm, its working, example, Word Count Problem,…
Learn how to use Pyomo Packare to solve linear programming problems. In recent years, with…
In today's rapidly evolving technological landscape, machine learning has emerged as a transformative discipline, revolutionizing…
Analyze employee churn, Why employees are leaving the company, and How to predict, who will…
Airflow operators are core components of any workflow defined in airflow. The operator represents a…
Machine Learning Operations (MLOps) is a multi-disciplinary field that combines machine learning and software development…