2023-08-24
Motivating example: Polynomial interpolation (this is a bit different from polynomial fitting)
Numerical issues not encountered when solving by hand:
Problem: Let \(c_1,\ldots,c_4\) be unknown constants. Find a cubic polynomial in \(t\), i.e., \[p\left(t\right)=c_1+c_2t+c_3t^2+c_4t^3\] so that \[p\left(-1\right)=-2,\ p^\prime\left(-1\right)=1,\ p\left(1\right)=0,\ p^\prime\left(1\right)=-1.\]
4×4 Matrix{Int64}:
1 -1 1 -1
0 1 -2 3
1 1 1 1
0 1 2 3
4-element Vector{Float64}:
-0.5
1.5
-0.5
-0.5
Problem: We now have a cubic polynomial with the desired characteristics. Present a visualization.
FNC.Polynomial()
Polynomial(-0.5 + 1.5*x - 0.5*x^2 - 0.5*x^3)
3-element Vector{Float64}:
1.5
-1.0
-1.5
Polynomial(1.5 - 1.0*x - 1.5*x^2)
.
for element-wise computing and accessing package-specific commands (similar to R’s ::
)!
for “appending”:
for options (?) and used for row/column access laterProblem: Consider the following system of linear equations: \[\underbrace{\begin{bmatrix}1 & -1 & 0 & \alpha-\beta & \beta \\ 0 & 1 & -1 & 0 & 0 \\ 0 & 0 & 1 & -1 & 0 \\ 0 & 0 &0 &1 & -1 \\ 0 & 0 & 0 & 0 & 1\end{bmatrix}}_{\mathbf{A}}\underbrace{\begin{bmatrix}x_1\\x_2\\x_3\\x_4\\x_5\end{bmatrix}}_{\mathbf{x}}=\underbrace{\begin{bmatrix}\alpha \\0 \\ 0 \\ 0 \\ 1\end{bmatrix}}_{\mathbf{b}}\]
If we solve for \(\mathbf{x}\) by hand:
Use Function 2.3.5 (FNC.backsub()
) to solve for \(\mathbf{x}\) with \(\alpha=0.1\) and \(\beta=10, 10^2, \ldots, 10^{12}\). Tabulate the values of \(\beta\) and \(|x_1-1|\).
FNC.diagm()
)FNC.backsub()
to solve for \(\mathbf{x}\)using FundamentalsNumericalComputation
α = 0.1;
β = 10 .^ (1:12);
for β in β
A = diagm(0 => ones(5), 1 => [-1,-1,-1,-1], 3 => [α-β,0], 4 => [β])
x = FNC.backsub(A, [α, 0, 0, 0, 1] )
@show [β abs(x[1] - 1.)]
end
[β abs(x[1] - 1.0)] = [10.0 4.440892098500626e-16]
[β abs(x[1] - 1.0)] = [100.0 5.773159728050814e-15]
[β abs(x[1] - 1.0)] = [1000.0 2.275957200481571e-14]
[β abs(x[1] - 1.0)] = [10000.0 3.638200851696638e-13]
[β abs(x[1] - 1.0)] = [100000.0 5.820788295807233e-12]
[β abs(x[1] - 1.0)] = [1.0e6 2.3283153183228933e-11]
[β abs(x[1] - 1.0)] = [1.0e7 3.725291186640334e-10]
[β abs(x[1] - 1.0)] = [1.0e8 5.9604645663569045e-9]
[β abs(x[1] - 1.0)] = [1.0e9 2.384185793236071e-8]
[β abs(x[1] - 1.0)] = [1.0e10 3.8146972658470446e-7]
[β abs(x[1] - 1.0)] = [1.0e11 6.1035156250222045e-6]
[β abs(x[1] - 1.0)] = [1.0e12 2.4414062500088818e-5]
using FundamentalsNumericalComputation
AbsAcc = [];
α = 0.1;
β = 10 .^ (1:12);
for β in β
A = diagm(0 => ones(5), 1 => [-1,-1,-1,-1], 3 => [α-β,0], 4 => [β])
x = FNC.backsub(A, [α, 0, 0, 0, 1])
push!(AbsAcc, abs(x[1] - 1.))
end
pretty_table((β=β,AbsAcc=AbsAcc),["β" "|x₁-1|"])
┌───────────────┬─────────────┐
│ β │ |x₁-1| │
├───────────────┼─────────────┤
│ 10 │ 4.44089e-16 │
│ 100 │ 5.77316e-15 │
│ 1000 │ 2.27596e-14 │
│ 10000 │ 3.6382e-13 │
│ 100000 │ 5.82079e-12 │
│ 1000000 │ 2.32832e-11 │
│ 10000000 │ 3.72529e-10 │
│ 100000000 │ 5.96046e-9 │
│ 1000000000 │ 2.38419e-8 │
│ 10000000000 │ 3.8147e-7 │
│ 100000000000 │ 6.10352e-6 │
│ 1000000000000 │ 2.44141e-5 │
└───────────────┴─────────────┘
FNC.backsub()
?Consider the following system of linear equations: \[\begin{bmatrix}U_{11} & U_{12} & U_{13} & U_{14} \\ 0 & U_{22} & U_{23} & U_{24} \\ 0 & 0& U_{33} & U_{34} \\ 0 & 0 & 0 & U_{44}\end{bmatrix}\begin{bmatrix}x_1\\x_2\\x_3\\x_4\end{bmatrix}=\begin{bmatrix}b_1\\b_2\\b_3\\b_4\end{bmatrix}\]
Numerical issues
The analytical solution is given by: \[\begin{eqnarray}x_4 &=& b_4/U_{44} \\ x_3 &=& \left(b_3-U_{34}x_4\right)/U_{33} \\ x_2 &=& \left(b_2-U_{23}x_3-U_{24}x_4\right)/U_{22} \\ x_1 &=& \left(b_1-U_{12}x_2-U_{13}x_3-U_{14}x_4\right)/U_{11} \end{eqnarray}\]
Look for patterns. Refer to code in Function 2.3.5.
@show
=>
which is the Pair
objectpush!()
which is inserting something into a collectionU[1, 1]
for \(U_{11}\)+=
Problem: Construct an \(\mathbf{LU}\) factorization so that \(\mathbf{U}\) is a unit upper triangular matrix instead. Write a function lufact2
that uses FNC.lufact()
without modification.
4×4 LowerTriangular{Float64, Adjoint{Float64, Matrix{Float64}}}:
1.0 ⋅ ⋅ ⋅
0.0 1.0 ⋅ ⋅
1.0 2.0 4.0 ⋅
0.0 1.0 4.0 4.0
4×4 UpperTriangular{Float64, Adjoint{Float64, Matrix{Float64}}}:
1.0 -1.0 1.0 -1.0
⋅ 1.0 -2.0 3.0
⋅ ⋅ 1.0 -1.0
⋅ ⋅ ⋅ 1.0
4×4 Matrix{Float64}:
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
Problem: Write a determinant()
function using FNC.lufact()
.
FNC.lufact()
Pseudocode:
FNC.lufact()
?float(copy(A))
A[k,:]
, A[:,k]
-=
Asymptotic notation:
So \(\sum_{k=1}^n k=O\left(n^2\right)\) and \(\sum_{k=1}^n k \sim n^2/2\).
Let \(n\) be the dimension of a square matrix.
Observe that the running times \(t\) obey a function that is \(O\left(n^p\right)\).
Any[]
for n in n
A = randn(n,n)
time = @elapsed for j in 1:12; lu(A); end
push!(t,time)
end
pretty_table((n=n,t=t),["size" "time";"" "(sec)"])
┌──────┬───────────┐
│ size │ time │
│ │ (sec) │
├──────┼───────────┤
│ 400 │ 0.0382276 │
│ 800 │ 0.15061 │
│ 1200 │ 0.294386 │
│ 1600 │ 0.616669 │
│ 2000 │ 1.14733 │
│ 2400 │ 1.97801 │
│ 2800 │ 3.07725 │
│ 3200 │ 4.55046 │
│ 3600 │ 6.40056 │
│ 4000 │ 6.67944 │
└──────┴───────────┘
# throwaway to force compilation
lu(randn(3,3));
Random.seed!(1234);
n = 400:400:4000;
t = [];
for n in n
A = randn(n,n)
time = @elapsed for j in 1:12; lu(A); end
push!(t,time)
end
pretty_table((n=n,t=t),["size" "time";"" "(sec)"])
┌──────┬───────────┐
│ size │ time │
│ │ (sec) │
├──────┼───────────┤
│ 400 │ 0.0176111 │
│ 800 │ 0.119493 │
│ 1200 │ 0.247341 │
│ 1600 │ 0.481889 │
│ 2000 │ 0.821774 │
│ 2400 │ 1.35721 │
│ 2800 │ 2.10107 │
│ 3200 │ 3.02571 │
│ 3600 │ 4.27144 │
│ 4000 │ 6.06547 │
└──────┴───────────┘
Things of note in the code:
for
loop in counting the elapsed time.FNC.lu()
is used rather than FNC.lufact()
.LU{Float64, Matrix{Float64}, Vector{Int64}}
L factor:
3×3 Matrix{Float64}:
1.0 0.0 0.0
-0.88136 1.0 0.0
0.29055 -0.371287 1.0
U factor:
3×3 Matrix{Float64}:
-1.8568 -0.82243 1.08881
0.0 -1.74805 -0.0414645
0.0 0.0 -1.11521