Notes on Matrices

For the course LBYMATH - Mathematical Economics (Laboratory) for Term 3, A.Y. 2025-2026

Preliminaries

Some packages shall be set.

library(matlib)
Warning: package 'matlib' was built under R version 4.5.3

Lecture No. 1 (5/21/2026)

Setting up matrices

In order to set a matrix, the following code shall be executed:

A <- matrix(c(1,2,3,4,5,6), nrow=2, ncol=3, byrow=TRUE)

# SYNTAX:
# matrix()  : the syntax to create a matrix
# c()       : concatatenate function
# nrow      : number of rows
# ncol      : number of columns
# byrow     : fills 1st rows first before moving on to the next

Column Vector

This is the default matrix when you simply input the figures.

A_col <- matrix(c(1,2,3,4,5,6))
A_col
     [,1]
[1,]    1
[2,]    2
[3,]    3
[4,]    4
[5,]    5
[6,]    6

If more than one column exists, the total number of elements will be distributed across the columns. All the spaces in the first column will be prioritized. Any excess value will be used to fill the next column from top to bottom, and so on.

A_test <- matrix(c(1,2,3,4,5,6),ncol=3)
A_test
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

If there is not enough data, the given data repeats to fill out the commanded number of columns (ncol). However, when the number of columns reach pass the maximum number of data, it will become a row vector.

A_test <- matrix(c(1,2,3,4,5,6), ncol=7)
Warning in matrix(c(1, 2, 3, 4, 5, 6), ncol = 7): data length [6] is not a
sub-multiple or multiple of the number of columns [7]
A_test
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    1    2    3    4    5    6    1

Row Vector

This is a type of matrix which has 1 row and n columns. Since the default matrix without any specification of rows and columns is a column vector, we have to specify that nrow=1

A_row <- matrix(c(1,2,3,4,5,6), nrow=1)
A_row
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    2    3    4    5    6

General Matrix

A matrix that has m x n matrices, where m and n are at least 2. In essence, a general matrix has at least 2 rows and 2 columns.

# Method 1
A <- matrix(c(1,2,3,4,5,6), nrow=2, ncol=3, byrow=TRUE)
A
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
# Method 2
A <- matrix(c(1,4,2,5,3,6), nrow=2, ncol=3)
A
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6

What would happen if Method 2 used c(1,2,3,4,5,6)?

A_row3 <- matrix(c(1,2,3,4,5,6), nrow=2, ncol=3)
A_row3
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

To replace an entry in a matrix, you can assign using A[i,j] <- x such that i is the row number and j is the column number. When replacing an entire row or column, simply omit either i or j.

# Replacing a singular entry with a new set of data
A[1,3] <- 7
A
     [,1] [,2] [,3]
[1,]    1    2    7
[2,]    4    5    6
#A[i,j] : where i = row, j is column
# Replacing an entire row with a new set of data
A[1,] <- c(7,8,9)
A
     [,1] [,2] [,3]
[1,]    7    8    9
[2,]    4    5    6

Matrix Operations

# Setting up matrices
B <- matrix(c(1,2,3,4,5,6), ncol=2, nrow=3, byrow=TRUE)
C <- matrix(c(3,-2,7,5,0,1), ncol=2, nrow=3, byrow=TRUE)
B
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6
C
     [,1] [,2]
[1,]    3   -2
[2,]    7    5
[3,]    0    1

Matrix Addition/Subtraction

Two matrices can be added only if they have the same dimensions.

D <- B+C
D
     [,1] [,2]
[1,]    4    0
[2,]   10    9
[3,]    5    7
# Set a new matrix to illustrate non-conformity.
E <- matrix(c(2,7,-5,3,5,7),ncol=3, nrow=2)
#add B (3x2) with E (2x3)
D <- B+E
D
## Error in B + E : non-conformable arrays

#add B (3x2) with E (2x3) D <- B+E D

While addition has commutative property (i.e., the order does not matter), subtraction needs to be ordered since the order does matter.

# Order 1
D <- B-C
D
     [,1] [,2]
