test_mlab.py 64 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709
  1. from numpy.testing import (assert_allclose, assert_almost_equal,
  2. assert_array_equal, assert_array_almost_equal_nulp)
  3. import numpy as np
  4. import pytest
  5. import matplotlib.mlab as mlab
  6. from matplotlib.cbook.deprecation import MatplotlibDeprecationWarning
  7. def _stride_repeat(*args, **kwargs):
  8. with pytest.warns(MatplotlibDeprecationWarning):
  9. return mlab.stride_repeat(*args, **kwargs)
  10. class TestStride:
  11. def get_base(self, x):
  12. y = x
  13. while y.base is not None:
  14. y = y.base
  15. return y
  16. def calc_window_target(self, x, NFFT, noverlap=0, axis=0):
  17. """
  18. This is an adaptation of the original window extraction algorithm.
  19. This is here to test to make sure the new implementation has the same
  20. result.
  21. """
  22. step = NFFT - noverlap
  23. ind = np.arange(0, len(x) - NFFT + 1, step)
  24. n = len(ind)
  25. result = np.zeros((NFFT, n))
  26. # do the ffts of the slices
  27. for i in range(n):
  28. result[:, i] = x[ind[i]:ind[i]+NFFT]
  29. if axis == 1:
  30. result = result.T
  31. return result
  32. @pytest.mark.parametrize('shape', [(), (10, 1)], ids=['0D', '2D'])
  33. def test_stride_windows_invalid_input_shape(self, shape):
  34. x = np.arange(np.prod(shape)).reshape(shape)
  35. with pytest.raises(ValueError):
  36. mlab.stride_windows(x, 5)
  37. @pytest.mark.parametrize('n, noverlap',
  38. [(0, None), (11, None), (2, 2), (2, 3)],
  39. ids=['n less than 1', 'n greater than input',
  40. 'noverlap greater than n',
  41. 'noverlap equal to n'])
  42. def test_stride_windows_invalid_params(self, n, noverlap):
  43. x = np.arange(10)
  44. with pytest.raises(ValueError):
  45. mlab.stride_windows(x, n, noverlap)
  46. @pytest.mark.parametrize('shape', [(), (10, 1)], ids=['0D', '2D'])
  47. def test_stride_repeat_invalid_input_shape(self, shape):
  48. x = np.arange(np.prod(shape)).reshape(shape)
  49. with pytest.raises(ValueError):
  50. _stride_repeat(x, 5)
  51. @pytest.mark.parametrize('axis', [-1, 2],
  52. ids=['axis less than 0',
  53. 'axis greater than input shape'])
  54. def test_stride_repeat_invalid_axis(self, axis):
  55. x = np.array(0)
  56. with pytest.raises(ValueError):
  57. _stride_repeat(x, 5, axis=axis)
  58. def test_stride_repeat_n_lt_1_ValueError(self):
  59. x = np.arange(10)
  60. with pytest.raises(ValueError):
  61. _stride_repeat(x, 0)
  62. @pytest.mark.parametrize('axis', [0, 1], ids=['axis0', 'axis1'])
  63. @pytest.mark.parametrize('n', [1, 5], ids=['n1', 'n5'])
  64. def test_stride_repeat(self, n, axis):
  65. x = np.arange(10)
  66. y = _stride_repeat(x, n, axis=axis)
  67. expected_shape = [10, 10]
  68. expected_shape[axis] = n
  69. yr = np.repeat(np.expand_dims(x, axis), n, axis=axis)
  70. assert yr.shape == y.shape
  71. assert_array_equal(yr, y)
  72. assert tuple(expected_shape) == y.shape
  73. assert self.get_base(y) is x
  74. @pytest.mark.parametrize('axis', [0, 1], ids=['axis0', 'axis1'])
  75. @pytest.mark.parametrize('n, noverlap',
  76. [(1, 0), (5, 0), (15, 2), (13, -3)],
  77. ids=['n1-noverlap0', 'n5-noverlap0',
  78. 'n15-noverlap2', 'n13-noverlapn3'])
  79. def test_stride_windows(self, n, noverlap, axis):
  80. x = np.arange(100)
  81. y = mlab.stride_windows(x, n, noverlap=noverlap, axis=axis)
  82. expected_shape = [0, 0]
  83. expected_shape[axis] = n
  84. expected_shape[1 - axis] = 100 // (n - noverlap)
  85. yt = self.calc_window_target(x, n, noverlap=noverlap, axis=axis)
  86. assert yt.shape == y.shape
  87. assert_array_equal(yt, y)
  88. assert tuple(expected_shape) == y.shape
  89. assert self.get_base(y) is x
  90. @pytest.mark.parametrize('axis', [0, 1], ids=['axis0', 'axis1'])
  91. def test_stride_windows_n32_noverlap0_unflatten(self, axis):
  92. n = 32
  93. x = np.arange(n)[np.newaxis]
  94. x1 = np.tile(x, (21, 1))
  95. x2 = x1.flatten()
  96. y = mlab.stride_windows(x2, n, axis=axis)
  97. if axis == 0:
  98. x1 = x1.T
  99. assert y.shape == x1.shape
  100. assert_array_equal(y, x1)
  101. def test_stride_ensure_integer_type(self):
  102. N = 100
  103. x = np.full(N + 20, np.nan)
  104. y = x[10:-10]
  105. y[:] = 0.3
  106. # previous to #3845 lead to corrupt access
  107. y_strided = mlab.stride_windows(y, n=33, noverlap=0.6)
  108. assert_array_equal(y_strided, 0.3)
  109. # previous to #3845 lead to corrupt access
  110. y_strided = mlab.stride_windows(y, n=33.3, noverlap=0)
  111. assert_array_equal(y_strided, 0.3)
  112. # even previous to #3845 could not find any problematic
  113. # configuration however, let's be sure it's not accidentally
  114. # introduced
  115. y_strided = _stride_repeat(y, n=33.815)
  116. assert_array_equal(y_strided, 0.3)
  117. def _apply_window(*args, **kwargs):
  118. with pytest.warns(MatplotlibDeprecationWarning):
  119. return mlab.apply_window(*args, **kwargs)
  120. class TestWindow:
  121. def setup(self):
  122. np.random.seed(0)
  123. n = 1000
  124. self.sig_rand = np.random.standard_normal(n) + 100.
  125. self.sig_ones = np.ones(n)
  126. def check_window_apply_repeat(self, x, window, NFFT, noverlap):
  127. """
  128. This is an adaptation of the original window application algorithm.
  129. This is here to test to make sure the new implementation has the same
  130. result.
  131. """
  132. step = NFFT - noverlap
  133. ind = np.arange(0, len(x) - NFFT + 1, step)
  134. n = len(ind)
  135. result = np.zeros((NFFT, n))
  136. if np.iterable(window):
  137. windowVals = window
  138. else:
  139. windowVals = window(np.ones(NFFT, x.dtype))
  140. # do the ffts of the slices
  141. for i in range(n):
  142. result[:, i] = windowVals * x[ind[i]:ind[i]+NFFT]
  143. return result
  144. def test_window_none_rand(self):
  145. res = mlab.window_none(self.sig_ones)
  146. assert_array_equal(res, self.sig_ones)
  147. def test_window_none_ones(self):
  148. res = mlab.window_none(self.sig_rand)
  149. assert_array_equal(res, self.sig_rand)
  150. def test_window_hanning_rand(self):
  151. targ = np.hanning(len(self.sig_rand)) * self.sig_rand
  152. res = mlab.window_hanning(self.sig_rand)
  153. assert_allclose(targ, res, atol=1e-06)
  154. def test_window_hanning_ones(self):
  155. targ = np.hanning(len(self.sig_ones))
  156. res = mlab.window_hanning(self.sig_ones)
  157. assert_allclose(targ, res, atol=1e-06)
  158. def test_apply_window_1D_axis1_ValueError(self):
  159. x = self.sig_rand
  160. window = mlab.window_hanning
  161. with pytest.raises(ValueError):
  162. _apply_window(x, window, axis=1, return_window=False)
  163. def test_apply_window_1D_els_wrongsize_ValueError(self):
  164. x = self.sig_rand
  165. window = mlab.window_hanning(np.ones(x.shape[0]-1))
  166. with pytest.raises(ValueError):
  167. _apply_window(x, window)
  168. def test_apply_window_0D_ValueError(self):
  169. x = np.array(0)
  170. window = mlab.window_hanning
  171. with pytest.raises(ValueError):
  172. _apply_window(x, window, axis=1, return_window=False)
  173. def test_apply_window_3D_ValueError(self):
  174. x = self.sig_rand[np.newaxis][np.newaxis]
  175. window = mlab.window_hanning
  176. with pytest.raises(ValueError):
  177. _apply_window(x, window, axis=1, return_window=False)
  178. def test_apply_window_hanning_1D(self):
  179. x = self.sig_rand
  180. window = mlab.window_hanning
  181. window1 = mlab.window_hanning(np.ones(x.shape[0]))
  182. y, window2 = _apply_window(x, window, return_window=True)
  183. yt = window(x)
  184. assert yt.shape == y.shape
  185. assert x.shape == y.shape
  186. assert_allclose(yt, y, atol=1e-06)
  187. assert_array_equal(window1, window2)
  188. def test_apply_window_hanning_1D_axis0(self):
  189. x = self.sig_rand
  190. window = mlab.window_hanning
  191. y = _apply_window(x, window, axis=0, return_window=False)
  192. yt = window(x)
  193. assert yt.shape == y.shape
  194. assert x.shape == y.shape
  195. assert_allclose(yt, y, atol=1e-06)
  196. def test_apply_window_hanning_els_1D_axis0(self):
  197. x = self.sig_rand
  198. window = mlab.window_hanning(np.ones(x.shape[0]))
  199. window1 = mlab.window_hanning
  200. y = _apply_window(x, window, axis=0, return_window=False)
  201. yt = window1(x)
  202. assert yt.shape == y.shape
  203. assert x.shape == y.shape
  204. assert_allclose(yt, y, atol=1e-06)
  205. def test_apply_window_hanning_2D_axis0(self):
  206. x = np.random.standard_normal([1000, 10]) + 100.
  207. window = mlab.window_hanning
  208. y = _apply_window(x, window, axis=0, return_window=False)
  209. yt = np.zeros_like(x)
  210. for i in range(x.shape[1]):
  211. yt[:, i] = window(x[:, i])
  212. assert yt.shape == y.shape
  213. assert x.shape == y.shape
  214. assert_allclose(yt, y, atol=1e-06)
  215. def test_apply_window_hanning_els1_2D_axis0(self):
  216. x = np.random.standard_normal([1000, 10]) + 100.
  217. window = mlab.window_hanning(np.ones(x.shape[0]))
  218. window1 = mlab.window_hanning
  219. y = _apply_window(x, window, axis=0, return_window=False)
  220. yt = np.zeros_like(x)
  221. for i in range(x.shape[1]):
  222. yt[:, i] = window1(x[:, i])
  223. assert yt.shape == y.shape
  224. assert x.shape == y.shape
  225. assert_allclose(yt, y, atol=1e-06)
  226. def test_apply_window_hanning_els2_2D_axis0(self):
  227. x = np.random.standard_normal([1000, 10]) + 100.
  228. window = mlab.window_hanning
  229. window1 = mlab.window_hanning(np.ones(x.shape[0]))
  230. y, window2 = _apply_window(x, window, axis=0, return_window=True)
  231. yt = np.zeros_like(x)
  232. for i in range(x.shape[1]):
  233. yt[:, i] = window1*x[:, i]
  234. assert yt.shape == y.shape
  235. assert x.shape == y.shape
  236. assert_allclose(yt, y, atol=1e-06)
  237. assert_array_equal(window1, window2)
  238. def test_apply_window_hanning_els3_2D_axis0(self):
  239. x = np.random.standard_normal([1000, 10]) + 100.
  240. window = mlab.window_hanning
  241. window1 = mlab.window_hanning(np.ones(x.shape[0]))
  242. y, window2 = _apply_window(x, window, axis=0, return_window=True)
  243. yt = _apply_window(x, window1, axis=0, return_window=False)
  244. assert yt.shape == y.shape
  245. assert x.shape == y.shape
  246. assert_allclose(yt, y, atol=1e-06)
  247. assert_array_equal(window1, window2)
  248. def test_apply_window_hanning_2D_axis1(self):
  249. x = np.random.standard_normal([10, 1000]) + 100.
  250. window = mlab.window_hanning
  251. y = _apply_window(x, window, axis=1, return_window=False)
  252. yt = np.zeros_like(x)
  253. for i in range(x.shape[0]):
  254. yt[i, :] = window(x[i, :])
  255. assert yt.shape == y.shape
  256. assert x.shape == y.shape
  257. assert_allclose(yt, y, atol=1e-06)
  258. def test_apply_window_hanning_2D_els1_axis1(self):
  259. x = np.random.standard_normal([10, 1000]) + 100.
  260. window = mlab.window_hanning(np.ones(x.shape[1]))
  261. window1 = mlab.window_hanning
  262. y = _apply_window(x, window, axis=1, return_window=False)
  263. yt = np.zeros_like(x)
  264. for i in range(x.shape[0]):
  265. yt[i, :] = window1(x[i, :])
  266. assert yt.shape == y.shape
  267. assert x.shape == y.shape
  268. assert_allclose(yt, y, atol=1e-06)
  269. def test_apply_window_hanning_2D_els2_axis1(self):
  270. x = np.random.standard_normal([10, 1000]) + 100.
  271. window = mlab.window_hanning
  272. window1 = mlab.window_hanning(np.ones(x.shape[1]))
  273. y, window2 = _apply_window(x, window, axis=1, return_window=True)
  274. yt = np.zeros_like(x)
  275. for i in range(x.shape[0]):
  276. yt[i, :] = window1 * x[i, :]
  277. assert yt.shape == y.shape
  278. assert x.shape == y.shape
  279. assert_allclose(yt, y, atol=1e-06)
  280. assert_array_equal(window1, window2)
  281. def test_apply_window_hanning_2D_els3_axis1(self):
  282. x = np.random.standard_normal([10, 1000]) + 100.
  283. window = mlab.window_hanning
  284. window1 = mlab.window_hanning(np.ones(x.shape[1]))
  285. y = _apply_window(x, window, axis=1, return_window=False)
  286. yt = _apply_window(x, window1, axis=1, return_window=False)
  287. assert yt.shape == y.shape
  288. assert x.shape == y.shape
  289. assert_allclose(yt, y, atol=1e-06)
  290. def test_apply_window_stride_windows_hanning_2D_n13_noverlapn3_axis0(self):
  291. x = self.sig_rand
  292. window = mlab.window_hanning
  293. yi = mlab.stride_windows(x, n=13, noverlap=2, axis=0)
  294. y = _apply_window(yi, window, axis=0, return_window=False)
  295. yt = self.check_window_apply_repeat(x, window, 13, 2)
  296. assert yt.shape == y.shape
  297. assert x.shape != y.shape
  298. assert_allclose(yt, y, atol=1e-06)
  299. def test_apply_window_hanning_2D_stack_axis1(self):
  300. ydata = np.arange(32)
  301. ydata1 = ydata+5
  302. ydata2 = ydata+3.3
  303. ycontrol1 = _apply_window(ydata1, mlab.window_hanning)
  304. ycontrol2 = mlab.window_hanning(ydata2)
  305. ydata = np.vstack([ydata1, ydata2])
  306. ycontrol = np.vstack([ycontrol1, ycontrol2])
  307. ydata = np.tile(ydata, (20, 1))
  308. ycontrol = np.tile(ycontrol, (20, 1))
  309. result = _apply_window(ydata, mlab.window_hanning, axis=1,
  310. return_window=False)
  311. assert_allclose(ycontrol, result, atol=1e-08)
  312. def test_apply_window_hanning_2D_stack_windows_axis1(self):
  313. ydata = np.arange(32)
  314. ydata1 = ydata+5
  315. ydata2 = ydata+3.3
  316. ycontrol1 = _apply_window(ydata1, mlab.window_hanning)
  317. ycontrol2 = mlab.window_hanning(ydata2)
  318. ydata = np.vstack([ydata1, ydata2])
  319. ycontrol = np.vstack([ycontrol1, ycontrol2])
  320. ydata = np.tile(ydata, (20, 1))
  321. ycontrol = np.tile(ycontrol, (20, 1))
  322. result = _apply_window(ydata, mlab.window_hanning, axis=1,
  323. return_window=False)
  324. assert_allclose(ycontrol, result, atol=1e-08)
  325. def test_apply_window_hanning_2D_stack_windows_axis1_unflatten(self):
  326. n = 32
  327. ydata = np.arange(n)
  328. ydata1 = ydata+5
  329. ydata2 = ydata+3.3
  330. ycontrol1 = _apply_window(ydata1, mlab.window_hanning)
  331. ycontrol2 = mlab.window_hanning(ydata2)
  332. ydata = np.vstack([ydata1, ydata2])
  333. ycontrol = np.vstack([ycontrol1, ycontrol2])
  334. ydata = np.tile(ydata, (20, 1))
  335. ycontrol = np.tile(ycontrol, (20, 1))
  336. ydata = ydata.flatten()
  337. ydata1 = mlab.stride_windows(ydata, 32, noverlap=0, axis=0)
  338. result = _apply_window(ydata1, mlab.window_hanning, axis=0,
  339. return_window=False)
  340. assert_allclose(ycontrol.T, result, atol=1e-08)
  341. class TestDetrend:
  342. def setup(self):
  343. np.random.seed(0)
  344. n = 1000
  345. x = np.linspace(0., 100, n)
  346. self.sig_zeros = np.zeros(n)
  347. self.sig_off = self.sig_zeros + 100.
  348. self.sig_slope = np.linspace(-10., 90., n)
  349. self.sig_slope_mean = x - x.mean()
  350. sig_rand = np.random.standard_normal(n)
  351. sig_sin = np.sin(x*2*np.pi/(n/100))
  352. sig_rand -= sig_rand.mean()
  353. sig_sin -= sig_sin.mean()
  354. self.sig_base = sig_rand + sig_sin
  355. self.atol = 1e-08
  356. def test_detrend_none_0D_zeros(self):
  357. input = 0.
  358. targ = input
  359. mlab.detrend_none(input)
  360. assert input == targ
  361. def test_detrend_none_0D_zeros_axis1(self):
  362. input = 0.
  363. targ = input
  364. mlab.detrend_none(input, axis=1)
  365. assert input == targ
  366. def test_detrend_str_none_0D_zeros(self):
  367. input = 0.
  368. targ = input
  369. mlab.detrend(input, key='none')
  370. assert input == targ
  371. def test_detrend_detrend_none_0D_zeros(self):
  372. input = 0.
  373. targ = input
  374. mlab.detrend(input, key=mlab.detrend_none)
  375. assert input == targ
  376. def test_detrend_none_0D_off(self):
  377. input = 5.5
  378. targ = input
  379. mlab.detrend_none(input)
  380. assert input == targ
  381. def test_detrend_none_1D_off(self):
  382. input = self.sig_off
  383. targ = input
  384. res = mlab.detrend_none(input)
  385. assert_array_equal(res, targ)
  386. def test_detrend_none_1D_slope(self):
  387. input = self.sig_slope
  388. targ = input
  389. res = mlab.detrend_none(input)
  390. assert_array_equal(res, targ)
  391. def test_detrend_none_1D_base(self):
  392. input = self.sig_base
  393. targ = input
  394. res = mlab.detrend_none(input)
  395. assert_array_equal(res, targ)
  396. def test_detrend_none_1D_base_slope_off_list(self):
  397. input = self.sig_base + self.sig_slope + self.sig_off
  398. targ = input.tolist()
  399. res = mlab.detrend_none(input.tolist())
  400. assert res == targ
  401. def test_detrend_none_2D(self):
  402. arri = [self.sig_base,
  403. self.sig_base + self.sig_off,
  404. self.sig_base + self.sig_slope,
  405. self.sig_base + self.sig_off + self.sig_slope]
  406. input = np.vstack(arri)
  407. targ = input
  408. res = mlab.detrend_none(input)
  409. assert_array_equal(res, targ)
  410. def test_detrend_none_2D_T(self):
  411. arri = [self.sig_base,
  412. self.sig_base + self.sig_off,
  413. self.sig_base + self.sig_slope,
  414. self.sig_base + self.sig_off + self.sig_slope]
  415. input = np.vstack(arri)
  416. targ = input
  417. res = mlab.detrend_none(input.T)
  418. assert_array_equal(res.T, targ)
  419. def test_detrend_mean_0D_zeros(self):
  420. input = 0.
  421. targ = 0.
  422. res = mlab.detrend_mean(input)
  423. assert_almost_equal(res, targ)
  424. def test_detrend_str_mean_0D_zeros(self):
  425. input = 0.
  426. targ = 0.
  427. res = mlab.detrend(input, key='mean')
  428. assert_almost_equal(res, targ)
  429. def test_detrend_detrend_mean_0D_zeros(self):
  430. input = 0.
  431. targ = 0.
  432. res = mlab.detrend(input, key=mlab.detrend_mean)
  433. assert_almost_equal(res, targ)
  434. def test_detrend_mean_0D_off(self):
  435. input = 5.5
  436. targ = 0.
  437. res = mlab.detrend_mean(input)
  438. assert_almost_equal(res, targ)
  439. def test_detrend_str_mean_0D_off(self):
  440. input = 5.5
  441. targ = 0.
  442. res = mlab.detrend(input, key='mean')
  443. assert_almost_equal(res, targ)
  444. def test_detrend_detrend_mean_0D_off(self):
  445. input = 5.5
  446. targ = 0.
  447. res = mlab.detrend(input, key=mlab.detrend_mean)
  448. assert_almost_equal(res, targ)
  449. def test_detrend_mean_1D_zeros(self):
  450. input = self.sig_zeros
  451. targ = self.sig_zeros
  452. res = mlab.detrend_mean(input)
  453. assert_allclose(res, targ, atol=self.atol)
  454. def test_detrend_mean_1D_base(self):
  455. input = self.sig_base
  456. targ = self.sig_base
  457. res = mlab.detrend_mean(input)
  458. assert_allclose(res, targ, atol=self.atol)
  459. def test_detrend_mean_1D_base_off(self):
  460. input = self.sig_base + self.sig_off
  461. targ = self.sig_base
  462. res = mlab.detrend_mean(input)
  463. assert_allclose(res, targ, atol=self.atol)
  464. def test_detrend_mean_1D_base_slope(self):
  465. input = self.sig_base + self.sig_slope
  466. targ = self.sig_base + self.sig_slope_mean
  467. res = mlab.detrend_mean(input)
  468. assert_allclose(res, targ, atol=self.atol)
  469. def test_detrend_mean_1D_base_slope_off(self):
  470. input = self.sig_base + self.sig_slope + self.sig_off
  471. targ = self.sig_base + self.sig_slope_mean
  472. res = mlab.detrend_mean(input)
  473. assert_allclose(res, targ, atol=1e-08)
  474. def test_detrend_mean_1D_base_slope_off_axis0(self):
  475. input = self.sig_base + self.sig_slope + self.sig_off
  476. targ = self.sig_base + self.sig_slope_mean
  477. res = mlab.detrend_mean(input, axis=0)
  478. assert_allclose(res, targ, atol=1e-08)
  479. def test_detrend_mean_1D_base_slope_off_list(self):
  480. input = self.sig_base + self.sig_slope + self.sig_off
  481. targ = self.sig_base + self.sig_slope_mean
  482. res = mlab.detrend_mean(input.tolist())
  483. assert_allclose(res, targ, atol=1e-08)
  484. def test_detrend_mean_1D_base_slope_off_list_axis0(self):
  485. input = self.sig_base + self.sig_slope + self.sig_off
  486. targ = self.sig_base + self.sig_slope_mean
  487. res = mlab.detrend_mean(input.tolist(), axis=0)
  488. assert_allclose(res, targ, atol=1e-08)
  489. def test_detrend_mean_2D_default(self):
  490. arri = [self.sig_off,
  491. self.sig_base + self.sig_off]
  492. arrt = [self.sig_zeros,
  493. self.sig_base]
  494. input = np.vstack(arri)
  495. targ = np.vstack(arrt)
  496. res = mlab.detrend_mean(input)
  497. assert_allclose(res, targ, atol=1e-08)
  498. def test_detrend_mean_2D_none(self):
  499. arri = [self.sig_off,
  500. self.sig_base + self.sig_off]
  501. arrt = [self.sig_zeros,
  502. self.sig_base]
  503. input = np.vstack(arri)
  504. targ = np.vstack(arrt)
  505. res = mlab.detrend_mean(input, axis=None)
  506. assert_allclose(res, targ,
  507. atol=1e-08)
  508. def test_detrend_mean_2D_none_T(self):
  509. arri = [self.sig_off,
  510. self.sig_base + self.sig_off]
  511. arrt = [self.sig_zeros,
  512. self.sig_base]
  513. input = np.vstack(arri).T
  514. targ = np.vstack(arrt)
  515. res = mlab.detrend_mean(input, axis=None)
  516. assert_allclose(res.T, targ,
  517. atol=1e-08)
  518. def test_detrend_mean_2D_axis0(self):
  519. arri = [self.sig_base,
  520. self.sig_base + self.sig_off,
  521. self.sig_base + self.sig_slope,
  522. self.sig_base + self.sig_off + self.sig_slope]
  523. arrt = [self.sig_base,
  524. self.sig_base,
  525. self.sig_base + self.sig_slope_mean,
  526. self.sig_base + self.sig_slope_mean]
  527. input = np.vstack(arri).T
  528. targ = np.vstack(arrt).T
  529. res = mlab.detrend_mean(input, axis=0)
  530. assert_allclose(res, targ,
  531. atol=1e-08)
  532. def test_detrend_mean_2D_axis1(self):
  533. arri = [self.sig_base,
  534. self.sig_base + self.sig_off,
  535. self.sig_base + self.sig_slope,
  536. self.sig_base + self.sig_off + self.sig_slope]
  537. arrt = [self.sig_base,
  538. self.sig_base,
  539. self.sig_base + self.sig_slope_mean,
  540. self.sig_base + self.sig_slope_mean]
  541. input = np.vstack(arri)
  542. targ = np.vstack(arrt)
  543. res = mlab.detrend_mean(input, axis=1)
  544. assert_allclose(res, targ,
  545. atol=1e-08)
  546. def test_detrend_mean_2D_axism1(self):
  547. arri = [self.sig_base,
  548. self.sig_base + self.sig_off,
  549. self.sig_base + self.sig_slope,
  550. self.sig_base + self.sig_off + self.sig_slope]
  551. arrt = [self.sig_base,
  552. self.sig_base,
  553. self.sig_base + self.sig_slope_mean,
  554. self.sig_base + self.sig_slope_mean]
  555. input = np.vstack(arri)
  556. targ = np.vstack(arrt)
  557. res = mlab.detrend_mean(input, axis=-1)
  558. assert_allclose(res, targ,
  559. atol=1e-08)
  560. def test_detrend_2D_default(self):
  561. arri = [self.sig_off,
  562. self.sig_base + self.sig_off]
  563. arrt = [self.sig_zeros,
  564. self.sig_base]
  565. input = np.vstack(arri)
  566. targ = np.vstack(arrt)
  567. res = mlab.detrend(input)
  568. assert_allclose(res, targ, atol=1e-08)
  569. def test_detrend_2D_none(self):
  570. arri = [self.sig_off,
  571. self.sig_base + self.sig_off]
  572. arrt = [self.sig_zeros,
  573. self.sig_base]
  574. input = np.vstack(arri)
  575. targ = np.vstack(arrt)
  576. res = mlab.detrend(input, axis=None)
  577. assert_allclose(res, targ, atol=1e-08)
  578. def test_detrend_str_mean_2D_axis0(self):
  579. arri = [self.sig_base,
  580. self.sig_base + self.sig_off,
  581. self.sig_base + self.sig_slope,
  582. self.sig_base + self.sig_off + self.sig_slope]
  583. arrt = [self.sig_base,
  584. self.sig_base,
  585. self.sig_base + self.sig_slope_mean,
  586. self.sig_base + self.sig_slope_mean]
  587. input = np.vstack(arri).T
  588. targ = np.vstack(arrt).T
  589. res = mlab.detrend(input, key='mean', axis=0)
  590. assert_allclose(res, targ,
  591. atol=1e-08)
  592. def test_detrend_str_constant_2D_none_T(self):
  593. arri = [self.sig_off,
  594. self.sig_base + self.sig_off]
  595. arrt = [self.sig_zeros,
  596. self.sig_base]
  597. input = np.vstack(arri).T
  598. targ = np.vstack(arrt)
  599. res = mlab.detrend(input, key='constant', axis=None)
  600. assert_allclose(res.T, targ,
  601. atol=1e-08)
  602. def test_detrend_str_default_2D_axis1(self):
  603. arri = [self.sig_base,
  604. self.sig_base + self.sig_off,
  605. self.sig_base + self.sig_slope,
  606. self.sig_base + self.sig_off + self.sig_slope]
  607. arrt = [self.sig_base,
  608. self.sig_base,
  609. self.sig_base + self.sig_slope_mean,
  610. self.sig_base + self.sig_slope_mean]
  611. input = np.vstack(arri)
  612. targ = np.vstack(arrt)
  613. res = mlab.detrend(input, key='default', axis=1)
  614. assert_allclose(res, targ,
  615. atol=1e-08)
  616. def test_detrend_detrend_mean_2D_axis0(self):
  617. arri = [self.sig_base,
  618. self.sig_base + self.sig_off,
  619. self.sig_base + self.sig_slope,
  620. self.sig_base + self.sig_off + self.sig_slope]
  621. arrt = [self.sig_base,
  622. self.sig_base,
  623. self.sig_base + self.sig_slope_mean,
  624. self.sig_base + self.sig_slope_mean]
  625. input = np.vstack(arri).T
  626. targ = np.vstack(arrt).T
  627. res = mlab.detrend(input, key=mlab.detrend_mean, axis=0)
  628. assert_allclose(res, targ,
  629. atol=1e-08)
  630. def test_detrend_bad_key_str_ValueError(self):
  631. input = self.sig_slope[np.newaxis]
  632. with pytest.raises(ValueError):
  633. mlab.detrend(input, key='spam')
  634. def test_detrend_bad_key_var_ValueError(self):
  635. input = self.sig_slope[np.newaxis]
  636. with pytest.raises(ValueError):
  637. mlab.detrend(input, key=5)
  638. def test_detrend_mean_0D_d0_ValueError(self):
  639. input = 5.5
  640. with pytest.raises(ValueError):
  641. mlab.detrend_mean(input, axis=0)
  642. def test_detrend_0D_d0_ValueError(self):
  643. input = 5.5
  644. with pytest.raises(ValueError):
  645. mlab.detrend(input, axis=0)
  646. def test_detrend_mean_1D_d1_ValueError(self):
  647. input = self.sig_slope
  648. with pytest.raises(ValueError):
  649. mlab.detrend_mean(input, axis=1)
  650. def test_detrend_1D_d1_ValueError(self):
  651. input = self.sig_slope
  652. with pytest.raises(ValueError):
  653. mlab.detrend(input, axis=1)
  654. def test_detrend_mean_2D_d2_ValueError(self):
  655. input = self.sig_slope[np.newaxis]
  656. with pytest.raises(ValueError):
  657. mlab.detrend_mean(input, axis=2)
  658. def test_detrend_2D_d2_ValueError(self):
  659. input = self.sig_slope[np.newaxis]
  660. with pytest.raises(ValueError):
  661. mlab.detrend(input, axis=2)
  662. def test_detrend_linear_0D_zeros(self):
  663. input = 0.
  664. targ = 0.
  665. res = mlab.detrend_linear(input)
  666. assert_almost_equal(res, targ)
  667. def test_detrend_linear_0D_off(self):
  668. input = 5.5
  669. targ = 0.
  670. res = mlab.detrend_linear(input)
  671. assert_almost_equal(res, targ)
  672. def test_detrend_str_linear_0D_off(self):
  673. input = 5.5
  674. targ = 0.
  675. res = mlab.detrend(input, key='linear')
  676. assert_almost_equal(res, targ)
  677. def test_detrend_detrend_linear_0D_off(self):
  678. input = 5.5
  679. targ = 0.
  680. res = mlab.detrend(input, key=mlab.detrend_linear)
  681. assert_almost_equal(res, targ)
  682. def test_detrend_linear_1d_off(self):
  683. input = self.sig_off
  684. targ = self.sig_zeros
  685. res = mlab.detrend_linear(input)
  686. assert_allclose(res, targ, atol=self.atol)
  687. def test_detrend_linear_1d_slope(self):
  688. input = self.sig_slope
  689. targ = self.sig_zeros
  690. res = mlab.detrend_linear(input)
  691. assert_allclose(res, targ, atol=self.atol)
  692. def test_detrend_linear_1d_slope_off(self):
  693. input = self.sig_slope + self.sig_off
  694. targ = self.sig_zeros
  695. res = mlab.detrend_linear(input)
  696. assert_allclose(res, targ, atol=self.atol)
  697. def test_detrend_str_linear_1d_slope_off(self):
  698. input = self.sig_slope + self.sig_off
  699. targ = self.sig_zeros
  700. res = mlab.detrend(input, key='linear')
  701. assert_allclose(res, targ, atol=self.atol)
  702. def test_detrend_detrend_linear_1d_slope_off(self):
  703. input = self.sig_slope + self.sig_off
  704. targ = self.sig_zeros
  705. res = mlab.detrend(input, key=mlab.detrend_linear)
  706. assert_allclose(res, targ, atol=self.atol)
  707. def test_detrend_linear_1d_slope_off_list(self):
  708. input = self.sig_slope + self.sig_off
  709. targ = self.sig_zeros
  710. res = mlab.detrend_linear(input.tolist())
  711. assert_allclose(res, targ, atol=self.atol)
  712. def test_detrend_linear_2D_ValueError(self):
  713. input = self.sig_slope[np.newaxis]
  714. with pytest.raises(ValueError):
  715. mlab.detrend_linear(input)
  716. def test_detrend_str_linear_2d_slope_off_axis0(self):
  717. arri = [self.sig_off,
  718. self.sig_slope,
  719. self.sig_slope + self.sig_off]
  720. arrt = [self.sig_zeros,
  721. self.sig_zeros,
  722. self.sig_zeros]
  723. input = np.vstack(arri).T
  724. targ = np.vstack(arrt).T
  725. res = mlab.detrend(input, key='linear', axis=0)
  726. assert_allclose(res, targ, atol=self.atol)
  727. def test_detrend_detrend_linear_1d_slope_off_axis1(self):
  728. arri = [self.sig_off,
  729. self.sig_slope,
  730. self.sig_slope + self.sig_off]
  731. arrt = [self.sig_zeros,
  732. self.sig_zeros,
  733. self.sig_zeros]
  734. input = np.vstack(arri).T
  735. targ = np.vstack(arrt).T
  736. res = mlab.detrend(input, key=mlab.detrend_linear, axis=0)
  737. assert_allclose(res, targ, atol=self.atol)
  738. def test_detrend_str_linear_2d_slope_off_axis0_notranspose(self):
  739. arri = [self.sig_off,
  740. self.sig_slope,
  741. self.sig_slope + self.sig_off]
  742. arrt = [self.sig_zeros,
  743. self.sig_zeros,
  744. self.sig_zeros]
  745. input = np.vstack(arri)
  746. targ = np.vstack(arrt)
  747. res = mlab.detrend(input, key='linear', axis=1)
  748. assert_allclose(res, targ, atol=self.atol)
  749. def test_detrend_detrend_linear_1d_slope_off_axis1_notranspose(self):
  750. arri = [self.sig_off,
  751. self.sig_slope,
  752. self.sig_slope + self.sig_off]
  753. arrt = [self.sig_zeros,
  754. self.sig_zeros,
  755. self.sig_zeros]
  756. input = np.vstack(arri)
  757. targ = np.vstack(arrt)
  758. res = mlab.detrend(input, key=mlab.detrend_linear, axis=1)
  759. assert_allclose(res, targ, atol=self.atol)
  760. @pytest.mark.parametrize('iscomplex', [False, True],
  761. ids=['real', 'complex'], scope='class')
  762. @pytest.mark.parametrize('sides', ['onesided', 'twosided', 'default'],
  763. scope='class')
  764. @pytest.mark.parametrize(
  765. 'fstims,len_x,NFFT_density,nover_density,pad_to_density,pad_to_spectrum',
  766. [
  767. ([], None, -1, -1, -1, -1),
  768. ([4], None, -1, -1, -1, -1),
  769. ([4, 5, 10], None, -1, -1, -1, -1),
  770. ([], None, None, -1, -1, None),
  771. ([], None, -1, -1, None, None),
  772. ([], None, None, -1, None, None),
  773. ([], 1024, 512, -1, -1, 128),
  774. ([], 256, -1, -1, 33, 257),
  775. ([], 255, 33, -1, -1, None),
  776. ([], 256, 128, -1, 256, 256),
  777. ([], None, -1, 32, -1, -1),
  778. ],
  779. ids=[
  780. 'nosig',
  781. 'Fs4',
  782. 'FsAll',
  783. 'nosig_noNFFT',
  784. 'nosig_nopad_to',
  785. 'nosig_noNFFT_no_pad_to',
  786. 'nosig_trim',
  787. 'nosig_odd',
  788. 'nosig_oddlen',
  789. 'nosig_stretch',
  790. 'nosig_overlap',
  791. ],
  792. scope='class')
  793. class TestSpectral:
  794. @pytest.fixture(scope='class', autouse=True)
  795. def stim(self, request, fstims, iscomplex, sides, len_x, NFFT_density,
  796. nover_density, pad_to_density, pad_to_spectrum):
  797. Fs = 100.
  798. x = np.arange(0, 10, 1 / Fs)
  799. if len_x is not None:
  800. x = x[:len_x]
  801. # get the stimulus frequencies, defaulting to None
  802. fstims = [Fs / fstim for fstim in fstims]
  803. # get the constants, default to calculated values
  804. if NFFT_density is None:
  805. NFFT_density_real = 256
  806. elif NFFT_density < 0:
  807. NFFT_density_real = NFFT_density = 100
  808. else:
  809. NFFT_density_real = NFFT_density
  810. if nover_density is None:
  811. nover_density_real = 0
  812. elif nover_density < 0:
  813. nover_density_real = nover_density = NFFT_density_real // 2
  814. else:
  815. nover_density_real = nover_density
  816. if pad_to_density is None:
  817. pad_to_density_real = NFFT_density_real
  818. elif pad_to_density < 0:
  819. pad_to_density = int(2**np.ceil(np.log2(NFFT_density_real)))
  820. pad_to_density_real = pad_to_density
  821. else:
  822. pad_to_density_real = pad_to_density
  823. if pad_to_spectrum is None:
  824. pad_to_spectrum_real = len(x)
  825. elif pad_to_spectrum < 0:
  826. pad_to_spectrum_real = pad_to_spectrum = len(x)
  827. else:
  828. pad_to_spectrum_real = pad_to_spectrum
  829. if pad_to_spectrum is None:
  830. NFFT_spectrum_real = NFFT_spectrum = pad_to_spectrum_real
  831. else:
  832. NFFT_spectrum_real = NFFT_spectrum = len(x)
  833. nover_spectrum = 0
  834. NFFT_specgram = NFFT_density
  835. nover_specgram = nover_density
  836. pad_to_specgram = pad_to_density
  837. NFFT_specgram_real = NFFT_density_real
  838. nover_specgram_real = nover_density_real
  839. if sides == 'onesided' or (sides == 'default' and not iscomplex):
  840. # frequencies for specgram, psd, and csd
  841. # need to handle even and odd differently
  842. if pad_to_density_real % 2:
  843. freqs_density = np.linspace(0, Fs / 2,
  844. num=pad_to_density_real,
  845. endpoint=False)[::2]
  846. else:
  847. freqs_density = np.linspace(0, Fs / 2,
  848. num=pad_to_density_real // 2 + 1)
  849. # frequencies for complex, magnitude, angle, and phase spectrums
  850. # need to handle even and odd differently
  851. if pad_to_spectrum_real % 2:
  852. freqs_spectrum = np.linspace(0, Fs / 2,
  853. num=pad_to_spectrum_real,
  854. endpoint=False)[::2]
  855. else:
  856. freqs_spectrum = np.linspace(0, Fs / 2,
  857. num=pad_to_spectrum_real // 2 + 1)
  858. else:
  859. # frequencies for specgram, psd, and csd
  860. # need to handle even and odd differentl
  861. if pad_to_density_real % 2:
  862. freqs_density = np.linspace(-Fs / 2, Fs / 2,
  863. num=2 * pad_to_density_real,
  864. endpoint=False)[1::2]
  865. else:
  866. freqs_density = np.linspace(-Fs / 2, Fs / 2,
  867. num=pad_to_density_real,
  868. endpoint=False)
  869. # frequencies for complex, magnitude, angle, and phase spectrums
  870. # need to handle even and odd differently
  871. if pad_to_spectrum_real % 2:
  872. freqs_spectrum = np.linspace(-Fs / 2, Fs / 2,
  873. num=2 * pad_to_spectrum_real,
  874. endpoint=False)[1::2]
  875. else:
  876. freqs_spectrum = np.linspace(-Fs / 2, Fs / 2,
  877. num=pad_to_spectrum_real,
  878. endpoint=False)
  879. freqs_specgram = freqs_density
  880. # time points for specgram
  881. t_start = NFFT_specgram_real // 2
  882. t_stop = len(x) - NFFT_specgram_real // 2 + 1
  883. t_step = NFFT_specgram_real - nover_specgram_real
  884. t_specgram = x[t_start:t_stop:t_step]
  885. if NFFT_specgram_real % 2:
  886. t_specgram += 1 / Fs / 2
  887. if len(t_specgram) == 0:
  888. t_specgram = np.array([NFFT_specgram_real / (2 * Fs)])
  889. t_spectrum = np.array([NFFT_spectrum_real / (2 * Fs)])
  890. t_density = t_specgram
  891. y = np.zeros_like(x)
  892. for i, fstim in enumerate(fstims):
  893. y += np.sin(fstim * x * np.pi * 2) * 10**i
  894. if iscomplex:
  895. y = y.astype('complex')
  896. # Interestingly, the instance on which this fixture is called is not
  897. # the same as the one on which a test is run. So we need to modify the
  898. # class itself when using a class-scoped fixture.
  899. cls = request.cls
  900. cls.Fs = Fs
  901. cls.sides = sides
  902. cls.fstims = fstims
  903. cls.NFFT_density = NFFT_density
  904. cls.nover_density = nover_density
  905. cls.pad_to_density = pad_to_density
  906. cls.NFFT_spectrum = NFFT_spectrum
  907. cls.nover_spectrum = nover_spectrum
  908. cls.pad_to_spectrum = pad_to_spectrum
  909. cls.NFFT_specgram = NFFT_specgram
  910. cls.nover_specgram = nover_specgram
  911. cls.pad_to_specgram = pad_to_specgram
  912. cls.t_specgram = t_specgram
  913. cls.t_density = t_density
  914. cls.t_spectrum = t_spectrum
  915. cls.y = y
  916. cls.freqs_density = freqs_density
  917. cls.freqs_spectrum = freqs_spectrum
  918. cls.freqs_specgram = freqs_specgram
  919. cls.NFFT_density_real = NFFT_density_real
  920. def check_freqs(self, vals, targfreqs, resfreqs, fstims):
  921. assert resfreqs.argmin() == 0
  922. assert resfreqs.argmax() == len(resfreqs)-1
  923. assert_allclose(resfreqs, targfreqs, atol=1e-06)
  924. for fstim in fstims:
  925. i = np.abs(resfreqs - fstim).argmin()
  926. assert vals[i] > vals[i+2]
  927. assert vals[i] > vals[i-2]
  928. def check_maxfreq(self, spec, fsp, fstims):
  929. # skip the test if there are no frequencies
  930. if len(fstims) == 0:
  931. return
  932. # if twosided, do the test for each side
  933. if fsp.min() < 0:
  934. fspa = np.abs(fsp)
  935. zeroind = fspa.argmin()
  936. self.check_maxfreq(spec[:zeroind], fspa[:zeroind], fstims)
  937. self.check_maxfreq(spec[zeroind:], fspa[zeroind:], fstims)
  938. return
  939. fstimst = fstims[:]
  940. spect = spec.copy()
  941. # go through each peak and make sure it is correctly the maximum peak
  942. while fstimst:
  943. maxind = spect.argmax()
  944. maxfreq = fsp[maxind]
  945. assert_almost_equal(maxfreq, fstimst[-1])
  946. del fstimst[-1]
  947. spect[maxind-5:maxind+5] = 0
  948. def test_spectral_helper_raises(self):
  949. # We don't use parametrize here to handle ``y = self.y``.
  950. for kwargs in [ # Various error conditions:
  951. {"y": self.y+1, "mode": "complex"}, # Modes requiring ``x is y``.
  952. {"y": self.y+1, "mode": "magnitude"},
  953. {"y": self.y+1, "mode": "angle"},
  954. {"y": self.y+1, "mode": "phase"},
  955. {"mode": "spam"}, # Bad mode.
  956. {"y": self.y, "sides": "eggs"}, # Bad sides.
  957. {"y": self.y, "NFFT": 10, "noverlap": 20}, # noverlap > NFFT.
  958. {"NFFT": 10, "noverlap": 10}, # noverlap == NFFT.
  959. {"y": self.y, "NFFT": 10,
  960. "window": np.ones(9)}, # len(win) != NFFT.
  961. ]:
  962. with pytest.raises(ValueError):
  963. mlab._spectral_helper(x=self.y, **kwargs)
  964. @pytest.mark.parametrize('mode', ['default', 'psd'])
  965. def test_single_spectrum_helper_unsupported_modes(self, mode):
  966. with pytest.raises(ValueError):
  967. mlab._single_spectrum_helper(x=self.y, mode=mode)
  968. @pytest.mark.parametrize("mode, case", [
  969. ("psd", "density"),
  970. ("magnitude", "specgram"),
  971. ("magnitude", "spectrum"),
  972. ])
  973. def test_spectral_helper_psd(self, mode, case):
  974. freqs = getattr(self, f"freqs_{case}")
  975. spec, fsp, t = mlab._spectral_helper(
  976. x=self.y, y=self.y,
  977. NFFT=getattr(self, f"NFFT_{case}"),
  978. Fs=self.Fs,
  979. noverlap=getattr(self, f"nover_{case}"),
  980. pad_to=getattr(self, f"pad_to_{case}"),
  981. sides=self.sides,
  982. mode=mode)
  983. assert_allclose(fsp, freqs, atol=1e-06)
  984. assert_allclose(t, getattr(self, f"t_{case}"), atol=1e-06)
  985. assert spec.shape[0] == freqs.shape[0]
  986. assert spec.shape[1] == getattr(self, f"t_{case}").shape[0]
  987. def test_csd(self):
  988. freqs = self.freqs_density
  989. spec, fsp = mlab.csd(x=self.y, y=self.y+1,
  990. NFFT=self.NFFT_density,
  991. Fs=self.Fs,
  992. noverlap=self.nover_density,
  993. pad_to=self.pad_to_density,
  994. sides=self.sides)
  995. assert_allclose(fsp, freqs, atol=1e-06)
  996. assert spec.shape == freqs.shape
  997. def test_csd_padding(self):
  998. """Test zero padding of csd()."""
  999. if self.NFFT_density is None: # for derived classes
  1000. return
  1001. sargs = dict(x=self.y, y=self.y+1, Fs=self.Fs, window=mlab.window_none,
  1002. sides=self.sides)
  1003. spec0, _ = mlab.csd(NFFT=self.NFFT_density, **sargs)
  1004. spec1, _ = mlab.csd(NFFT=self.NFFT_density*2, **sargs)
  1005. assert_almost_equal(np.sum(np.conjugate(spec0)*spec0).real,
  1006. np.sum(np.conjugate(spec1/2)*spec1/2).real)
  1007. def test_psd(self):
  1008. freqs = self.freqs_density
  1009. spec, fsp = mlab.psd(x=self.y,
  1010. NFFT=self.NFFT_density,
  1011. Fs=self.Fs,
  1012. noverlap=self.nover_density,
  1013. pad_to=self.pad_to_density,
  1014. sides=self.sides)
  1015. assert spec.shape == freqs.shape
  1016. self.check_freqs(spec, freqs, fsp, self.fstims)
  1017. @pytest.mark.parametrize(
  1018. 'make_data, detrend',
  1019. [(np.zeros, mlab.detrend_mean), (np.zeros, 'mean'),
  1020. (np.arange, mlab.detrend_linear), (np.arange, 'linear')])
  1021. def test_psd_detrend(self, make_data, detrend):
  1022. if self.NFFT_density is None:
  1023. return
  1024. ydata = make_data(self.NFFT_density)
  1025. ydata1 = ydata+5
  1026. ydata2 = ydata+3.3
  1027. ydata = np.vstack([ydata1, ydata2])
  1028. ydata = np.tile(ydata, (20, 1))
  1029. ydatab = ydata.T.flatten()
  1030. ydata = ydata.flatten()
  1031. ycontrol = np.zeros_like(ydata)
  1032. spec_g, fsp_g = mlab.psd(x=ydata,
  1033. NFFT=self.NFFT_density,
  1034. Fs=self.Fs,
  1035. noverlap=0,
  1036. sides=self.sides,
  1037. detrend=detrend)
  1038. spec_b, fsp_b = mlab.psd(x=ydatab,
  1039. NFFT=self.NFFT_density,
  1040. Fs=self.Fs,
  1041. noverlap=0,
  1042. sides=self.sides,
  1043. detrend=detrend)
  1044. spec_c, fsp_c = mlab.psd(x=ycontrol,
  1045. NFFT=self.NFFT_density,
  1046. Fs=self.Fs,
  1047. noverlap=0,
  1048. sides=self.sides)
  1049. assert_array_equal(fsp_g, fsp_c)
  1050. assert_array_equal(fsp_b, fsp_c)
  1051. assert_allclose(spec_g, spec_c, atol=1e-08)
  1052. # these should not be almost equal
  1053. with pytest.raises(AssertionError):
  1054. assert_allclose(spec_b, spec_c, atol=1e-08)
  1055. def test_psd_window_hanning(self):
  1056. if self.NFFT_density is None:
  1057. return
  1058. ydata = np.arange(self.NFFT_density)
  1059. ydata1 = ydata+5
  1060. ydata2 = ydata+3.3
  1061. ycontrol1, windowVals = _apply_window(ydata1,
  1062. mlab.window_hanning,
  1063. return_window=True)
  1064. ycontrol2 = mlab.window_hanning(ydata2)
  1065. ydata = np.vstack([ydata1, ydata2])
  1066. ycontrol = np.vstack([ycontrol1, ycontrol2])
  1067. ydata = np.tile(ydata, (20, 1))
  1068. ycontrol = np.tile(ycontrol, (20, 1))
  1069. ydatab = ydata.T.flatten()
  1070. ydataf = ydata.flatten()
  1071. ycontrol = ycontrol.flatten()
  1072. spec_g, fsp_g = mlab.psd(x=ydataf,
  1073. NFFT=self.NFFT_density,
  1074. Fs=self.Fs,
  1075. noverlap=0,
  1076. sides=self.sides,
  1077. window=mlab.window_hanning)
  1078. spec_b, fsp_b = mlab.psd(x=ydatab,
  1079. NFFT=self.NFFT_density,
  1080. Fs=self.Fs,
  1081. noverlap=0,
  1082. sides=self.sides,
  1083. window=mlab.window_hanning)
  1084. spec_c, fsp_c = mlab.psd(x=ycontrol,
  1085. NFFT=self.NFFT_density,
  1086. Fs=self.Fs,
  1087. noverlap=0,
  1088. sides=self.sides,
  1089. window=mlab.window_none)
  1090. spec_c *= len(ycontrol1)/(np.abs(windowVals)**2).sum()
  1091. assert_array_equal(fsp_g, fsp_c)
  1092. assert_array_equal(fsp_b, fsp_c)
  1093. assert_allclose(spec_g, spec_c, atol=1e-08)
  1094. # these should not be almost equal
  1095. with pytest.raises(AssertionError):
  1096. assert_allclose(spec_b, spec_c, atol=1e-08)
  1097. def test_psd_window_hanning_detrend_linear(self):
  1098. if self.NFFT_density is None:
  1099. return
  1100. ydata = np.arange(self.NFFT_density)
  1101. ycontrol = np.zeros(self.NFFT_density)
  1102. ydata1 = ydata+5
  1103. ydata2 = ydata+3.3
  1104. ycontrol1 = ycontrol
  1105. ycontrol2 = ycontrol
  1106. ycontrol1, windowVals = _apply_window(ycontrol1,
  1107. mlab.window_hanning,
  1108. return_window=True)
  1109. ycontrol2 = mlab.window_hanning(ycontrol2)
  1110. ydata = np.vstack([ydata1, ydata2])
  1111. ycontrol = np.vstack([ycontrol1, ycontrol2])
  1112. ydata = np.tile(ydata, (20, 1))
  1113. ycontrol = np.tile(ycontrol, (20, 1))
  1114. ydatab = ydata.T.flatten()
  1115. ydataf = ydata.flatten()
  1116. ycontrol = ycontrol.flatten()
  1117. spec_g, fsp_g = mlab.psd(x=ydataf,
  1118. NFFT=self.NFFT_density,
  1119. Fs=self.Fs,
  1120. noverlap=0,
  1121. sides=self.sides,
  1122. detrend=mlab.detrend_linear,
  1123. window=mlab.window_hanning)
  1124. spec_b, fsp_b = mlab.psd(x=ydatab,
  1125. NFFT=self.NFFT_density,
  1126. Fs=self.Fs,
  1127. noverlap=0,
  1128. sides=self.sides,
  1129. detrend=mlab.detrend_linear,
  1130. window=mlab.window_hanning)
  1131. spec_c, fsp_c = mlab.psd(x=ycontrol,
  1132. NFFT=self.NFFT_density,
  1133. Fs=self.Fs,
  1134. noverlap=0,
  1135. sides=self.sides,
  1136. window=mlab.window_none)
  1137. spec_c *= len(ycontrol1)/(np.abs(windowVals)**2).sum()
  1138. assert_array_equal(fsp_g, fsp_c)
  1139. assert_array_equal(fsp_b, fsp_c)
  1140. assert_allclose(spec_g, spec_c, atol=1e-08)
  1141. # these should not be almost equal
  1142. with pytest.raises(AssertionError):
  1143. assert_allclose(spec_b, spec_c, atol=1e-08)
  1144. def test_psd_windowarray(self):
  1145. freqs = self.freqs_density
  1146. spec, fsp = mlab.psd(x=self.y,
  1147. NFFT=self.NFFT_density,
  1148. Fs=self.Fs,
  1149. noverlap=self.nover_density,
  1150. pad_to=self.pad_to_density,
  1151. sides=self.sides,
  1152. window=np.ones(self.NFFT_density_real))
  1153. assert_allclose(fsp, freqs, atol=1e-06)
  1154. assert spec.shape == freqs.shape
  1155. def test_psd_windowarray_scale_by_freq(self):
  1156. win = mlab.window_hanning(np.ones(self.NFFT_density_real))
  1157. spec, fsp = mlab.psd(x=self.y,
  1158. NFFT=self.NFFT_density,
  1159. Fs=self.Fs,
  1160. noverlap=self.nover_density,
  1161. pad_to=self.pad_to_density,
  1162. sides=self.sides,
  1163. window=mlab.window_hanning)
  1164. spec_s, fsp_s = mlab.psd(x=self.y,
  1165. NFFT=self.NFFT_density,
  1166. Fs=self.Fs,
  1167. noverlap=self.nover_density,
  1168. pad_to=self.pad_to_density,
  1169. sides=self.sides,
  1170. window=mlab.window_hanning,
  1171. scale_by_freq=True)
  1172. spec_n, fsp_n = mlab.psd(x=self.y,
  1173. NFFT=self.NFFT_density,
  1174. Fs=self.Fs,
  1175. noverlap=self.nover_density,
  1176. pad_to=self.pad_to_density,
  1177. sides=self.sides,
  1178. window=mlab.window_hanning,
  1179. scale_by_freq=False)
  1180. assert_array_equal(fsp, fsp_s)
  1181. assert_array_equal(fsp, fsp_n)
  1182. assert_array_equal(spec, spec_s)
  1183. assert_allclose(spec_s*(win**2).sum(),
  1184. spec_n/self.Fs*win.sum()**2,
  1185. atol=1e-08)
  1186. @pytest.mark.parametrize(
  1187. "kind", ["complex", "magnitude", "angle", "phase"])
  1188. def test_spectrum(self, kind):
  1189. freqs = self.freqs_spectrum
  1190. spec, fsp = getattr(mlab, f"{kind}_spectrum")(
  1191. x=self.y,
  1192. Fs=self.Fs, sides=self.sides, pad_to=self.pad_to_spectrum)
  1193. assert_allclose(fsp, freqs, atol=1e-06)
  1194. assert spec.shape == freqs.shape
  1195. if kind == "magnitude":
  1196. self.check_maxfreq(spec, fsp, self.fstims)
  1197. self.check_freqs(spec, freqs, fsp, self.fstims)
  1198. @pytest.mark.parametrize(
  1199. 'kwargs',
  1200. [{}, {'mode': 'default'}, {'mode': 'psd'}, {'mode': 'magnitude'},
  1201. {'mode': 'complex'}, {'mode': 'angle'}, {'mode': 'phase'}])
  1202. def test_specgram(self, kwargs):
  1203. freqs = self.freqs_specgram
  1204. spec, fsp, t = mlab.specgram(x=self.y,
  1205. NFFT=self.NFFT_specgram,
  1206. Fs=self.Fs,
  1207. noverlap=self.nover_specgram,
  1208. pad_to=self.pad_to_specgram,
  1209. sides=self.sides,
  1210. **kwargs)
  1211. if kwargs.get('mode') == 'complex':
  1212. spec = np.abs(spec)
  1213. specm = np.mean(spec, axis=1)
  1214. assert_allclose(fsp, freqs, atol=1e-06)
  1215. assert_allclose(t, self.t_specgram, atol=1e-06)
  1216. assert spec.shape[0] == freqs.shape[0]
  1217. assert spec.shape[1] == self.t_specgram.shape[0]
  1218. if kwargs.get('mode') not in ['complex', 'angle', 'phase']:
  1219. # using a single freq, so all time slices should be about the same
  1220. if np.abs(spec.max()) != 0:
  1221. assert_allclose(
  1222. np.diff(spec, axis=1).max() / np.abs(spec.max()), 0,
  1223. atol=1e-02)
  1224. if kwargs.get('mode') not in ['angle', 'phase']:
  1225. self.check_freqs(specm, freqs, fsp, self.fstims)
  1226. def test_specgram_warn_only1seg(self):
  1227. """Warning should be raised if len(x) <= NFFT."""
  1228. with pytest.warns(UserWarning, match="Only one segment is calculated"):
  1229. mlab.specgram(x=self.y, NFFT=len(self.y), Fs=self.Fs)
  1230. def test_psd_csd_equal(self):
  1231. Pxx, freqsxx = mlab.psd(x=self.y,
  1232. NFFT=self.NFFT_density,
  1233. Fs=self.Fs,
  1234. noverlap=self.nover_density,
  1235. pad_to=self.pad_to_density,
  1236. sides=self.sides)
  1237. Pxy, freqsxy = mlab.csd(x=self.y, y=self.y,
  1238. NFFT=self.NFFT_density,
  1239. Fs=self.Fs,
  1240. noverlap=self.nover_density,
  1241. pad_to=self.pad_to_density,
  1242. sides=self.sides)
  1243. assert_array_almost_equal_nulp(Pxx, Pxy)
  1244. assert_array_equal(freqsxx, freqsxy)
  1245. @pytest.mark.parametrize("mode", ["default", "psd"])
  1246. def test_specgram_auto_default_psd_equal(self, mode):
  1247. """
  1248. Test that mlab.specgram without mode and with mode 'default' and 'psd'
  1249. are all the same.
  1250. """
  1251. speca, freqspeca, ta = mlab.specgram(x=self.y,
  1252. NFFT=self.NFFT_specgram,
  1253. Fs=self.Fs,
  1254. noverlap=self.nover_specgram,
  1255. pad_to=self.pad_to_specgram,
  1256. sides=self.sides)
  1257. specb, freqspecb, tb = mlab.specgram(x=self.y,
  1258. NFFT=self.NFFT_specgram,
  1259. Fs=self.Fs,
  1260. noverlap=self.nover_specgram,
  1261. pad_to=self.pad_to_specgram,
  1262. sides=self.sides,
  1263. mode=mode)
  1264. assert_array_equal(speca, specb)
  1265. assert_array_equal(freqspeca, freqspecb)
  1266. assert_array_equal(ta, tb)
  1267. @pytest.mark.parametrize(
  1268. "mode, conv", [
  1269. ("magnitude", np.abs),
  1270. ("angle", np.angle),
  1271. ("phase", lambda x: np.unwrap(np.angle(x), axis=0))
  1272. ])
  1273. def test_specgram_complex_equivalent(self, mode, conv):
  1274. specc, freqspecc, tc = mlab.specgram(x=self.y,
  1275. NFFT=self.NFFT_specgram,
  1276. Fs=self.Fs,
  1277. noverlap=self.nover_specgram,
  1278. pad_to=self.pad_to_specgram,
  1279. sides=self.sides,
  1280. mode='complex')
  1281. specm, freqspecm, tm = mlab.specgram(x=self.y,
  1282. NFFT=self.NFFT_specgram,
  1283. Fs=self.Fs,
  1284. noverlap=self.nover_specgram,
  1285. pad_to=self.pad_to_specgram,
  1286. sides=self.sides,
  1287. mode=mode)
  1288. assert_array_equal(freqspecc, freqspecm)
  1289. assert_array_equal(tc, tm)
  1290. assert_allclose(conv(specc), specm, atol=1e-06)
  1291. def test_psd_windowarray_equal(self):
  1292. win = mlab.window_hanning(np.ones(self.NFFT_density_real))
  1293. speca, fspa = mlab.psd(x=self.y,
  1294. NFFT=self.NFFT_density,
  1295. Fs=self.Fs,
  1296. noverlap=self.nover_density,
  1297. pad_to=self.pad_to_density,
  1298. sides=self.sides,
  1299. window=win)
  1300. specb, fspb = mlab.psd(x=self.y,
  1301. NFFT=self.NFFT_density,
  1302. Fs=self.Fs,
  1303. noverlap=self.nover_density,
  1304. pad_to=self.pad_to_density,
  1305. sides=self.sides)
  1306. assert_array_equal(fspa, fspb)
  1307. assert_allclose(speca, specb, atol=1e-08)
  1308. # extra test for cohere...
  1309. def test_cohere():
  1310. N = 1024
  1311. np.random.seed(19680801)
  1312. x = np.random.randn(N)
  1313. # phase offset
  1314. y = np.roll(x, 20)
  1315. # high-freq roll-off
  1316. y = np.convolve(y, np.ones(20) / 20., mode='same')
  1317. cohsq, f = mlab.cohere(x, y, NFFT=256, Fs=2, noverlap=128)
  1318. assert_allclose(np.mean(cohsq), 0.837, atol=1.e-3)
  1319. assert np.isreal(np.mean(cohsq))
  1320. #*****************************************************************
  1321. # These Tests where taken from SCIPY with some minor modifications
  1322. # this can be retrieved from:
  1323. # https://github.com/scipy/scipy/blob/master/scipy/stats/tests/test_kdeoth.py
  1324. #*****************************************************************
  1325. class TestGaussianKDE:
  1326. def test_kde_integer_input(self):
  1327. """Regression test for #1181."""
  1328. x1 = np.arange(5)
  1329. kde = mlab.GaussianKDE(x1)
  1330. y_expected = [0.13480721, 0.18222869, 0.19514935, 0.18222869,
  1331. 0.13480721]
  1332. np.testing.assert_array_almost_equal(kde(x1), y_expected, decimal=6)
  1333. def test_gaussian_kde_covariance_caching(self):
  1334. x1 = np.array([-7, -5, 1, 4, 5], dtype=float)
  1335. xs = np.linspace(-10, 10, num=5)
  1336. # These expected values are from scipy 0.10, before some changes to
  1337. # gaussian_kde. They were not compared with any external reference.
  1338. y_expected = [0.02463386, 0.04689208, 0.05395444, 0.05337754,
  1339. 0.01664475]
  1340. # set it to the default bandwidth.
  1341. kde2 = mlab.GaussianKDE(x1, 'scott')
  1342. y2 = kde2(xs)
  1343. np.testing.assert_array_almost_equal(y_expected, y2, decimal=7)
  1344. def test_kde_bandwidth_method(self):
  1345. np.random.seed(8765678)
  1346. n_basesample = 50
  1347. xn = np.random.randn(n_basesample)
  1348. # Default
  1349. gkde = mlab.GaussianKDE(xn)
  1350. # Supply a callable
  1351. gkde2 = mlab.GaussianKDE(xn, 'scott')
  1352. # Supply a scalar
  1353. gkde3 = mlab.GaussianKDE(xn, bw_method=gkde.factor)
  1354. xs = np.linspace(-7, 7, 51)
  1355. kdepdf = gkde.evaluate(xs)
  1356. kdepdf2 = gkde2.evaluate(xs)
  1357. assert kdepdf.all() == kdepdf2.all()
  1358. kdepdf3 = gkde3.evaluate(xs)
  1359. assert kdepdf.all() == kdepdf3.all()
  1360. class TestGaussianKDECustom:
  1361. def test_no_data(self):
  1362. """Pass no data into the GaussianKDE class."""
  1363. with pytest.raises(ValueError):
  1364. mlab.GaussianKDE([])
  1365. def test_single_dataset_element(self):
  1366. """Pass a single dataset element into the GaussianKDE class."""
  1367. with pytest.raises(ValueError):
  1368. mlab.GaussianKDE([42])
  1369. def test_silverman_multidim_dataset(self):
  1370. """Test silverman's for a multi-dimensional array."""
  1371. x1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
  1372. with pytest.raises(np.linalg.LinAlgError):
  1373. mlab.GaussianKDE(x1, "silverman")
  1374. def test_silverman_singledim_dataset(self):
  1375. """Test silverman's output for a single dimension list."""
  1376. x1 = np.array([-7, -5, 1, 4, 5])
  1377. mygauss = mlab.GaussianKDE(x1, "silverman")
  1378. y_expected = 0.76770389927475502
  1379. assert_almost_equal(mygauss.covariance_factor(), y_expected, 7)
  1380. def test_scott_multidim_dataset(self):
  1381. """Test scott's output for a multi-dimensional array."""
  1382. x1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
  1383. with pytest.raises(np.linalg.LinAlgError):
  1384. mlab.GaussianKDE(x1, "scott")
  1385. def test_scott_singledim_dataset(self):
  1386. """Test scott's output a single-dimensional array."""
  1387. x1 = np.array([-7, -5, 1, 4, 5])
  1388. mygauss = mlab.GaussianKDE(x1, "scott")
  1389. y_expected = 0.72477966367769553
  1390. assert_almost_equal(mygauss.covariance_factor(), y_expected, 7)
  1391. def test_scalar_empty_dataset(self):
  1392. """Test the scalar's cov factor for an empty array."""
  1393. with pytest.raises(ValueError):
  1394. mlab.GaussianKDE([], bw_method=5)
  1395. def test_scalar_covariance_dataset(self):
  1396. """Test a scalar's cov factor."""
  1397. np.random.seed(8765678)
  1398. n_basesample = 50
  1399. multidim_data = [np.random.randn(n_basesample) for i in range(5)]
  1400. kde = mlab.GaussianKDE(multidim_data, bw_method=0.5)
  1401. assert kde.covariance_factor() == 0.5
  1402. def test_callable_covariance_dataset(self):
  1403. """Test the callable's cov factor for a multi-dimensional array."""
  1404. np.random.seed(8765678)
  1405. n_basesample = 50
  1406. multidim_data = [np.random.randn(n_basesample) for i in range(5)]
  1407. def callable_fun(x):
  1408. return 0.55
  1409. kde = mlab.GaussianKDE(multidim_data, bw_method=callable_fun)
  1410. assert kde.covariance_factor() == 0.55
  1411. def test_callable_singledim_dataset(self):
  1412. """Test the callable's cov factor for a single-dimensional array."""
  1413. np.random.seed(8765678)
  1414. n_basesample = 50
  1415. multidim_data = np.random.randn(n_basesample)
  1416. kde = mlab.GaussianKDE(multidim_data, bw_method='silverman')
  1417. y_expected = 0.48438841363348911
  1418. assert_almost_equal(kde.covariance_factor(), y_expected, 7)
  1419. def test_wrong_bw_method(self):
  1420. """Test the error message that should be called when bw is invalid."""
  1421. np.random.seed(8765678)
  1422. n_basesample = 50
  1423. data = np.random.randn(n_basesample)
  1424. with pytest.raises(ValueError):
  1425. mlab.GaussianKDE(data, bw_method="invalid")
  1426. class TestGaussianKDEEvaluate:
  1427. def test_evaluate_diff_dim(self):
  1428. """
  1429. Test the evaluate method when the dim's of dataset and points have
  1430. different dimensions.
  1431. """
  1432. x1 = np.arange(3, 10, 2)
  1433. kde = mlab.GaussianKDE(x1)
  1434. x2 = np.arange(3, 12, 2)
  1435. y_expected = [
  1436. 0.08797252, 0.11774109, 0.11774109, 0.08797252, 0.0370153
  1437. ]
  1438. y = kde.evaluate(x2)
  1439. np.testing.assert_array_almost_equal(y, y_expected, 7)
  1440. def test_evaluate_inv_dim(self):
  1441. """
  1442. Invert the dimensions; i.e., for a dataset of dimension 1 [3, 2, 4],
  1443. the points should have a dimension of 3 [[3], [2], [4]].
  1444. """
  1445. np.random.seed(8765678)
  1446. n_basesample = 50
  1447. multidim_data = np.random.randn(n_basesample)
  1448. kde = mlab.GaussianKDE(multidim_data)
  1449. x2 = [[1], [2], [3]]
  1450. with pytest.raises(ValueError):
  1451. kde.evaluate(x2)
  1452. def test_evaluate_dim_and_num(self):
  1453. """Tests if evaluated against a one by one array"""
  1454. x1 = np.arange(3, 10, 2)
  1455. x2 = np.array([3])
  1456. kde = mlab.GaussianKDE(x1)
  1457. y_expected = [0.08797252]
  1458. y = kde.evaluate(x2)
  1459. np.testing.assert_array_almost_equal(y, y_expected, 7)
  1460. def test_evaluate_point_dim_not_one(self):
  1461. x1 = np.arange(3, 10, 2)
  1462. x2 = [np.arange(3, 10, 2), np.arange(3, 10, 2)]
  1463. kde = mlab.GaussianKDE(x1)
  1464. with pytest.raises(ValueError):
  1465. kde.evaluate(x2)
  1466. def test_evaluate_equal_dim_and_num_lt(self):
  1467. x1 = np.arange(3, 10, 2)
  1468. x2 = np.arange(3, 8, 2)
  1469. kde = mlab.GaussianKDE(x1)
  1470. y_expected = [0.08797252, 0.11774109, 0.11774109]
  1471. y = kde.evaluate(x2)
  1472. np.testing.assert_array_almost_equal(y, y_expected, 7)
  1473. def test_psd_onesided_norm():
  1474. u = np.array([0, 1, 2, 3, 1, 2, 1])
  1475. dt = 1.0
  1476. Su = np.abs(np.fft.fft(u) * dt)**2 / (dt * u.size)
  1477. P, f = mlab.psd(u, NFFT=u.size, Fs=1/dt, window=mlab.window_none,
  1478. detrend=mlab.detrend_none, noverlap=0, pad_to=None,
  1479. scale_by_freq=None,
  1480. sides='onesided')
  1481. Su_1side = np.append([Su[0]], Su[1:4] + Su[4:][::-1])
  1482. assert_allclose(P, Su_1side, atol=1e-06)
  1483. def test_psd_oversampling():
  1484. """Test the case len(x) < NFFT for psd()."""
  1485. u = np.array([0, 1, 2, 3, 1, 2, 1])
  1486. dt = 1.0
  1487. Su = np.abs(np.fft.fft(u) * dt)**2 / (dt * u.size)
  1488. P, f = mlab.psd(u, NFFT=u.size*2, Fs=1/dt, window=mlab.window_none,
  1489. detrend=mlab.detrend_none, noverlap=0, pad_to=None,
  1490. scale_by_freq=None,
  1491. sides='onesided')
  1492. Su_1side = np.append([Su[0]], Su[1:4] + Su[4:][::-1])
  1493. assert_almost_equal(np.sum(P), np.sum(Su_1side)) # same energy