def __imul__(left, right):
    """
        multiply quaternion in place
        
        :arg left: left multiplicand
        :type left: Quaternion, UnitQuaternion
        :arg right: right multiplicand
        :type right: Quaternion, UnitQuaternion, 3-vector, float
        :return: product
        :rtype: Quaternion, UnitQuaternion
        :raises: ValueError
        
        ==============   ==============   ==============  ================
                   Multiplicands                   Product
        -------------------------------   --------------------------------
            left             right            type           result
        ==============   ==============   ==============  ================
        Quaternion       Quaternion       Quaternion      Hamilton product
        Quaternion       UnitQuaternion   Quaternion      Hamilton product
        Quaternion       scalar           Quaternion      scalar product
        UnitQuaternion   Quaternion       Quaternion      Hamilton product
        UnitQuaternion   UnitQuaternion   UnitQuaternion  Hamilton product
        UnitQuaternion   scalar           Quaternion      scalar product
        UnitQuaternion   3-vector         3-vector        vector rotation
        ==============   ==============   ==============  ================

        Any other input combinations result in a ValueError.
        
        Note that left and right can have a length greater than 1 in which case:
        
        ====   =====   ====  ================================
        left   right   len     operation
        ====   =====   ====  ================================
         1      1       1    ``prod = left * right``
         1      N       N    ``prod[i] = left * right[i]``
         N      1       N    ``prod[i] = left[i] * right``
         N      N       N    ``prod[i] = left[i] * right[i]``
         N      M       -    ``ValueError``
        ====   =====   ====  ================================

        A scalar of length N is a list, tuple or numpy array.
        A 3-vector of length N is a 3xN numpy array, where each column is a 3-vector.
        """
    return left.__mul__(right)
