## I like cell mode.
# This let's me group a whole bunch of expressions together and run them all at once.
function f(x)
y = x^2
return y + 1
end
f(3)
10
## This is a cell delimiter, so this won't run with the previous block
f(4)
17
## Why I like cell mode is you can build up a lot of code and then run it piece by piece
# Now let's prepare a plot
using CairoMakie
fig = lines(0:10, f.(0:10))
##
save("2025-Lecture-4-myplot.pdf", fig)
CairoMakie.Screen{PDF}
## Julia great types and function support
module MyModule
""" A simple matrix type
that represents a single non-zero entry
in a sparse matrix.
"""
struct MySingleIndexMatrix <: AbstractMatrix{Float64}
i::Int
j::Int
m::Int
n::Int
value::Float64
end
import Base.getindex, Base.size, Base.:+
function +(A::MySingleIndexMatrix, B::AbstractMatrix{Float64})
#println("Adding MySingleIndexMatrix to a dense matrix")
C = copy(B)
C[A.i, A.j] += A.value
return C
end
size(A::MySingleIndexMatrix) = (A.m, A.n)
function getindex(A::MySingleIndexMatrix, i::Int, j::Int)
if i == A.i && j == A.j
return A.value
else
return 0.0
end
end
end
A = MyModule.MySingleIndexMatrix(2, 3, 5, 5, 10.0)
A
5×5 Main.MyModule.MySingleIndexMatrix: 0.0 0.0 0.0 0.0 0.0 0.0 0.0 10.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
##
B = MyModule.MySingleIndexMatrix(2, 3, 1_000, 10_000, 10.0)
@time B + zeros(1_000, 10_000); # This is fast?
0.175680 seconds (5.75 k allocations: 152.875 MiB, 83.17% gc time, 3.19% compilation time)
## This is the way you should really do it
using BenchmarkTools
@btime begin
D2 = B + C;
end setup = (C = zeros(1_000, 10_000); B = MyModule.MySingleIndexMatrix(2, 3, 1_000, 10_000, 10.0);)
ArgumentError: Package BenchmarkTools not found in current path. - Run `import Pkg; Pkg.add("BenchmarkTools")` to install the BenchmarkTools package. Stacktrace: [1] macro expansion @ ./loading.jl:2296 [inlined] [2] macro expansion @ ./lock.jl:273 [inlined] [3] __require(into::Module, mod::Symbol) @ Base ./loading.jl:2271 [4] #invoke_in_world#3 @ ./essentials.jl:1089 [inlined] [5] invoke_in_world @ ./essentials.jl:1086 [inlined] [6] require(into::Module, mod::Symbol) @ Base ./loading.jl:2260
## Without the optimized routine, I see about 5ms vs. 3.6ms with it.