[1,]   -2    4
[2,]   -4   -1
[3,]    5    5
# Order 2
D <- C-B
D
     [,1] [,2]
[1,]    2   -4
[2,]    4    1
[3,]   -5   -5

Scalar Multiplication

This is essentially multiplying a matrix with a scalar. A scalar is a fixed number which can be used to scale all entries in a matrix by the same amount. You can use a regular * notation for scalar multiplication.

D <- 6*C
D
     [,1] [,2]
[1,]   18  -12
[2,]   42   30
[3,]    0    6

Matrix Multiplication

A difference in matrix multiplication is that the notation is used is not *, but rather *%*. Note the differences in output between the two methods.

# Matrix multiplication using correct operators
G <- A %*% C
G
     [,1] [,2]
[1,]   77   35
[2,]   47   23
# Matrix multiplication using regular multiplication operators
# G <- A*C
# Error in A * C : non-conformable arrays

Matrix Transposition

This is an operation where an entry moves from row i and column j to row j and column i. Essentially,in a matrix transposition, \(a_{ij} \rightarrow a_{ji}\).

A
     [,1] [,2] [,3]
[1,]    7    8    9
[2,]    4    5    6
H <- t(A)
H
     [,1] [,2]
[1,]    7    4
[2,]    8    5
[3,]    9    6

Types of Matrices

Square Matrix

This is a matrix that has the same number of rows and columns. In essence, a square matrix has n x n dimensions.

S <- matrix(c(1,2,3,4),nrow=2,ncol=2)
S
     [,1] [,2]
[1,]    1    3
[2,]    2    4

Symmetric Matrix

A symmetric matrix is a matrix that when transposed is still equal to its original form.

J <- matrix(c(-1,0,3,0,7,6,3,6,-5), nrow=3, ncol=3, byrow=TRUE)
J
     [,1] [,2] [,3]
[1,]   -1    0    3
[2,]    0    7    6
[3,]    3    6   -5
# Perform transposition
H <- t(J)
H
     [,1] [,2] [,3]
[1,]   -1    0    3
[2,]    0    7    6
[3,]    3    6   -5

Diagonal Matrix

In diagonal matrices, the matrix must be a square matrix wherein all data points are placed in the principal diagonal.

\[ D = \begin{bmatrix}d_{11} & 0 & \cdots & 0 \\0 & d_{22} & \cdots & 0 \\\vdots & \vdots & \ddots & \vdots \\0 & 0 & \cdots & d_{nn}\end{bmatrix} \]

There are two ways to use diagonal matrices using the diag() prompt:

  1. To construct a diagonal matrix by nesting a c() function
  2. To extract entries from the main diagonal by inputting a matrix as an argument within the diag() prompt
  3. To replace the diagonal elements in a matrix
# Construct a diagonal matrix
K <- diag(c(1,2,3))
K
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    2    0
[3,]    0    0    3
# Extract a diagonal matrix
J
     [,1] [,2] [,3]
[1,]   -1    0    3
[2,]    0    7    6
[3,]    3    6   -5
diag(J)
[1] -1  7 -5
# Replace the diagonal elements in a matrix
diag(J) <- c(1,2,3)

Lecture No. 2 (05/25/2026)

Continuing the discussion on diagonal matrices.

Another way to create non-square matrix by specific the nrow and ncol.

L <- diag(c(1,2,3),nrow=3,ncol=2)
L
     [,1] [,2]
[1,]    1    0
[2,]    0    2
[3,]    0    0

Identity Matrix

An identity matrix is a diagonal matrix where all diagonal entries are one. A key property of identity matrices is that \(AI = IA = A\).

I <- diag(3)
I
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    0    1    0
[3,]    0    0    1
M <- diag(nrow=3,ncol=2)
M
     [,1] [,2]
[1,]    1    0
[2,]    0    1
[3,]    0    0

Trace

For a square matrix, the trace is the sum of its diagonal elements. Get the sum of the diagonal elements using the built-in sum() in R.

