def test_quaternion(self, T):
        # Simple API.
        Quaternion = mut.Quaternion_[T]
        cast = np.vectorize(T)
        q_identity = Quaternion()
        self.assertEqual(numpy_compare.resolve_type(q_identity.wxyz()), T)
        numpy_compare.assert_float_equal(q_identity.wxyz(), [1., 0, 0, 0])
        numpy_compare.assert_float_equal(
            copy.copy(q_identity).wxyz(), [1., 0, 0, 0])
        numpy_compare.assert_equal(q_identity.wxyz(),
                                   Quaternion.Identity().wxyz())
        if T == float:
            self.assertEqual(str(q_identity),
                             "Quaternion_[float](w=1.0, x=0.0, y=0.0, z=0.0)")
        self.check_cast(mut.Quaternion_, T)
        # Test ordering.
        q_wxyz = normalize([0.1, 0.3, 0.7, 0.9])
        q = Quaternion(w=q_wxyz[0], x=q_wxyz[1], y=q_wxyz[2], z=q_wxyz[3])
        # - Accessors.
        numpy_compare.assert_float_equal(q.w(), q_wxyz[0])
        numpy_compare.assert_float_equal(q.x(), q_wxyz[1])
        numpy_compare.assert_float_equal(q.y(), q_wxyz[2])
        numpy_compare.assert_float_equal(q.z(), q_wxyz[3])
        numpy_compare.assert_float_equal(q.xyz(), q_wxyz[1:])
        numpy_compare.assert_float_equal(q.wxyz(), q_wxyz)
        # - Mutators.
        q_wxyz_new = q_wxyz[::-1]
        numpy_compare.assert_not_equal(q_wxyz, q_wxyz_new)
        q.set_wxyz(wxyz=q_wxyz_new)
        numpy_compare.assert_float_equal(q.wxyz(), q_wxyz_new)
        q.set_wxyz(w=q_wxyz_new[0],
                   x=q_wxyz_new[1],
                   y=q_wxyz_new[2],
                   z=q_wxyz_new[3])
        numpy_compare.assert_float_equal(q.wxyz(), q_wxyz_new)
        # Alternative constructors.
        q_other = Quaternion(wxyz=q_wxyz)
        numpy_compare.assert_float_equal(q_other.wxyz(), q_wxyz)
        R = np.array([[0., 0, 1], [1, 0, 0], [0, 1, 0]])
        q_wxyz_expected = np.array([0.5, 0.5, 0.5, 0.5])
        q_other = Quaternion(q_wxyz_expected)
        numpy_compare.assert_float_equal(q_other.rotation(), R)
        R_I = np.eye(3, 3)
        q_other.set_rotation(R_I)
        numpy_compare.assert_equal(q_other.wxyz(), q_identity.wxyz())
        # - Copy constructor.
        cp = Quaternion(other=q)
        numpy_compare.assert_equal(q.wxyz(), cp.wxyz())
        # Bad values.
        if T != Expression:
            q = Quaternion.Identity()
            # - wxyz
            q_wxyz_bad = [1., 2, 3, 4]
            with self.assertRaises(RuntimeError):
                q.set_wxyz(q_wxyz_bad)
            numpy_compare.assert_float_equal(q.wxyz(), [1., 0, 0, 0])
            # - Rotation.
            R_bad = np.copy(R)
            R_bad[0, 0] = 10
            with self.assertRaises(RuntimeError):
                q_other.set_rotation(R_bad)
            numpy_compare.assert_float_equal(q_other.rotation(), R_I)

        # Operations.
        q_AB = Quaternion(wxyz=[0.5, 0.5, 0.5, 0.5])
        q_I = q_AB.inverse().multiply(q_AB)
        numpy_compare.assert_float_equal(q_I.wxyz(), [1., 0, 0, 0])
        if six.PY3:
            numpy_compare.assert_float_equal(
                eval("q_AB.inverse() @ q_AB").wxyz(), [1., 0, 0, 0])
        v_B = np.array([1., 2, 3])
        v_A = np.array([3., 1, 2])
        numpy_compare.assert_float_allclose(q_AB.multiply(vector=v_B), v_A)
        vlist_B = np.array([v_B, v_B]).T
        vlist_A = np.array([v_A, v_A]).T
        numpy_compare.assert_float_equal(q_AB.multiply(vector=vlist_B),
                                         vlist_A)
        # Test deprecation.
        with catch_drake_warnings(expected_count=2):
            self.assertEqual(q_AB.multiply(position=v_B).shape, v_B.shape)
            self.assertEqual(
                q_AB.multiply(position=vlist_B).shape, vlist_B.shape)
        with catch_drake_warnings(expected_count=0):
            # No deprecation should happen with position arguments.
            self.assertEqual(q_AB.multiply(v_B).shape, v_B.shape)
            self.assertEqual(q_AB.multiply(vlist_B).shape, vlist_B.shape)

        q_AB_conj = q_AB.conjugate()
        numpy_compare.assert_float_equal(q_AB_conj.wxyz(),
                                         [0.5, -0.5, -0.5, -0.5])

        # Test `type_caster`s.
        if T == float:
            value = test_util.create_quaternion()
            self.assertTrue(isinstance(value, mut.Quaternion))
            test_util.check_quaternion(value)
