Julia Tutorial
Reference
Julia cheat sheet if you are familiar with Python/MATLAB.
Official Julia Docs for advanced topics and looking up.
First steps
Comments
# This is a single-line comment
#=
This is a
multiple-line comment
=#
How to see the output
@show expression
shows both the expression and the result.println(stuff)
for regular print and@printf
for C-like formatted output.The result of the last expression will be displayed inline and saved to
ans
variable in the Julia REPL
# Regular text output: println() and print()
println("Using println()")
print(1, 2, 3, ' ')
# @show will print something like x = val
1 + 1
# Inline display of the last expression
"Done"
Data and variables
Assignment operator =
binds a name to a value : x = val
.
The data val
could be virtually anything: a literal (numbers, string, symbols), a data structure, a type, a function, a module, etc.
# Integer, 64 bit
x = 1
# Floating-point, 64-bit
y = 1.0
# A character is surrounded by single quotes
c = ' '
# Strings (Text) is surrounded by double quotes
s = "Julia"
# Constants will emit a warning if you try to change it
const theUltimateAnswer = 42
# Range object for a evenly-spaced sequence
# start:step:end, step is optional and defaults to 1
# They only store 2~3 numbers instead of a full array of numbers to save memory
xs = 1:10
ys = 10.0:-0.1:1.0
zs = range(1.0, 10.0, length=101)
Use typeof(val)
to see its data type.
typeof(x)
typeof(y)
typeof(c)
typeof(s)
convert(T , x
) converts x
to type T
if applicable.
convert(Float64, 2)
Use the question mark ?
if you are not sure about the parameters.
?range
Special characters
Type \xxx<TAB>
α = 1 # \alpha<TAB>
β = 3.0 # \beta<TAB>
Use a question mark (?
) to ask Julia how to type a special character.
?π
Binary operators
a = 2
b = 3
# Addition
a + b
# Substraction
a - b
# Multiplication
a * b
# Division with real number output
b / a
typeof(b / a)
# Power
a^a
# Modulus
b % a
# integer division: \div <TAB>`, equivalent to div(a, b)`
a÷b
typeof(a÷b)
# rational number
a//b
# Approximation operator `\approx<TAB>` to compare floating point numbers
# Equivalent to isapprox(1e10 + 1.0, 1e10)
1e10 + 1.0 ≈ 1e10
Common math functions
sin(0.5*π)
cos(0.5*π)
cospi(1//2) # More accurate alternative to cos(0.5*π)
sqrt(π)
√π #\sqrt<TAB>\pi<TAB>
log(10) # Natual log
log10(10) # Common log
exp(-5)
exp(1e-10)-1, expm1(1e-10)
# Random number generator
uni01 = rand() # Uniform distributed between 0 and 1
dics = rand(1:6)
randomcharacter = rand("Hello");
Official doc for rand(): https://docs.julialang.org/en/v1/stdlib/Random/
String manipulation
See: https://benlauwens.github.io/ThinkJulia.jl/latest/book.html#chap08
A string
is a sequence of characters.
''
for one character" ... "
for one line strings""" .... """
for multiline stringsstr1*str2
orstring(str1, str2)
to concatenate strings (the latter is recommended for it's more general and works not only in strings but also anything can turn into strings (e.g. numbers))^
to repeat a string:str^3
[idx]
to access an individual character$
to insert values into a stringstring(a, b)
to convert a and b into strings and concatenate them
'a' == "a"
"""
Multiline
string
is here
"""
str1 = "BEBI"
str2 = "5009"
string("The class is ", str1, '-', str2)
"The class is $str1-$str2"
# println() supports multiple arguments
println("println(): The class is ", str1, '-', str2)
str1[2]
str1^3
str1*"-"*str2
Controlling the flow of execution
if
clause
if cond1
exe1
elseif cond2
exe2
else
exe3
end
score = 30 + 70 * rand()
println("score is ", score)
if 80 < score <= 100
println("Good")
elseif 60 < score <= 80
println("Okay")
else
println("Uh-Oh")
end
Iterations (Loops)
while loops
while cond
# code here
end
for loops
for x in sequence
# process x
end
Use
break
to exit the loopUse
continue
to jump to the nextx
orcond
Use
start[:step]:end
for ranges (end-inclusive)
let s = 0
for i in 1:100
s = s + i
end
println("Sum of 1 to 100 is ", s)
end # let
xs = [1, 2, 3]
for x in xs
println(x)
end
let n = rand(1:1000000)
print("The length of hailstone sequence for ", n, " is ")
step = 0
# Hailstone sequence (3n+1 problem)
while n != 1
if n % 2 == 0
n = n÷2
else
n = 3n+1
end
step = step + 1
end
println(step)
end # let
Functions
For code reuse and encapsulating algorithms.
Formal definition.
x
can be 0 - multiple arguments.
function f(x)
# ....
end
one-line functions
f(x) = ....
anonymous functions
x -> ....
"Mechaelis-Menton function" # Function documentations
function mm(x, k)
result = x / (x +k)
return result # With explicit return statement
end
"Repressive Mechaelis-Menton function"
function mmr(x, k)
mm(k, x) # Implicitly returns the last statement, not recommended
end
"Hill function"
hill(x, k, n) = mm(x^n, k^n) # simple function are best for one-liners
"Repressive hill function"
hillr = (x, k, n) -> hill(k, x, n) # Usually for single use (e.g. inside map()) only
# Example for anonymous functions
# map(f, seq) takes a function and a sequence
map(x -> x^2, 1:5)
Optional arguments
https://techytok.com/lesson-functions/#optional-positional-arguments
function func(a, b, c=1)
...
end
Keyword arguments
https://techytok.com/lesson-functions/#keyword-arguments
function func(a, b; c=1)
...
end
Sequential objects and Data Structures
https://techytok.com/lesson-data-structures/
1-based indexing
length(seq)
to get the size of seq[]
to access elements in sequences (arrays, dictionaries, tuples)[start:step:end]
to access a slie of a sequences (not for dictionaries)
Empty arrays and dictionaries may have element type of
Any
and thus slower speed.Use
...
to splatting (unpack) arrays / tuples and pass its arguments to a functionObjects may share memory space, beware changing values accidentally
Dot syntax (e.g.
a .+ b
) for element-wise (broadcasting) operations
Ranges
Low-cost alternative to full arrays if the sequence is evenly spaced.
# Julia's linspace()
range(1, 10, length=100)
r1 = 1:2:9 # Lazy evaluation to save mem/CPU
length(r1)
collect(r1) # Until it's really needed (e.g. converting to arrays)
# Julia's logspace
# Using dot syntax for element-wise (broadcasting) operations
exp10.(-3.0:3.0)
Arrays
The bread and butter for scientific computing. Similar to numpy
's ndarrays
.
But with some caveats:
1-based indexing
Column-major (like Fortran) instead of C-style row-major
# 1D array (column vector)
x = [5, 6, 7]
# 2D array (matrix)
A = [1 2 3;
4 5 6]
# Matrix-vector multiplication
A*x
# Find the solution of x of Ax = b
# Using left division operator `/`
b = [38, 92]
A\b # Should be approximately [5, 6, 7]
# convert `arr` to an 1D array (i.e. vectors)
vec(A)
# Arrays are mutable (i.e. you can replace the contents)
b = copy(x) # Make a copy to preserve the original
b[1] = 0
b
# append `x` at the end of `arr`
append!(b, 10)
Tuples
Immutable (you could not replace the elements)
Stack-allocated, faster than arrays in short sequences
a = (1, 2, 3)
a[1]
# a[1] = 0 # (you could not replace the elements)
tuple(1, 2, 3)
# Splat operator ... to unfold a sequence to a series of arguments
# Slow at long sequence
tuple([1, 2, 3]...)
# Returns multiple values in a function
function return_multiple()
return (4, 5, 6)
end
return_multiple()
Named tuples
Tuples with named fields so you don't have to remember the index number.
nt = (a=1, b=2, c=4)
nt[1]
nt.a
nt[:a]
nt.a == nt[:a] && nt.a == nt[1]
Comprehensions
# comprehension for shorhand of sequence / matrix construction
[i + j for i in 0:3, j in 0:3] # Constructing a 2D array
[i + j for i in 0:3 for j in 0:3] # Note the difference (a 1D array)
Dictionaries
Mapping of key
=> value
.
eng2sp = Dict("one" => "uno", "two" => "dos", "three" => "tres")
keys(eng2sp)
values(eng2sp)
eng2sp["one"]
get(eng2sp, "one", "N/A")
# @show eng2sp["four"]
get(eng2sp, "four", "N/A")
# Add entry
eng2sp["four"] = "cuatro"
eng2sp["four"]
# Unordered keys
for (k ,v) in eng2sp
println(k, " => ", v)
end
# Alternative ways to build a dict
# From a tuple
t = [('a', 1), ('c', 3), ('b', 2)]
Dict(t)
d = Dict(zip("abc", 1:3))
Custom data structures
struct
or mutable struct
I recommend a helper for structs: Parameters.jl
using Pkg
Pkg.add("Parameters")
using Parameters
# The famous point example
struct Point
x = 0.0
y = 0.0
end
origin = Point() # Use default values
pA = Point(1, 2)
# Define a function specialized to Point type
distance(a::Point) = hypot(a.x, a.y)
distance(a::Point, b::Point) = hypot(a.x - b.x, a.y - b.y)
distance(pA) ≈ sqrt(5)
pB = Point(pA; y=4) # Reuse some of a's value
distance(pA, pB)