2025-08-25 Functions¶
Review last time
Julia intro
Julia plotting
Floating point numbers
Relative & absolute errors
Julia¶
Fairly new (2012)
Can be complied or interperted
Easy to pick up if you know Matlab or Python
CSCI provides JupyterHub at https://coding.csel.io
[1]:
# Note which one gets printed out
x = 13
y = 42
[1]:
42
[2]:
# Semicolons supress output printing
x = 9;
[3]:
# Can also do formatted printing
println("$x + $y = $(x + y)")
9 + 42 = 51
[4]:
# Also have the ability to print the operation and result
# Note the annoying side effect here of the parsing rules
@show x + y
x + y = 51
[4]:
51
[5]:
# And math can be written *as* math
@show area = π * x^2;
area = π * x ^ 2 = 254.46900494077323
Numbers¶
[6]:
# What are all of these types?
typeof(42), typeof(big(42)), typeof(42.0f0), typeof(42.0), typeof(big(42.0))
[6]:
(Int64, BigInt, Float32, Float64, BigFloat)
[7]:
# What are the promotion rules?
@show 13 + 42.0
@show 13.0f0 + 42.0
@show 13 + 42.0f0;
13 + 42.0 = 55.0
13.0f0 + 42.0 = 55.0
13 + 42.0f0 = 55.0f0
[8]:
# Watch out for division rules
@show 42 / 13
@show 42 ÷ 13;
42 / 13 = 3.230769230769231
42 ÷ 13 = 3
[9]:
# And how integer division works
@show -42 / 13
@show -42 ÷ 13;
-42 / 13 = -3.230769230769231
-42 ÷ 13 = -3
Arrays¶
[10]:
# Note that changing the type in assigment is ok
x = [1, 2, 3]
[10]:
3-element Vector{Int64}:
1
2
3
[11]:
# But I want floats?
x = Float64[4, 5, 6]
[11]:
3-element Vector{Float64}:
4.0
5.0
6.0
[12]:
# Note promotion rules still work
[1, 2, 3.] + [4, 5, 6]
[12]:
3-element Vector{Float64}:
5.0
7.0
9.0
[13]:
# 1 based indexing scheme (😭)
@show x[2] = 13
typeof(x[2])
x[2] = 13 = 13
[13]:
Float64
[14]:
# And matrixes are 2D arrays
A = [1. 2 3; 4 5 6; 7 8 9]
[14]:
3×3 Matrix{Float64}:
1.0 2.0 3.0
4.0 5.0 6.0
7.0 8.0 9.0
Functions¶
[15]:
# Basic syntax
function f(x, y; z = 3)
return (x + y) * z
end
[15]:
f (generic function with 1 method)
[16]:
# z is an optional parameter with a default value
@show y1 = f(1, 2)
@show y2 = f(1, 2; z = 4);
y1 = f(1, 2) = 9
y2 = f(1, 2; z = 4) = 12
[17]:
# But what is returned here?
function f(x, y; z = 3)
(x + y) * z
end
[17]:
f (generic function with 1 method)
[18]:
# Last statement executed in functino return value
@show y1 = f(1, 2)
@show y2 = f(1, 2; z = 4);
y1 = f(1, 2) = 9
y2 = f(1, 2; z = 4) = 12
[19]:
# Function 'assignment form'
f(x, y; z = 3) = (x + y) * z
[19]:
f (generic function with 1 method)
[20]:
# It works the same way - that's comforting
@show y1 = f(1, 2)
@show y2 = f(1, 2; z = 4);
y1 = f(1, 2) = 9
y2 = f(1, 2; z = 4) = 12
[21]:
# Anonymous functions
((x, y; z = 3) -> (x + y) * z)(1, 2; z = 8)
[21]:
24
[22]:
# This is useful in the same way as in Python or JS
map(x -> x^2, [2, 3, 4])
[22]:
3-element Vector{Int64}:
4
9
16
[23]:
[1, 2, 3] .* [4, 5, 6]
[23]:
3-element Vector{Int64}:
4
10
18
Loops¶
[24]:
# Ranges like in Python or Rust
1:13
[24]:
1:13
[25]:
# Can create arrays this way
collect(1:13.)
[25]:
13-element Vector{Float64}:
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
9.0
10.0
11.0
12.0
13.0
[26]:
# And for loops use ranges
iterations = 420000
hits = 0
for i in 1:iterations
hits += √(rand()^2 + rand()^2) ≤ 1
end
estimate = 4 * hits / iterations
@show π - estimate;
π - estimate = -0.00033115593401644716
[27]:
# List comprehension also works
estimate = sum([1/n^2 for n in 1:13000])
@show π^2 / 6 - estimate;
π ^ 2 / 6 - estimate = 7.692011841831103e-5
Plotting¶
[28]:
# Need to add package first
using Pkg
pkg"add Plots"
using Plots
default(lw=4, ms=5, legendfontsize=12, xtickfontsize=12, ytickfontsize=12)
a = 1e-15
plot(x -> (1 + x) - 1, xlim=(-a, a))
plot!(x -> x)
Updating registry at `~/.julia/registries/General.toml`
Resolving package versions...
No Changes to `~/.julia/environments/v1.11/Project.toml`
No Changes to `~/.julia/environments/v1.11/Manifest.toml`
[28]:
Machine precision¶
Floating point numbers do not exactly represent continuous values.
There exists \(\epsilon_\text{machine}\) such that
\[1 \oplus x = 1\]
for all
\[\lvert x \rvert < \epsilon_\text{machine}\]
Note: \(\oplus, \ominus, \otimes, \oslash\) are the floating point arithmatic versions of \(+, -, \times, /\)
[29]:
# Computing machine precision
ϵ = 1
while 1 + ϵ != 1
ϵ = ϵ / 2
end
# And lets ask Julia what ϵ actually is
@show ϵ
@show eps();
ϵ = 1.1102230246251565e-16
eps() = 2.220446049250313e-16
[30]:
# But why do we care?
f1(x) = log(1 + x)
f2(x) = x - x^2 / 2 + x^3 / 3 # Taylor series
f3(x) = log1p(x)
plot([f1, f2, f3], xlims=[-5 * ϵ, 5 * ϵ], label=["\$log(1+x)\$" "Taylor series" "\$log1p(x)\$"])
[30]:
[31]:
# How to measure the error?
y1 = f1(1e-8)
y2 = f2(1e-8)
# Absolute
println("absolute error: $(y1 - y2)")
# Relative
println("relative error: $((y1 - y2) / y2)")
absolute error: -6.07747099184471e-17
relative error: -6.077471022232065e-9