Example #2
0
    def test_quaternion(self):
        # Simple API.
        q_identity = mut.Quaternion()
        self.assertTrue(np.allclose(q_identity.wxyz(), [1, 0, 0, 0]))
        self.assertTrue(np.allclose(
            q_identity.wxyz(), mut.Quaternion.Identity().wxyz()))
        self.assertEqual(
            str(q_identity), "Quaternion(w=1.0, x=0.0, y=0.0, z=0.0)")
        # Test ordering.
        q_wxyz = normalize([0.1, 0.3, 0.7, 0.9])
        q = mut.Quaternion(w=q_wxyz[0], x=q_wxyz[1], y=q_wxyz[2], z=q_wxyz[3])
        # - Accessors.
        self.assertEqual(q.w(), q_wxyz[0])
        self.assertEqual(q.x(), q_wxyz[1])
        self.assertEqual(q.y(), q_wxyz[2])
        self.assertEqual(q.z(), q_wxyz[3])
        self.assertTrue(np.allclose(q.xyz(), q_wxyz[1:]))
        self.assertTrue(np.allclose(q.wxyz(), q_wxyz))
        # - Mutators.
        q_wxyz_new = q_wxyz[::-1]
        self.assertFalse(np.allclose(q_wxyz, q_wxyz_new))
        q.set_wxyz(wxyz=q_wxyz_new)
        self.assertTrue(np.allclose(q.wxyz(), q_wxyz_new))
        q.set_wxyz(
            w=q_wxyz_new[0], x=q_wxyz_new[1], y=q_wxyz_new[2], z=q_wxyz_new[3])
        self.assertTrue(np.allclose(q.wxyz(), q_wxyz_new))
        # Alternative constructors.
        q_other = mut.Quaternion(wxyz=q_wxyz)
        self.assertTrue(np.allclose(q_other.wxyz(), q_wxyz))
        R = np.array([
            [0, 0, 1],
            [1, 0, 0],
            [0, 1, 0]])
        q_wxyz_expected = np.array([0.5, 0.5, 0.5, 0.5])
        q_other = mut.Quaternion(q_wxyz_expected)
        self.assertTrue(np.allclose(q_other.rotation(), R))
        R_I = np.eye(3, 3)
        q_other.set_rotation(R_I)
        self.assertTrue(np.allclose(q_other.wxyz(), q_identity.wxyz()))
        # - Copy constructor.
        cp = mut.Quaternion(other=q)
        self.assertTrue(np.allclose(q.wxyz(), cp.wxyz()))
        # Bad values.
        q = mut.Quaternion.Identity()
        # - wxyz
        q_wxyz_bad = [1., 2, 3, 4]
        with self.assertRaises(RuntimeError):
            q.set_wxyz(q_wxyz_bad)
        self.assertTrue(np.allclose(q.wxyz(), [1, 0, 0, 0]))
        # - Rotation.
        R_bad = np.copy(R)
        R_bad[0, 0] = 10
        with self.assertRaises(RuntimeError):
            q_other.set_rotation(R_bad)
        self.assertTrue(np.allclose(q_other.rotation(), R_I))

        # Operations.
        q = mut.Quaternion(wxyz=[0.5, 0.5, 0.5, 0.5])
        self.assertTrue(
            (q.multiply(position=[1, 2, 3]) == [3, 1, 2]).all())
        q_I = q.inverse().multiply(q)
        self.assertTrue(np.allclose(q_I.wxyz(), [1, 0, 0, 0]))
        if six.PY3:
            self.assertTrue(np.allclose(
                eval("q.inverse() @ q").wxyz(), [1, 0, 0, 0]))
        q_conj = q.conjugate()
        self.assertTrue(np.allclose(q_conj.wxyz(), [0.5, -0.5, -0.5, -0.5]))

        # Test `type_caster`s.
        value = test_util.create_quaternion()
        self.assertTrue(isinstance(value, mut.Quaternion))
        test_util.check_quaternion(value)
