Julia Tutorial

Reference

  1. Think Julia

  2. From zero to Julia

  3. Julia cheat sheet if you are familiar with Python/MATLAB.

  4. Official Julia Docs for advanced topics and looking up.

First steps

Comments

# This is a single-line comment
#=
This is a
multiple-line comment
=#
2.6s
Julia

How to see the output

  • @show expression shows both the expression and the result.

  • println(stuff)for regular print and @printffor 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
@show 1 + 1
# Inline display of the last expression
"Done"
1.0s
Julia

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)
1.2s
Julia

Use  typeof(val) to see its data type.

@show typeof(x)
@show typeof(y)
@show typeof(c)
@show typeof(s)
0.7s
Julia

convert(T , x) converts x to type T if applicable.

@show convert(Float64, 2)
0.5s
Julia

Use the question mark ? if you are not sure about the parameters.

?range
0.9s
Julia

Special characters

Type \xxx<TAB>

α = 1  # \alpha<TAB>
β = 3.0 # \beta<TAB>
0.1s
Julia

Use a question mark (?) to ask Julia how to type a special character.

?π
0.5s
Julia

Binary operators

a = 2
b = 3
# Addition
@show a + b
# Substraction
@show a - b
# Multiplication
@show a * b
# Division with real number output
@show b / a
@show typeof(b / a)
# Power
@show a^a
# Modulus
@show b % a
# integer division: \div <TAB>`, equivalent to div(a, b)`
@show a÷b
@show typeof(a÷b)
# rational number
@show a//b      
# Approximation operator `\approx<TAB>` to compare floating point numbers
#  Equivalent to isapprox(1e10 + 1.0, 1e10)
@show 1e10 + 1.0  1e10
0.6s
Julia

Common math functions

@show sin(0.5*π)
@show cos(0.5*π)
@show cospi(1//2)  # More accurate alternative to cos(0.5*π)
@show sqrt(π)
@show π        #\sqrt<TAB>\pi<TAB>
@show log(10)   # Natual log
@show log10(10) # Common log
@show exp(-5)
@show exp(1e-10)-1, expm1(1e-10)
# Random number generator
@show uni01 = rand()     # Uniform distributed between 0 and 1 
@show dics = rand(1:6)
@show randomcharacter = rand("Hello");
0.9s
Julia

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 strings

  • str1*str2 or string(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 string

  • string(a, b) to convert a and b into strings and concatenate them

@show 'a' == "a"
@info """ 
Multiline
string
is here
"""
str1 = "BEBI"
str2 = "5009"
@show string("The class is ", str1, '-', str2)
@show "The class is $str1-$str2"
# println() supports multiple arguments
println("println(): The class is ", str1, '-', str2)
@show str1[2]
@show str1^3
@show str1*"-"*str2
0.7s
Julia

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
0.7s
Julia

Iterations (Loops)

while loops

while cond
    # code here
end

for loops

for x in sequence
    # process x
end
  • Use break to exit the loop

  • Use continue to jump to the next x or cond

  • 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
0.5s
Julia
Sum of 1 to 100 is 5050
xs = [1, 2, 3]
for x in xs
  println(x)
end
0.4s
Julia
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
0.4s
Julia

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
0.8s
Julia
# Example for anonymous functions
# map(f, seq) takes a function and a sequence
map(x -> x^2, 1:5)
1.5s
Julia

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 function

  • Objects 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)
0.2s
Julia
r1 = 1:2:9  # Lazy evaluation to save mem/CPU
0.5s
Julia
@show length(r1)
0.3s
Julia
length(r1) = 5
collect(r1)  # Until it's really needed (e.g. converting to arrays)
0.2s
Julia
# Julia's logspace
# Using dot syntax for element-wise (broadcasting) operations 
exp10.(-3.0:3.0)
0.9s
Julia

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]
0.2s
Julia
# 2D array (matrix)
A = [1 2 3;
     4 5 6]  
