I was trying to knit following code to Pdf (knit without code is working well)

But i got following error

ERROR

processing file: pdf-test.Rmd

output file: pdf-test.knit.md

"C:/RStudio/resources/app/bin/quarto/bin/tools/pandoc" +RTS -K512m -RTS pdf-test.knit.md --to latex --from markdown+autolink_bare_uris+tex_math_single_backslash --output pdf-test.tex --lua-filter "C:\Users\Sava\AppData\Local\R\win-library\4.3\rmarkdown\rmarkdown\lua\pagebreak.lua" --lua-filter "C:\Users\Sava\AppData\Local\R\win-library\4.3\rmarkdown\rmarkdown\lua\latex-div.lua" --embed-resources --standalone --highlight-style tango --pdf-engine pdflatex --variable graphics --variable "geometry:margin=1in"

! Illegal parameter number in definition of \GetTitleStringResult.

Error: LaTeX failed to compile pdf-test.tex. See The R package tinytex - Helper Functions to Manage TinyTeX, and Compile LaTeX Documents - Yihui Xie | 谢益辉 for debugging tips. See pdf-test.log for more info.

Execution halted

## CODE

##
title: "NEWTEST2"

output: pdf_document

date: "2023-11-21"

```
knitr::opts_chunk$set(echo = TRUE)
```

```
library(microbenchmark)
```

#AUFGABE 25 A

```
create_hilbert_matrix <- function(n) {
hilbert_matrix <- matrix(NA, nrow = n, ncol = n)
for (i in 1:n) {
for (j in 1:n) {
hilbert_matrix[i, j] <- 1 / (i + j - 1)
}
}
return(hilbert_matrix)
}
# function with n = 6
n <- 6
result <- create_hilbert_matrix(n)
print(result)
```

#AUFGABE 25 B

```
library(microbenchmark)
# Function to create a Hilbert matrix
create_hilbert_matrix <- function(n) {
outer(1:n, 1:n, function(x, y) 1 / (x + y - 1))
}
# Function to compare Cholesky decomposition and solve() for matrix inversion
compare_inversion_methods <- function(n) {
# Generate Hilbert
hilbert <- create_hilbert_matrix(n)
# Compute inverse using Cholesky decomposition
chol_inv <- function() solve(chol(hilbert))
# Compute inverse using solve()
solve_inv <- function() solve(hilbert)
# Perform the microbenchmark comparison
mb <- microbenchmark(
chol_inv(),
solve_inv(),
times = 100
)
return(mb)
}
# Compare for n = 3
result_n3 <- compare_inversion_methods(3)
print(result_n3)
# Compare for n = 10
result_n10 <- compare_inversion_methods(10)
print(result_n10)
```

```
library(microbenchmark)
# Function to create a Hilbert matrix
hilbert_matrix <- function(n) {
outer(1:n, 1:n, function(x, y) 1 / (x + y - 1))
}
#Matrices
hilbert1 <- hilbert_matrix(3)
hilbert2 <- hilbert_matrix(10)
result1 <- microbenchmark(solve(hilbert1),
chol2inv(chol(hilbert1)),
setup = set.seed(120))
result1
```

###For the 3×3

#solve(hilbert1) had a higher average computation time (mean = 40.786 microseconds) compared to chol2inv(chol(hilbert1)) (mean = 21.436 microseconds). This suggests that for a 3×3 Hilbert matrix, using Cholesky decomposition followed by inversion (chol2inv()) is faster than direct inversion using solve()

```
res2 <- microbenchmark(solve(hilbert2),
chol2inv(chol(hilbert2)),
setup = set.seed(120))
res2
```

###For the 10×10

#chol2inv(chol(hilbert2)) showed lower average computation time (mean = 34.093 microseconds) compared to solve(hilbert2) (mean = 48.82 microseconds). Again, indicating that for a larger 10×10 Hilbert matrix, using Cholesky decomposition followed by inversion is faster than direct inversion using solve().

###AUFGABE 26 A

```
# Given matrix X
X <- matrix(c(1, 2, 3, 1, 4, 9), ncol = 2)
# Compute Y = 1.5 * X
Y <- 1.5 * X
# Compute X as Y divided by 1.5
X <- Y / drop(1.5)
```

```
# Compute transposed Y
t_Y <- t(Y)
# Display transposed Y
t_Y
```

```
# Calculate cross-product of Y
first_transposed <- crossprod(Y)
# Calculate cross-product using tcrossprod()
second_transposed <- tcrossprod(Y)
# Benchmarking with microbenchmark
microbenchmark(
crossprod(Y),
tcrossprod(Y),
times = 100L,
setup = set.seed(120)
)
```

# Explanation of crossprod and tcrossprod functions in R:

# The crossprod function computes the cross-product of matrices by multiplying the transposed matrix with itself.

# The tcrossprod function calculates the cross-product of matrices, but in a different way.

