'Transform the cartesian coordinates using a 3x3 matrix.
This returns a new representation and does not modify the original one.
Any differentials attached to this representation will also be
transformed.
Parameters
matrix : `~numpy.ndarray`
A 3x3 transformation matrix, such as a rotation matrix.
Examples
We can start off by creating a cartesian representation object:
>>> from astropy import units as u
>>> from astropy.coordinates import CartesianRepresentation
>>> rep = CartesianRepresentation([1, 2] * u.pc,
...                               [2, 3] * u.pc,
...                               [3, 4] * u.pc)
We now create a rotation matrix around the z axis:
>>> from astropy.coordinates.matrix_utilities import rotation_matrix
>>> rotation = rotation_matrix(30 * u.deg, axis=\'z\')
Finally, we can apply this transformation:
>>> rep_new = rep.transform(rotation)
>>> rep_new.xyz  # doctest: +FLOAT_CMP
<Quantity [[ 1.8660254 , 3.23205081],
[ 1.23205081, 1.59807621],
[ 3.        , 4.        ]] pc>'

def transform(self, matrix):

    try:
        matrix_shape = matrix.shape
    except AttributeError:
        matrix = np.array(matrix)
        matrix_shape = matrix.shape
    if (matrix_shape[(-2):] != (3, 3)):
        raise ValueError(u"tried    to    do    matrix    multiplication    with    an    array    that    doesn't    end    in    3x3")
    oldxyz = self.xyz
    if (self.isscalar and (not matrix_shape[:(-2)])):
        newxyz = matrix.dot(oldxyz.value)
    else:
        newxyz = np.einsum(u'...ij,j...->i...', matrix, oldxyz.value)
    newxyz = u.Quantity(newxyz, oldxyz.unit, copy=False)
    if self.differentials:
        new_diffs = dict(((k, d.from_cartesian(d.to_cartesian().transform(matrix))) for (k, d) in self.differentials.items()))
    else:
        new_diffs = None
    return self.__class__(copy=False, differentials=new_diffs, *newxyz)
