Introduction to Julia¶

STFC-Rutherford Appleton Laboratory, England

Thursday December 8, 2022

Alexis Montoison (alexis.montoison@polymtl.ca)

  • How to use Julia
  • Basic syntax and types
  • Control flow
  • Functions
  • More on types
  • Linear algebra
  • Package management
  • Advanced features

How to use Julia¶

REPL¶

The Read-Eval-Print-Loop (REPL) is the julia interactive shell

julia

Command line¶

You can execute a julia script from the command line

julia script.jl

To pass command line arguments

julia script.jl arg1 arg2 arg3

Command-line arguments are accessed within julia via the variable ARGS.

Jupyter¶

Julia is the "Ju" in "Jupyter"!

To run Julia in a notebook:

  • Install Jupyter (e.g. via Anaconda)
  • Install the IJulia package
  • Launch Jupyter

(if you skip the Jupyter installation, Julia will install a julia-only conda distribution)

Basic syntax and types¶

Basic types¶

Booleans

In [266]:
true
Out[266]:
true
In [267]:
typeof(true)
Out[267]:
Bool

Integers

In [268]:
1 + 1
Out[268]:
2
In [269]:
typeof(1)
Out[269]:
Int64

Floating point

In [270]:
1.0 + 2.0
Out[270]:
3.0
In [271]:
typeof(1.0)
Out[271]:
Float64

Floating-point arithmetic has limited precision!

In [272]:
(1.0 + 1e-16) == 1.0
Out[272]:
true
In [273]:
(1.0 + 1e-16) - 1e-16 == 1.0 + (1e-16 - 1e-16)
Out[273]:
false

Type correspondence:

Julia C
Int32 int
Int64 long
Float32 float
Float64 double

Strings are defined with double quotes

In [274]:
"Hello world!"
Out[274]:
"Hello world!"

Concatenate strings with *

In [275]:
"Hello" * " " * "world!"
Out[275]:
"Hello world!"

String interpolation eases the need for concatenation

In [276]:
x, y, z = "Alice", "Bob", "Charles"
"Hello $(x), $y and $(z)!"
Out[276]:
"Hello Alice, Bob and Charles!"

Symbols are human-readable unique identifiers

In [277]:
:symbol
typeof(:symbol)
Out[277]:
Symbol

Elementary data structures¶

Tuples are immutable collections of values

In [278]:
t1 = (1, 2, 3)
t2 = ("hello", 1, :x)
Out[278]:
("hello", 1, :x)
In [279]:
typeof(t1)
Out[279]:
Tuple{Int64, Int64, Int64}
In [280]:
typeof(t2)
Out[280]:
Tuple{String, Int64, Symbol}

Arrays are collections of values of the same type that are stored contiguously in memory.

In [281]:
u = [1, 2, 3]
Out[281]:
3-element Vector{Int64}:
 1
 2
 3
In [282]:
typeof(u)
Out[282]:
Vector{Int64} (alias for Array{Int64, 1})

/!\ Array indexing starts at 1 /!\

In [283]:
u[1]
Out[283]:
1

Elements automatically get promoted to the same type if necessary

In [284]:
v = [1.0, 2, 3]
Out[284]:
3-element Vector{Float64}:
 1.0
 2.0
 3.0
In [285]:
typeof(v)
Out[285]:
Vector{Float64} (alias for Array{Float64, 1})

If no common type can be inferred, the element type is Any

In [286]:
w = ["hello", 1, :x]
Out[286]:
3-element Vector{Any}:
  "hello"
 1
  :x
In [287]:
typeof(w)
Out[287]:
Vector{Any} (alias for Array{Any, 1})

Dictionnaries

In [288]:
d = Dict("a" => 1, "b" => 2, "c" => 3)
Out[288]:
Dict{String, Int64} with 3 entries:
  "c" => 3
  "b" => 2
  "a" => 1
In [289]:
d["a"]
Out[289]:
1
In [290]:
d["a"] = 2
d
Out[290]:
Dict{String, Int64} with 3 entries:
  "c" => 3
  "b" => 2
  "a" => 2
In [291]:
d["d"] = 4
Out[291]:
4

Control flow¶

If-then-else¶

In [292]:
if x == 0
    println("Hello 0!")
elseif x == 1
    println("Hello 1!")
elseif x == -1
    println("Hello -1!")
else
    println("Hello x")
end
Hello x

For loops¶

In [293]:
for i in 1:5
    println("Hello $(i)!")
end
Hello 1!
Hello 2!
Hello 3!
Hello 4!
Hello 5!

Iterate over arrays

In [294]:
u = [1, 4, 9, 16]
for x in u
    println(x)
end
1
4
9
16

Iterate over dictionnaries

In [295]:
d = Dict("a" => 1, "b" => 2, "c" => 3)
for (key, val) in d
    println("Key: $key, val: $val")
end
Key: c, val: 3
Key: b, val: 2
Key: a, val: 1

More generally: iterate over any collection

Comprehensions¶

Build a list of increasing integers

In [296]:
u = [i for i in 1:4]
Out[296]:
4-element Vector{Int64}:
 1
 2
 3
 4
