🌐 EN | πŸ‡―πŸ‡΅ JP | Last sync: 2025-11-16

Chapter 2: Determinants and Systems of Linear Equations

Determinants and Systems of Linear Equations

2.1 Definition and Calculation of Determinants

Definition: Determinant
The determinant det(A) or |A| of an nΓ—n square matrix A is a scalar value satisfying the following properties:
2Γ—2 matrix: $\det\begin{pmatrix}a&b\\c&d\end{pmatrix} = ad - bc$
3Γ—3 matrix: calculated using Sarrus's rule or cofactor expansion

Code Example 1: Calculating Determinants

Python Implementation: Calculating Determinants
# Requirements:
# - Python 3.9+
# - numpy>=1.24.0, <2.0.0

"""
Example: Code Example 1: Calculating Determinants

Purpose: Demonstrate core concepts and implementation patterns
Target: Beginner to Intermediate
Execution time: ~5 seconds
Dependencies: None
"""

import numpy as np

# 2Γ—2 matrix determinant
A_2x2 = np.array([[3, 8],
                  [4, 6]])

det_A = np.linalg.det(A_2x2)
det_manual = 3*6 - 8*4  # ad - bc

print("2Γ—2 Matrix Determinant:")
print(f"A =\n{A_2x2}")
print(f"det(A) = {det_A:.4f}")
print(f"Manual calculation: 3Γ—6 - 8Γ—4 = {det_manual}")

# 3Γ—3 matrix determinant
A_3x3 = np.array([[1, 2, 3],
                  [4, 5, 6],
                  [7, 8, 9]])

det_A_3x3 = np.linalg.det(A_3x3)
print(f"\n3Γ—3 Matrix Determinant:")
print(f"A =\n{A_3x3}")
print(f"det(A) = {det_A_3x3:.10f}")
print("det(A) β‰ˆ 0 so singular matrix (no inverse)")
Theorem: Properties of Determinants
  • det(AB) = det(A) det(B) (product of determinants)
  • det(A^T) = det(A) (invariant under transpose)
  • det(kA) = k^n det(A) (scalar multiplication of nΓ—n matrix)
  • det(A) β‰  0 ⇔ A is non-singular (inverse exists)
  • Swapping rows changes sign

Code Example 2: Verification of Determinant Properties

A = np.array([[2, 1], [3, 4]]) B = np.array([[5, 6], [7, 8]]) det_A = np.linalg.det(A) det_B = np.linalg.det(B) det_AB = np.linalg.det(A @ B) print("Verification of Determinant Properties:") print(f"det(A) = {det_A:.4f}") print(f"det(B) = {det_B:.4f}") print(f"det(AB) = {det_AB:.4f}") print(f"det(A) Γ— det(B) = {det_A * det_B:.4f}") print(f"det(AB) = det(A)Γ—det(B)? {np.isclose(det_AB, det_A * det_B)}") # Transpose det_AT = np.linalg.det(A.T) print(f"\ndet(A^T) = {det_AT:.4f}") print(f"det(A) = det(A^T)? {np.isclose(det_A, det_AT)}")

2.2 Solving Systems of Linear Equations

Definition: System of Linear Equations
Equation system represented as Ax = b. A: coefficient matrix, x: unknown vector, b: constant term vector

Code Example 3: Solving Linear Systems with NumPy

# System of equations: 2x + 3y = 8, x - y = -1 A = np.array([[2, 3], [1, -1]]) b = np.array([8, -1]) # Solve with np.linalg.solve x = np.linalg.solve(A, b) print("Solution of Linear System:") print(f"2x + 3y = 8") print(f"x - y = -1") print(f"\nSolution: x = {x[0]:.4f}, y = {x[1]:.4f}") # Verification b_check = A @ x print(f"\nVerification: Ax = {b_check}") print(f"Error: {np.linalg.norm(b - b_check):.2e}")

Code Example 4: Cramer's Rule

def cramers_rule(A, b): """ Solve linear system using Cramer's rule x_i = det(A_i) / det(A) A_i: matrix with i-th column replaced by b """ det_A = np.linalg.det(A) if np.abs(det_A) < 1e-10: raise ValueError("Determinant is zero, cannot solve") n = len(b) x = np.zeros(n) for i in range(n): A_i = A.copy() A_i[:, i] = b # Replace i-th column with b x[i] = np.linalg.det(A_i) / det_A return x # Solve the same system x_cramer = cramers_rule(A, b) print("Cramer's Rule:") print(f"Solution: x = {x_cramer[0]:.4f}, y = {x_cramer[1]:.4f}") print(f"Difference from np.linalg.solve: {np.linalg.norm(x - x_cramer):.2e}")

2.3 Gaussian Elimination

Code Example 5: Implementation of Gaussian Elimination

def gaussian_elimination(A, b): """ Solve linear system using Gaussian elimination Forward elimination β†’ Back substitution """ n = len(b) # Create augmented matrix Ab = np.hstack([A.astype(float), b.reshape(-1, 1)]) # Forward elimination for i in range(n): # Pivot selection (partial pivoting) max_row = np.argmax(np.abs(Ab[i:, i])) + i Ab[[i, max_row]] = Ab[[max_row, i]] # Normalize i-th row Ab[i] = Ab[i] / Ab[i, i] # Zero out below i-th column for j in range(i+1, n): Ab[j] = Ab[j] - Ab[j, i] * Ab[i] # Back substitution x = np.zeros(n) for i in range(n-1, -1, -1): x[i] = Ab[i, -1] - np.dot(Ab[i, i+1:n], x[i+1:]) return x # Test A_test = np.array([[2.0, 1.0, -1.0], [-3.0, -1.0, 2.0], [-2.0, 1.0, 2.0]]) b_test = np.array([8.0, -11.0, -3.0]) x_gauss = gaussian_elimination(A_test.copy(), b_test.copy()) x_numpy = np.linalg.solve(A_test, b_test) print("Gaussian Elimination:") print(f"Gaussian solution: {x_gauss}") print(f"NumPy solution: {x_numpy}") print(f"Difference: {np.linalg.norm(x_gauss - x_numpy):.2e}")