# When computing Y^T * Y and Y * Y^T, where Y is a matrix:

# - tcrossprod(Y) is faster for computing Y * Y^T as it performs the multiplication without explicitly transposing Y.

# - crossprod(t(Y)) is used for computing Y^T * Y but requires explicitly transposing Y before the cross-product.

#tcrossprod(Y) is more efficient for matrix multiplication involving the matrix and its transpose due to its direct calculation.

#AUFGABE 26 B

```
A <- matrix(rep(1, 1000000), nrow = 1000)
v <- rep(1, 1000)
# Benchmarking the matrix multiplications for 10 times
microbenchmark(
A2v = A %*% A %*% v,
AA_v = (A %*% A) %*% v,
A_Av = A %*% (A %*% v),
times = 10L,
setup = set.seed(120)
)
```

# For operation A^2v:

# The attempt to directly compute A^2v using the %^% operator resulted in an error,

# as this operator is not a standard operation in R for matrix exponentiation.

# To emulate A^2v, the code was adjusted to perform A * A * v using %*% for matrix multiplication.

# For operation (AA)v:

# This operation calculated (AA)v by performing A * A (matrix multiplication)

# and then multiplying the resulting matrix with vector v.

# For operation A(Av):

# A(Av) was calculated by first computing A * v (matrix-vector multiplication)

# and then multiplying the resulting vector with matrix A.

# The results indicated differences in computational times among these operations:

# - A(Av) operation demonstrated significantly lower execution times compared to the other operations.

# - A^2v and (AA)v operations displayed similar execution times, which were notably higher than the A(Av) operation.

##AUFGABE 26 C

```
B <- diag(1, 1000)
A <- matrix(rep(1, 1000000), nrow = 1000)
v <- rep(1, 1000)
microbenchmark(
Av = A %*% v,
ABv = A %*% B %*% v,
AB_v = (A %*% B) %*% v,
A_Bv = A %*% (B %*% v),
times = 10L,
setup = set.seed(120)
)
```

# Discussion of Benchmarking Results for Matrix Operations Av, ABv, (AB)v, and A(Bv):

# Av Operation:

# The operation A %*% v represents a straightforward matrix-vector multiplication.

# It exhibited the fastest execution time among the four operations, taking approximately 5.02 milliseconds.

# This operation involves multiplying matrix A with vector v, which is less computationally complex and faster.

# ABv and (AB)v Operations:

# Both ABv and (AB)v involve matrix multiplication with A and B followed by a matrix-vector multiplication with v.

# ABv took approximately 2182.66 milliseconds, while (AB)v took around 2231.87 milliseconds.

# These operations are more computationally intensive due to the additional step of matrix multiplication involving both matrices (A and B).

# A(Bv) Operation:

# The A(Bv) operation involves a matrix-vector multiplication of matrix B with vector v,

# followed by a matrix-vector multiplication with matrix A.

# It took about 9.18 milliseconds, which is longer than Av but shorter than ABv and (AB)v.

# This operation includes the multiplication of matrix B with vector v before further matrix-vector multiplication with matrix A.

# Conclusion:

# - Av, being the simplest operation, executed the fastest.

# - ABv and (AB)v, involving matrix multiplications with both A and B, took longer due to their computational complexity.

# - A(Bv) took longer than Av due to the additional multiplication of B with v before the final matrix-vector multiplication.

###AUFGABE 27 A

```
X <- hilbert_matrix(6)
H <- X%*% solve(t(X) %*% X) %*% t(X)
```

###AUFGABE 27 B

```
eig_H <- eigen(H, symmetric=TRUE)
str(eig_H)
eigenvalues <- eig_H$values
eigenvalues
```

# The command "str(my_eigen)" returns a list consisting of 2 elements.

# The first element of the list is a vector containing eigenvalues,

# and the second element is a vector containing eigenvectors.

# Accessing eigenvalues can be done using the "$" operator.

# "my_eigen$values" provides us with all the eigenvalues.

###AUFGABE 27 C

```
trace <- function(x) sum(diag(x))
trace(H)
sum(eigenvalues)
```

###AUFGABE 27 D

```
det(H)
prod(eigenvalues)
```

###AUFGABE 27 E

```
#eigenvalues of matrix X
x_eigen <- eigen(X)
x_val <- x_eigen$values
#inverse of matrix X
inv_X <- solve(X)
#eigenvalues of the inverse matrix
xinv_eigen <- eigen(inv_X)
xinv_val <- xinv_eigen$values
#reciprocal of eigenvalues of matrix X
to_check <- 1 / x_val
#comparison
sorted_xinv_val <- sort(xinv_val)
sorted_to_check <- sort(to_check)
print(sorted_xinv_val)
print(sorted_to_check)
```

###AUFGABE 28 A