In [297]:
v = [1 for _ in 1:4]
Out[297]:
4-element Vector{Int64}:
 1
 1
 1
 1

Build a matrix

In [298]:
A = [i*j for i in 1:4, j in 1:4]
Out[298]:
4×4 Matrix{Int64}:
 1  2   3   4
 2  4   6   8
 3  6   9  12
 4  8  12  16

Filter out some values

In [299]:
v = [i for i in 1:10 if i % 2 == 1]  # odd integers between 1 and 10
Out[299]:
5-element Vector{Int64}:
 1
 3
 5
 7
 9

Dictionnaries

In [300]:
d = Dict("$i" => i^2 for i in 1:5)
Out[300]:
Dict{String, Int64} with 5 entries:
  "4" => 16
  "1" => 1
  "5" => 25
  "2" => 4
  "3" => 9

Functions¶

To define a function:

In [301]:
function print_hello()
    println("Hello world!")
end
print_hello()
Hello world!

Functions can have arguments

In [302]:
function print_it(x, y)
    println(x)
    println(y)
end
print_it("Hello", 1)
print_it([1, 2], 47.0)
Hello
1
[1, 2]
47.0

Optional arguments are possible

In [303]:
function print_info(x; prefix="Value : ")
    println("$(prefix)$x")
end
print_info(3.1415)
print_info(3.1415, prefix="π = ")
Value : 3.1415
π = 3.1415

The return value of a function is specified with the keyword return

In [304]:
function my_mul(x, y)
    return x * y
end
my_mul(1, 2)
Out[304]:
2

Otherwise, the function returns the result of the last expression

Docstrings are written before the body of the function, and start/end with """. You can use Markdown syntax within docstrings.

In [305]:
"""
    my_mul(x, y, z)

Compute the product `x*y*z`
"""
function my_mul(x, y, z)
    return x * y * z
end
Out[305]:
my_mul

Always write docstrings!

Getting help¶

You can display a function's docstring by pre-prending ? to its name

In [306]:
?my_mul
search: my_mul

Out[306]:
my_mul(x, y, z)

Compute the product x*y*z

More on types¶

Everything in Julia has a type.

You don't need to specify types when declaring variables or function arguments... but sometimes it helps.

To avoid errors

In [307]:
"""
    my_fact(n)

