A set of introductory exercises for Julia. Based on 100 NumPy Exercises.
In order to generate this file:
- Clone the repository (Or download).
- Activate the project.
- Run:
using Literate;
Literate.markdown("Julia100Exercises.jl", name = "README", execute = true, flavor = Literate.CommonMarkFlavor());
Remark: Tested with Julia 1.7.2
.
To Do:
- Reevaluate the difficulty level of each question.
using Literate;
using LinearAlgebra;
using Statistics;
using Dates;
using DelimitedFiles;
using UnicodePlots;
using Random;
using Tullio;
using StaticKernels;
Import the LinearAlgebra
package under the name LA
. (β
ββ)
import LinearAlgebra as LA;
Print the version of Julia. (β ββ)
println(VERSION);
1.7.2
Create a non initialized vector of size 10 of Float64
. (β
ββ)
vA = Vector{Float64}(undef, 10)
10-element Vector{Float64}:
1.105174653e-315
9.951449764e-315
1.34117363e-314
9.952699395e-315
1.105267774e-315
1.10526801e-315
1.10526825e-315
9.9526956e-315
9.95269718e-315
9.9526975e-315
Which is equivalent of
vA = Array{Float64, 1}(undef, 10)
10-element Vector{Float64}:
1.105174653e-315
9.951449764e-315
1.34117363e-314
9.952699395e-315
1.105267774e-315
1.10526801e-315
1.10526825e-315
9.9526956e-315
9.95269718e-315
9.9526975e-315
Find the memory size of any array. (β ββ)
sizeof(vA)
80
Show the documentation of the +
(Add) method. (β
ββ)
@doc +
+(x, y...)
Addition operator. x+y+z+...
calls this function with all arguments, i.e. +(x, y, z, ...)
.
julia> 1 + 20 + 4
25
julia> +(1, 20, 4)
25
dt::Date + t::Time -> DateTime
The addition of a Date
with a Time
produces a DateTime
. The hour, minute, second, and millisecond parts of the Time
are used along with the year, month, and day of the Date
to create the new DateTime
. Non-zero microseconds or nanoseconds in the Time
type will result in an InexactError
being thrown.
Create a vector of zeros of size 10 but the fifth value which is 1. (β ββ)
vA = zeros(10);
vA[5] = 1.0;
vA
10-element Vector{Float64}:
0.0
0.0
0.0
0.0
1.0
0.0
0.0
0.0
0.0
0.0
Create a vector with values ranging from 7 to 12. (β ββ)
vA = 7:12
7:12
The above is efficient type. In order to explicitly create a vector:
vA = collect(7:12)
6-element Vector{Int64}:
7
8
9
10
11
12
Reverse a vector (first element becomes last). (β ββ)
vA = collect(1:3);
vB = vA[end:-1:1];
vB
3-element Vector{Int64}:
3
2
1
Alternative 001:
vB = reverse(vA);
Alternative 002 (In place):
reverse!(vA);
vA
3-element Vector{Int64}:
3
2
1
Create a 3x3
matrix with values ranging from 0 to 8. (β
ββ)
mA = reshape(0:8, 3, 3)
3Γ3 reshape(::UnitRange{Int64}, 3, 3) with eltype Int64:
0 3 6
1 4 7
2 5 8
Another way would be:
mA = Matrix{Float64}(undef, 3, 3);
mA[:] = 0:8;
Find indices of non zero elements from [1, 2, 0, 0, 4, 0]
. (β
ββ)
findall(!iszero, [1, 2, 0, 0, 4, 0])
3-element Vector{Int64}:
1
2
5
Create a 3x3 identity matrix. (β ββ)
mA = I(3)
3Γ3 Diagonal{Bool, Vector{Bool}}:
1 β
β
β
1 β
β
β
1
An alternative method (Explicit matrix) would be:
mA = Matrix(I, 3, 3) #<! For Float64: Matrix{Float64}(I, 3, 3)
3Γ3 Matrix{Bool}:
1 0 0
0 1 0
0 0 1
Create a 2x2x2
array with random values. (β
ββ)
mA = randn(2, 2, 2)
2Γ2Γ2 Array{Float64, 3}:
[:, :, 1] =
-1.12002 -0.135022
-0.154535 -0.194005
[:, :, 2] =
0.237614 -1.06059
0.239212 0.743754
Create a 5x5
array with random values and find the minimum and maximum values. (β
ββ)
mA = rand(5, 5);
minVal = minimum(mA)
0.11843693176016645
maxVal = maximum(mA)
0.9086898461640768
Using extrema()
one could get both values at once:
minVal, maxVal = extrema(mA);
Create a random vector of size 30 and find the mean value. (β ββ)
meanVal = mean(randn(30))
-0.13831178016103773
Create a 2d array with 1 on the border and 0 inside. (β ββ)
mA = zeros(4, 4);
mA[:, [1, end]] .= 1;
mA[[1, end], :] .= 1;
mA
4Γ4 Matrix{Float64}:
1.0 1.0 1.0 1.0
1.0 0.0 0.0 1.0
1.0 0.0 0.0 1.0
1.0 1.0 1.0 1.0
An alternative way:
mA = ones(4, 5);
mA[2:(end - 1), 2:(end - 1)] .= 0;
Using one line code:
mA = zeros(4, 5);
mA[[LinearIndices(mA)[cartIdx] for cartIdx in CartesianIndices(mA) if (any(cartIdx.I .== 1) || cartIdx.I[1] == size(mA, 1) || cartIdx.I[2] == size(mA, 2))]] .= 1;
Add a border of zeros around the array. (β ββ)
mB = zeros(size(mA) .+ 2);
mB[2:(end - 1), 2:(end - 1)] = mA;
mB
6Γ7 Matrix{Float64}:
0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 1.0 1.0 1.0 1.0 1.0 0.0
0.0 1.0 0.0 0.0 0.0 1.0 0.0
0.0 1.0 0.0 0.0 0.0 1.0 0.0
0.0 1.0 1.0 1.0 1.0 1.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0
Evaluate the following expressions. (β ββ)
0 * NaN
NaN
NaN == NaN
false
Inf > NaN
false
NaN - NaN
NaN
NaN in [NaN]
false
0.3 == 3 * 0.1
false
Create a 5x5
matrix with values [1, 2, 3, 4]
just below the diagonal. (β
ββ)
mA = diagm(5, 5, -1 => 1:4)
5Γ5 Matrix{Int64}:
0 0 0 0 0
1 0 0 0 0
0 2 0 0 0
0 0 3 0 0
0 0 0 4 0
Create a 8x8
matrix and fill it with a checkerboard pattern. (β
ββ)
mA = zeros(8, 8);
mA[2:2:end, 1:2:end] .= 1;
mA[1:2:end, 2:2:end] .= 1;
mA
8Γ8 Matrix{Float64}:
0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0
1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0
0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0
1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0
0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0
1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0
0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0
1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0
Convert the linear index 100 to a Cartesian Index of a size (6,7,8)
. (β
ββ)
mA = rand(6, 7, 8);
cartIdx = CartesianIndices(mA)[100]; #<! See https://discourse.julialang.org/t/14666
mA[cartIdx] == mA[100]
true
Create a checkerboard 8x8
matrix using the repeat()
function. (β
ββ)
mA = repeat([0 1; 1 0], 4, 4)
8Γ8 Matrix{Int64}:
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
Normalize a 4x4
random matrix. (β
ββ)
mA = rand(4, 4);
mA .= (mA .- mean(mA)) ./ std(mA) #<! Pay attention that `@.` will yield error (`std()` and `mean()`)
4Γ4 Matrix{Float64}:
1.34223 0.0929506 -1.27461 -0.0797268
0.189861 0.613144 -0.638085 0.0922141
1.96086 -0.858936 1.18456 0.886155
-1.31798 -0.788833 -0.147229 -1.25656
Create a custom type that describes a color as four unsigned bytes (RGBA
). (β
ββ)
struct sColor
R::UInt8;
G::UInt8;
B::UInt8;
A::UInt8;
end
sMyColor = sColor(rand(UInt8, 4)...)
Main.##513.sColor(0x35, 0x5e, 0x5b, 0x29)
Multiply a 2x4
matrix by a 4x3
matrix. (β
ββ)
mA = rand(2, 4) * randn(4, 3)
2Γ3 Matrix{Float64}:
0.431128 1.28048 1.24199
0.559976 1.2333 -0.223052
Given a 1D array, negate all elements which are between 3 and 8, in place. (β ββ)
vA = rand(1:10, 8);
map!(x -> ((x > 3) && (x < 8)) ? -x : x, vA, vA)
8-element Vector{Int64}:
8
10
9
-5
10
8
10
2
Using logical indices one could use:
vA[3 .< vA .< 8] .*= -1;
Sum the array 1:4
with initial value of -10. (β
ββ)
sum(1:4, init = -10)
0
Consider an integer vector vZ
validate the following expressions. (β
ββ)
vZ .^ vZ
2 << vZ >> 2
vZ <- vZ
1im * vZ
vZ / 1 / 1
vZ < Z > Z
vZ = rand(1:10, 3);
vZ .^ vZ
3-element Vector{Int64}:
27
823543
16777216
try
2 << vZ >> 2
catch e
println(e)
end
MethodError(<<, (2, [3, 7, 8]), 0x0000000000008786)
vZ <- vZ
false
1im * vZ
3-element Vector{Complex{Int64}}:
0 + 3im
0 + 7im
0 + 8im
vZ / 1 / 1
3-element Vector{Float64}:
3.0
7.0
8.0
vZ < vZ > vZ
false
Evaluate the following expressions. (β ββ)
[0] ./ [0]
1-element Vector{Float64}:
NaN
try
[0] .Γ· [0]
catch e
println(e)
end
DivideError()
try
convert(Float, convert(Int, NaN))
catch e
println(e)
end
InexactError(:Int64, Int64, NaN)
Round away from zero a float array. (β ββ)
vA = randn(10);
map(x -> x > 0 ? ceil(x) : floor(x), vA)
10-element Vector{Float64}:
2.0
-3.0
1.0
-2.0
1.0
-1.0
-1.0
-1.0
1.0
1.0
Find common values between two arrays. (β ββ)
vA = rand(1:10, 6);
vB = rand(1:10, 6);
vA[findall(in(vB), vA)]
2-element Vector{Int64}:
1
6
Suppress Julia's warnings. (β ββ)
One could use Suppressor.jl.
Compare sqrt(-1)
and sqrt(-1 + 0im)
. (β
ββ)
try
sqrt(-1)
catch e
println(e)
end
DomainError(-1.0, "sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).")
sqrt(-1 + 0im)
0.0 + 1.0im
Display yesterday, today and tomorrow's date. (β ββ)
println("Yesterday: $(today() - Day(1))");
println("Today: $(today())");
println("Tomorrow: $(today() + Day(1))");
Yesterday: 2022-04-04
Today: 2022-04-05
Tomorrow: 2022-04-06
Display all the dates corresponding to the month of July 2016. (β β β)
collect(Date(2016,7,1):Day(1):Date(2016,7,31))
31-element Vector{Date}:
2016-07-01
2016-07-02
2016-07-03
2016-07-04
2016-07-05
2016-07-06
2016-07-07
2016-07-08
2016-07-09
2016-07-10
2016-07-11
2016-07-12
2016-07-13
2016-07-14
2016-07-15
2016-07-16
2016-07-17
2016-07-18
2016-07-19
2016-07-20
2016-07-21
2016-07-22
2016-07-23
2016-07-24
2016-07-25
2016-07-26
2016-07-27
2016-07-28
2016-07-29
2016-07-30
2016-07-31
Compute ((mA + mB) * (-mA / 2))
in place. (β
β
β)
mA = rand(2, 2);
mB = rand(2, 2);
mA .= ((mA .+ mB) .* (.-mA ./ 2))
2Γ2 Matrix{Float64}:
-0.716514 -0.287942
-0.459809 -0.0957858
Using the dot macro:
@. mA = ((mA + mB) * (-mA / 2));
Extract the integer part of a random array of positive numbers using 4 different methods. (β β β)
mA = 5 * rand(3, 3);
Option 1:
floor.(mA)
3Γ3 Matrix{Float64}:
0.0 0.0 4.0
2.0 4.0 2.0
0.0 0.0 3.0
Option 2:
round.(mA .- 0.5) #<! Generates -0.0 for numbers smaller than 0.5
3Γ3 Matrix{Float64}:
0.0 -0.0 4.0
2.0 4.0 2.0
-0.0 -0.0 3.0
Option 3:
mA .Γ· 1
3Γ3 Matrix{Float64}:
0.0 0.0 4.0
2.0 4.0 2.0
0.0 0.0 3.0
Option 4:
mA .- rem.(mA, 1)
3Γ3 Matrix{Float64}:
0.0 0.0 4.0
2.0 4.0 2.0
0.0 0.0 3.0
Create a 5x5
matrix with row values ranging from 0 to 4. (β
β
β)
mA = repeat(reshape(0:4, 1, 5), 5, 1)
5Γ5 Matrix{Int64}:
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
Generate an array using a generator of 10 numbers. (β ββ)
vA = collect(x for x in 1:10)
10-element Vector{Int64}:
1
2
3
4
5
6
7
8
9
10
Create a vector of size 10 with values ranging from 0 to 1, both excluded. (β β β)
vA = LinRange(0, 1, 12)[2:(end - 1)]
10-element LinRange{Float64, Int64}:
0.0909091,0.181818,0.272727,0.363636,β¦,0.636364,0.727273,0.818182,0.909091
Create a random vector of size 10 and sort it. (β β β)
vA = rand(1:10, 10);
sort(vA)
10-element Vector{Int64}:
2
3
5
6
7
8
9
10
10
10
Implement the sum()
function manually. (β
β
β)
vA = rand(100);
sumVal = vA[1]
# Using `global` for scope in Literate
for ii in 2:length(vA)
global sumVal += vA[ii];
end
Check for equality of 2 arrays. (β β β)
vA = rand(10);
vB = rand(10);
all(vA .== vB)
false
Make an array immutable (Read only). (β β β)
This is a work in progress for Julia at in Issue 31630.
Consider a random 10x2
matrix representing cartesian coordinates, convert them to polar coordinates. (β
β
β)
mA = rand(10, 2);
ConvToPolar = vX -> [hypot(vX[1], vX[2]), atan(vX[2], vX[1])]
mB = [ConvToPolar(vX) for vX in eachrow(mA)]
10-element Vector{Vector{Float64}}:
[1.0342714791984575, 1.1989657491878698]
[0.7045389786998569, 0.1921491695022224]
[0.31035926344991027, 1.3026023251244419]
[1.0624296169601883, 0.7254615242441507]
[0.94885770476467, 0.8871276771856663]
[0.2361595528107809, 0.40583158436212574]
[0.8041091113858672, 1.4110614710947795]
[0.5384618185678928, 1.2029909800968146]
[1.1685058296714874, 1.0266622603133366]
[1.0074657448112765, 0.3457689802159463]
Create random vector of size 10 and replace the maximum value by 0. (β β β)
vA = randn(10);
vA[argmax(vA)] = 0;
vA
10-element Vector{Float64}:
0.028103284893873676
0.0
-0.0026211741731395925
0.31075481380381964
-1.345740166667141
0.2837383953720179
-0.9733906335012982
-0.8530062415785653
-0.7623795477199276
-1.4595036250308264
Create a a grid of x
and y
coordinates covering the [0, 1] x [0, 1]
area. (β
β
β)
numGridPts = 5;
vX = LinRange(0, 1, numGridPts);
vY = LinRange(0, 1, numGridPts);
MeshGrid = (vX, vY) -> ([x for _ in vY, x in vX], [y for y in vY, _ in vX]);
mX, mY = MeshGrid(vX, vY); #<! See https://discourse.julialang.org/t/48679
@show mX
5Γ5 Matrix{Float64}:
0.0 0.25 0.5 0.75 1.0
0.0 0.25 0.5 0.75 1.0
0.0 0.25 0.5 0.75 1.0
0.0 0.25 0.5 0.75 1.0
0.0 0.25 0.5 0.75 1.0
@show mY
5Γ5 Matrix{Float64}:
0.0 0.0 0.0 0.0 0.0
0.25 0.25 0.25 0.25 0.25
0.5 0.5 0.5 0.5 0.5
0.75 0.75 0.75 0.75 0.75
1.0 1.0 1.0 1.0 1.0
Given two vectors, vX
and vY
, construct the Cauchy matrix mC
: (Cij = 1 / (xi - yj))
. (β
β
β)
vX = rand(5);
vY = rand(5);
mC = 1 ./ (vX .- vY')
5Γ5 Matrix{Float64}:
1.33315 1.73655 1.66349 23.6667 13.2553
3.64656 10.0021 7.98267 -2.30616 -2.4973
10.117 -13.2612 -19.9539 -1.64202 -1.73665
9.61626 -14.2326 -22.2376 -1.65601 -1.75232
5.2049 55.9446 23.1658 -1.93902 -2.07238
Print the minimum and maximum representable value for each Julia scalar type. (β β β)
vT = [UInt8 UInt16 UInt32 UInt64 Int8 Int16 Int32 Int64 Float16 Float32 Float64]
for juliaType in vT
println(typemin(juliaType));
println(typemax(juliaType));
end
0
255
0
65535
0
4294967295
0
18446744073709551615
-128
127
-32768
32767
-2147483648
2147483647
-9223372036854775808
9223372036854775807
-Inf
Inf
-Inf
Inf
-Inf
Inf
Print all the values of an array. (β β β)
mA = rand(3, 3);
print(mA);
[0.7371138352302956 0.8092889789289097 0.656319669336122; 0.30299206720289407 0.7986562653880566 0.5426153520046326; 0.27311149235083343 0.18859551945726816 0.19598246895936644]
Find the closest value to a given scalar in a vector. (β β β)
inputVal = 0.5;
vA = rand(10);
vA[argmin(abs.(vA .- inputVal))]
0.6215852606336593
Create a structured array representing a position (x, y)
and a color (r, g, b)
. (β
β
β)
struct sPosColor
x::Int
y::Int
R::UInt8;
G::UInt8;
B::UInt8;
A::UInt8;
end
numPixels = 10;
maxVal = typemax(UInt32);
vMyColor = [sPosColor(rand(1:maxVal, 2)..., rand(UInt8, 4)...) for _ in 1:numPixels];
Consider a random vector with shape (5, 2)
representing coordinates, find the distances matrix mD
: $ {D}{i, j} = {\left| {x}{i} - {x}{j} \right|}{2} $. (β
β
β)
mX = rand(5, 2);
vSumSqr = sum(vX -> vX .^ 2, mX, dims = 2);
mD = vSumSqr .+ vSumSqr' - 2 * (mX * mX');
mD
5Γ5 Matrix{Float64}:
0.0 1.01933 0.48352 0.392089 0.581276
1.01933 0.0 0.545751 0.472062 0.559936
0.48352 0.545751 3.46945e-18 0.00811257 1.14793
0.392089 0.472062 0.00811257 0.0 0.964828
0.581276 0.559936 1.14793 0.964828 0.0
Convert a float (32 bits) array into an integer (32 bits) in place. (β β β)
vA = 100 .* rand(Float32, 5);
vA .= round.(Int32, vA)
5-element Vector{Float32}:
34.0
65.0
43.0
20.0
74.0
Read the following file (Q0054.txt
). (β
β
β)
1, 2, 3, 4, 5
6, , , 7, 8
, , 9,10,11
mA = readdlm("Q0054.txt", ',')
3Γ5 Matrix{Any}:
1 2 3 4 5
6 " " " " 7 8
" " " " 9 10 11
Enumerate array in a loop. (β β β)
mA = rand(3, 3);
for (elmIdx, elmVal) in enumerate(mA) #<! See https://discourse.julialang.org/t/48877
println(elmIdx);
println(elmVal);
end
1
0.6101626581113386
2
0.47648577931401126
3
0.3275502864792046
4
0.5912118096687773
5
0.31674509844656396
6
0.03335906220495588
7
0.17751962779022468
8
0.3062350362480154
9
0.6048101285486847
Generate a generic 2D Gaussian like array with ΞΌ = 0
, Ο = 1
and indices over {-5, -4, ..., 0, 1, ..., 5}
. (β
β
β)
vA = -5:5;
ΞΌ = 0;
Ο = 1;
mG = [(1 / (2 * pi * Ο)) * exp(-0.5 * ((([x, y] .- ΞΌ)' * ([x, y] .- ΞΌ)) / (Ο * Ο))) for x in vA, y in vA];
heatmap(mG)
βββββββββββββ
11 βββββββββββββ ββββ 0.2
βββββββββββββ ββββ
βββββββββββββ ββββ
βββββββββββββ ββββ
βββββββββββββ ββββ
1 βββββββββββββ ββββ 2.0e-12
βββββββββββββ
1 11
Using the separability of the Gaussian function:
vG = (1 / (sqrt(2 * pi) * Ο)) .* exp.(-0.5 .* (((vA .- ΞΌ) .^ 2) / (Ο * Ο)));
mG = vG * vG';
Place 5
elements in a 5x5
array randomly. (β
β
β)
mA = rand(5, 5);
mA[rand(1:25, 5)] = rand(5);
Another option which avoids setting into the same indices:
mA[randperm(25)[1:5]] = rand(5);
Subtract the mean of each row of a matrix. (β β β)
mA = rand(3, 3);
mA .-= mean(mA, dims = 2);
mean(mA, dims = 1)
1Γ3 Matrix{Float64}:
0.216947 0.115339 -0.332285
Sort an array by a column. (β β β)
colIdx = 2;
mA = rand(3, 3);
mA[sortperm(mA[:, colIdx]), :]
3Γ3 Matrix{Float64}:
0.218443 0.376531 0.0282801
0.681957 0.43126 0.965238
0.0201171 0.75897 0.341389
Using sortslices()
:
sortslices(mA, dims = 1, by = x -> x[colIdx]);
Tell if a given 2D array has null (All zeros) columns. (β β β)
mA = rand(0:1, 3, 9);
any(all(iszero.(mA), dims = 1))
true
Find the 2nd nearest value from a given value in an array. (β β β)
inputVal = 0.5;
vA = rand(10);
vA[sortperm(abs.(vA .- inputVal))[2]]
0.5389429248869007
Alternative way (More efficient)
closeFirst = Inf;
closeSecond = Inf;
closeFirstIdx = 0;
closeSecondIdx = 0;
# Using `global` for scope in Literate
for (elmIdx, elmVal) in enumerate(abs.(vA .- inputVal))
if (elmVal < closeFirst)
global closeSecond = closeFirst;
global closeFirst = elmVal;
global closeSecondIdx = closeFirstIdx;
global closeFirstIdx = elmIdx;
elseif (elmVal < closeSecond)
global closeSecond = elmVal;
global closeSecondIdx = elmIdx;
end
end
vA[closeSecondIdx] == vA[sortperm(abs.(vA .- inputVal))[2]]
true
Considering two arrays with shape (1, 3)
and (3, 1)
, Compute their sum using an iterator. (β
β
β)
vA = rand(1, 3);
vB = rand(3, 1);
sum([aVal + bVal for aVal in vA, bVal in vB])
6.976866131317638
Create an array class that has a name attribute. (β β β)
One could use NamedArrays.jl
or AxisArrays.jl
.
Given a vector, add 1
to each element indexed by a second vector (Be careful with repeated indices). (β
β
β
)
vA = rand(1:10, 5);
vB = rand(1:5, 3);
println(vA);
# Julia is very efficient with loops
for bIdx in vB
vA[bIdx] += 1;
end
println(vA);
[7, 4, 9, 8, 4]
[8, 6, 9, 8, 4]
Accumulate elements of a vector X
to an array F
based on an index list I
. (β
β
β
)
vX = rand(1:5, 10);
vI = rand(1:15, 10);
numElements = maximum(vI);
vF = zeros(numElements);
for (ii, iIdx) in enumerate(vI)
vF[iIdx] += vX[ii];
end
println("vX: $vX");
println("vI: $vI");
println("vF: $vF");
vX: [1, 5, 1, 5, 5, 5, 1, 2, 2, 2]
vI: [6, 15, 4, 2, 6, 6, 13, 8, 7, 9]
vF: [0.0, 5.0, 0.0, 1.0, 0.0, 11.0, 2.0, 2.0, 2.0, 0.0, 0.0, 0.0, 1.0, 0.0, 5.0]
One could also use counts()
from StatsBase.jl
.
Considering an image of size w x h x 3
image of type UInt8
, compute the number of unique colors. (β
β
β)
mI = rand(UInt8, 1000, 1000, 3);
numColors = length(unique([reinterpret(UInt32, [iPx[1], iPx[2], iPx[3], 0x00])[1] for iPx in eachrow(reshape(mI, :, 3))]));
print("Number of Unique Colors: $numColors");
Number of Unique Colors: 970857
Another option:
numColors = length(unique([UInt32(iPx[1]) + UInt32(iPx[2]) << 8 + UInt32(iPx[3]) << 16 for iPx in eachrow(reshape(mI, :, 3))]));
print("Number of Unique Colors: $numColors");
Number of Unique Colors: 970857
Considering a three dimensions array, get sum over the last two axis at once. (β β β )
mA = rand(2, 2, 2, 2);
sum(reshape(mA, (2, 2, :)), dims = 3)
2Γ2Γ1 Array{Float64, 3}:
[:, :, 1] =
1.01592 2.46702
0.956257 2.5832
Considering a one dimensional vector vA
, how to compute means of subsets of vA
using a vector vS
of same size describing subset indices. (β
β
β
)
# Bascially extending `Q0065` with another vector of number of additions.
vX = rand(1:5, 10);
vI = rand(1:15, 10);
numElements = maximum(vI);
vF = zeros(numElements);
vN = zeros(Int, numElements);
for (ii, iIdx) in enumerate(vI)
vF[iIdx] += vX[ii];
vN[iIdx] += 1;
end
# We only divide the mean if the number of elements accumulated is bigger than 1
for ii in 1:numElements
vF[ii] = ifelse(vN[ii] > 1, vF[ii] / vN[ii], vF[ii]);
end
println("vX: $vX");
println("vI: $vI");
println("vF: $vF");
vX: [3, 4, 4, 3, 5, 3, 1, 3, 3, 1]
vI: [11, 8, 13, 7, 2, 15, 8, 2, 10, 7]
vF: [0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.5, 0.0, 3.0, 3.0, 0.0, 4.0, 0.0, 3.0]
Get the diagonal of a matrix product. (β β β )
mA = rand(5, 7);
mB = rand(7, 4);
numDiagElements = min(size(mA, 1), size(mB, 2));
vD = [dot(mA[ii, :], mB[:, ii]) for ii in 1:numDiagElements]
4-element Vector{Float64}:
1.8164269853856725
1.7850099618240745
2.5823253181907906
1.54446354804799
Alternative way:
vD = reshape(sum(mA[1:numDiagElements, :]' .* mB[:, 1:numDiagElements], dims = 1), numDiagElements)
4-element Vector{Float64}:
1.8164269853856725
1.7850099618240747
2.5823253181907906
1.54446354804799
Consider the vector [1, 2, 3, 4, 5]
, build a new vector with 3 consecutive zeros interleaved between each value. (β
β
β
)
vA = 1:5;
# Since Julia is fast with loops, it would be the easiest choice
numElements = (4 * length(vA)) - 3;
vB = zeros(Int, numElements);
for (ii, bIdx) in enumerate(1:4:numElements)
vB[bIdx] = vA[ii];
end
println(vB);
# Alternative (MATLAB style) way:
mB = [reshape(collect(vA), 1, :); zeros(Int, 3, length(vA))];
vB = reshape(mB[1:(end - 3)], :);
println(vB);
[1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5]
[1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5]
Consider an array of dimension 5 x 5 x 3
, mulitply it by an array with dimensions 5 x 5
using broadcasting. (β
β
β
)
mA = rand(5, 5, 3);
mB = rand(5, 5);
mA .* mB #<! Very easy in Julia
5Γ5Γ3 Array{Float64, 3}:
[:, :, 1] =
0.712478 0.574484 0.485159 0.120744 0.808942
0.93736 0.150632 0.0544313 0.0539446 0.253715
0.0657162 0.0907123 0.0502358 0.284795 0.016639
0.398646 0.164165 0.273063 0.172124 0.278636
0.746676 0.0264016 0.329647 0.536519 0.450446
[:, :, 2] =
0.943394 0.311645 0.562925 0.145208 0.678142
0.0725279 0.0824635 0.301873 0.160442 0.0769263
0.0284919 0.0588473 0.77605 0.657093 0.0143115
0.568694 0.125906 0.00957802 0.131924 0.0574844
0.657746 0.19368 0.0417194 0.353421 0.190869
[:, :, 3] =
0.609843 0.290093 0.279946 0.137143 0.378344
0.468681 0.217494 0.0944444 0.0252494 0.238564
0.0019976 0.0585168 0.257611 0.370355 0.0244035
0.508656 0.23705 0.567699 0.0769483 0.266188
0.187367 0.0887679 0.435148 0.0229529 0.079558
Swap two rows of a 2D array. (β β β )
mA = rand(UInt8, 3, 2);
println(mA);
mA[[1, 2], :] .= mA[[2, 1], :];
println(mA);
UInt8[0x22 0x1a; 0x82 0x63; 0xd0 0xb0]
UInt8[0x82 0x63; 0x22 0x1a; 0xd0 0xb0]
Consider a set of 10 triplets describing 10 triangles (with shared vertices), find the set of unique line segments composing all the triangles. (β β β )
mA = rand(0:100, 10, 3); #<! Each row composes 3 veritces ([1] -> [2], [2] -> [3], [3] -> [1])
mC = [sort!([vC[mod1(ii, end)], vC[mod1(ii + 1, end)]]) for ii in 1:(size(mA, 2) + 1), vC in eachrow(mA)][:] #<! Sorted combinations of vertices
mC = unique(mC)
30-element Vector{Vector{Int64}}:
[34, 97]
[37, 97]
[34, 37]
[60, 96]
[16, 96]
[16, 60]
[59, 100]
[61, 100]
[59, 61]
[73, 99]
[37, 73]
[37, 99]
[28, 94]
[2, 94]
[2, 28]
[49, 71]
[17, 49]
[17, 71]
[84, 98]
[51, 98]
[51, 84]
[9, 47]
[9, 16]
[16, 47]
[38, 58]
[58, 89]
[38, 89]
[8, 29]
[5, 29]
[5, 8]
Given a sorted array vC
that corresponds to a bincount, produce an array vA
such that bincount(vA) == vC
. (β
β
β
)
vC = rand(0:7, 5);
numElements = sum(vC);
vA = zeros(Int, numElements);
elmIdx = 1;
# Using `global` for scope in Literate
for (ii, binCount) in enumerate(vC)
for jj in 1:binCount
vA[elmIdx] = ii;
global elmIdx += 1;
end
end
Compute averages using a sliding window over an array. (β β β )
numElements = 10;
winRadius = 1;
winReach = 2 * winRadius;
winLength = 1 + winReach;
vA = rand(0:3, numElements);
vB = zeros(numElements - (2 * winRadius));
aIdx = 1 + winRadius;
# Using `global` for scope in Literate
for ii in 1:length(vB)
vB[ii] = mean(vA[(aIdx - winRadius):(aIdx + winRadius)]); #<! Using integral / running sum it would be faster.
global aIdx += 1;
end
Another method using running sum:
vC = zeros(numElements - winReach);
jj = 1;
sumVal = sum(vA[1:winLength]);
vC[jj] = sumVal / winLength;
jj += 1;
# Using `global` for scope in Literate
for ii in 2:(numElements - winReach)
global sumVal += vA[ii + winReach] - vA[ii - 1];
vC[jj] = sumVal / winLength;
global jj += 1;
end
maximum(abs.(vC - vB)) < 1e-8
true
Consider a one dimensional array vA
, build a two dimensional array whose first row is [ vA[0], vA[1], vA[2] ]
and each subsequent row is shifted by 1. (β
β
β
)
vA = rand(10);
numCols = 3;
numRows = length(vA) - numCols + 1;
mA = zeros(numRows, numCols);
for ii in 1:numRows
mA[ii, :] = vA[ii:(ii + numCols - 1)]; #<! One could optimize the `-1` out
end
Negate a boolean or to change the sign of a float inplace. (β β β )
vA = rand(Bool, 10);
vA .= .!vA;
vA = randn(10);
vA .*= -1;
Consider 2 sets of points mP1
, mP2
describing lines (2d) and a point vP
, how to compute distance from the point vP
to each line i
: [mP1[i, :], mP2[i, :]
. (β
β
β
)
# See distance of a point from a line in Wikipedia (https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line).
# Specifically _Line Defined by Two Points_.
numLines = 10;
mP1 = randn(numLines, 2);
mP2 = randn(numLines, 2);
vP = randn(2);
vD = [(abs(((vP2[1] - vP1[1]) * (vP1[2] - vP[2])) - ((vP1[1] - vP[1]) * (vP2[2] - vP1[2]))) / hypot((vP2 - vP1)...)) for (vP1, vP2) in zip(eachrow(mP1), eachrow(mP2))];
minDist = minimum(vD);
println("Min Distance: $minDist");
Min Distance: 0.09760767836967893
Consider 2 sets of points mP1
, mP2
describing lines (2d) and a set of points mP
, how to compute distance from the point vP = mP[j, :]
to each line i
: [mP1[i, :], mP2[i, :]
. (β
β
β
)
numLines = 5;
mP1 = randn(numLines, 2);
mP2 = randn(numLines, 2);
mP = randn(numLines, 2);
mD = [(abs(((vP2[1] - vP1[1]) * (vP1[2] - vP[2])) - ((vP1[1] - vP[1]) * (vP2[2] - vP1[2]))) / hypot((vP2 - vP1)...)) for (vP1, vP2) in zip(eachrow(mP1), eachrow(mP2)), vP in eachrow(mP)];
for jj in 1:numLines
minDist = minimum(mD[jj, :]);
println("The minimum distance from the $jj -th point: $minDist");
end
β Warning: Assignment to `minDist` in soft scope is ambiguous because a global variable by the same name exists: `minDist` will be treated as a new local. Disambiguate by using `local minDist` to suppress this warning or `global minDist` to assign to the existing global variable.
β @ string:9
The minimum distance from the 1 -th point: 0.248602785991477
The minimum distance from the 2 -th point: 0.431943667181171
The minimum distance from the 3 -th point: 0.6987892484779133
The minimum distance from the 4 -th point: 0.1739485392546949
The minimum distance from the 5 -th point: 0.2122207728711098
Consider an arbitrary 2D array, write a function that extract a subpart with a fixed shape and centered on a given element (Handel out of bounds). (β β β )
# One could use `PaddedViews.jl` to easily solve this.
arrayLength = 10;
winRadius = 3;
vWinCenter = [7, 9];
mA = rand(arrayLength, arrayLength);
winLength = (2 * winRadius) + 1;
mB = zeros(winLength, winLength);
verShift = -winRadius;
# Using `global` for scope in Literate
for ii in 1:winLength
horShift = -winRadius;
for jj in 1:winLength
mB[ii, jj] = mA[min(max(vWinCenter[1] + verShift, 1), arrayLength), min(max(vWinCenter[2] + horShift, 1), arrayLength)]; #<! Nearest neighbor extrapolation
horShift += 1;
end
global verShift += 1;
end
Consider an array vA = [1, 2, 3, ..., 13, 14]
, generate an array vB = [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], ..., [11, 12, 13, 14]]
. (β
β
β
)
vA = collect(1:14);
winNumElements = 4;
winReach = winNumElements - 1;
vB = [vA[ii:(ii + winReach)] for ii in 1:(length(vA) - winReach)]
11-element Vector{Vector{Int64}}:
[1, 2, 3, 4]
[2, 3, 4, 5]
[3, 4, 5, 6]
[4, 5, 6, 7]
[5, 6, 7, 8]
[6, 7, 8, 9]
[7, 8, 9, 10]
[8, 9, 10, 11]
[9, 10, 11, 12]
[10, 11, 12, 13]
[11, 12, 13, 14]
Compute a matrix rank. (β β β )
numRows = 5;
numCols = 4;
mA = randn(numRows, numCols);
rank(mA)
4
Find the most frequent value in an array. (β β β )
vA = rand(1:5, 15);
MATLAB Style (Manual loop might be faster)
vB = unique(vA);
# vB[argmax(sum(vA .== vB', dims = 1)[:])] #<! The input to `argmax()` is a `1 x n` vector, hence squeezed so `argmax()` won't return Cartesian Index.
vB[argmax(dropdims(sum(vA .== vB', dims = 1), dims = 1))] #<! The input to `argmax()` is a `1 x n` vector, hence squeezed so `argmax()` won't return Cartesian Index.
4
Comparing bits:
One could convert at the bits level to integers and then use something like counts()
from StatsBase.jl
.
Support to 1:4 bytes of data:
numBytes = sizeof(vA[1]);
if (sizeof(vA[1]) == 1)
vB = reinterpret(UInt8, vA);
elseif (sizeof(vA[1]) == 2)
vB = reinterpret(UInt16, vA);
elseif (sizeof(vA[1]) == 4)
vB = reinterpret(UInt32, vA);
elseif (sizeof(vA[1]) == 8)
vB = reinterpret(UInt64, vA);
end
Extract all the contiguous 3x3
blocks from a random 5x5
matrix. (β
β
β
)
numRows = 5;
numCols = 5;
mA = rand(1:9, numRows, numCols);
winRadius = 1;
winReach = 2 * winRadius;
winLength = winReach + 1;
mB = [mA[ii:(ii + winReach), jj:(jj + winReach)] for ii in 1:(numRows - winReach), jj in 1:(numCols - winReach)]
3Γ3 Matrix{Matrix{Int64}}:
[1 4 2; 8 4 7; 2 8 5] [4 2 3; 4 7 6; 8 5 4] [2 3 9; 7 6 1; 5 4 5]
[8 4 7; 2 8 5; 5 7 3] [4 7 6; 8 5 4; 7 3 4] [7 6 1; 5 4 5; 3 4 4]
[2 8 5; 5 7 3; 4 6 9] [8 5 4; 7 3 4; 6 9 9] [5 4 5; 3 4 4; 9 9 7]
Create a 2D array struct such that mA[i, j] == mA[j, i]
(Symmetric matrix). (β
β
β
)
struct SymmetricMatrix{T <: Number} <: AbstractArray{T, 2}
numRows::Int
data::Matrix{T}
function SymmetricMatrix(mA::Matrix{T}) where {T <: Number}
size(mA, 1) == size(mA, 2) || throw(ArgumentError("Input matrix must be square"))
new{T}(size(mA, 1), Matrix(Symmetric(mA)));
end
end
function Base.size(mA::SymmetricMatrix)
(mA.numRows, mA.numRows);
end
function Base.getindex(mA::SymmetricMatrix, ii::Int)
mA.data[ii];
end
function Base.getindex(mA::SymmetricMatrix, ii::Int, jj::Int)
mA.data[ii, jj];
end
function Base.setindex!(mA::SymmetricMatrix, v, ii::Int, jj::Int)
setindex!(mA.data, v, ii, jj);
setindex!(mA.data, v, jj, ii);
end
mA = SymmetricMatrix(zeros(Int, 2, 2));
mA[1, 2] = 5;
mA
2Γ2 Main.##513.SymmetricMatrix{Int64}:
0 5
5 0
Consider a set of p
matrices of shape nxn
and a set of p
vectors with length n
. Compute the sum of of the p
matrix vector products at once (Result is a vector of length n
). (β
β
β
)
# One could use `TensorOperations.jl` or `Einsum.jl` for a more elegant solution.
numRows = 5;
numMat = 3;
tP = [randn(numRows, numRows) for _ in 1:numMat];
mP = [randn(numRows) for _ in 1:numMat];
vA = reduce(+, (mP * vP for (mP, vP) in zip(tP, mP)));
vB = zeros(numRows);
for ii in 1:numMat
vB .+= tP[ii] * mP[ii];
end
vA == vB
true
Consider a 16x16
array, calculate the block sum (Block size is 4x4
). (β
β
β
)
We solve a more general case for any size of blocks.
numRows = 16;
numCols = 8;
vBlockSize = [2, 4]; #<! [numRows, numCols] ./ vBlockSize == integer
mA = rand(numRows, numCols);
numBlocksVert = numRows Γ· vBlockSize[1];
numBlocksHori = numCols Γ· vBlockSize[2];
numBlocks = numBlocksVert * numBlocksHori;
mA = reshape(mA, vBlockSize[1], :);
We number the blocks column wise and create their block index per column of the reshaped mA
.
vBlockIdx = 1:numBlocks;
mBlockIdx = reshape(vBlockIdx, numBlocksVert, numBlocksHori);
mBlockIdx = repeat(mBlockIdx, 1, 1, vBlockSize[2]);
mBlockIdx = permutedims(mBlockIdx, (1, 3, 2));
vBlockIdx = mBlockIdx[:]; #<! Matches the block index per column of the reshaped `mA`.
vA = dropdims(sum(mA, dims = 1), dims = 1);
vB = zeros(numBlocks);
for ii = 1:(numBlocks * vBlockSize[2])
vB[vBlockIdx[ii]] += vA[ii];
end
vB
16-element Vector{Float64}:
3.8521997502509646
3.693738739870798
3.91855708888581
4.585043939428366
3.651044959292372
4.543612923663371
5.260850695678567
3.2359843557841317
3.7672701181556736
5.226776126146337
2.8603438360755145
3.8382079034695056
3.8581152070821765
3.5996600839182356
3.3368117982151557
3.5502199385321767
Implement the simulation Game of Life using arrays. (β β β )
numRows = 20;
numCols = 20;
gofKernel = @kernel w -> w[-1, -1] + w[-1, 0] + w[-1, 1] + w[0, -1] + w[0, 1] + w[1, -1] + w[1, 0] + w[1, 1];
gofNumLives = round(Int, 0.05 * numRows * numCols);
gofNumGenerations = 50;
vI = randperm(numRows * numCols)[1:gofNumLives];
mG = zeros(UInt8, numRows, numCols);
mG[vI] .= UInt8(1);
mB = similar(mG);
heatmap(mG) #<! Initialization
ββββββββββββββββββββββ
20 ββββββββββββββββββββββ ββββ 1
ββββββββββββββββββββββ ββββ
ββββββββββββββββββββββ ββββ
ββββββββββββββββββββββ ββββ
ββββββββββββββββββββββ ββββ
ββββββββββββββββββββββ ββββ
ββββββββββββββββββββββ ββββ
ββββββββββββββββββββββ ββββ
ββββββββββββββββββββββ ββββ
1 ββββββββββββββββββββββ ββββ 0
ββββββββββββββββββββββ
1 20
for ii in 1:numGridPts
map!(gofKernel, mB, extend(mG, StaticKernels.ExtensionConstant(0))); #<! One may use `ExtensionCircular`
for ii in eachindex(mB)
mG[ii] = UInt8((mB[ii] >= 3) || ((mB[ii] > 0) && (mB[ii] == 2))); #<! Could be done with broadcasting
end
end
heatmap(mG) #<! Final state
ββββββββββββββββββββββ
20 ββββββββββββββββββββββ ββββ 1
ββββββββββββββββββββββ ββββ
ββββββββββββββββββββββ ββββ
ββββββββββββββββββββββ ββββ
ββββββββββββββββββββββ ββββ
ββββββββββββββββββββββ ββββ
ββββββββββββββββββββββ ββββ
ββββββββββββββββββββββ ββββ
ββββββββββββββββββββββ ββββ
1 ββββββββββββββββββββββ ββββ 0
ββββββββββββββββββββββ
1 20
TODO: Use O(1) implementation for Box Blur.
Get the n
largest values of an array. (β
β
β
)
vA = rand(10);
numValues = 3;
vA[partialsortperm(vA, 1:numValues, rev = true)]
3-element Vector{Float64}:
0.8579438669183439
0.8065061873505688
0.7678831732040585
Given an arbitrary number of vectors, build the Cartesian Product (Every combinations of every item). (β β β )
function CartesianProduct(tupleX)
return collect(Iterators.product(tupleX...))[:];
end
vA = 1:3;
vB = 8:9;
vC = 4:5;
CartesianProduct((vA, vB, vC))
12-element Vector{Tuple{Int64, Int64, Int64}}:
(1, 8, 4)
(2, 8, 4)
(3, 8, 4)
(1, 9, 4)
(2, 9, 4)
(3, 9, 4)
(1, 8, 5)
(2, 8, 5)
(3, 8, 5)
(1, 9, 5)
(2, 9, 5)
(3, 9, 5)
Create an array which can be accessed like a record array in NumPy. (β β β )
One could use StructArrays.jl
.
Consider a large vector vA
, compute vA
to the power of 3 using 3 different methods. (β
β
β
)
vA = rand(1000);
Method 001:
vB = vA .^ 3;
Method 002:
vC = [valA ^ 3 for valA in vA];
Method 003:
vD = zeros(length(vA));
for (ii, valA) in enumerate(vA)
vD[ii] = valA * valA * valA;
end
vB β vC β vD
true
Consider two arrays mA
and mB
of shape 8x3
and 2x2
. Find rows of mA
that contain elements of each row of mB
regardless of the order of the elements in mB
. (β
β
β
)
The way I interpret the question is rows in mA
which contain at least 1 element from each row of mB
.
mA = rand(0:4, 8, 3);
mB = rand(0:4, 2, 2);
mC = [any(vA .== vB') for vB in eachrow(mB), vA in eachrow(mA)]; #<! General solution, will work for any size of `mA` and `mB`
vD = [all(vC) for vC in eachcol(mC)]
8-element Vector{Bool}:
0
0
0
1
1
0
1
0
In order to have a solution without the intermediate array mC
function Iterate2(iA; iterState = missing)
if(ismissing(iterState))
valA, iterState = iterate(iA);
else
valA, iterState = iterate(iA, iterState);
end
valB, iterState = iterate(iA, iterState);
return (valA, valB), iterState
end
tT = (any(vA .== vB') for vB in eachrow(mB), vA in eachrow(mA));
iterState = missing;
vE = zeros(Bool, size(mA, 1));
for ii = 1:length(vD)
global iterState;
(valA, valB), iterState = Iterate2(tT; iterState = iterState);
vE[ii] = valA && valB;
end
vD == vE
true
Considering a 10x3
matrix, extract rows with unequal values. (β
β
β
)
mA = rand(1:3, 10, 3);
vD = [maximum(vA) != minimum(vA) for vA in eachrow(mA)]
10-element Vector{Bool}:
1
1
1
1
1
1
1
1
1
1
Convert a vector of ints into a matrix binary representation. (β β β )
vA = rand(UInt8, 10);
mB = zeros(Bool, length(vA), 8);
# See https://discourse.julialang.org/t/26663
for ii in 1:length(vA)
vS = bitstring(vA[ii]);
for jj in 1:size(mB, 2)
mB[ii, jj] = vS[jj] == '1';
end
end
mB
10Γ8 Matrix{Bool}:
1 1 1 1 1 1 1 0
1 0 0 1 1 1 1 1
0 1 0 1 0 1 1 0
1 0 1 0 1 0 0 1
1 0 1 1 0 0 1 0
0 1 1 0 1 0 0 0
0 0 1 1 1 1 1 1
1 1 0 1 0 0 1 1
1 1 1 1 1 0 0 1
1 1 1 0 0 0 1 0
Given a two dimensional array, extract unique rows. (β β β )
mA = UInt8.(rand(1:3, 10, 3));
vS = [reduce(*, bitstring(valA) for valA in vA) for vA in eachrow(mA)]; #<! Supports any array!
vU = unique(vS);
vI = [findfirst(valU .== vS) for valU in vU];
An alternative way:
vB = indexin(vU, vS);
vB == vI
true
Considering 2 vectors vA
and vB
, write the einsum equivalent (Using Einsum.jl
) of inner, outer, sum, and mul function. (β
β
β
)
vA = rand(5);
vB = rand(5);
Inner Product
@tullio tullioVal = vA[ii] * vB[ii];
tullioVal β dot(vA, vB) #<! Inner product
true
Outer Product
@tullio mTullio[ii, jj] := vA[ii] * vB[jj]; #<! Outer product
mTullio β vA * vB'
true
Sum
@tullio tullioVal = vA[ii];
tullioVal β sum(vA) #<! Sum
true
Multiplication
@tullio vTullio[ii] := vA[ii] * vB[ii];
vTullio β vA .* vB #<! Multiplication
true
Considering a path described by two vectors vX
and `vY, sample it using equidistant samples. (β
β
β
)
The way I interpreted the question is to create sub segments of the same length.
numPts = 100;
numSegments = 1000;
vX = sort(10 * rand(numPts));
vY = sort(10 * rand(numPts));
vR = cumsum(hypot.(diff(vX), diff(vY)));
pushfirst!(vR, 0.0);
vRSegment = LinRange(0.0, vR[end], numSegments);
struct LinearInterpolator1D{T <: Number} <: AbstractArray{T, 1}
vX::Vector{T};
vY::Vector{T};
function LinearInterpolator1D(vX::Vector{T}, vY::Vector{T}) where {T <: Number}
length(vX) == length(vX) || throw(ArgumentError("Input vectors must have the same length"));
new{T}(vX, vY);
end
end
function Base.size(vA::LinearInterpolator1D)
size(vA.vX);
end
function Base.getindex(vA::LinearInterpolator1D, ii::Number)
if (ii >= vA.vX[end])
return vA.vY[end];
end
if (ii <= vA.vX[1])
return vA.vY[1];
end
rightIdx = findfirst(vA.vX .>= ii);
leftIdx = rightIdx - 1;
tt = (ii - vA.vX[leftIdx]) / (vA.vX[rightIdx] - vA.vX[leftIdx]);
return ((1 - tt) * vA.vY[leftIdx]) + (tt * vA.vY[rightIdx]);
end
function Base.setindex!(vA::LinearInterpolator1D, valX, valY, ii::Int, jj::Int)
setindex!(sLinInterp.vX, valX, ii);
setindex!(sLinInterp.vY, valY, ii);
end
vXInt = LinearInterpolator1D(vR, vX);
vYInt = LinearInterpolator1D(vR, vY);
vXSegment = [vXInt[intIdx] for intIdx in vRSegment];
vYSegment = [vYInt[intIdx] for intIdx in vRSegment];
hP = lineplot(vX, vY, canvas = DotCanvas, name = "Samples");
lineplot!(hP, vXSegment, vYSegment, name = "Interpolated");
hP
ββββββββββββββββββββββββββββββββββββββββββ
10 β :'β Samples
β .:'' β Interpolated
β :'' β
β :' β
β :' β
β .:' β
β ..:' β
β ..:''' β
β .:''' β
β ..:'' β
β .:''' β
β .: β
β .:' β
β :' β
0 β..:'' β
ββββββββββββββββββββββββββββββββββββββββββ
0 10
Remark: In order to be mathematically accurate the resolution of vRSegment
must be high enough to be an integer factor of each segment.
It can be done if the resolution is 1 / (prod(vR))
which is easily infeasible with Float64
. So this is a good enough approximation.
Given an integer n
and a 2D array mA
, find the rows which can be interpreted as draws from a multinomial distribution with n
(Rows which only contain integers and which sum to n
). (β
β
β
)
mA = rand([0, 0.5, 1, 2, 3], 15, 3);
sumVal = 4;
vI = [all(vA .== round.(vA)) && sum(vA) == sumVal for vA in eachrow(mA)];
Compute bootstrapped 95%
confidence intervals for the mean of a 1D array vA
. Namely, resample the elements of an array with replacement N
times, compute the mean of each sample and then compute percentiles over the means. (β
β
β
)
numTrials = 1000;
numSamples = 100;
ΞΌ = 0.5;
vA = ΞΌ .+ randn(numSamples);
tM = (mean(vA[rand(1:numSamples, numSamples)]) for _ in 1:numTrials);
quantile(tM, [0.025, 0.975])
2-element Vector{Float64}:
0.28060907794649925
0.6789787323427712
This page was generated using Literate.jl.