Solving Linear Systems#

Teng-Jui Lin

Content adapted from UW CHEME 375, Chemical Engineering Computer Skills, in Spring 2021.

Balancing chemical equations#

Problem Statement. (FRB 4.62a) Mammalian cells convert glucose to glutamic acid by the reaction

\[ \mathrm{C_6H_12O_6} + a \mathrm{NH_3} + b \mathrm{O_2} \to p \mathrm{C_5H_9NO_4} + q \mathrm{CO_2} + r \mathrm{H_2O} \]

Determine the stoichiometric coefficients.

Solution. We establish atomic balance between reactants and products:

\[\begin{split} \begin{aligned} &\text{C balance:} &6 &= 5p + q \\ &\text{H balance:} &12 + 3a &= 9p + 2r \\ &\text{O balance:} &6 + 2b &= 4p + 2q + r \\ &\text{N balance:} &a &= p \end{aligned} \end{split}\]

Reorganize the equations so that variables are on the left and constant are on the right:

\[\begin{split} \begin{aligned} &\text{C balance:} &5p + q &= 6 \\ &\text{H balance:} &9p + 2r -3a &= 12 \\ &\text{O balance:} &4p + 2q + r - 2b &= 6 \\ &\text{N balance:} &a -p &= 0 \end{aligned} \end{split}\]

Because we have five variables but only four equations, we need to assume an arbitrary basis. Here, we can assume a basis of stoichiometric coefficient of \(\mathrm{C_5H_9NO_4}\) being one:

\[ \begin{aligned} &\text{Basis:} &p &= 1 \end{aligned} \]

Now we have five variables and equations, so we can rewrite them to the form of

\[\mathbf{A}\mathbf{x} = \mathbf{b}\]

where

\[\begin{split} \mathbf{A} = \begin{bmatrix} 0 & 0 & 5 & 1 & 0 \\ -3 & 0 & 9 & 0 & 2 \\ 0 & -2 & 4 & 2 & 1 \\ 1 & 0 & -1 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 \end{bmatrix}, \mathbf{b} = \begin{bmatrix} 6 \\ 12 \\ 6 \\ 0 \\ 1 \end{bmatrix}, \mathbf{x} = \begin{bmatrix} a \\ b \\ p \\ q \\ r \end{bmatrix} \end{split}\]

We can then solve for \(\mathbf{x}\) and get the coefficients:

\[\begin{split} \begin{aligned} \mathbf{A}^{-1}\mathbf{A}\mathbf{x} &= \mathbf{A}^{-1}\mathbf{b} \\ \mathbf{x} &= \mathbf{A}^{-1}\mathbf{b} \end{aligned} \end{split}\]

The resulting coefficients are scalable, so we can scale them to whole number for reporting if needed.

Implementation: solving linear systems using numpy.linalg.inv()#

In this approach, we use numpy.linalg.inv() to solve the linear system by matrix inversion.

import numpy as np
from numpy.linalg import inv
# define the matrix and vector
A = np.array([[0, 0, 5, 1, 0], 
               [-3, 0, 9, 0, 2], 
               [0, -2, 4, 2, 1], 
               [1, 0, -1, 0, 0],
               [0, 0, 1, 0, 0]])
b = np.array([6, 12, 6, 0, 1])
# calculate the unknown vector using inverse and matrix multiplication
x = inv(A) @ b
x
array([1. , 1.5, 1. , 1. , 3. ])

Therefore, we have the solution

\[\begin{split} \mathbf{x} = \begin{bmatrix} a \\ b \\ p \\ q \\ r \end{bmatrix} = \begin{bmatrix} 1 \\ 1.5 \\ 1 \\ 1 \\ 3 \end{bmatrix}. \end{split}\]

We have the balanced chemical equation

\[ \mathrm{C_6H_{12}O_6} + \mathrm{NH_3} + 1.5 \mathrm{O_2} \to \mathrm{C_5H_9NO_4} + \mathrm{CO_2} + 3 \mathrm{H_2O} \]

Implementation: solving linear systems using numpy.linalg.solve()#

In this approach, we use numpy.linalg.solve() to directly solve the linear system.

from numpy.linalg import solve
x = solve(A, b)
x
array([1. , 1.5, 1. , 1. , 3. ])

This approach gives the same result and is computationally more efficient.