Compute the factorial of `n`, i.e., `1*2*...*(n-1)*n`.
"""
function my_fact(n)
    if n == 1
        return 1
    else
        return n * my_fact(n - 1)
    end
end
my_fact(10)
Out[307]:
3628800
In [308]:
my_fact(1.5)
StackOverflowError:

Stacktrace:
 [1] my_fact(n::Float64) (repeats 79984 times)
   @ Main ./In[307]:10

Declaring your own types¶

Abstract types¶

In [309]:
abstract type AbstractFoo end

Abstract types

  • cannot have attributes
  • cannot be instantiated
In [310]:
AbstractFoo()
MethodError: no constructors have been defined for AbstractFoo

Stacktrace:
 [1] top-level scope
   @ In[310]:1
 [2] eval
   @ ./boot.jl:368 [inlined]
 [3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
   @ Base ./loading.jl:1428

Immutable types¶

are called struct in Julia (like C)

In [311]:
struct Foo
    x
end
In [312]:
foo = Foo(1.0)
Out[312]:
Foo(1.0)

You cannot modify the attributes of an immutable type

In [313]:
foo.x = 2
setfield!: immutable struct of type Foo cannot be changed

Stacktrace:
 [1] setproperty!(x::Foo, f::Symbol, v::Int64)
   @ Base ./Base.jl:39
 [2] top-level scope
   @ In[313]:1
 [3] eval
   @ ./boot.jl:368 [inlined]
 [4] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
   @ Base ./loading.jl:1428

Mutable types¶

are structs whose attributes can be modified.

In [314]:
mutable struct FooBar
    x
end
In [315]:
foo = FooBar(1.0)
typeof(foo)
Out[315]:
FooBar
In [316]:
foo.x = 2
Out[316]:
2

Parametrized types¶

Types can be parametrized by other types

In [317]:
Vector
Out[317]:
Vector (alias for Array{T, 1} where T)

You can parametrize by multiple types

In [318]:
struct MyFoo{Ti<:Integer, Tv<:AbstractFloat}
    i::Ti
    v::Tv
end
typeof(MyFoo(1, 1.0))
Out[318]:
MyFoo{Int64, Float64}
In [319]:
typeof(MyFoo(0x01, 1.0f0))
Out[319]:
MyFoo{UInt8, Float32}

What about functions?¶

Functions are not "attached" to classes like in object-oriented languages.

Functions have methods that are dispatched based on the types of all arguments: it's called multiple dispatch

In [320]:
@which +(1.0, 1.0)
Out[320]:
+(x::T, y::T) where T<:Union{Float16, Float32, Float64} in Base at float.jl:383
In [321]:
@which +(1.0, 1)
Out[321]:
+(x::Number, y::Number) in Base at promotion.jl:388
In [322]:
+
Out[322]:
+ (generic function with 206 methods)
In [323]:
methods(+)
Out[323]:
# 206 methods for generic function +:
  • +(x::T, y::T) where T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8} in Base at int.jl:87
  • +(x::T, y::T) where T<:Union{Float16, Float32, Float64} in Base at float.jl:383
  • +(c::Union{UInt16, UInt32, UInt64, UInt8}, x::BigInt) in Base.GMP at gmp.jl:531
  • +(c::Union{Int16, Int32, Int64, Int8}, x::BigInt) in Base.GMP at gmp.jl:537
  • +(c::Union{UInt16, UInt32, UInt64, UInt8}, x::BigFloat) in Base.MPFR at mpfr.jl:398
  • +(c::Union{Int16, Int32, Int64, Int8}, x::BigFloat) in Base.MPFR at mpfr.jl:406
  • +(c::Union{Float16, Float32, Float64}, x::BigFloat) in Base.MPFR at mpfr.jl:414
  • +(x::Union{Dates.CompoundPeriod, Dates.Period}) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/periods.jl:378
  • +(r1::StepRangeLen{T, R}, r2::StepRangeLen{T, R}) where {R<:Base.TwicePrecision, T} in Base at twiceprecision.jl:644
  • +(r1::StepRangeLen{T, S}, r2::StepRangeLen{T, S}) where {T, S} in Base at range.jl:1446
  • +(F::Hessenberg, J::UniformScaling) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:641
  • +(A::Symmetric, B::Symmetric) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/symmetric.jl:469
  • +(A::Symmetric, B::SymTridiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/symmetric.jl:486
  • +(S::Symmetric, D::Diagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/diagonal.jl:191
  • +(A::Symmetric{<:Any, <:AbstractSparseMatrix}, B::AbstractSparseMatrix) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/linalg.jl:15
  • +(A::Symmetric, B::AbstractSparseMatrix) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/linalg.jl:18
  • +(A::Symmetric{<:Real, <:AbstractSparseMatrix}, B::Hermitian{<:Any, <:AbstractSparseMatrix}) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/linalg.jl:25
  • +(A::Symmetric{var"#s884", S} where {var"#s884"<:Real, S<:(AbstractMatrix{<:var"#s884"})}, B::Hermitian) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/symmetric.jl:484
  • +(A::Symmetric{<:Any, <:AbstractSparseMatrix}, B::Hermitian{<:Any, <:AbstractSparseMatrix}) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/linalg.jl:23
  • +(x::T, y::Integer) where T<:AbstractChar in Base at char.jl:237
  • +(A::SparseArrays.AbstractSparseMatrixCSC, B::SparseArrays.AbstractSparseMatrixCSC) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/sparsematrix.jl:1829
  • +(A::SparseArrays.AbstractSparseMatrixCSC, B::Array) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/sparsematrix.jl:1832
  • +(A::SparseArrays.AbstractSparseMatrixCSC, J::UniformScaling) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/sparsematrix.jl:3821
  • +(y::AbstractFloat, x::Bool) in Base at bool.jl:172
  • +(r1::OrdinalRange, r2::OrdinalRange) in Base at range.jl:1423
  • +(A::BitArray, B::BitArray) in Base at bitarray.jl:1184
  • +(x::Base.TwicePrecision, y::Number) in Base at twiceprecision.jl:290
  • +(x::Base.TwicePrecision{T}, y::Base.TwicePrecision{T}) where T in Base at twiceprecision.jl:296
  • +(x::Base.TwicePrecision, y::Base.TwicePrecision) in Base at twiceprecision.jl:301
  • +(A::UnitLowerTriangular, B::LowerTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/triangular.jl:643
  • +(A::UnitLowerTriangular, B::UnitLowerTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/triangular.jl:645
  • +(UL::UnitLowerTriangular, J::UniformScaling) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/uniformscaling.jl:181
  • +(A::UnitLowerTriangular, B::Bidiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:98
  • +(x::Rational, y::Integer) in Base at rational.jl:313
  • +(A::UpperHessenberg, B::UpperHessenberg) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:101
  • +(H::UpperHessenberg, x::UniformScaling) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:108
  • +(H::UpperHessenberg, x::Diagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:108
  • +(H::UpperHessenberg, x::Bidiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:108
  • +(H::UpperHessenberg, x::Tridiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:108
  • +(H::UpperHessenberg, x::SymTridiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:108
  • +(H::UpperHessenberg, x::UpperTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:108
  • +(H::UpperHessenberg, x::UnitUpperTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:108
  • +(A::UnitUpperTriangular, B::UpperTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/triangular.jl:642
  • +(A::UnitUpperTriangular, B::UnitUpperTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/triangular.jl:644
  • +(UL::UnitUpperTriangular, J::UniformScaling) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/uniformscaling.jl:181
  • +(x::UnitUpperTriangular, H::UpperHessenberg) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:109
  • +(A::UnitUpperTriangular, B::Bidiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:98
  • +(Da::Diagonal, Db::Diagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/diagonal.jl:184
  • +(D::Diagonal, S::Symmetric) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/diagonal.jl:188
  • +(D::Diagonal{var"#s885", V} where {var"#s885"<:Real, V<:AbstractVector{var"#s885"}}, H::Hermitian) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/diagonal.jl:194
  • +(x::Diagonal, H::UpperHessenberg) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:109
  • +(A::Diagonal, B::Bidiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:137
  • +(A::Diagonal, B::SymTridiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:147
  • +(A::Diagonal, B::Tridiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:175
  • +(A::Diagonal{var"#s885", V} where {var"#s885"<:Number, V<:AbstractVector{var"#s885"}}, B::UniformScaling) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:253
  • +(x::AbstractSparseVector, y::AbstractSparseVector) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/sparsevector.jl:1392
  • +(A::AbstractSparseMatrix, B::Hermitian{<:Any, <:AbstractSparseMatrix}) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/linalg.jl:14
  • +(A::AbstractSparseMatrix, B::Hermitian) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/linalg.jl:17
  • +(A::AbstractSparseMatrix, B::Symmetric{<:Any, <:AbstractSparseMatrix}) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/linalg.jl:14
  • +(A::AbstractSparseMatrix, B::Symmetric) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/linalg.jl:17
  • +(index1::CartesianIndex{N}, index2::CartesianIndex{N}) where N in Base.IteratorsMD at multidimensional.jl:114
  • +(r1::LinRange{T}, r2::LinRange{T}) where T in Base at range.jl:1430
  • +(r1::Union{LinRange, OrdinalRange, StepRangeLen}, r2::Union{LinRange, OrdinalRange, StepRangeLen}) in Base at range.jl:1439
  • +(r::AbstractRange{<:Dates.TimeType}, x::Dates.Period) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/ranges.jl:64
  • +(x::AbstractArray{<:Dates.TimeType}, y::Union{Dates.CompoundPeriod, Dates.Period}) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/deprecated.jl:6
  • +(J::UniformScaling) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/uniformscaling.jl:149
  • +(J::UniformScaling, x::Number) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/uniformscaling.jl:144
  • +(J1::UniformScaling, J2::UniformScaling) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/uniformscaling.jl:150
  • +(J::UniformScaling, B::BitMatrix) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/uniformscaling.jl:152
  • +(x::UniformScaling, H::UpperHessenberg) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:109
  • +(J::UniformScaling, F::Hessenberg) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:642
  • +(A::UniformScaling, B::Tridiagonal{var"#s885", V} where {var"#s885"<:Number, V<:AbstractVector{var"#s885"}}) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:257
  • +(A::UniformScaling, B::SymTridiagonal{var"#s885", V} where {var"#s885"<:Number, V<:AbstractVector{var"#s885"}}) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:262
  • +(A::UniformScaling, B::Bidiagonal{var"#s885", V} where {var"#s885"<:Number, V<:AbstractVector{var"#s885"}}) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:267
  • +(A::UniformScaling, B::Diagonal{var"#s885", V} where {var"#s885"<:Number, V<:AbstractVector{var"#s885"}}) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:272
  • +(J::UniformScaling, A::AbstractMatrix) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/uniformscaling.jl:153
  • +(A::Bidiagonal, B::Bidiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/bidiag.jl:365
  • +(x::Bidiagonal, H::UpperHessenberg) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:109
  • +(A::Bidiagonal, B::UpperTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:106
  • +(A::Bidiagonal, B::UnitUpperTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:106
  • +(A::Bidiagonal, B::LowerTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:106
  • +(A::Bidiagonal, B::UnitLowerTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:106
  • +(A::Bidiagonal, B::Diagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:127
  • +(A::Bidiagonal, B::Tridiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:195
  • +(A::Bidiagonal, B::SymTridiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:215
  • +(A::Bidiagonal{var"#s885", V} where {var"#s885"<:Number, V<:AbstractVector{var"#s885"}}, B::UniformScaling) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:248
  • +(x::Dates.Instant) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:4
  • +(x::Ptr, y::Integer) in Base at pointer.jl:159
  • +(A::Tridiagonal, B::Tridiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/tridiag.jl:741
  • +(x::Tridiagonal, H::UpperHessenberg) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:109
  • +(A::Tridiagonal, B::SymTridiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:169
  • +(A::Tridiagonal, B::Diagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:185
  • +(A::Tridiagonal, B::Bidiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:205
  • +(A::Tridiagonal{var"#s885", V} where {var"#s885"<:Number, V<:AbstractVector{var"#s885"}}, B::UniformScaling) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:238
  • +(A::Hermitian, B::Hermitian) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/symmetric.jl:469
  • +(A::Hermitian, B::SymTridiagonal{var"#s882", V} where {var"#s882"<:Real, V<:AbstractVector{var"#s882"}}) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/symmetric.jl:488
  • +(H::Hermitian, D::Diagonal{var"#s885", V} where {var"#s885"<:Real, V<:AbstractVector{var"#s885"}}) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/diagonal.jl:197
  • +(A::Hermitian, J::UniformScaling{<:Complex}) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/uniformscaling.jl:195
  • +(A::Hermitian{<:Any, <:AbstractSparseMatrix}, B::AbstractSparseMatrix) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/linalg.jl:15
  • +(A::Hermitian, B::AbstractSparseMatrix) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/linalg.jl:18
  • +(A::Hermitian{<:Any, <:AbstractSparseMatrix}, B::Symmetric{<:Real, <:AbstractSparseMatrix}) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/linalg.jl:26
  • +(A::Hermitian, B::Symmetric{var"#s885", S} where {var"#s885"<:Real, S<:(AbstractMatrix{<:var"#s885"})}) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/symmetric.jl:483
  • +(A::Hermitian{<:Any, <:AbstractSparseMatrix}, B::Symmetric{<:Any, <:AbstractSparseMatrix}) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/linalg.jl:24
  • +(x::P, y::P) where P<:Dates.Period in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/periods.jl:77
  • +(x::Dates.Period, y::Dates.Period) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/periods.jl:367
  • +(y::Dates.Period, x::Dates.CompoundPeriod) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/periods.jl:369
  • +(y::Dates.Period, x::Dates.TimeType) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:85
  • +(x::Dates.Period, r::AbstractRange{<:Dates.TimeType}) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/ranges.jl:63
  • +(y::Union{Dates.CompoundPeriod, Dates.Period}, x::AbstractArray{<:Dates.TimeType}) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/deprecated.jl:14
  • +(z::Complex, w::Complex) in Base at complex.jl:288
  • +(y::Dates.TimeType, x::StridedArray{<:Union{Dates.CompoundPeriod, Dates.Period}}) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/deprecated.jl:18
  • +(A::SymTridiagonal, B::SymTridiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/tridiag.jl:207
  • +(A::SymTridiagonal, B::Symmetric) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/symmetric.jl:485
  • +(A::SymTridiagonal{var"#s883", V} where {var"#s883"<:Real, V<:AbstractVector{var"#s883"}}, B::Hermitian) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/symmetric.jl:487
  • +(x::SymTridiagonal, H::UpperHessenberg) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:109
  • +(A::SymTridiagonal, B::Diagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:157
  • +(A::SymTridiagonal, B::Tridiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:171
  • +(A::SymTridiagonal, B::Bidiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:225
  • +(A::SymTridiagonal{var"#s885", V} where {var"#s885"<:Number, V<:AbstractVector{var"#s885"}}, B::UniformScaling) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:243
  • +(A::LowerTriangular, B::LowerTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/triangular.jl:639
  • +(A::LowerTriangular, B::UnitLowerTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/triangular.jl:641
  • +(A::LowerTriangular, B::Bidiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:98
  • +(A::UpperTriangular, B::UpperTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/triangular.jl:638
  • +(A::UpperTriangular, B::UnitUpperTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/triangular.jl:640
  • +(A::LinearAlgebra.AbstractTriangular, B::LinearAlgebra.AbstractTriangular) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/triangular.jl:646
  • +(x::UpperTriangular, H::UpperHessenberg) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/hessenberg.jl:109
  • +(A::UpperTriangular, B::Bidiagonal) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/special.jl:98
  • +(x::AbstractIrrational, y::AbstractIrrational) in Base at irrationals.jl:158
  • +(A::Array, Bs::Array...) in Base at arraymath.jl:12
  • +(X::StridedArray{<:Union{Dates.CompoundPeriod, Dates.Period}}, Y::StridedArray{<:Union{Dates.CompoundPeriod, Dates.Period}}) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/deprecated.jl:62
  • +(A::Array, B::SparseArrays.AbstractSparseMatrixCSC) in SparseArrays at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/SparseArrays/src/sparsematrix.jl:1833
  • +(x::StridedArray{<:Union{Dates.CompoundPeriod, Dates.Period}}) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/deprecated.jl:55
  • +(x::StridedArray{<:Union{Dates.CompoundPeriod, Dates.Period}}, y::Dates.TimeType) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/deprecated.jl:10
  • +(A::AbstractArray, B::AbstractArray) in Base at arraymath.jl:6
  • +(x::BigFloat, c::Union{UInt16, UInt32, UInt64, UInt8}) in Base.MPFR at mpfr.jl:393
  • +(x::BigFloat, c::Union{Int16, Int32, Int64, Int8}) in Base.MPFR at mpfr.jl:401
  • +(x::BigFloat, c::Union{Float16, Float32, Float64}) in Base.MPFR at mpfr.jl:409
  • +(x::BigFloat, y::BigFloat) in Base.MPFR at mpfr.jl:386
  • +(x::BigFloat, c::BigInt) in Base.MPFR at mpfr.jl:417
  • +(a::BigFloat, b::BigFloat, c::BigFloat) in Base.MPFR at mpfr.jl:558
  • +(a::BigFloat, b::BigFloat, c::BigFloat, d::BigFloat) in Base.MPFR at mpfr.jl:564
  • +(a::BigFloat, b::BigFloat, c::BigFloat, d::BigFloat, e::BigFloat) in Base.MPFR at mpfr.jl:571
  • +(x::BigInt, c::Union{UInt16, UInt32, UInt64, UInt8}) in Base.GMP at gmp.jl:530
  • +(x::BigInt, c::Union{Int16, Int32, Int64, Int8}) in Base.GMP at gmp.jl:536
  • +(x::BigInt, y::BigInt) in Base.GMP at gmp.jl:482
  • +(a::BigInt, b::BigInt, c::BigInt) in Base.GMP at gmp.jl:522
  • +(a::BigInt, b::BigInt, c::BigInt, d::BigInt) in Base.GMP at gmp.jl:523
  • +(a::BigInt, b::BigInt, c::BigInt, d::BigInt, e::BigInt) in Base.GMP at gmp.jl:524
  • +(x::BigInt, y::BigInt, rest::BigInt...) in Base.GMP at gmp.jl:657
  • +(c::BigInt, x::BigFloat) in Base.MPFR at mpfr.jl:422
  • +(x::Rational{BigInt}, y::Rational{BigInt}) in Base.GMP.MPQ at gmp.jl:922
  • +(x::Rational) in Base at rational.jl:270
  • +(x::Rational, y::Rational) in Base at rational.jl:284
  • +(level::Base.CoreLogging.LogLevel, inc::Integer) in Base.CoreLogging at logging.jl:131
  • +(x::Bool) in Base at bool.jl:159
  • +(x::Integer, y::Ptr) in Base at pointer.jl:161
  • +(y::Integer, x::Rational) in Base at rational.jl:320
  • +(x::Integer, y::AbstractChar) in Base at char.jl:247
  • +(x::Bool, y::T) where T<:AbstractFloat in Base at bool.jl:169
  • +(x::Bool, y::Bool) in Base at bool.jl:162
  • +(a::Integer, b::Integer) in Base at int.jl:987
  • +(x::Bool, z::Complex{Bool}) in Base at complex.jl:299
  • +(x::Real, z::Complex{Bool}) in Base at complex.jl:313
  • +(x::Bool, z::Complex) in Base at complex.jl:306
  • +(x::Real, z::Complex) in Base at complex.jl:325
  • +(::Missing) in Base at missing.jl:101
  • +(::Missing, ::Number) in Base at missing.jl:123
  • +(x::Missing, y::Dates.AbstractTime) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:89
  • +(::Missing, ::Missing) in Base at missing.jl:122
  • +(z::Complex{Bool}, x::Bool) in Base at complex.jl:300
  • +(z::Complex, x::Bool) in Base at complex.jl:307
  • +(z::Complex{Bool}, x::Real) in Base at complex.jl:314
  • +(z::Complex) in Base at complex.jl:286
  • +(x::Number, y::Base.TwicePrecision) in Base at twiceprecision.jl:294
  • +(::Number, ::Missing) in Base at missing.jl:124
  • +(x::Number, J::UniformScaling) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/uniformscaling.jl:145
  • +(z::Complex, x::Real) in Base at complex.jl:326
  • +(x::Number) in Base at operators.jl:528
  • +(x::T, y::T) where T<:Number in Base at promotion.jl:463
  • +(x::Number, y::Number) in Base at promotion.jl:388
  • +(a::Pkg.Resolve.FieldValue, b::Pkg.Resolve.FieldValue) in Pkg.Resolve at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Pkg/src/Resolve/fieldvalues.jl:43
  • +(dt::Dates.DateTime, y::Dates.Year) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:23
  • +(dt::Dates.DateTime, z::Dates.Month) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:47
  • +(x::Dates.DateTime, y::Dates.Quarter) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:75
  • +(x::Dates.DateTime, y::Dates.Period) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:81
  • +(a::Pkg.Resolve.VersionWeight, b::Pkg.Resolve.VersionWeight) in Pkg.Resolve at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Pkg/src/Resolve/versionweights.jl:22
  • +(x::Dates.Time, y::Dates.TimePeriod) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:83
  • +(t::Dates.Time, dt::Dates.Date) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:20
  • +(dt::Dates.Date, t::Dates.Time) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:19
  • +(dt::Dates.Date, y::Dates.Year) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:27
  • +(dt::Dates.Date, z::Dates.Month) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:54
  • +(x::Dates.Date, y::Dates.Quarter) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:73
  • +(x::Dates.Date, y::Dates.Week) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:77
  • +(x::Dates.Date, y::Dates.Day) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:79
  • +(x::Dates.TimeType) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:8
  • +(x::Dates.AbstractTime, y::Missing) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/arithmetic.jl:88
  • +(a::Dates.TimeType, b::Dates.Period, c::Dates.Period) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/periods.jl:389
  • +(a::Dates.TimeType, b::Dates.Period, c::Dates.Period, d::Dates.Period...) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/periods.jl:390
  • +(x::Dates.TimeType, y::Dates.CompoundPeriod) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/periods.jl:392
  • +(B::BitMatrix, J::UniformScaling) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/uniformscaling.jl:151
  • +(A::AbstractMatrix, J::UniformScaling) in LinearAlgebra at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/uniformscaling.jl:214
  • +(x::AbstractArray{<:Number}) in Base at abstractarraymath.jl:220
  • +(x::Dates.CompoundPeriod, y::Dates.Period) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/periods.jl:368
  • +(x::Dates.CompoundPeriod, y::Dates.TimeType) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/periods.jl:398
  • +(x::Dates.CompoundPeriod, y::Dates.CompoundPeriod) in Dates at /home/alexis/julia/julia-1.8.3/share/julia/stdlib/v1.8/Dates/src/periods.jl:370
  • +(a, b, c, xs...) in Base at operators.jl:591

Linear algebra¶

To use linear algebra functions, use the LinearAlgebra package (part of the standard library)

In [324]:
using LinearAlgebra

Vectors and Matrices¶

A vector is a uni-dimensional array

In [325]:
Vector{Float32}
Out[325]:
Vector{Float32} (alias for Array{Float32, 1})
In [326]:
x = [1.0, 2.0]
Out[326]:
2-element Vector{Float64}:
 1.0
 2.0

A matrix is a two-dimensional array

In [327]:
Matrix{Float64}
Out[327]:
Matrix{Float64} (alias for Array{Float64, 2})
In [328]:
A = [
    1.0 2.0;
    3.0 4.0
]
Out[328]:
2×2 Matrix{Float64}:
 1.0  2.0
 3.0  4.0

Linear algebra operations¶

Matrix-vector products work out of the box

In [329]:
A * x  # mul!(y, A, x) for an in-place variant
Out[329]:
2-element Vector{Float64}:
  5.0
 11.0

Solve linear systems

In [330]:
b = A * x
y = A \ b
Out[330]:
2-element Vector{Float64}:
 1.0
 2.0

You can't multiply two vectors

In [331]:
x * x
MethodError: no method matching *(::Vector{Float64}, ::Vector{Float64})
Closest candidates are:
  *(::Any, ::Any, ::Any, ::Any...) at operators.jl:591
  *(::StridedMatrix{T}, ::StridedVector{S}) where {T<:Union{Float32, Float64, ComplexF32, ComplexF64}, S<:Real} at ~/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/matmul.jl:49
  *(::StridedVecOrMat, ::Adjoint{<:Any, <:LinearAlgebra.LQPackedQ}) at ~/julia/julia-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/lq.jl:269
  ...

Stacktrace:
 [1] top-level scope
   @ In[331]:1
 [2] eval
   @ ./boot.jl:368 [inlined]
 [3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
   @ Base ./loading.jl:1428

But inner and outer product is OK

In [332]:
x' * x  # inner product
Out[332]:
5.0
In [333]:
x * x'  # outer product
Out[333]:
2×2 Matrix{Float64}:
 1.0  2.0
 2.0  4.0

BLAS / LAPACK¶

For real/complex numbers in Float32, Float64 precision:

  • dense vector-vector, matrix-vector, matrix-matrix operations call BLAS
  • dense matrix factorizations call LAPACK

You can also call BLAS/LAPACK functions directly

In [334]:
C = zeros(2, 2);
A = ones(2, 4);
BLAS.syrk!('U', 'N', 1.0, A, 0.0, C)  # computes C = α A*A' + β C
Out[334]:
2×2 Matrix{Float64}:
 4.0  4.0
 0.0  4.0

Sparse linear algebra¶

In [335]:
using SparseArrays
In [336]:
A = sparse([1, 2, 3], [1, 2, 3], [1.0, 1.0, 1.0])
Out[336]:
3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
 1.0   ⋅    ⋅ 
  ⋅   1.0   ⋅ 
  ⋅    ⋅   1.0
In [337]:
Matrix(A)
Out[337]:
3×3 Matrix{Float64}:
 1.0  0.0  0.0
 0.0  1.0  0.0
 0.0  0.0  1.0

Sparse factorization call the CHOLMOD module from SuiteSparse.

Community wrappers to MUMPS, Pardiso, HSL linear solvers.

Package management¶

Julia's package manager is Pkg (https://julialang.github.io/Pkg.jl/v1/).

In [338]:
using Pkg

Packages are organized into environments.

An environment is a set of packages.

Install / remove packages¶

Install a package with Pkg.add

In [339]:
Pkg.add("HSL")
   Resolving package versions...
   Installed HSL ─ v0.3.5
    Updating `~/Bureau/Angleterre/presentation/Project.toml`
  [34c5aeac] + HSL v0.3.5
    Updating `~/Bureau/Angleterre/presentation/Manifest.toml`
  [34c5aeac] + HSL v0.3.5
  [40b5814e] + METIS4_jll v400.0.301+0
⌅ [656ef2d0] + OpenBLAS32_jll v0.3.17+0
        Info Packages marked with ⌅ have new versions available but compatibility constraints restrict them from upgrading. To see why use `status --outdated -m`
    Building HSL → `~/.julia/scratchspaces/44cfe95a-1eb2-52ea-b672-e2afdf69b78f/7fecf9d7da2d5442a966b721952e0f4f3d8ad833/build.log`
Precompiling project...
  ✓ HSL
  1 dependency successfully precompiled in 2 seconds. 176 already precompiled.

Update a package

In [340]:
Pkg.update("HSL")
    Updating registry at `~/.julia/registries/General.toml`
  No Changes to `~/Bureau/Angleterre/presentation/Project.toml`
  No Changes to `~/Bureau/Angleterre/presentation/Manifest.toml`

Remove a package

In [341]:
Pkg.rm("HSL")
    Updating `~/Bureau/Angleterre/presentation/Project.toml`
  [34c5aeac] - HSL v0.3.5
    Updating `~/Bureau/Angleterre/presentation/Manifest.toml`
  [34c5aeac] - HSL v0.3.5
  [40b5814e] - METIS4_jll v400.0.301+0
  [656ef2d0] - OpenBLAS32_jll v0.3.17+0

Projects and Project.toml¶

The project file describes the project on a high level, for example the package/project dependencies and compatibility constraints are listed in the project file.

The Project.toml file contains the list of all packages in that environment and compatibility requirements (if any).

In [342]:
; cat Project.toml
[deps]
DoubleFloats = "497a8b3b-efae-58df-a0af-a86822472b78"
HarwellRutherfordBoeing = "ce388394-9b3f-5993-a911-eb95552e4f2e"
ILUZero = "88f59080-6952-5380-9ea5-54057fb9a43f"
IncompleteLU = "40713840-3770-5561-ab4c-a76e7d0d7895"
Krylov = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7"
LimitedLDLFactorizations = "f5a24dde-3ab7-510b-b81b-6a72c6098d3b"
LinearOperators = "5c8ed15e-5a4c-59e4-a42b-c7e8811fb125"
MAT = "23992714-dd62-5051-b70f-ba57cb901cac"
MatrixMarket = "4d4711f2-db25-561a-b6b3-d35e7d4047d3"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Quadmath = "be4d8f0f-7fa4-5f49-b795-2f01399ab2dd"
SuiteSparseMatrixCollection = "ac199af8-68bc-55b8-82c4-7abd6f96ed98"
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"

Package versions and Manifest.toml¶

The exact set of packages and versions in an environment is captured in a manifest file which can be checked into a project repository and tracked in version control

The Manifest.toml file contains the exact version of every installed package, including all hidden dependencies.

If your Manifest.toml file is the same, your package version are the same.

Working with environments¶

From Julia: use Pkg.activate

In [343]:
# activate environment located in current folder
Pkg.activate(".")
  Activating project at `~/Bureau/Angleterre/presentation`

When using Julia from the command line

julia --project=. script.jl

Re-using someone else's environment¶

First download and install all packages

In [344]:
Pkg.activate(".")  # activate environment
Pkg.instantiate()  # download and install packages
  Activating project at `~/Bureau/Angleterre/presentation`

Good to go!

Code structure¶

When starting a new project¶

  • Create a new environment at the root of the repository
  • Use version control on Project.toml and Manifest.toml
--docs/
--src/
--test/
Project.toml
Manifest.toml
README.md

Code loading¶

https://docs.julialang.org/en/v1/manual/code-loading/

Code inclusion¶

Code from a different file can be loaded

In [345]:
include("hello.jl")
Hello world! Current time is 1.670461640667626e9s
In [346]:
include("hello.jl")
Hello world! Current time is 1.670461642692941e9s

This causes the contents of the file to be evaluated in the global scope.

Your code gets executed every time you call include.

Package loading¶

You can load packages with import / using

In [347]:
import Krylov
cg
Out[347]:
cg (generic function with 2 methods)
In [348]:
Krylov.cg
Out[348]:
cg (generic function with 2 methods)

using allows you to use exported names in the current namespace

In [349]:
using Krylov
cg
Out[349]:
cg (generic function with 2 methods)

Compilation and timing¶

In Julia code is compiled just-in-time => some compilation happens while you execute your code.

Be careful when timing code execution!

In [350]:
"""Compute the sum of the elements in a vector."""
function my_sum(u::Vector{T}) where{T}
    s = zero(T)
    for x in u
        s += x
    end
    return s
end

u = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
v = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0];

The first time a function is called, it is compiled. Subsequent calls are fast.

In [351]:
@time my_sum(u)  # First time (with Int64): compilation happens
@time my_sum(u)  # Second time: no compilation
  0.028128 seconds (4.03 k allocations: 196.912 KiB, 99.86% compilation time)
  0.000006 seconds
Out[351]:
55
In [352]:
@time my_sum(v)  # First time (with Float64): compilation happens
@time my_sum(v)  # Second time: no compilation
  0.024584 seconds (4.03 k allocations: 196.717 KiB, 99.84% compilation time)
  0.000030 seconds (1 allocation: 16 bytes)
Out[352]:
55.0

Timing code properly¶

If you only care about the result => compilation doesn't impact you.

If you care about execution time => compilation does impact you.

Possible fix:

  • Run your function twice, time only the second execution
  • Run your function on a small example, then on your real problem

Command line execution¶

Everytime you run

julia --project=. hello.jl

Julia has to re-compile a part of your code.

Make sure what you're timing does not include compilation times!