Exemple #1
0
    def test_matrix(self):

        dofs = spin.ExponentialMap.random()
        rot = spin.ExponentialMap(dofs)
        rot2 = spin.ExponentialMap.from_rotation(rot)
        rot3 = ExponentialMap(dofs)

        print(make_title('Cython (from dofs)'))
        print(rot)

        print(make_title('Cython (from matrix)'))
        print(rot2)

        print(make_title('Python (from dofs)'))
        print(rot3)

        axis, angle = rot.axis_angle
        r, theta, phi = csb.polar3d(axis)
        axisangle = spin.AxisAngle([theta, phi, angle])
        rot4 = spin.Rotation(csb.rotation_matrix(axis, -angle))

        self.assertTrue(spin.distance(rot, rot2) < self.tol)
        self.assertTrue(spin.distance(rot, rot4) < self.tol)
        self.assertTrue(spin.distance(rot3, rot4) < self.tol)
        self.assertTrue(spin.distance(rot2, axisangle) < self.tol)
Exemple #2
0
    def test_analytical(self):
        """
        Test analytical calculation of the upper bound using SVD
        and eigenvalue decomposition.
        """
        tol = 1e-10
        n   = int(1e3)

        X, Y = load_coords(['1ake', '4ake'])

        A = np.dot(X.T, Y)
        R = fit(X, Y)[0]

        func  = spin.NearestRotation(A)
        func2 = spin.NearestUnitQuaternion(A)

        self.assertTrue(spin.distance(func.optimum(), R) < tol)
        self.assertTrue(np.linalg.norm(func2.optimum().dofs-spin.Quaternion(R).dofs) < tol)

        rotations = spin.random_rotation(n)

        vals  = np.array(list(map(func, rotations)))
        vals2 = np.dot(rotations.reshape(n,-1), A.flatten())

        self.assertTrue(np.fabs(vals-vals2).max() < tol)
        self.assertTrue(np.all(vals <= func(func.optimum().matrix)))
        self.assertTrue(np.all(vals <= func2(func2.optimum())))
Exemple #3
0
    def test_lsq(self):

        rotation, score = self.lsq['svd'].optimum()

        rmsd_ = [
            np.sqrt(score / len(self.coords[0])),
            self.lsq['svd'].rmsd(rotation.matrix),
            rmsd(*self.coords)
        ]
        lsq_ = [0.5 * score, self.lsq['svd'](rotation.matrix)]

        for name in ('euler', 'axisangle', 'expmap', 'axisangle'):

            dofs = self.lsq[name].trafo.from_rotation(rotation).dofs
            lsq_.append(self.lsq[name](dofs))

        rmsd_ = np.round(rmsd_, 5)
        lsq_ = np.round(lsq_, 2)

        print(make_title('checking LSQ optimization using SVD'))
        print('RMSD: {0}'.format(rmsd_))
        print(' LSQ: {0}'.format(lsq_))

        tol = 1e-10

        self.assertTrue(np.all(np.fabs(rmsd_ - rmsd_[0]) < tol))
        self.assertTrue(np.all(np.fabs(lsq_ - lsq_[0]) < tol))
        self.assertAlmostEqual(spin.distance(
            fit(*self.coords)[0], rotation.matrix),
                               0.,
                               delta=tol)
Exemple #4
0
    def test_opt(self):

        print(make_title('test optimization of least-squares residual'))

        out = '{0:>14}: #steps={1:3d}, RMSD: {5:.2f}->{2:.2f}, ' + \
              'accuracy: {3:.3e} (rot), {4:.3e} (trans)'

        start = spin.random_rotation(), np.random.standard_normal(3) * 10
        R, t = fit(*self.coords)

        rot = []
        trans = []
        rmsds = []

        for trafo in self.trafos[1:]:

            trafo.matrix_vector = start

            f = spin.LeastSquares(*self.coords, trafo=trafo)
            x = trafo.dofs.copy()
            y = opt.fmin_bfgs(f, x, f.gradient, disp=False)

            rot.append(spin.distance(R, trafo.rotation))
            trans.append(np.linalg.norm(t - trafo.translation.vector))
            rmsds.append(np.sqrt(2 * f(y) / len(self.coords[0])))

            print(
                out.format(trafo.rotation.name, len(f.values), rmsds[-1],
                           rot[-1], trans[-1],
                           np.sqrt(2 * f(x) / len(self.coords[0]))))

            self.assertAlmostEqual(rot[-1], 0., delta=1e-5)
            self.assertAlmostEqual(trans[-1], 0., delta=1e-5)

        self.assertAlmostEqual(np.std(rmsds), 0., delta=1e-5)