Example #3
0
    def test_quaternion(self):
        # Simple API.
        q_identity = mut.Quaternion()
        self.assertTrue(np.allclose(q_identity.wxyz(), [1, 0, 0, 0]))
        self.assertTrue(
            np.allclose(q_identity.wxyz(),
                        mut.Quaternion.Identity().wxyz()))
        self.assertEqual(str(q_identity),
                         "Quaternion(w=1.0, x=0.0, y=0.0, z=0.0)")
        # Test ordering.
        q_wxyz = normalize([0.1, 0.3, 0.7, 0.9])
        q = mut.Quaternion(w=q_wxyz[0], x=q_wxyz[1], y=q_wxyz[2], z=q_wxyz[3])
        # - Accessors.
        self.assertEqual(q.w(), q_wxyz[0])
        self.assertEqual(q.x(), q_wxyz[1])
        self.assertEqual(q.y(), q_wxyz[2])
        self.assertEqual(q.z(), q_wxyz[3])
        self.assertTrue(np.allclose(q.xyz(), q_wxyz[1:]))
        self.assertTrue(np.allclose(q.wxyz(), q_wxyz))
        # - Mutators.
        q_wxyz_new = q_wxyz[::-1]
        self.assertFalse(np.allclose(q_wxyz, q_wxyz_new))
        q.set_wxyz(wxyz=q_wxyz_new)
        self.assertTrue(np.allclose(q.wxyz(), q_wxyz_new))
        q.set_wxyz(w=q_wxyz_new[0],
                   x=q_wxyz_new[1],
                   y=q_wxyz_new[2],
                   z=q_wxyz_new[3])
        self.assertTrue(np.allclose(q.wxyz(), q_wxyz_new))
        # Alternative constructors.
        q_other = mut.Quaternion(wxyz=q_wxyz)
        self.assertTrue(np.allclose(q_other.wxyz(), q_wxyz))
        R = np.array([[0, 0, 1], [1, 0, 0], [0, 1, 0]])
        q_wxyz_expected = np.array([0.5, 0.5, 0.5, 0.5])
        q_other = mut.Quaternion(q_wxyz_expected)
        self.assertTrue(np.allclose(q_other.rotation(), R))
        R_I = np.eye(3, 3)
        q_other.set_rotation(R_I)
        self.assertTrue(np.allclose(q_other.wxyz(), q_identity.wxyz()))
        # - Copy constructor.
        cp = mut.Quaternion(other=q)
        self.assertTrue(np.allclose(q.wxyz(), cp.wxyz()))
        # Bad values.
        q = mut.Quaternion.Identity()
        # - wxyz
        q_wxyz_bad = [1., 2, 3, 4]
        with self.assertRaises(RuntimeError):
            q.set_wxyz(q_wxyz_bad)
        self.assertTrue(np.allclose(q.wxyz(), [1, 0, 0, 0]))
        # - Rotation.
        R_bad = np.copy(R)
        R_bad[0, 0] = 10
        with self.assertRaises(RuntimeError):
            q_other.set_rotation(R_bad)
        self.assertTrue(np.allclose(q_other.rotation(), R_I))

        # Operations.
        q = mut.Quaternion(wxyz=[0.5, 0.5, 0.5, 0.5])
        self.assertTrue((q.multiply(position=[1, 2, 3]) == [3, 1, 2]).all())
        q_I = q.inverse().multiply(q)
        self.assertTrue(np.allclose(q_I.wxyz(), [1, 0, 0, 0]))
        q_conj = q.conjugate()
        self.assertTrue(np.allclose(q_conj.wxyz(), [0.5, -0.5, -0.5, -0.5]))

        # Test `type_caster`s.
        value = test_util.create_quaternion()
        self.assertTrue(isinstance(value, mut.Quaternion))
        test_util.check_quaternion(value)
    def test_quaternion(self, T):
        # Simple API.
        Quaternion = mut.Quaternion_[T]
        cast = np.vectorize(T)
        q_identity = Quaternion()
        self.assertEqual(numpy_compare.resolve_type(q_identity.wxyz()), T)
        numpy_compare.assert_float_equal(q_identity.wxyz(), [1., 0, 0, 0])
        numpy_compare.assert_float_equal(
            copy.copy(q_identity).wxyz(), [1., 0, 0, 0])
        numpy_compare.assert_equal(q_identity.wxyz(),
                                   Quaternion.Identity().wxyz())
        if T == float:
            self.assertEqual(str(q_identity),
                             "Quaternion_[float](w=1.0, x=0.0, y=0.0, z=0.0)")
        # Test ordering.
        q_wxyz = normalize([0.1, 0.3, 0.7, 0.9])
        q = Quaternion(w=q_wxyz[0], x=q_wxyz[1], y=q_wxyz[2], z=q_wxyz[3])
        # - Accessors.
        numpy_compare.assert_float_equal(q.w(), q_wxyz[0])
        numpy_compare.assert_float_equal(q.x(), q_wxyz[1])
        numpy_compare.assert_float_equal(q.y(), q_wxyz[2])
        numpy_compare.assert_float_equal(q.z(), q_wxyz[3])
        numpy_compare.assert_float_equal(q.xyz(), q_wxyz[1:])
        numpy_compare.assert_float_equal(q.wxyz(), q_wxyz)
        # - Mutators.
        q_wxyz_new = q_wxyz[::-1]
        numpy_compare.assert_not_equal(q_wxyz, q_wxyz_new)
        q.set_wxyz(wxyz=q_wxyz_new)
        numpy_compare.assert_float_equal(q.wxyz(), q_wxyz_new)
        q.set_wxyz(w=q_wxyz_new[0],
                   x=q_wxyz_new[1],
                   y=q_wxyz_new[2],
                   z=q_wxyz_new[3])
        numpy_compare.assert_float_equal(q.wxyz(), q_wxyz_new)
        # Alternative constructors.
        q_other = Quaternion(wxyz=q_wxyz)
        numpy_compare.assert_float_equal(q_other.wxyz(), q_wxyz)
        R = np.array([[0., 0, 1], [1, 0, 0], [0, 1, 0]])
        q_wxyz_expected = np.array([0.5, 0.5, 0.5, 0.5])
        q_other = Quaternion(q_wxyz_expected)
        numpy_compare.assert_float_equal(q_other.rotation(), R)
        R_I = np.eye(3, 3)
        q_other.set_rotation(R_I)
        numpy_compare.assert_equal(q_other.wxyz(), q_identity.wxyz())
        # - Copy constructor.
        cp = Quaternion(other=q)
        numpy_compare.assert_equal(q.wxyz(), cp.wxyz())
        # Bad values.
        if T != Expression:
            q = Quaternion.Identity()
            # - wxyz
            q_wxyz_bad = [1., 2, 3, 4]
            with self.assertRaises(RuntimeError):
                q.set_wxyz(q_wxyz_bad)
            numpy_compare.assert_float_equal(q.wxyz(), [1., 0, 0, 0])
            # - Rotation.
            R_bad = np.copy(R)
            R_bad[0, 0] = 10
            with self.assertRaises(RuntimeError):
                q_other.set_rotation(R_bad)
            numpy_compare.assert_float_equal(q_other.rotation(), R_I)

        # Operations.
        q = Quaternion(wxyz=[0.5, 0.5, 0.5, 0.5])
        numpy_compare.assert_float_equal(q.multiply(position=[1, 2, 3]),
                                         [3., 1, 2])
        q_I = q.inverse().multiply(q)
        numpy_compare.assert_float_equal(q_I.wxyz(), [1., 0, 0, 0])
        if six.PY3:
            numpy_compare.assert_float_equal(
                eval("q.inverse() @ q").wxyz(), [1., 0, 0, 0])
        q_conj = q.conjugate()
        numpy_compare.assert_float_equal(q_conj.wxyz(),
                                         [0.5, -0.5, -0.5, -0.5])

        # Test `type_caster`s.
        if T == float:
            value = test_util.create_quaternion()
            self.assertTrue(isinstance(value, mut.Quaternion))
            test_util.check_quaternion(value)
    def check_quaternion(self, T):
        # Simple API.
        Quaternion = mut.Quaternion_[T]
        cast = np.vectorize(T)
        q_identity = Quaternion()
        self.assertEqual(npc.resolve_type(q_identity.wxyz()), T)
        npc.assert_float_equal(q_identity.wxyz(), [1., 0, 0, 0])
        npc.assert_float_equal(copy.copy(q_identity).wxyz(), [1., 0, 0, 0])
        npc.assert_equal(q_identity.wxyz(), Quaternion.Identity().wxyz())
        if T == float:
            self.assertEqual(
                str(q_identity),
                "Quaternion_[float](w=1.0, x=0.0, y=0.0, z=0.0)")
        # Test ordering.
        q_wxyz = normalize([0.1, 0.3, 0.7, 0.9])
        q = Quaternion(w=q_wxyz[0], x=q_wxyz[1], y=q_wxyz[2], z=q_wxyz[3])
        # - Accessors.
        npc.assert_float_equal(q.w(), q_wxyz[0])
        npc.assert_float_equal(q.x(), q_wxyz[1])
        npc.assert_float_equal(q.y(), q_wxyz[2])
        npc.assert_float_equal(q.z(), q_wxyz[3])
        npc.assert_float_equal(q.xyz(), q_wxyz[1:])
        npc.assert_float_equal(q.wxyz(), q_wxyz)
        # - Mutators.
        q_wxyz_new = q_wxyz[::-1]
        npc.assert_not_equal(q_wxyz, q_wxyz_new)
        q.set_wxyz(wxyz=q_wxyz_new)
        npc.assert_float_equal(q.wxyz(), q_wxyz_new)
        q.set_wxyz(
            w=q_wxyz_new[0], x=q_wxyz_new[1], y=q_wxyz_new[2], z=q_wxyz_new[3])
        npc.assert_float_equal(q.wxyz(), q_wxyz_new)
        # Alternative constructors.
        q_other = Quaternion(wxyz=q_wxyz)
        npc.assert_float_equal(q_other.wxyz(), q_wxyz)
        R = np.array([
            [0., 0, 1],
            [1, 0, 0],
            [0, 1, 0]])
        q_wxyz_expected = np.array([0.5, 0.5, 0.5, 0.5])
        q_other = Quaternion(q_wxyz_expected)
        npc.assert_float_equal(q_other.rotation(), R)
        R_I = np.eye(3, 3)
        q_other.set_rotation(R_I)
        npc.assert_equal(q_other.wxyz(), q_identity.wxyz())
        # - Copy constructor.
        cp = Quaternion(other=q)
        npc.assert_equal(q.wxyz(), cp.wxyz())
        # Bad values.
        if T != Expression:
            q = Quaternion.Identity()
            # - wxyz
            q_wxyz_bad = [1., 2, 3, 4]
            with self.assertRaises(RuntimeError):
                q.set_wxyz(q_wxyz_bad)
            npc.assert_float_equal(q.wxyz(), [1., 0, 0, 0])
            # - Rotation.
            R_bad = np.copy(R)
            R_bad[0, 0] = 10
            with self.assertRaises(RuntimeError):
                q_other.set_rotation(R_bad)
            npc.assert_float_equal(q_other.rotation(), R_I)

        # Operations.
        q = Quaternion(wxyz=[0.5, 0.5, 0.5, 0.5])
        npc.assert_float_equal(q.multiply(position=[1, 2, 3]), [3., 1, 2])
        q_I = q.inverse().multiply(q)
        npc.assert_float_equal(q_I.wxyz(), [1., 0, 0, 0])
        if six.PY3:
            npc.assert_float_equal(
                eval("q.inverse() @ q").wxyz(), [1., 0, 0, 0])
        q_conj = q.conjugate()
        npc.assert_float_equal(q_conj.wxyz(), [0.5, -0.5, -0.5, -0.5])

        # Test `type_caster`s.
        if T == float:
            value = test_util.create_quaternion()
            self.assertTrue(isinstance(value, mut.Quaternion))
            test_util.check_quaternion(value)