1.1s
Julia
# Matrix-vector multiplication
@show A*x
0.6s
Julia
A * x = [38, 92]
# Find the solution of x of Ax = b
# Using left division operator `/`
b = [38, 92]
@show A\b  # Should be approximately [5, 6, 7]
2.1s
Julia
A \ b = [5.000000000000002, 6.0, 6.999999999999997]
# convert `arr` to an 1D array (i.e. vectors)
@show vec(A)
0.3s
Julia
vec(A) = [1, 4, 2, 5, 3, 6]
# Arrays are mutable (i.e. you can replace the contents)
b = copy(x)  # Make a copy to preserve the original
0.1s
Julia
b[1] = 0
@show b
0.3s
Julia
b = [0, 6, 7]
# append `x` at the end of `arr`
append!(b, 10)
0.2s
Julia

Tuples

  • Immutable (you could not replace the elements)

  • Stack-allocated, faster than arrays in short sequences

a = (1, 2, 3)
@show a[1]
0.2s
Julia
a[1] = 1
# a[1] = 0  # (you could not replace the elements)
0.1s
Julia
tuple(1, 2, 3)
0.4s
Julia
# Splat operator ... to unfold a sequence to a series of arguments
# Slow at long sequence
tuple([1, 2, 3]...)
0.1s
Julia
# Returns multiple values in a function
function return_multiple()
    return (4, 5, 6)
end
return_multiple()
0.1s
Julia

Named tuples

Tuples with named fields so you don't have to remember the index number.

nt = (a=1, b=2, c=4)
0.5s
Julia
nt[1]
0.6s
Julia
nt.a
0.2s
Julia
nt[:a]
0.2s
Julia
nt.a == nt[:a] && nt.a == nt[1]
0.1s
Julia

Comprehensions

# comprehension for shorhand of sequence / matrix construction
[i + j for i in 0:3, j in 0:3]  # Constructing a 2D array
0.5s
Julia
[i + j for i in 0:3 for j in 0:3] # Note the difference (a 1D array)
0.3s
Julia

Dictionaries

Mapping of key => value.

eng2sp = Dict("one" => "uno", "two" => "dos", "three" => "tres")
1.1s
Julia
@show keys(eng2sp)
1.1s
Julia
keys(eng2sp) = ["two", "one", "three"]
@show values(eng2sp)
0.9s
Julia
values(eng2sp) = ["dos", "uno", "tres"]
@show eng2sp["one"]
0.3s
Julia
eng2sp["one"] = "uno"
@show get(eng2sp, "one", "N/A")
0.3s
Julia
get(eng2sp, "one", "N/A") = "uno"
# @show eng2sp["four"]
0.5s
Julia
@show get(eng2sp, "four", "N/A")
0.3s
Julia
get(eng2sp, "four", "N/A") = "N/A"
# Add entry
eng2sp["four"] = "cuatro"
@show eng2sp["four"]
0.3s
Julia
eng2sp["four"] = "cuatro"
# Unordered keys
for (k ,v) in eng2sp
    println(k, " => ", v)
end
0.5s
Julia
two => dos four => cuatro one => uno three => tres
# Alternative ways to build a dict
# From a tuple
t = [('a', 1), ('c', 3), ('b', 2)]
@show Dict(t)
1.1s
Julia
Dict(t) = Dict('a' => 1,'c' => 3,'b' => 2)
d = Dict(zip("abc", 1:3))
0.4s
Julia

Custom data structures

struct or mutable struct

I recommend a helper for structs: Parameters.jl

using Pkg
Pkg.add("Parameters")
parameters.jl
using Parameters
# The famous point example
@with_kw struct Point
    x = 0.0
    y = 0.0
end
2.0s
Julia
origin = Point()  # Use default values
0.4s
Julia
pA = Point(1, 2)
0.2s
Julia
# 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)
0.6s
Julia
distance(pA)  sqrt(5)
0.4s
Julia
pB = Point(pA; y=4)  # Reuse some of a's value
distance(pA, pB)
0.5s
Julia

Appendix

Runtimes (1)