```
#Hilbert matrix for n = 20
hilb20 <- hilbert_matrix(20)
# Explanation of the situation:
# The Cholesky decomposition function (chol()) requires a matrix to be positive definite.
# A symmetric matrix, like the Hilbert matrix, is considered positive definite if all its eigenvalues are positive.
# However, for the Hilbert matrix hilb20 with n = 20, its entries become exceedingly small.
# Upon analyzing the eigenvalues of hilb20, some are significantly smaller than the machine epsilon (.Machine$double.eps).
# These extremely small eigenvalues, below the machine epsilon, cause issues:
# R interprets these values as close to zero or potentially negative, making the matrix non-positive definite.
hilb20_eig <- eigen(hilb20)
hilb20_eig_values <- hilb20_eig$values
# Check eigenvalues smaller or equal to the machine epsilon
hilb20_small_eig <- hilb20_eig_values <= .Machine$double.eps
hilb20_small_eig
```

#This "issue" occurs with all Hilbert matrices where n>12, and Cholesky decomposition cannot be performed

###AUFGABE 28 B

```
# Calculate condition numbers for Hilbert matrices of different sizes
cond_num_3x3 <- kappa(hilbert_matrix(3))
cond_num_5x5 <- kappa(hilbert_matrix(5))
cond_num_7x7 <- kappa(hilbert_matrix(7))
cond_num_20x20 <- kappa(hilbert_matrix(20))
# Display the computed condition numbers
print(cond_num_3x3)
print(cond_num_5x5)
print(cond_num_7x7)
print(cond_num_20x20)
```

```
#condition numbers for Hilbert matrices of sizes 1x1 to 20x20
n <- 20
conditionHilbert <- rep(NA, n)
for (i in 1:n) {
conditionHilbert[i] <- kappa(hilbert_matrix(i))
}
#condition numbers against the size of Hilbert matrices
plot(1:n, conditionHilbert, pch = 20, col = "green",
xlab = "Size of Hilbert Matrix",
ylab = "Condition number",
log = "y",
main = "Condition Number of Hilbert Matrices")
# Explanation of the plot
# The y-axis is logarithmically scaled to display logarithms of condition numbers in the plot.
# Logarithmic scaling helps visualize linear growth in log-transformed condition numbers,
# indicating exponential growth in the original condition numbers.
# Therefore, as the size of the Hilbert matrix increases, its condition number also increases exponentially.
# A peculiarity is observed after n = 13 where condition numbers almost stabilize and remain close to each other.
# Selecting condition numbers for specific Hilbert matrix sizes
interesting_values <- conditionHilbert[c(3, 5, 7, 20)]
interesting_values
```

###AUFGABE 29 A

```
LmNaive <- function(y, X) {
XtX <- t(X) %*% X
# Check if XtX is full rank before inverting
if (qr(XtX)$rank < ncol(XtX)) {
stop("The matrix (X^TX) is not full rank. OLS estimation failed.")
}
beta_hat <- solve(XtX) %*% t(X) %*% y
return(beta_hat)
}
```

```
LmNaive <- function(y, X) {
XtX <- t(X) %*% X
XtX_inv <- solve(XtX)
Xty <- t(X) %*% y
beta_hat <- XtX_inv %*% Xty
return(beta_hat)
}
```

###AUFGABE 29 B

```
LmCP <- function(y, X) {
# Compute X'X and its inverse using crossprod and solve
XtX_inv <- solve(crossprod(X)) # Compute (X'X)^(-1)
# Compute βˆ using tcrossprod and solve
beta_hat <- solve(tcrossprod(X, y)) %*% XtX_inv %*% tcrossprod(X, y)
return(beta_hat) # Return the estimated coefficients βˆ
}
```

###AUFGABE 29 c

```
# LmChol function computes OLS coefficients using Cholesky decomposition
LmChol <- function(y, X) {
# X'X and its Cholesky decomposition
XtX <- t(X) %*% X # Compute X'X
XtX_chol <- chol(XtX) # Cholesky decomposition of X'X
# X'y
Xty <- t(X) %*% y # Calculate X'y
# Solving Lz = X'y using forward substitution
z <- forwardsolve(t(XtX_chol), Xty) # Solve Lz = X'y
# Solving L'β = z using back substitution
beta_hat <- backsolve(XtX_chol, z) # Solve L'β = z
return(beta_hat)
}
```

###AUFGABE 29 D

```
LmSvd <- function(y, X){
svd_output <- svd(X)
U <- svd_output[["u"]]
V <- svd_output[["v"]]
sigma <- svd_output[["d"]]
beta <- V %*% diag(1 / sigma) %*% t(U) %*% y
return(beta)
}
```

###AUFGABE 29 E

```
#βˆ = R−1QT y
LmQR <- function(y, X){
QR <- qr(X)
Q <- qr.Q(QR)
R <- qr.R(QR)
beta_hat <- backsolve(R, crossprod(Q, y))
return(beta_hat)
}
```

###AUFGABE 29 F

```
?lm.fit()
```