PageRenderTime 55ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/mlabwrap_dev/tests/old_test_mlabwrap.py

https://bitbucket.org/joshayers/mlabwrap
Python | 433 lines | 356 code | 20 blank | 57 comment | 17 complexity | 908428299995663ba6ac4852d672fe6c MD5 | raw file
  1. import sys, os, re
  2. import gc
  3. try:
  4. import numpy
  5. from numpy.random import rand, randn
  6. toscalar = lambda a:a.item()
  7. except ImportError:
  8. import Numeric as numpy
  9. from MLab import rand, randn
  10. toscalar = lambda a:a.toscalar()
  11. from tempfile import mktemp
  12. try: # python >= 2.3 has better mktemp
  13. from tempfile import mkstemp as _mkstemp
  14. mktemp = lambda *args,**kwargs: _mkstemp(*args, **kwargs)[1]
  15. except ImportError: pass
  16. degensym_proxy = lambda s, rex=re.compile(r'(PROXY_VAL)\d+'): rex.sub(r'\1',s)
  17. import unittest
  18. from mlabwrap.awmstools import indexme, without
  19. from mlabwrap.mlabwrap_core import *
  20. BUFSIZE=4096 # must be the same as in mlabraw.cpp
  21. #XXX for testing in running session with existing mlab
  22. ## mlab
  23. mlab = matlab()
  24. mlab._dont_proxy['cell'] = True
  25. WHO_AT_STARTUP = mlab.who()
  26. mlab._dont_proxy['cell'] = False
  27. mlab.close()
  28. del mlab
  29. # FIXME should do this differentlya
  30. funnies = without(WHO_AT_STARTUP, ['HOME', 'V', 'WLVERBOSE', 'MLABRAW_ERROR_'])
  31. if funnies:
  32. print >> sys.stderr, "Hmm, got some funny stuff in matlab env: %s" % funnies
  33. #FIXME both below untested
  34. def fitString(s, maxCol=79, newlineReplacement="\\n"):
  35. if newlineReplacement or isinstance(newlineReplacement, basestring):
  36. s = s.replace("\n", newlineReplacement)
  37. if maxCol is not None and len(s) > maxCol:
  38. s = "%s..." % s[:maxCol-3]
  39. return s
  40. class NumericTestCase(unittest.TestCase):
  41. """Simple extension to TestCase to handle array equality tests 'correctly'
  42. (i.e. work around rich comparisons). Since array repr's can also be
  43. very large, the printing of large reprs is controlled by
  44. ``maxReprLength`` (None to print everything) and
  45. ``reprNewlineReplacement`` (None not to replace newlines in the repr).
  46. """
  47. maxReprLength = 30 #
  48. reprNewlineReplacement = "\\n"
  49. def _reallyEqual(self, first, second, testShape=True):
  50. #FIXME should this check for identical argument type, too?
  51. res = first == second
  52. # find out if are dealing with a sized object; looking for a __len__
  53. # attr does *NOT* work, because of #$@-C extension crap
  54. try:
  55. len(res)
  56. except TypeError:
  57. return res
  58. else:
  59. # HACK
  60. if len(first) == len(second) == 0:
  61. return `first` == `second` # deal with empty arrays
  62. res = ((not testShape or numpy.shape(first) == numpy.shape(second)) and
  63. # it is necessary to exclude 0 element arrays, because
  64. # identical zero-element arrays don't compare true (``and True`` normalizes)
  65. (not len(first) and not len(second)
  66. or bool(numpy.alltrue((numpy.ravel(first == second))))))
  67. return res
  68. def _smallRepr(self, *args):
  69. return tuple([fitString(repr(arg), maxCol=self.maxReprLength,
  70. newlineReplacement=self.reprNewlineReplacement)
  71. for arg in args])
  72. def assertEqual(self, first, second, msg=None):
  73. if not self._reallyEqual(first, second):
  74. raise self.failureException, \
  75. (msg or '%s != %s' % self._smallRepr(first, second))
  76. assertEqual = failUnlessEqual = assertEqual
  77. def assertNotEqual(self, first, second, msg=None):
  78. if self._reallyEqual(first, second):
  79. raise self.failureException, \
  80. (msg or '%s == %s' % self._smallRepr(first, second))
  81. assertNotEquals = failIfEqual = assertNotEqual
  82. def assertAlmostEqual(self, first, second, places=7, msg=None):
  83. if not (numpy.shape(first) == numpy.shape(second) and \
  84. self._reallyEqual(numpy.around(second-first, places), 0, testShape=False)):
  85. raise self.failureException, \
  86. (msg or '%s != %s within %s places' % self._smallRepr(first,second,places))
  87. assertAlmostEquals = failUnlessAlmostEqual = assertAlmostEqual
  88. def assertNotAlmostEqual(self, first, second, places=7, msg=None):
  89. if not (numpy.shape(first) == numpy.shape(second) and \
  90. not self._reallyEqual(numpy.around(second-first, places), 0, testShape=False)):
  91. raise self.failureException, \
  92. (msg or '%s == %s within %s places' % self._smallRepr(first,second,places))
  93. failIfAlmostEqual = assertNotAlmostEquals = assertNotAlmostEqual
  94. def _canonicalMShape(a):
  95. """Matlab arrays are rank-less (rank is specified by indexing), so all
  96. arrays w/ trailing 1s in their shape are equivalent. This returns the
  97. canonical form for comparison purposes: no trailing 1s in the shape,
  98. unless the array would otherwise become a scalar or vector.
  99. """
  100. s = list(a.shape)
  101. if len(s) < 2: s.append(1)
  102. while s[2:] and s[-1] == 1: s.pop()
  103. return a.reshape(s)
  104. class mlabwrapTC(NumericTestCase):
  105. ## def assertEqual(self, first, second):
  106. ## res = first == second
  107. ## if len(res):
  108. ## res = numpy.shape(first) == numpy.shape(second) and \
  109. ## bool(numpy.alltrue((numpy.ravel(a1 == a2))))
  110. ## super(TestCase, self).assertEquals(res, True)
  111. def setUp(self):
  112. self.mlab = matlab()
  113. """Back up options."""
  114. self.backup = {}
  115. for opt in """\
  116. _array_cast
  117. _autosync_dirs
  118. _flatten_row_vecs
  119. _flatten_col_vecs
  120. _clear_call_args
  121. _session
  122. _proxies
  123. _proxy_count
  124. _mlabraw_can_convert
  125. _dont_proxy""".split():
  126. self.backup[opt] = self.mlab.__dict__[opt]
  127. self.mlab.addpath(os.path.dirname(__file__)) # XXX
  128. print "ADDPATHed", os.path.dirname(__file__)
  129. def tearDown(self):
  130. """Reset options."""
  131. self.mlab.__dict__.update(self.backup)
  132. self.mlab.close()
  133. def testBasic(self):
  134. """Test basic behavior."""
  135. array = numpy.array
  136. from random import randrange
  137. for isComplex in [False, True]:
  138. for i in range(30):
  139. #flat vector
  140. if i % 3:
  141. nDims = 1
  142. dims = randrange(1, 20)
  143. #2 - 6 dimensions.
  144. else:
  145. nDims = randrange(2, 7)
  146. dims = [randrange(1, 7) for j in range(nDims)]
  147. a = numpy.random.random(dims)
  148. if isComplex: a = a + 1j*numpy.random.random(dims)
  149. a1 = a.copy()
  150. self.mlab._set('a', a)
  151. #### test simple get ####
  152. self.assertEqual(_canonicalMShape(a), self.mlab._get('a'))
  153. self.assertEqual(a,a1)
  154. ### test sliced arrays (stride handling test) ###
  155. b = a1.copy()
  156. for i in range(nDims):
  157. z=0
  158. while not z: z = randrange(-3,4)
  159. b = b[::z]
  160. self.mlab._set('b',b)
  161. self.assertEqual(_canonicalMShape(b),self.mlab._get('b'))
  162. self.assertEqual(a1,a)
  163. ########## test for aliasing problems ##########
  164. if nDims > 1:
  165. newA = self.mlab._get('a')
  166. newA -= 1e4
  167. if len(newA):
  168. self.assertNotEqual(newA, self.mlab._get('a'))
  169. self.assertEqual(a,a1)
  170. self.mlab.clear('a')
  171. self.mlab.clear('b')
  172. # the tricky diversity of empty arrays
  173. self.mlab._set('a', [[]])
  174. self.assertEqual(self.mlab._get('a'), numpy.zeros((1, 0), 'd'))
  175. self.mlab._set('a', numpy.zeros((0,0)))
  176. self.assertEqual(self.mlab._get('a'), numpy.zeros((0, 0), 'd'))
  177. self.mlab._set('a', [])
  178. self.assertEqual(self.mlab._get('a'), numpy.zeros((0, 0), 'd'))
  179. # complex empty
  180. self.mlab._set('a', numpy.zeros((0,0), 'D'))
  181. self.assertEqual(self.mlab._get('a'), numpy.zeros((0, 0), 'd')) #XXX
  182. # 0d
  183. self.mlab._set('a', -2)
  184. self.assertEqual(self.mlab._get('a'), array([ [-2.]]))
  185. self.mlab._set('a', array(-2))
  186. self.assertEqual(self.mlab._get('a'), array([ [-2.]]))
  187. self.mlab.clear('a')
  188. # try basic error handling
  189. self.failUnlessRaises(MlabError, self.mlab._get, 'dontexist')
  190. self.failUnlessRaises(MlabError,self.mlab.round)
  191. assert toscalar(self.mlab.round(1.6)) == 2.0
  192. self.assertEqual(self.mlab.max([20,10],nout=2), (numpy.array([[20]]), array([[1]])))
  193. self.assertEqual(self.mlab.max([20,10]), numpy.array([[20]]))
  194. def testDoc(self):
  195. """Test that docstring extraction works OK."""
  196. self.mlab.who.__doc__.index('WHO lists the variables in the current workspace')
  197. def testCallArgs(self):
  198. self.mlab._dont_proxy['cell'] = True
  199. try:
  200. self.mlab._clear_call_args = False
  201. self.mlab.sin(1.23)
  202. assert self.mlab._get('arg0__', True) == 1.23
  203. self.mlab._clear_call_args = True
  204. self.mlab.sin(1.23)
  205. assert not 'arg0__' in self.mlab.who()
  206. finally:
  207. self.mlab._clear_call_args = True
  208. self.mlab._dont_proxy['cell'] = False
  209. def testXXXSubtler(self):
  210. """test more subtle stuff. This must come last, hence the XXX"""
  211. import os, cPickle
  212. array = numpy.array
  213. # simple strings:
  214. assert (self.mlab._do("''"), self.mlab._do("'foobar'")) == ('', 'foobar')
  215. self.assertEqual(self.mlab.sort(1), numpy.array([[1.]]))
  216. self.assertEqual(self.mlab.sort([3,1,2]), numpy.array([[1.], [2.], [3.]]))
  217. self.assertEqual(self.mlab.sort(numpy.array([3,1,2])), numpy.array([[1.], [2.], [3.]]))
  218. sct = self.mlab._do("struct('type',{'big','little'},'color','red','x',{3 4})")
  219. bct = self.mlab._do("struct('type',{'BIG','little'},'color','red')")
  220. self.assertEqual(sct[1].x, numpy.array([[4]]))
  221. self.assertEqual(sct[0].x, numpy.array([[3]]))
  222. #FIXME sct[:].x wouldn't work, but currently I'm not sure that's my fault
  223. sct[1].x = 'New Value'
  224. assert sct[1].x == 'New Value'
  225. assert bct[0].type == 'BIG' and sct[0].type == 'big'
  226. self.mlab._set('foo', 1)
  227. assert self.mlab._get('foo') == numpy.array([1.])
  228. assert (self.mlab._do("{'A', 'b', {3,4, {5,6}}}") !=
  229. ['A', 'b', [array([[ 3.]]), array([[ 4.]]),
  230. [array([[ 5.]]), array([[ 6.]])]]])
  231. self.mlab._dont_proxy['cell'] = True
  232. self.assertEquals(self.mlab._do("{'a', 'b', {3,4, {5,6}}}"),
  233. ['a', 'b', [array([ 3.]), array([ 4.]),
  234. [array([ 5.]), array([ 6.])]]])
  235. self.mlab._dont_proxy['cell'] = False
  236. self.mlab.clear('foo')
  237. self.assertRaises(MlabError, self.mlab._get, 'foo')
  238. # XXX: note to self: ``format compact`` in startup.m will cause this
  239. # test to fail, but should otherwise be harmless.
  240. self.assertEquals(degensym_proxy(repr(sct)),
  241. "<MlabObjectProxy of matlab-class: 'struct'; "
  242. "internal name: 'PROXY_VAL__'; has parent: no>\n"
  243. "1x2 struct array with fields:\n"
  244. " type\n color\n x\n\n")
  245. #FIXME: add tests for assigning and nesting proxies
  246. ## ensure proxies work OK as arguments
  247. self.assertEqual(self.mlab.size(sct), array([[1., 2.]]))
  248. self.assertEqual(self.mlab.size(sct, 1), array([[1]]))
  249. # test that exceptions on calls with proxy arguments don't result in
  250. # trouble
  251. self.assertRaises(MlabError, self.mlab.svd, sct)
  252. self.assertEqual(self.mlab.size(sct, [2]), array([[2]]))
  253. self.mlab._dont_proxy['cell'] = True
  254. gc.collect()
  255. assert map(degensym_proxy,without(self.mlab.who(), WHO_AT_STARTUP)) == (
  256. ['PROXY_VAL__', 'PROXY_VAL__'])
  257. # test pickling
  258. pickleFilename = mktemp()
  259. f = open(pickleFilename, 'wb')
  260. try:
  261. cPickle.dump({'sct': sct, 'bct': bct},f,1)
  262. f.close()
  263. f = open(pickleFilename, 'rb')
  264. namespace = cPickle.load(f)
  265. f.close()
  266. finally:
  267. os.remove(pickleFilename)
  268. gc.collect()
  269. assert len(self.mlab._proxies) == 4, "%d proxies!" % len(self.mlab._proxies)
  270. assert namespace['sct'][1].x == 'New Value'
  271. namespace['sct'][1].x = 'Even Newer Value'
  272. assert namespace['sct'][1].x == 'Even Newer Value'
  273. assert sct[1].x == 'New Value'
  274. del sct
  275. del bct
  276. del namespace['sct']
  277. del namespace['bct']
  278. self.mlab._set('bar', '1234')
  279. x = []
  280. self.mlab._do("disp 'hallo'" ,nout=0, handle_out=x.append)
  281. assert x[0] == 'hallo\n'
  282. self.mlab._dont_proxy['cell'] = False
  283. self.assertRaises(ValueError, getattr, self.mlab, "buggy('ipython lookup')")
  284. def testSparseArrays(self):
  285. """Make sure sparse arrays work."""
  286. s = self.mlab.sparse(numpy.zeros([100,100]))
  287. self.assertEqual(self.mlab.full(s), numpy.zeros([100,100]))
  288. # FIXME: add these once we have multi-dimensional proxying
  289. ## s = self.mlab.sparse(numpy.zeros([100,100]))
  290. ## self.assertEqual(s[0,0], 0.0)
  291. ## self.assertEqual(s[99,99], 0.0)
  292. ## t = self.mlab.sparse(numpy.array([[1.,2,3],[0,0,0],[4,5,6]]))
  293. ## self.assertEqual(t[0,0], 1.0)
  294. ## self.assertEqual(t[1,1], 0)
  295. ## self.assertEqual(t[2,2], 6)
  296. def testProxyIndexing(self):
  297. "indexing and co: time for some advanced proxied __getitem__ and __setitem__ etc.."
  298. p=self.mlab.proxyTest(self.mlab.struct('a', 1, 'b', '2'))
  299. p.c = [[4,5]]
  300. self.assertEqual(p.a, 1.0)
  301. assert p.a == 1.0
  302. assert p.b == '2'
  303. assert list(p.c.flat) == [4,5]
  304. # test all combinations of 1D indexing
  305. sv = self.mlab.proxyTest(range(4))
  306. assert sv[0] == 0
  307. sv[0] = -33
  308. assert sv[0] == -33
  309. # test curly indexing; the proxyTest class in matlab arbitrarily uses
  310. # string conversion on ``{}`` indexing to have something to distinguish
  311. # it from "normal" ``()`` indexing
  312. sv._[0] = '0'
  313. assert sv._[0] == '0' == str(int(toscalar(sv[0])))
  314. assert sv["some'string\nwith\\funny\tstuff"] == (
  315. "you ()-indexed with the string <<some'string\nwith\\funny\tstuff>>")
  316. # FIXME this is something to potentially add, but that also raises issues
  317. ## assert numpy.ndim(sv) == 2 # FIXME change that to 1?
  318. ## assert numpy.shape(sv[:]) == (4,1) # FIXME change that to 1?
  319. assert list(sv[:].flat) == range(4)
  320. # more complicated "open-ended" slices aren't supported (yet)
  321. self.assertEqual(sv[0:], sv[:])
  322. self.assertEqual(sv[:-1], sv[0:-1])
  323. self.assertEqual(sv[0:-1:1], sv[:-1])
  324. self.assertEqual(sv[-4:], sv[:])
  325. self.assertEqual(sv[-4:-3], sv[0:1])
  326. for b in [None] + range(-4,4):
  327. for e in [None] + range(-4,4):
  328. for s in [None,1]:
  329. assert list(sv[b:e:s].flat) == range(4)[b:e:s], (
  330. "sv[b:e:s]: %s (b,e,s): %s" % (sv[b:e:s], (b,e,s)))
  331. sv[:-1] = -numpy.arange(3)
  332. assert list(sv[:].flat) == [-x for x in range(3)] + [3]
  333. sv[:] = numpy.arange(4)
  334. assert list(sv[:].flat) == range(4)
  335. sv[-2:] = numpy.arange(2)+10
  336. assert list(sv[:].flat) == [0,1,10,11]
  337. # FIXME math ops aren't yet implemented
  338. # sv *= 10
  339. # sv[1:3] *= 10 # FIXME
  340. # sv + 3
  341. # FIXME multi-D stuff isn't either
  342. ## sm = self.mlab.proxyTest(arange(6).reshape(3,2))
  343. ## assert sm.ndim == 2
  344. ## assert sm.shape == (3,2)
  345. ## assert len(sm) == 3
  346. ## assert len(sm).T
  347. ## p.sv = sv
  348. ## assert p.sv is sv
  349. ## assert p.sv[:]
  350. def testRawMlabraw(self):
  351. """A few explicit tests for mlabraw"""
  352. from mlabwrap import mlabraw
  353. #print "test mlabraw"
  354. self.assertRaises(TypeError, mlabraw.put, 33, 'a',1)
  355. self.assertRaises(TypeError, mlabraw.get, object(), 'a')
  356. self.assertRaises(TypeError, mlabraw.eval, object(), '1')
  357. # -100 is picked kinda arbitrarily to account for internal "overhead";
  358. # I don't want to hardcode the exact value; users can assume 1000
  359. # chars is safe
  360. mlabraw.eval(self.mlab._session, '1'*(BUFSIZE-100))
  361. assert numpy.inf == mlabraw.get(self.mlab._session, 'ans');
  362. # test for buffer overflow detection
  363. self.assertRaises(Exception, mlabraw.eval, self.mlab._session, '1'*BUFSIZE)
  364. self.assertEqual(mlabraw.eval(self.mlab._session, r"fprintf('1\n')"),'1\n')
  365. try:
  366. self.assertEqual(mlabraw.eval(self.mlab._session, r"1"),'')
  367. finally:
  368. mlabraw.eval(self.mlab._session,'clear ans')
  369. #print "tested mlabraw"
  370. def testOrder(self):
  371. """Testing order flags cause no problems"""
  372. try: import numpy
  373. except ImportError: return
  374. fa=numpy.array([[1,2,3],[4,5,6]],order='F')
  375. self.assertEqual(self.mlab.conj(fa),fa)
  376. self.assertEqual([[2]],self.mlab.subsref(fa, self.mlab.struct('type', '()', 'subs',self.mlab._do('{{1,2}}'))))
  377. suite = unittest.TestSuite(map(unittest.makeSuite,
  378. (mlabwrapTC,
  379. )))
  380. unittest.TextTestRunner(verbosity=2).run(suite)
  381. #FIXME strangely enough we can't test this in the function!
  382. #gc.collect()
  383. #mlab._dont_proxy['cell'] = True
  384. ## XXX got no idea where HOME comes from, not there under win
  385. #assert without(mlab.who(), WHO_AT_STARTUP) == ['bar'], "who is:%r" % mlab.who()
  386. #mlab.clear()
  387. #assert without(mlab.who(), ['MLABRAW_ERROR_']) == [] == mlab._do('{}'),(
  388. # "who is:%r" % mlab.who())
  389. #mlab._dont_proxy['cell'] = False