2.4 LU Decomposition

Definition: LU Decomposition
Decompose matrix A into lower triangular matrix L and upper triangular matrix U: A = LU
Linear system Ax = b can be solved in two stages: Ly = b β†’ Ux = y

Code Example 6: Solving Linear Systems with LU Decomposition

from scipy.linalg import lu # LU decomposition A_lu = np.array([[4, 3], [6, 3]]) P, L, U = lu(A_lu) print("LU Decomposition:") print(f"A =\n{A_lu}\n") print(f"P (permutation matrix) =\n{P}\n") print(f"L (lower triangular) =\n{L}\n") print(f"U (upper triangular) =\n{U}\n") # Verification: PA = LU print(f"PA =\n{P @ A_lu}\n") print(f"LU =\n{L @ U}\n") print(f"PA = LU? {np.allclose(P @ A_lu, L @ U)}") # Solve linear system using LU decomposition b_lu = np.array([10, 12]) # Step 1: Solve Ly = Pb (forward substitution) y = np.linalg.solve(L, P @ b_lu) # Step 2: Solve Ux = y (back substitution) x_lu = np.linalg.solve(U, y) print(f"\nSolution of linear system Ax = b:") print(f"x = {x_lu}") # Verification print(f"Ax = {A_lu @ x_lu}") print(f"b = {b_lu}")

2.5 Rank and Existence Conditions for Solutions

Theorem: Existence Conditions for Solutions
For Ax = b:
  • rank(A) = rank([A|b]) = n β†’ unique solution
  • rank(A) = rank([A|b]) < n β†’ infinite solutions
  • rank(A) < rank([A|b]) β†’ no solution

Code Example 7: Rank Calculation and Solution Classification

# Rank calculation A_rank = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) rank_A = np.linalg.matrix_rank(A_rank) print("Rank Calculation:") print(f"A =\n{A_rank}") print(f"rank(A) = {rank_A}") print(f"A is 3Γ—3 square matrix but rank < 3 so singular matrix\n") # Example with unique solution A_unique = np.array([[1, 2], [3, 4]]) b_unique = np.array([5, 6]) Ab_unique = np.column_stack([A_unique, b_unique]) rank_A_u = np.linalg.matrix_rank(A_unique) rank_Ab_u = np.linalg.matrix_rank(Ab_unique) print("Unique Solution Example:") print(f"rank(A) = {rank_A_u}") print(f"rank([A|b]) = {rank_Ab_u}") print(f"rank(A) = rank([A|b]) = 2 β†’ unique solution") x_unique = np.linalg.solve(A_unique, b_unique) print(f"Solution: {x_unique}\n") # Example with no solution A_no_sol = np.array([[1, 2], [2, 4]]) b_no_sol = np.array([3, 7]) # 2nd equation is 2Γ— 1st equation but RHS inconsistent Ab_no_sol = np.column_stack([A_no_sol, b_no_sol]) rank_A_n = np.linalg.matrix_rank(A_no_sol) rank_Ab_n = np.linalg.matrix_rank(Ab_no_sol) print("No Solution Example:") print(f"rank(A) = {rank_A_n}") print(f"rank([A|b]) = {rank_Ab_n}") print(f"rank(A) < rank([A|b]) β†’ no solution")

2.6 Application to Materials Science: Stoichiometry Calculations

Application Example: Balancing Chemical Equations
By solving chemical equation coefficients as linear equations, we can derive reaction formulas that satisfy elemental balance.

Code Example 8: Balancing Chemical Equations

# Chemical equation: aFe + bO2 β†’ cFe2O3 # Elemental balance: # Fe: a = 2c # O: 2b = 3c # Express in matrix form # Coefficient matrix (unknowns on left, knowns on right) # a - 2c = 0 # 2b - 3c = 0 # c = 1 (fix arbitrarily) # Transform to solvable form A_chem = np.array([[1, 0, -2], # Fe balance [0, 2, -3]]) # O balance # With c=1 c = 1 b_chem = np.array([2*c, 3*c]) # Find least squares solution x_chem = np.linalg.lstsq(A_chem[:, :2], b_chem, rcond=None)[0] a, b = x_chem print("Chemical Equation Balancing:") print(f"Fe + O2 β†’ Fe2O3") print(f"\nCoefficients:") print(f"a (Fe) = {a:.1f}") print(f"b (O2) = {b:.1f}") print(f"c (Fe2O3) = {c:.1f}") print(f"\nBalanced Equation:") print(f"{int(a*2)}Fe + {int(b*2)}O2 β†’ {int(c*2)}Fe2O3") # Verification print(f"\nElemental Balance Verification:") print(f"Fe: left = {int(a*2)}, right = {int(c*2)*2}") print(f"O: left = {int(b*2)*2}, right = {int(c*2)*3}")

Summary

Disclaimer