Example #6
0
    def test_quaternion(self, T):
        # Simple API.
        Quaternion = mut.Quaternion_[T]
        cast = np.vectorize(T)
        q_identity = Quaternion()
        self.assertEqual(numpy_compare.resolve_type(q_identity.wxyz()), T)
        numpy_compare.assert_float_equal(q_identity.wxyz(), [1., 0, 0, 0])
        numpy_compare.assert_float_equal(
            copy.copy(q_identity).wxyz(), [1., 0, 0, 0])
        numpy_compare.assert_equal(q_identity.wxyz(),
                                   Quaternion.Identity().wxyz())
        if T == float:
            self.assertEqual(str(q_identity),
                             "Quaternion_[float](w=1.0, x=0.0, y=0.0, z=0.0)")
        self.check_cast(mut.Quaternion_, T)
        # Test ordering.
        q_wxyz = normalize([0.1, 0.3, 0.7, 0.9])
        q = Quaternion(w=q_wxyz[0], x=q_wxyz[1], y=q_wxyz[2], z=q_wxyz[3])
        # - Accessors.
        numpy_compare.assert_float_equal(q.w(), q_wxyz[0])
        numpy_compare.assert_float_equal(q.x(), q_wxyz[1])
        numpy_compare.assert_float_equal(q.y(), q_wxyz[2])
        numpy_compare.assert_float_equal(q.z(), q_wxyz[3])
        numpy_compare.assert_float_equal(q.xyz(), q_wxyz[1:])
        numpy_compare.assert_float_equal(q.wxyz(), q_wxyz)
        # - Mutators.
        q_wxyz_new = q_wxyz[::-1]
        numpy_compare.assert_not_equal(q_wxyz, q_wxyz_new)
        q.set_wxyz(wxyz=q_wxyz_new)
        numpy_compare.assert_float_equal(q.wxyz(), q_wxyz_new)
        q.set_wxyz(w=q_wxyz_new[0],
                   x=q_wxyz_new[1],
                   y=q_wxyz_new[2],
                   z=q_wxyz_new[3])
        numpy_compare.assert_float_equal(q.wxyz(), q_wxyz_new)
        # Alternative constructors.
        q_other = Quaternion(wxyz=q_wxyz)
        numpy_compare.assert_float_equal(q_other.wxyz(), q_wxyz)
        R = np.array([[0., 0, 1], [1, 0, 0], [0, 1, 0]])
        q_wxyz_expected = np.array([0.5, 0.5, 0.5, 0.5])
        q_other = Quaternion(q_wxyz_expected)
        numpy_compare.assert_float_equal(q_other.rotation(), R)
        R_I = np.eye(3, 3)
        q_other.set_rotation(R_I)
        numpy_compare.assert_equal(q_other.wxyz(), q_identity.wxyz())
        # - Copy constructor.
        cp = Quaternion(other=q)
        numpy_compare.assert_equal(q.wxyz(), cp.wxyz())
        # Bad values.
        if T != Expression:
            q = Quaternion.Identity()
            # - wxyz
            q_wxyz_bad = [1., 2, 3, 4]
            with self.assertRaises(RuntimeError):
                q.set_wxyz(q_wxyz_bad)
            numpy_compare.assert_float_equal(q.wxyz(), [1., 0, 0, 0])
            # - Rotation.
            R_bad = np.copy(R)
            R_bad[0, 0] = 10
            with self.assertRaises(RuntimeError):
                q_other.set_rotation(R_bad)
            numpy_compare.assert_float_equal(q_other.rotation(), R_I)

        # Operations.
        q_AB = Quaternion(wxyz=[0.5, 0.5, 0.5, 0.5])
        q_I = q_AB.inverse().multiply(q_AB)
        numpy_compare.assert_float_equal(q_I.wxyz(), [1., 0, 0, 0])
        numpy_compare.assert_float_equal((q_AB.inverse() @ q_AB).wxyz(),
                                         [1., 0, 0, 0])
        v_B = np.array([1., 2, 3])
        v_A = np.array([3., 1, 2])
        numpy_compare.assert_float_allclose(q_AB.multiply(vector=v_B), v_A)
        vlist_B = np.array([v_B, v_B]).T
        vlist_A = np.array([v_A, v_A]).T
        numpy_compare.assert_float_equal(q_AB.multiply(vector=vlist_B),
                                         vlist_A)

        q_AB_conj = q_AB.conjugate()
        numpy_compare.assert_float_equal(q_AB_conj.wxyz(),
                                         [0.5, -0.5, -0.5, -0.5])

        numpy_compare.assert_float_equal(
            q_I.slerp(t=0, other=q_I).wxyz(), [1., 0, 0, 0])

        # - Test shaping (#13885).
        v = np.array([0., 0., 0.])
        vs = np.array([[1., 2., 3.], [4., 5., 6.]]).T
        self.assertEqual((q_AB @ v).shape, (3, ))
        self.assertEqual((q_AB @ v.reshape((3, 1))).shape, (3, 1))
        self.assertEqual((q_AB @ vs).shape, (3, 2))

        # Test `type_caster`s.
        if T == float:
            value = test_util.create_quaternion()
            self.assertTrue(isinstance(value, mut.Quaternion))
            test_util.check_quaternion(value)

        assert_pickle(self, q_AB, Quaternion.wxyz, T=T)