Exemple #5
0
    def test_matrix(self):

        angles = np.random.random(3)
        euler = spin.EulerAngles(angles)
        euler2 = spin.EulerAngles.from_rotation(euler)
        euler3 = compose_euler(*angles)

        a, b, c = angles
        euler4 = spin.compose(R_z(c), R_y(b), R_z(a))

        R = np.zeros((3, 3))

        eulerlib.matrix(angles, R)

        self.assertTrue(spin.distance(euler, euler2) < self.tol)
        self.assertTrue(spin.distance(euler, euler3) < self.tol)
        self.assertTrue(spin.distance(euler, euler4) < self.tol)
        self.assertTrue(spin.distance(euler, R) < self.tol)
Exemple #6
0
    def test_compose(self):

        n = 10
        R = [spin.EulerAngles() for _ in range(n)]

        M = np.eye(3)
        for R_ in R:
            M = M.dot(R_.matrix)

        R_tot = spin.compose(*R)

        self.assertTrue(spin.distance(M, R_tot) < self.tol)
Exemple #7
0
    def test_optimizers(self):
        """
        Test various optimizers for finding the optimal rotation
        in Euler parameterization
        """
        optimizers = OrderedDict()
        optimizers['nedler-mead'] = opt.fmin
        optimizers['powell'] = opt.fmin_powell
        optimizers['bfgs'] = opt.fmin_bfgs

        print(make_title('Testing different optimizers'))

        rotation, _ = self.lsq['svd'].optimum()
        lsq_opt = self.lsq['svd'](rotation.matrix)
        output = '{0:11s} : min.score={1:.2f}, dist={2:.3e}, nsteps={3:d}'

        for name, lsq in self.lsq.items():

            if name == 'svd': continue

            print(make_title(lsq.trafo.name))

            start = lsq.trafo.random()

            results = OrderedDict()

            for method, run in optimizers.items():

                lsq.values = []

                args = [lsq, start.copy()
                        ] + ([lsq.gradient] if method == 'bfgs' else [])
                best = run(*args, disp=False)

                results[method] = np.array(lsq.values)

                summary = lsq(best), spin.distance(rotation,
                                                   lsq.trafo), len(lsq.values)

                print(output.format(*((method, ) + summary)))

            fig, ax = plt.subplots(1, 1, figsize=(10, 6))
            fig.suptitle(lsq.trafo.name)
            for method, values in results.items():
                ax.plot(values, lw=5, alpha=0.7, label=method)
            ax.axhline(lsq_opt, lw=3, ls='--', color='r')
            ax.legend()
Exemple #8
0
    def test_params(self):

        rigid = self.trafos[0]

        print(make_title('comparing matrix and vector'))
        out = '{0:14s} : distance rotation={1:.3e}, translation={2:.3e}'

        for other in self.trafos[1:]:

            dist_rot = spin.distance(rigid.rotation, other.rotation)
            dist_trans = np.linalg.norm(rigid.translation.vector -
                                        other.translation.vector)

            print(out.format(other.rotation.name, dist_rot, dist_trans))

            self.assertAlmostEqual(dist_rot, 0., delta=1e-10)
            self.assertAlmostEqual(dist_trans, 0., delta=1e-10)
Exemple #9
0
Compare least-squares fitting with unit quaternions (Kearsley's algorithm)
with fitting using singular value decomposition (Kabsch's algorithm). 
"""
from __future__ import print_function

import spin
import time
import numpy as np

from littlehelpers import load_coords

from csb.bio.utils import fit

X, Y = load_coords(['1ake', '4ake'])

n = 1000
X = np.repeat(X, n, axis=0)
Y = np.repeat(Y, n, axis=0)

t = time.clock()
A = spin.qfit(X, Y)
t = time.clock() - t

t2 = time.clock()
B = fit(X, Y)
t2 = time.clock() - t2

print('dist(R_quat,R_svd) = {0:.3f}'.format(spin.distance(A[0], B[0])))
print('dist(t_quat,t_svd) = {0:.3f}'.format(np.linalg.norm(A[1] - B[1])))
print('times: {0:.3f} vs {1:.3f} (quat vs svd)'.format(t, t2))
Exemple #10
0
import spin
import numpy as np

from scipy.spatial.distance import squareform, cdist, pdist

n    = 1000
rot  = (spin.EulerAngles(), spin.ExponentialMap(), spin.AxisAngle(), spin.Quaternion())[-1]
dofs = rot.random(n).T
R    = []
for x in dofs:
    rot.dofs = np.ascontiguousarray(x)
    R.append(rot.matrix.copy())

R = np.array(R)
a = pdist(dofs)

if isinstance(rot, spin.Quaternion):
    ## see Mitchell et al: Generating Uniform Incremental Grids on SO(3) Using the Hopf Fibration
    a = squareform(np.dot(dofs,dofs.T),checks=False)
    a = np.arccos(np.fabs(a))
    
b = [spin.distance(R1,R2) for i, R1 in enumerate(R) for R2 in R[i+1:]]

figure()
title(rot.__class__.__name__)
scatter(a,b,alpha=0.1,s=1)