sum(diag(J))
[1] 6

We can also build trace functions that can stop when a matrix is not a square matrix.

tr <- function(X){
  stopifnot(nrow(X) == ncol(X))   # the function shall stop if nrow =/= ncol
  sum(diag(X))                    # returns the trace established earlier
}
tr(J)
[1] 6

# Practice: Get the trace of matrix A.

tr <- function(X){
  stopifnot(nrow(X) == ncol(X))   # the function shall stop if nrow =/= ncol
  sum(diag(X))                    # returns the trace established earlier
}
tr(A)

Triangular Matrix

A square matrix where all entries either above (lower triangular) or below (upper triangular) are zero.

Upper Triangular Matrix Lower Triangular Matrix
General Form \(a_{ij}=0\) for \(i > j\) \(a_{ij}=0\) for \(i < j\)

# Practice: Construct matrices M and N.

Idempotent Matrix

An idempotent matrix is a square matrix that satifies: \(A^2 = A.\) That is, \(A=A^2=A^3=\cdots=A^n\). Use the package expm to multiply matrices exponentially using %^%

# install.packages("expm")
library(expm)
Warning: package 'expm' was built under R version 4.5.3
Loading required package: Matrix

Attaching package: 'expm'
The following object is masked from 'package:Matrix':

    expm
O <- S %^% 3
A
     [,1] [,2] [,3]
[1,]    7    8    9
[2,]    4    5    6
O
     [,1] [,2]
[1,]   37   81
[2,]   54  118

Matrix Inverse

A square matrix has an inverse matrix \(A^{-1}\) if \(AA^{-1} = I\) or \(A^{-1}A = 1\). The square matrix has to be non-singular, i.e., det(A) =/= 0, for an inverse matrix to exist.

In R, we can use the built-in function solve() to determine the inverse of a matrix. We can place ?solve() to access the help feature in R that shows the detail of the function.

\[ A^{-1} = \begin{bmatrix}17 & 11 \\47 & 23\end{bmatrix}^{-1}=\frac{1}{det(G)}\begin{bmatrix}23 & -47 \\-11 & 17\end{bmatrix} \]

# Invertible or non-invertible matrix?
det(G)
solve(G)
           [,1]       [,2]
[1,]  0.1825397 -0.2777778
[2,] -0.3730159  0.6111111

\[ \begin{cases} 2x + 3y &= 7 \\ x - 4y &= -2\end{cases} \implies A = \begin{bmatrix}1 & 1\\2 &1 \end{bmatrix}, x=\begin{bmatrix}x \\ y \end{bmatrix}, x=\begin{bmatrix}4 \\ 7 \end{bmatrix} \\ \implies Ax = B \\ \implies x = A^{-1}b \]

Solving for x using R, we need matrices A and b, hoever we have to make sure that A is invertible

A <- matrix(c(1,2,1,1),nrow=2,ncol=2)
A
     [,1] [,2]
[1,]    1    1
[2,]    2    1
det(A)
[1] -1
b <- c(4,7)
b
[1] 4 7
showEqn(A,b)
1*x1 + 1*x2  =  4 
2*x1 + 1*x2  =  7 
#In Base R
solve(A,b)
[1] 3 1
#Solve() using matlib
Solve(A,b)
x1    =  3 
  x2  =  1 

We can use plotEqn() function in the matlib to visualize the system of two linear equations.

plotEqn(A,b,xlim=c(-10,10))
  x[1] + x[2]  =  4 
2*x[1] + x[2]  =  7 

With a system of 3 linear equations, we can visualize the function with plotEqn3d().

rgl::setupKnitr(autoprint=TRUE)

A <- matrix(c(2,1,-1,1,-2,1,3,-1,-2),nrow=3,ncol=3,byrow=TRUE)
b <- c(4,1,3)
Solve(A,b,fractions=T)
x1      =  2 
  x2    =  1 
    x3  =  1 
plotEqn3d(A,b,xlim=c(-5,5),ylim=c(-5,5),zlim=c(-5,5))