The question addressed here (from OR Stack Exchange) is how to find all left inverses of a matrix. The question specifies dimensions around 200 x 10, which is what we will use. Before proceeding, we note that for an \(m\times n\) matrix \(A\) with \(m \ge n\) to have a left inverse \(B,\) \(A\) must have full column rank. If it does not, a nonzero vector \(x\) exists for which \(Ax = \mathbf{0},\) in which case \(B(Ax) = \mathbf{0} = (BA)x = Ix,\) a contradiction.

For the computations, we will use the pracma package.

library(pracma)

The first step is to create a sample matrix \(A\).

set.seed(71522) # for reproducibility
rows <- 200
cols <- 10
A <- matrix(rnorm(rows * cols), nrow = rows)

To get one left inverse, we use the pracma method pinv. This computes the Moore-Penrose pseudoinverse of the original matrix.

B <- pinv(A)

We can verify the result by computing \(B \cdot A\) (and rounding away decimal dust).

round(B %*% A, digits = 5)
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    1    0    0    0    0    0    0    0    0     0
 [2,]    0    1    0    0    0    0    0    0    0     0
 [3,]    0    0    1    0    0    0    0    0    0     0
 [4,]    0    0    0    1    0    0    0    0    0     0
 [5,]    0    0    0    0    1    0    0    0    0     0
 [6,]    0    0    0    0    0    1    0    0    0     0
 [7,]    0    0    0    0    0    0    1    0    0     0
 [8,]    0    0    0    0    0    0    0    1    0     0
 [9,]    0    0    0    0    0    0    0    0    1     0
[10,]    0    0    0    0    0    0    0    0    0     1

For any other left inverse \(C\), we have \((C - B) \cdot A =I - I = \mathbf{0}\), so \(C = B + M\) where \(M\) is a matrix whose rows belong to the left null space of \(A.\) We can use the pracma method nullspace to get a basis for the left null space. To do so, we transpose \(A\) and then transpose the basis.

N <- A |> t() |> pracma::nullspace() |> t()
dim(N)
[1] 190 200

The null space of \(A\) has dimension 190. Adding to \(B\) any 10 x 200 matrix whose rows are linear combinations of the rows of \(N\) forms another left inverse. We demonstrate this with a random combination.

C <- matrix(rnorm(cols * nrow(N)), nrow = cols) %*% N + B
round(C %*% A, digits = 5)
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    1    0    0    0    0    0    0    0    0     0
 [2,]    0    1    0    0    0    0    0    0    0     0
 [3,]    0    0    1    0    0    0    0    0    0     0
 [4,]    0    0    0    1    0    0    0    0    0     0
 [5,]    0    0    0    0    1    0    0    0    0     0
 [6,]    0    0    0    0    0    1    0    0    0     0
 [7,]    0    0    0    0    0    0    1    0    0     0
 [8,]    0    0    0    0    0    0    0    1    0     0
 [9,]    0    0    0    0    0    0    0    0    1     0
