Assignment 5


Assignment 5: Matrix Algebra in R

For this assignment, I explored how to create and inspect matrices in R, how to compute matrix inverses and determinants, and how to handle errors when working with non-square matrices. I also reflected on issues of numeric stability and performance that arise in matrix algebra computations.

R Code

# 1. Create the matrices

A <- matrix(1:100, nrow = 10)

B <- matrix(1:1000, nrow = 10)

# 2. Inspect dimensions

dimA <- dim(A) # should be 10 × 10

dimB <- dim(B) # should be 10 × 100

print("Dimensions of A:")

print(dimA)

print("Dimensions of B:")

print(dimB)

# 3. Compute inverse and determinant for A

invA <- solve(A)

detA <- det(A)

print("Inverse of A:")

print(invA)

print("Determinant of A:")

print(detA)

# 4. Handle non-square matrix B with tryCatch

invB <- tryCatch(solve(B), error = function(e) e)

detB <- tryCatch(det(B), error = function(e) e)

print("Inverse of B attempt:")

print(invB)

print("Determinant of B attempt:")

print(detB)


Output

Step 1 — Creating Matrices

  • A is a 10 × 10 matrix filled with integers from 1 to 100.

  • B is a 10 × 100 matrix filled with integers from 1 to 1000.

These definitions allow us to test matrix operations on both square and non-square matrices.

Step 2 — Inspecting Dimensions

From the output, we confirm:

  • A is indeed a square matrix (10 × 10).

  • B is a rectangular matrix (10 × 100), meaning some operations like determinant and inverse will not be valid.

Step 3 — Computing Inverse and Determinant for A

  • solve(A) failed because A is singular (determinant = 0).

  • det(A) successfully computed, but returned 0, confirming the singularity of A.

  • Since solve(A) failed, there is no object invA.


  • solve(B) fails because B is not square (10 × 100).

  • det(B) fails for the same reason: determinants are defined only for square matrices.

  • Errors are caught by tryCatch() so the script continues without stopping.

Step 4 — Handling Non‑Square Matrix B


Why solve(A) and det(A) work (or fail)

Matrix A is a square matrix (10 × 10), which is the first requirement for finding a determinant or an inverse.

  • The command det(A) works and gives 0, meaning the matrix is singular. This tells us the matrix does not have an inverse because some of its rows or columns are dependent on each other.

  • Because the determinant is zero, solve(A) fails with an error:

    Lapack routine dgesv: system is exactly singular: U[8,8] = 0

This error occurs because the LAPACK algorithm R uses for matrix inversion detects that A has no inverse due to singularity. Mathematically, the inverse exists only when the determinant is non‑zero. Thus, det(A) works but solve(A) fails — the result aligns with linear algebra theory.

Why operations on B fail (non‑square matrix)

Matrix B has dimensions 10 × 100, making it a rectangular matrix. Determinants and inverses are only defined for square matrices, where the number of rows equals the number of columns.

When attempting:

solve(B)

R returns the error:

'a' (10 x 100) must be square

Similarly, for:

det(B)

R returns:

'x' must be a square matrix

This is because the underlying mathematical definitions require square matrices. 

Notes on Numeric Stability and Performance

  • Numeric Stability:
    Computing determinants and inverses for large matrices can be unstable due to rounding errors and loss of precision, especially when the determinant is close to zero. Small numerical errors can significantly affect results. For singular or nearly singular matrices, inversion algorithms detect instability and throw errors or warnings, as in the case of A.

  • Performance:
    For small matrices like A (10 × 10), performance is not an issue. However, for larger matrices, computing inverses directly is computationally expensive and less numerically stable. Instead, solving linear systems with solve(A, b) is more efficient and accurate than computing the inverse explicitly.

  • Error Handling:
    Using tryCatch() for operations on matrices ensures robust scripts that don’t break when encountering errors, which is essential for real-world numerical computing.


Examples to Try 

Here, I extend the assignment with examples suggested in the helper notes, focusing on transposition, matrix–vector multiplication, and matrix–matrix multiplication.

R Code

# Create the matrices

A <- matrix(1:100,  nrow = 10)

B <- matrix(1:1000, nrow = 10)

# 1. Transpose (flip rows/columns)

A_t <- t(A)

B_t <- t(B)

# 2. Multiply matrix by a vector

v <- 1:10

A_multiplied <- A %*% v

# 3. Multiply two matrices

C <- A %*% B

dimC <- dim(C)

print("Transpose of A:")

print(A_t[1:5, 1:5])  # print sample

print("Transpose of B:")

print(B_t[1:5, 1:5])  # print sample

print("Matrix A times vector v:")

print(A_multiplied)

print("Dimensions of C = A %*% B:")

print(dimC)


Output

1. Transpose

  • Transposing flips rows into columns.

  • For example, A_t[1:5, 1:5] shows:


  • Similarly, B_t flips B (10×100 → 100×10), producing a similar pattern for its first few rows.

2. Matrix–Vector Multiplication

  • A %*% v multiplies A (10×10) by a vector v of length 10.

  • This results in a 10 ×vector:

  • Each entry is the dot product of a row of A with vector v.

3. Matrix–Matrix Multiplication

  • A %*% B multiplies a 10×1010\times10 matrix by a 10×10010\times100 matrix → resulting in a 10× matrix.

  • dim(C) confirms this:

  • This is an important operation in matrix algebra, showing that multiplication is possible when inner dimensions match.

Key Ideas

  • t() flips rows into columns (transpose).

  • A %*% v shows matrix–vector multiplication (10×10 times length-10 vector → 10×1 result).

  • C <- A %*% B is the important step. Since A is 10×10 and B is 10×100, the inner dimensions (10) match, and R produces a valid product: a new 10×100 matrix. Each value in C comes from the dot product of a row of A with a column of B. 



Comments

Popular posts from this blog

Assignment 6

Assignment 2