def quaternion_multiply(r, q):
    """Multiplies two quaternions.

    Parameters
    ----------
    r : list
        Quaternion as a list of four real values ``[rw, rx, ry, rz]``.
    q : list
        Quaternion as a list of four real values ``[qw, qx, qy, qz]``.

    Returns
    -------
    list
        Quaternion :math:`p = rq` as a list of four real values ``[pw, px, py, pz]``.

    Notes
    -----
    Multiplication of two quaternions :math:`p = rq` can be interpreted as applying rotation :math:`r` to an orientation :math:`q`,
    provided that both :math:`r` and :math:`q` are unit-length.
    The result is also unit-length.
    Multiplication of quaternions is not commutative!

    References
    ----------
    .. _mathworld quaternion: http://mathworld.wolfram.com/Quaternion.html

    """
    rw, rx, ry, rz = r
    qw, qx, qy, qz = q
    pw = rw*qw - rx*qx - ry*qy - rz*qz
    px = rw*qx + rx*qw + ry*qz - rz*qy
    py = rw*qy - rx*qz + ry*qw + rz*qx
    pz = rw*qz + rx*qy - ry*qx + rz*qw
    return [pw, px, py, pz]