Package mvpa :: Package tests :: Module test_procrust
[hide private]
[frames] | no frames]

Source Code for Module mvpa.tests.test_procrust

  1  # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- 
  2  # vi: set ft=python sts=4 ts=4 sw=4 et: 
  3  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## 
  4  # 
  5  #   See COPYING file distributed along with the PyMVPA package for the 
  6  #   copyright and license terms. 
  7  # 
  8  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## 
  9  """Unit tests for PyMVPA Procrustean mapper""" 
 10   
 11   
 12  import unittest 
 13  import numpy as N 
 14  from numpy.linalg import norm 
 15  from mvpa.datasets import Dataset 
 16  from tests_warehouse import datasets, sweepargs 
 17  from mvpa.mappers.procrustean import ProcrusteanMapper 
18 19 20 -class ProcrusteanMapperTests(unittest.TestCase):
21 22 @sweepargs(oblique=(False,True))
23 - def testSimple(self, oblique):
24 d_orig = datasets['uni2large'].samples 25 d_orig2 = datasets['uni4large'].samples 26 for sdim, nf_s, nf_t, full_test \ 27 in (('Same 2D', 2, 2, True), 28 ('Same 10D', 10, 10, True), 29 ('2D -> 3D', 2, 3, True), 30 ('3D -> 2D', 3, 2, False)): 31 # figure out some "random" rotation 32 d = max(nf_s, nf_t) 33 _u, _s, _vh = N.linalg.svd(d_orig[:, :d]) 34 R = _vh[:nf_s, :nf_t] 35 if nf_s == nf_t: 36 # Test if it is indeed a rotation matrix ;) 37 # Lets flip first axis if necessary 38 if N.linalg.det(R) < 0: 39 R[:, 0] *= -1.0 40 adR = N.abs(1.0 - N.linalg.det(R)) 41 self.failUnless(adR < 1e-10, 42 "Determinant of rotation matrix should " 43 "be 1. Got it 1+%g" % adR) 44 self.failUnless(norm(N.dot(R, R.T) 45 - N.eye(R.shape[0])) < 1e-10) 46 47 for s, scaling in ((0.3, True), (1.0, False)): 48 pm = ProcrusteanMapper(scaling=scaling, oblique=oblique) 49 pm2 = ProcrusteanMapper(scaling=scaling, oblique=oblique) 50 51 t1, t2 = d_orig[23, 1], d_orig[22, 1] 52 53 # Create source/target data 54 d = d_orig[:, :nf_s] 55 d_s = d + t1 56 d_t = N.dot(s * d, R) + t2 57 58 # train bloody mapper(s) 59 pm.train(d_s, d_t) 60 ds2 = Dataset(samples=d_s, labels=d_t) 61 pm2.train(ds2) 62 63 # verify that both created the same transformation 64 npm2proj = norm(pm.proj - pm2.proj) 65 self.failUnless(npm2proj <= 1e-10, 66 msg="Got transformation different by norm %g." 67 " Had to be less than 1e-10" % npm2proj) 68 self.failUnless(norm(pm._offset_in - pm2._offset_in) <= 1e-10) 69 self.failUnless(norm(pm._offset_out - pm2._offset_out) <= 1e-10) 70 71 # do forward transformation on the same source data 72 d_s_f = pm.forward(d_s) 73 74 self.failUnlessEqual(d_s_f.shape, d_t.shape, 75 msg="Mapped shape should be identical to the d_t") 76 77 dsf = d_s_f - d_t 78 ndsf = norm(dsf)/norm(d_t) 79 if full_test: 80 dsR = norm(s*R - pm.proj) 81 82 if not oblique: 83 self.failUnless(dsR <= 1e-12, 84 msg="We should have got reconstructed rotation+scaling " 85 "perfectly. Now got d scale*R=%g" % dsR) 86 87 self.failUnless(N.abs(s - pm._scale) < 1e-12, 88 msg="We should have got reconstructed scale " 89 "perfectly. Now got %g for %g" % (pm._scale, s)) 90 91 self.failUnless(ndsf <= 1e-12, 92 msg="%s: Failed to get to the target space correctly." 93 " normed error=%g" % (sdim, ndsf)) 94 95 # Test if we get back 96 d_s_f_r = pm.reverse(d_s_f) 97 98 dsfr = d_s_f_r - d_s 99 ndsfr = norm(dsfr)/norm(d_s) 100 if full_test: 101 self.failUnless(ndsfr <= 1e-12, 102 msg="%s: Failed to reconstruct into source space correctly." 103 " normed error=%g" % (sdim, ndsfr))
104
105 106 107 -def suite():
108 return unittest.makeSuite(ProcrusteanMapperTests)
109 110 if __name__ == '__main__': 111 import runner 112