# How do I get the inverse of a homogeneous transformation matrix?

I want to get the inverse of this homogeneous transformation matrix:

iab = {
{1, 0, 0, 0},
{0, 0, -1, 0},
{0, 1, 0, 3},
{0, 0, 0, 1}
}


using the inverse function, but the problem is that I cannot directly use this function. Somehow I have to convert first the matrix to a transformation function.

iba = InverseFunction[iab] // MatrixForm


Using that I don't get any result. I can use TranslationTransform and RotationTransform to compute the inverse, but the problem with that approach is that I can only create a rotation matrix or a translation matrix, but not both in one transformation like in the above matrix I posted.

• I'm confused: your matrix is not invertible. If it was, you could just use Inverse. Am I missing something? Feb 12 '16 at 23:45
• Why my matrix is not invertible? I tried using Inverse and I got the following result: Inverse::sing: Matrix {{1,0,0,0},{0,0,-1,0},{0,1,0,3},{0,0,0,0}} is singular. >> Feb 12 '16 at 23:50
• You can write a function which does the inversion. However, you cannot use the Inverse[] as inverse of transformation matrix is different than inverse of a general matrix. By inverse of transformation matrix we mean the matrix which takes back a rigid body to original orientation and position. Feb 12 '16 at 23:50
• By the way the (4,4) element in your transformation matrix should be $1$ or some scaling factor, not $0$. Feb 12 '16 at 23:53
• Your matrix is singular because the last row is all zeros. Or to put it another way: Det[{{1, 0, 0, 0}, {0, 0, -1, 0}, {0, 1, 0, 3}, {0, 0, 0, 0}}] returns zero. Feb 12 '16 at 23:54

Here's a nice one-liner:

TransformationFunction[{{1, 0, 0, 0}, {0, 0, -1, 0}, {0, 1, 0, 3}, {0, 0, 0, 1}}]
// InverseFunction
TransformationFunction[{{1, 0, 0, 0}, {0, 0, 1, -3}, {0, -1, 0, 0}, {0, 0, 0, 1}}]


Note that TransformationFunction[] is the head of the results returned by geometric *Transform functions, which take a homogeneous transformation matrix as an argument. Since you have the matrix already, you merely need to add the wrapper and then use InverseFunction[] to invert the transformation.

For future reference: Composition[] is a handy way to chain together more than one TransformationFunction:

Composition[TranslationTransform[{0, 0, 3}], RotationTransform[π/2, {1, 0, 0}]]


Alternatively, AffineTransform[] allows a direct construction:

AffineTransform[{RotationMatrix[π/2, {1, 0, 0}], {0, 0, 3}}]


If you have a homogenous transformation matrix of the form $$\begin{bmatrix} \mathrm{R_{3 \times 3}} & \mathrm{d}_{3 \times 1} \\ 0_{1\times 3} & 1_{1\times 1} \end{bmatrix}$$ Then the inverse is given by $$\begin{bmatrix} \mathrm{R}^{-1} & -\mathrm{R}^{-1}\mathrm{d} \\ 0 & 1 \end{bmatrix}$$

Therefore, if your homogeneous matrix is (I have added the 1 in the lower corner that I think should be there)

iab = {{1, 0, 0, 0},
{0, 0, -1, 0},
{0, 1, 0, 3},
{0, 0, 0, 1}
};


then the inverse can be written as (note that for rotation matrices, the inverse is the transpose)

homogeneousTransformationInverse[mat_] /; Dimensions[mat] == {4, 4} :=
Module[{
rot = Transpose[mat[[1 ;; 3, 1 ;; 3]]],
vec = mat[[1 ;; 3, -1]],
inv = mat
},
inv[[1 ;; 3, 1 ;; 3]] = rot;
inv[[1 ;; 3, -1]] = -rot.vec;
inv
] I think the above is cleaner than the original version:

homogeneousTransformationInverse[mat_] /; Dimensions[mat] == {4, 4} :=
Module[
{rot = Transpose[mat[[1 ;; 3, 1 ;; 3]]], vec = mat[[1 ;; 3, -1]]},
ArrayFlatten[{{rot, Map[List, -rot.vec]}, {{{0, 0, 0}}, {{mat[[-1, -1]]}}}}]
]
homogeneousTransformationInverse[iab] // MatrixForm

• For rotation matrices, the transpose is same as inverse. Should use transpose as they are less expensive than inverse. Feb 13 '16 at 0:25
• @Saurav. True. Good recommendation. I will fix it. Feb 13 '16 at 0:26
• I suppose you can mention about the transpose being equal to inverse in the answer. Else someone might end up getting confused as code does not match with the explanation. This should complete the answer. Feb 13 '16 at 0:33
• How I'd have done it: homogeneousTransformationInverse[mat_?SquareMatrixQ] /; Length[mat] == 4 := With[{rot = Take[mat, 3, 3]}, Transpose[ArrayFlatten[{{rot, 0}, {{-mat[[;; -2, -1]].rot}, 1}}]]]. Of course, if the appropriate part of the matrix is not orthogonal, Inverse[]/LinearSolve[] would be used instead. Feb 13 '16 at 6:29
• @J.M. I toyed with various things. Your way is cleaner (well, actually, your answer above is actually the best). I always have a hard time getting the correct nesting using ArrayFlatten, so once I found the way that works, I went with it. Feb 13 '16 at 6:46