[10,]    0    0    0    0    0    0    0    0    0     1
LS0tCnRpdGxlOiAiRmluZGluZyBBbGwgTGVmdCBJbnZlcnNlcyIKYXV0aG9yOiBQYXVsIEEuIFJ1YmluCmRhdGU6IDE1IEp1bHkgMjAyMgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpUaGUgW3F1ZXN0aW9uXShodHRwczovL29yLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy84NjkzL2ZpbmRpbmctYWxsLWxlZnQtaW52ZXJzZXMtb2YtYS1tYXRyaXgvKSBhZGRyZXNzZWQgaGVyZSAoZnJvbSBPUiBTdGFjayBFeGNoYW5nZSkgaXMgaG93IHRvIGZpbmQgYWxsIGxlZnQgaW52ZXJzZXMgb2YgYSBtYXRyaXguIFRoZSBxdWVzdGlvbiBzcGVjaWZpZXMgZGltZW5zaW9ucyBhcm91bmQgMjAwIHggMTAsIHdoaWNoIGlzIHdoYXQgd2Ugd2lsbCB1c2UuIEJlZm9yZSBwcm9jZWVkaW5nLCB3ZSBub3RlIHRoYXQgZm9yIGFuICRtXHRpbWVzIG4kIG1hdHJpeCAkQSQgd2l0aCAkbSBcZ2UgbiQgdG8gaGF2ZSBhIGxlZnQgaW52ZXJzZSAkQiwkICRBJCBtdXN0IGhhdmUgZnVsbCBjb2x1bW4gcmFuay4gSWYgaXQgZG9lcyBub3QsIGEgbm9uemVybyB2ZWN0b3IgJHgkIGV4aXN0cyBmb3Igd2hpY2ggJEF4ID0gXG1hdGhiZnswfSwkIGluIHdoaWNoIGNhc2UgJEIoQXgpID0gXG1hdGhiZnswfSA9IChCQSl4ID0gSXgsJCBhIGNvbnRyYWRpY3Rpb24uIAoKRm9yIHRoZSBjb21wdXRhdGlvbnMsIHdlIHdpbGwgdXNlIHRoZSBgcHJhY21hYCBwYWNrYWdlLgoKYGBge3J9CmxpYnJhcnkocHJhY21hKQpgYGAKCgpUaGUgZmlyc3Qgc3RlcCBpcyB0byBjcmVhdGUgYSBzYW1wbGUgbWF0cml4ICRBJC4KCmBgYHtyfQpzZXQuc2VlZCg3MTUyMikgIyBmb3IgcmVwcm9kdWNpYmlsaXR5CnJvd3MgPC0gMjAwCmNvbHMgPC0gMTAKQSA8LSBtYXRyaXgocm5vcm0ocm93cyAqIGNvbHMpLCBucm93ID0gcm93cykKYGBgCgoKVG8gZ2V0IG9uZSBsZWZ0IGludmVyc2UsIHdlIHVzZSB0aGUgYHByYWNtYWAgbWV0aG9kIGBwaW52YC4gVGhpcyBjb21wdXRlcyB0aGUgW01vb3JlLVBlbnJvc2UgcHNldWRvaW52ZXJzZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTW9vcmUlRTIlODAlOTNQZW5yb3NlX2ludmVyc2UpIG9mIHRoZSBvcmlnaW5hbCBtYXRyaXguCgpgYGB7cn0KQiA8LSBwaW52KEEpCmBgYAoKCldlIGNhbiB2ZXJpZnkgdGhlIHJlc3VsdCBieSBjb21wdXRpbmcgJEIgXGNkb3QgQSQgKGFuZCByb3VuZGluZyBhd2F5IGRlY2ltYWwgZHVzdCkuCgpgYGB7cn0Kcm91bmQoQiAlKiUgQSwgZGlnaXRzID0gNSkKYGBgCgpGb3IgYW55IG90aGVyIGxlZnQgaW52ZXJzZSAkQyQsIHdlIGhhdmUgJChDIC0gQikgXGNkb3QgQSA9SSAtIEkgPSBcbWF0aGJmezB9JCwgc28gJEMgPSBCICsgTSQgd2hlcmUgJE0kIGlzIGEgbWF0cml4IHdob3NlIHJvd3MgYmVsb25nIHRvIHRoZSBsZWZ0IG51bGwgc3BhY2Ugb2YgJEEuJCBXZSBjYW4gdXNlIHRoZSBgcHJhY21hYCBtZXRob2QgYG51bGxzcGFjZWAgdG8gZ2V0IGEgYmFzaXMgZm9yIHRoZSBsZWZ0IG51bGwgc3BhY2UuIFRvIGRvIHNvLCB3ZSB0cmFuc3Bvc2UgJEEkIGFuZCB0aGVuIHRyYW5zcG9zZSB0aGUgYmFzaXMuCgpgYGB7cn0KTiA8LSBBIHw+IHQoKSB8PiBwcmFjbWE6Om51bGxzcGFjZSgpIHw+IHQoKQpkaW0oTikKYGBgCgpUaGUgbnVsbCBzcGFjZSBvZiAkQSQgaGFzIGRpbWVuc2lvbiAxOTAuIEFkZGluZyB0byAkQiQgYW55IDEwIHggMjAwIG1hdHJpeCB3aG9zZSByb3dzIGFyZSBsaW5lYXIgY29tYmluYXRpb25zIG9mIHRoZSByb3dzIG9mICROJCBmb3JtcyBhbm90aGVyIGxlZnQgaW52ZXJzZS4gV2UgZGVtb25zdHJhdGUgdGhpcyB3aXRoIGEgcmFuZG9tIGNvbWJpbmF0aW9uLgoKYGBge3J9CkMgPC0gbWF0cml4KHJub3JtKGNvbHMgKiBucm93KE4pKSwgbnJvdyA9IGNvbHMpICUqJSBOICsgQgpyb3VuZChDICUqJSBBLCBkaWdpdHMgPSA1KQpgYGAK