acoular 24.3__py3-none-any.whl → 24.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. acoular/__init__.py +118 -50
  2. acoular/calib.py +29 -38
  3. acoular/configuration.py +116 -73
  4. acoular/demo/__init__.py +10 -4
  5. acoular/demo/acoular_demo.py +78 -53
  6. acoular/environments.py +265 -262
  7. acoular/fastFuncs.py +361 -191
  8. acoular/fbeamform.py +1460 -1404
  9. acoular/grids.py +501 -545
  10. acoular/h5cache.py +50 -59
  11. acoular/h5files.py +154 -137
  12. acoular/internal.py +10 -11
  13. acoular/microphones.py +57 -53
  14. acoular/sdinput.py +47 -52
  15. acoular/signals.py +167 -179
  16. acoular/sources.py +818 -693
  17. acoular/spectra.py +349 -359
  18. acoular/tbeamform.py +414 -413
  19. acoular/tfastfuncs.py +178 -101
  20. acoular/tools/__init__.py +25 -0
  21. acoular/tools/aiaa.py +186 -0
  22. acoular/tools/helpers.py +189 -0
  23. acoular/tools/metrics.py +165 -0
  24. acoular/tprocess.py +1201 -1143
  25. acoular/traitsviews.py +513 -501
  26. acoular/trajectory.py +50 -52
  27. acoular/version.py +5 -6
  28. acoular/xml/minidsp_uma-16.xml +20 -0
  29. acoular/xml/{minidsp_uma16.xml → minidsp_uma-16_mirrored.xml} +3 -0
  30. {acoular-24.3.dist-info → acoular-24.5.dist-info}/METADATA +45 -46
  31. acoular-24.5.dist-info/RECORD +50 -0
  32. {acoular-24.3.dist-info → acoular-24.5.dist-info}/WHEEL +1 -1
  33. acoular-24.5.dist-info/licenses/LICENSE +28 -0
  34. acoular/fileimport.py +0 -380
  35. acoular/nidaqimport.py +0 -273
  36. acoular/tests/reference_data/BeamformerBase.npy +0 -0
  37. acoular/tests/reference_data/BeamformerBaseFalse1.npy +0 -0
  38. acoular/tests/reference_data/BeamformerBaseFalse2.npy +0 -0
  39. acoular/tests/reference_data/BeamformerBaseFalse3.npy +0 -0
  40. acoular/tests/reference_data/BeamformerBaseFalse4.npy +0 -0
  41. acoular/tests/reference_data/BeamformerBaseTrue1.npy +0 -0
  42. acoular/tests/reference_data/BeamformerBaseTrue2.npy +0 -0
  43. acoular/tests/reference_data/BeamformerBaseTrue3.npy +0 -0
  44. acoular/tests/reference_data/BeamformerBaseTrue4.npy +0 -0
  45. acoular/tests/reference_data/BeamformerCMFLassoLarsBIC.npy +0 -0
  46. acoular/tests/reference_data/BeamformerCMFNNLS.npy +0 -0
  47. acoular/tests/reference_data/BeamformerCapon.npy +0 -0
  48. acoular/tests/reference_data/BeamformerClean.npy +0 -0
  49. acoular/tests/reference_data/BeamformerCleansc.npy +0 -0
  50. acoular/tests/reference_data/BeamformerCleant.npy +0 -0
  51. acoular/tests/reference_data/BeamformerCleantSq.npy +0 -0
  52. acoular/tests/reference_data/BeamformerCleantSqTraj.npy +0 -0
  53. acoular/tests/reference_data/BeamformerCleantTraj.npy +0 -0
  54. acoular/tests/reference_data/BeamformerDamas.npy +0 -0
  55. acoular/tests/reference_data/BeamformerDamasPlus.npy +0 -0
  56. acoular/tests/reference_data/BeamformerEig.npy +0 -0
  57. acoular/tests/reference_data/BeamformerEigFalse1.npy +0 -0
  58. acoular/tests/reference_data/BeamformerEigFalse2.npy +0 -0
  59. acoular/tests/reference_data/BeamformerEigFalse3.npy +0 -0
  60. acoular/tests/reference_data/BeamformerEigFalse4.npy +0 -0
  61. acoular/tests/reference_data/BeamformerEigTrue1.npy +0 -0
  62. acoular/tests/reference_data/BeamformerEigTrue2.npy +0 -0
  63. acoular/tests/reference_data/BeamformerEigTrue3.npy +0 -0
  64. acoular/tests/reference_data/BeamformerEigTrue4.npy +0 -0
  65. acoular/tests/reference_data/BeamformerFunctional.npy +0 -0
  66. acoular/tests/reference_data/BeamformerGIB.npy +0 -0
  67. acoular/tests/reference_data/BeamformerGridlessOrth.npy +0 -0
  68. acoular/tests/reference_data/BeamformerMusic.npy +0 -0
  69. acoular/tests/reference_data/BeamformerOrth.npy +0 -0
  70. acoular/tests/reference_data/BeamformerSODIX.npy +0 -0
  71. acoular/tests/reference_data/BeamformerTime.npy +0 -0
  72. acoular/tests/reference_data/BeamformerTimeSq.npy +0 -0
  73. acoular/tests/reference_data/BeamformerTimeSqTraj.npy +0 -0
  74. acoular/tests/reference_data/BeamformerTimeTraj.npy +0 -0
  75. acoular/tests/reference_data/Environment.npy +0 -0
  76. acoular/tests/reference_data/Example1_numerical_values_testsum.h5 +0 -0
  77. acoular/tests/reference_data/FiltFiltOctave__.npy +0 -0
  78. acoular/tests/reference_data/FiltFiltOctave_band_100_0_fraction_Thirdoctave_.npy +0 -0
  79. acoular/tests/reference_data/FiltFreqWeight_weight_A_.npy +0 -0
  80. acoular/tests/reference_data/FiltFreqWeight_weight_C_.npy +0 -0
  81. acoular/tests/reference_data/FiltFreqWeight_weight_Z_.npy +0 -0
  82. acoular/tests/reference_data/FiltOctave__.npy +0 -0
  83. acoular/tests/reference_data/FiltOctave_band_100_0_fraction_Thirdoctave_.npy +0 -0
  84. acoular/tests/reference_data/Filter__.npy +0 -0
  85. acoular/tests/reference_data/GeneralFlowEnvironment.npy +0 -0
  86. acoular/tests/reference_data/OctaveFilterBank__.npy +0 -0
  87. acoular/tests/reference_data/OpenJet.npy +0 -0
  88. acoular/tests/reference_data/PointSource.npy +0 -0
  89. acoular/tests/reference_data/PowerSpectra_csm.npy +0 -0
  90. acoular/tests/reference_data/PowerSpectra_ev.npy +0 -0
  91. acoular/tests/reference_data/RotatingFlow.npy +0 -0
  92. acoular/tests/reference_data/SlotJet.npy +0 -0
  93. acoular/tests/reference_data/TimeAverage__.npy +0 -0
  94. acoular/tests/reference_data/TimeCumAverage__.npy +0 -0
  95. acoular/tests/reference_data/TimeExpAverage_weight_F_.npy +0 -0
  96. acoular/tests/reference_data/TimeExpAverage_weight_I_.npy +0 -0
  97. acoular/tests/reference_data/TimeExpAverage_weight_S_.npy +0 -0
  98. acoular/tests/reference_data/TimeInOut__.npy +0 -0
  99. acoular/tests/reference_data/TimePower__.npy +0 -0
  100. acoular/tests/reference_data/TimeReverse__.npy +0 -0
  101. acoular/tests/reference_data/UniformFlowEnvironment.npy +0 -0
  102. acoular/tests/reference_data/beamformer_traj_time_data.h5 +0 -0
  103. acoular/tests/run_tests.sh +0 -18
  104. acoular/tests/run_tests_osx.sh +0 -16
  105. acoular/tests/test.npy +0 -0
  106. acoular/tests/test_beamformer_results.py +0 -213
  107. acoular/tests/test_classes.py +0 -60
  108. acoular/tests/test_digest.py +0 -125
  109. acoular/tests/test_environments.py +0 -73
  110. acoular/tests/test_example1.py +0 -124
  111. acoular/tests/test_grid.py +0 -92
  112. acoular/tests/test_integrate.py +0 -102
  113. acoular/tests/test_signals.py +0 -60
  114. acoular/tests/test_sources.py +0 -65
  115. acoular/tests/test_spectra.py +0 -38
  116. acoular/tests/test_timecache.py +0 -35
  117. acoular/tests/test_tprocess.py +0 -90
  118. acoular/tests/test_traj_beamformer_results.py +0 -164
  119. acoular/tests/unsupported/SpeedComparison/OvernightTestcasesBeamformer_nMics32_nGridPoints100_nFreqs4_nTrials10.png +0 -0
  120. acoular/tests/unsupported/SpeedComparison/cythonBeamformer.pyx +0 -237
  121. acoular/tests/unsupported/SpeedComparison/mainForCython.py +0 -103
  122. acoular/tests/unsupported/SpeedComparison/mainForParallelJit.py +0 -143
  123. acoular/tests/unsupported/SpeedComparison/setupCythonOpenMP.py +0 -63
  124. acoular/tests/unsupported/SpeedComparison/sharedFunctions.py +0 -153
  125. acoular/tests/unsupported/SpeedComparison/timeOverNMics_AllImportantMethods.png +0 -0
  126. acoular/tests/unsupported/SpeedComparison/timeOverNMics_faverage.png +0 -0
  127. acoular/tests/unsupported/SpeedComparison/vglOptimierungFAverage.py +0 -204
  128. acoular/tests/unsupported/SpeedComparison/vglOptimierungGaussSeidel.py +0 -182
  129. acoular/tests/unsupported/SpeedComparison/vglOptimierungR_BEAMFULL_INVERSE.py +0 -764
  130. acoular/tests/unsupported/SpeedComparison/vglOptimierungR_BEAM_OS.py +0 -231
  131. acoular/tests/unsupported/SpeedComparison/whatsFastestWayFor_absASquared.py +0 -48
  132. acoular/tests/unsupported/functionalBeamformer.py +0 -123
  133. acoular/tests/unsupported/precisionTest.py +0 -153
  134. acoular/tests/unsupported/validationOfBeamformerFuncsPOSTAcoularIntegration.py +0 -254
  135. acoular/tests/unsupported/validationOfBeamformerFuncsPREeAcoularIntegration.py +0 -531
  136. acoular/tools.py +0 -422
  137. acoular-24.3.dist-info/RECORD +0 -148
  138. acoular-24.3.dist-info/licenses/LICENSE +0 -29
  139. {acoular-24.3.dist-info → acoular-24.5.dist-info}/licenses/AUTHORS.rst +0 -0
@@ -1,164 +0,0 @@
1
- import unittest
2
-
3
- from os.path import join
4
-
5
- import numpy as np
6
-
7
- from acoular import config
8
- config.global_caching = 'none'
9
-
10
- from acoular import WNoiseGenerator, MovingPointSource, WriteH5, Trajectory, MicGeom,\
11
- RectGrid, MaskedTimeSamples, SteeringVector, TimeAverage, BeamformerTimeSqTraj, BeamformerTimeTraj,\
12
- BeamformerCleantTraj, BeamformerCleantSqTraj, BeamformerTime, BeamformerTimeSq,\
13
- BeamformerCleant, BeamformerCleantSq
14
-
15
- # if this flag is set to True, new time data will be simulated and
16
- WRITE_NEW_REFERENCE_DATA = False
17
- # new beamformer results are generated for comparison during testing. Should always be False. Only set to
18
- # true, if it is necessary to recalculate the data, due to wanted changes of the Beamformers (or MovingPointSource).
19
-
20
- # Parameters
21
- FNAME = join('reference_data','beamformer_traj_time_data.h5')
22
- SFREQ = 6000
23
- SPEED = 10 # km/h
24
- SEED = 1
25
- D = .5
26
- SOURCE_POS = (0.0, 0.0, D)
27
- passby_dist = .5 # distance that the source is passing in front of array
28
- CONV_AMP = True
29
-
30
- # create linear mic geom
31
- MGEOM = MicGeom()
32
- N = 5
33
- L = .5
34
- MGEOM.mpos_tot = np.zeros((3, N), dtype=np.float64)
35
- win = np.sin(np.arange(N)*np.pi/(N-1))
36
- b = 0.4
37
- MGEOM.mpos_tot[0] = np.linspace(-L, L, N)*(1-b)/(win*b+1-b)
38
-
39
- # Monopole Trajectory
40
- t_passby = passby_dist/SPEED/3.6
41
- nsamples = int(t_passby*SFREQ)
42
- TRAJ = Trajectory() # source center
43
- TRAJ.points[0] = (-passby_dist/2 + SOURCE_POS[0], SOURCE_POS[1], SOURCE_POS[2])
44
- TRAJ.points[t_passby] = (+passby_dist/2, SOURCE_POS[1], SOURCE_POS[2])
45
-
46
-
47
- def create_test_time_data(nsamples):
48
- """
49
- creates test data for a single moving monopole emitting white noise
50
-
51
- Parameters
52
- ----------
53
- speed : float
54
- source velocity in m/s.
55
-
56
- Returns
57
- -------
58
- None.
59
-
60
- """
61
- n1 = WNoiseGenerator(sample_freq=SFREQ, numsamples=nsamples, seed=SEED)
62
- p1 = MovingPointSource(signal=n1, mics=MGEOM,
63
- trajectory=TRAJ, conv_amp=CONV_AMP)
64
- wh5 = WriteH5(source=p1, name=FNAME)
65
- print(50*"#")
66
- print(f"create {FNAME} ...")
67
- print(f"num samples: {nsamples}, pass-by time: {t_passby}s")
68
- print(50*"#")
69
- wh5.save()
70
-
71
- def get_beamformer_traj_result(Beamformer, num=32):
72
- """
73
- returns the result for a given Beamformer class
74
-
75
- Parameters
76
- ----------
77
- Beamformer : cls
78
- trajectory beamformer.
79
- num : int, optional
80
- number of samples to return. The default is 32.
81
-
82
- Returns
83
- -------
84
- array
85
- first block returned by the trajectory beamformers result() function.
86
-
87
- """
88
- ## with moving grid
89
- ts = MaskedTimeSamples(name=FNAME)
90
- gMoving = RectGrid(x_min=-.1, x_max=.1, y_min=0, y_max=0, z=0,
91
- increment=.1)
92
- stMoving = SteeringVector(grid=gMoving, mics=MGEOM)
93
- bt = Beamformer(source=ts, trajectory=TRAJ, steer=stMoving)
94
- if hasattr(bt,'n_iter'):
95
- bt.n_iter = 2
96
- return next(bt.result(num)).astype(np.float32)
97
-
98
- def get_beamformer_time_result(Beamformer, num=32):
99
- """
100
- returns the result for a given time Beamformer class
101
-
102
- Parameters
103
- ----------
104
- Beamformer : cls
105
- time beamformer.
106
- num : int, optional
107
- number of samples to return. The default is 32.
108
-
109
- Returns
110
- -------
111
- array
112
- first block returned by the time beamformers result() function.
113
-
114
- """
115
- ## with moving grid
116
- ts = MaskedTimeSamples(name=FNAME)
117
- gfixed = RectGrid(x_min=-.1, x_max=.1, y_min=0, y_max=0, z=D,
118
- increment=.1)
119
- stfixed = SteeringVector(grid=gfixed, mics=MGEOM)
120
- bt = Beamformer(source=ts,steer=stfixed)
121
- if hasattr(bt,'n_iter'):
122
- bt.n_iter = 2
123
- return next(bt.result(num)).astype(np.float32)
124
-
125
- class BeamformerTimeTest(unittest.TestCase):
126
- """
127
- A simple test case that varifies that the results of trajectory beamformers
128
- and fixed focus beamformers in time domain are not changing across different
129
- versions of code.
130
- """
131
-
132
- traj_beamformers = [BeamformerTimeTraj, BeamformerTimeSqTraj,
133
- BeamformerCleantTraj, BeamformerCleantSqTraj]
134
-
135
- time_beamformers = [BeamformerTime, BeamformerTimeSq,
136
- BeamformerCleant, BeamformerCleantSq]
137
-
138
- def test_beamformer_traj_result(self):
139
- """compare results of trajectory beamformers against previous
140
- results from .h5 file"""
141
- for beamformer in self.traj_beamformers:
142
- with self.subTest(beamformer.__name__):
143
- name = join('reference_data',f'{beamformer.__name__}.npy')
144
- actual_data = get_beamformer_traj_result(beamformer)
145
- if WRITE_NEW_REFERENCE_DATA:
146
- np.save(name,actual_data)
147
- ref_data = np.load(name)
148
- np.testing.assert_allclose(actual_data, ref_data, rtol=5e-5, atol=5e-6)
149
-
150
- def test_beamformer_time_result(self):
151
- """compare results of time beamformers with fixed focus against previous
152
- results from .h5 file"""
153
- for beamformer in self.time_beamformers:
154
- with self.subTest(beamformer.__name__):
155
- name = join('reference_data',f'{beamformer.__name__}.npy')
156
- actual_data = get_beamformer_time_result(beamformer)
157
- if WRITE_NEW_REFERENCE_DATA:
158
- np.save(name,actual_data)
159
- ref_data = np.load(name)
160
- np.testing.assert_allclose(actual_data, ref_data, rtol=5e-5, atol=5e-6)
161
-
162
-
163
- if __name__ == '__main__':
164
- unittest.main()
@@ -1,237 +0,0 @@
1
- import numpy as np
2
- cimport numpy as np
3
-
4
- from libc.math cimport exp as c_exp
5
- from libc.math cimport sin as c_sin
6
- from libc.math cimport cos as c_cos
7
-
8
- from cython.parallel import prange, parallel
9
- from cython import boundscheck, wraparound, nonecheck, cdivision
10
- from cpython cimport array
11
- import array
12
-
13
- #ZUM PARALLELISIEREN MIT CYTHON
14
- #1. Inplace Operatoren ("+=", etc) kommen hier eine besondere Bedeutung zu.
15
- #2. Bei Cython-Version 0.25.2 gibt es einen Bug beim Zuweisen von numpy-Arrays:
16
- # Wenn ein Vektor zuerst vollgeschrieben und im späteren Verlauf der Methode
17
- # wieder ausgelesen wird, wurden nicht die korrekten Werte ausgelesen.
18
- # Wurde der Vektor/Matrix allerdings nur einmalig geschrieben und dann returned,
19
- # war alles okay. Ist im Code unten nochmal am Bsp. "beamformerCython" beschrieben.
20
- # Dieses Problem tritt nur auf, falls der Code über prange parallelisiert wird.
21
- # Außerdem tritt der Fehler nicht immer auf. Liegt vllt an unausgereifter Ausnutzung
22
- # der gesharedten Caches.
23
- #3. Welche Variablen Thread-private und welche geshared werden sollen, entscheidet
24
- # Cython selbst.
25
- #4. Beim Beamformer (s.u.) hat das parallelisieren mit 'prange' zu erheblichen Einbußen in
26
- # der Laufzeit geführt (ca 5x LANGSAMER). Es gibt allerdings einfache BSPs
27
- # ("c_arrayOpenMP", "c_array", s.u.), bei denen mit gleichen Compiler-Optionen
28
- # wie beim Beamformer durch die Parallelisierung mit 'prange' erhebliche
29
- # Laufzeitverbesserungen erreicht werden.
30
- #5. Es muss ein setup-File mit den Kompilieroptionen erstellt werden. In diesem
31
- # Fall ist dies "setupCythonOpenMP.py". Danach wird über die Konsole mit dem
32
- # Befehl "python setupCythonOpenMP.py build_ext --inplace" kompiliert.
33
-
34
-
35
-
36
-
37
- #==============================================================================
38
- # # Das Ganze wird fuer effizientes indexing gebraucht...
39
- DTYPEComplex = np.complex128
40
- DTYPEReal = np.float
41
- ctypedef np.complex128_t DTYPEComplex_t
42
- ctypedef np.float_t DTYPEReal_t
43
- #==============================================================================
44
-
45
- # Die Dekoratoren sollen nochmals Schnelligkeit bringen.
46
- @nonecheck(False)
47
- @boundscheck(False)
48
- @wraparound(False)
49
- @cdivision(True)
50
- def beamformerCython(np.ndarray[DTYPEComplex_t, ndim=3] csm, np.ndarray[DTYPEReal_t] r0, np.ndarray[DTYPEReal_t, ndim=2] rm, np.ndarray[DTYPEComplex_t] kj):
51
- #def beamformerCython(complex[:,:,:] csm, double[:] r0, double[:,:] rm, complex[:] kj): # Standard Methodenkopf (laut Doku etwas langsamer)
52
- """ Dies ist eine Implementierung der Methode 'r_beamfull_inverse' der
53
- mit scipy.weave erzeugten 'beamformer.so'. Benutzt Parallelisierung via
54
- cythons 'prange' und Kompilierung mit OpenMP.
55
- """
56
- cdef int nFreqs = csm.shape[0]
57
- cdef int nGridPoints = len(r0)
58
- cdef int nMics = csm.shape[1]
59
-
60
- cdef double[:,:] beamformOutput = np.zeros([nFreqs, nGridPoints], dtype=DTYPEReal)
61
- cdef complex[:] steerVec = np.zeros([nMics], dtype=DTYPEComplex)
62
-
63
- cdef int cntFreqs, cntGrid, cntMics, cntMics2, cntMics1
64
- cdef double r01, kjj, rm1, temp1, rs, temp3
65
- cdef complex temp2
66
- # cdef float temp3 # Das hat erstmal nicht auf Anhieb geklappt, deshalb ist temp3 noch double
67
-
68
- for cntFreqs in range(nFreqs):
69
- kjj = kj[cntFreqs].imag
70
-
71
-
72
-
73
-
74
-
75
- with nogil, parallel():
76
-
77
-
78
- # Mit Chef drüber reden.
79
-
80
-
81
-
82
-
83
- for cntGrid in prange(nGridPoints, schedule='static'): # Parallelisierung
84
- r01 = r0[cntGrid]
85
- rs = r01 ** 2
86
- temp1 = 0.0
87
- for cntFreqs in range(nFreqs):
88
- kjj = kj[cntFreqs].imag
89
- for cntGrid in range(nGridPoints):
90
- rs = 0
91
- r01 = r0[cntGrid]
92
- for cntMics in range(nMics):
93
- rm1 = rm[cntGrid, cntMics]
94
- rs += 1.0 / (rm1 ** 2)
95
- temp3 = (kjj * (rm1 - r01))
96
- steerVec[cntMics] = (c_cos(temp3) - 1j * c_sin(temp3)) * rm1
97
- rs = r01 ** 2
98
-
99
- temp1 = 0.0
100
- for cntMics in range(nMics):
101
- temp2 = 0.0
102
- for cntMics2 in range(cntMics):
103
- temp2 = temp2 + csm[cntFreqs, cntMics2, cntMics] * steerVec[cntMics2] # Falls nicht mit prange gearbeitet wird, kann man "+= etc" wie sonst benutzen
104
- temp1 = temp1 + 2 * (temp2 * steerVec[cntMics].conjugate()).real
105
- temp1 = temp1 + (csm[cntFreqs, cntMics, cntMics] * (steerVec[cntMics]).conjugate() * steerVec[cntMics]).real
106
- beamformOutput[cntFreqs, cntGrid] = (temp1 / rs)
107
- return beamformOutput
108
-
109
- @boundscheck(False)
110
- @wraparound(False)
111
- @nonecheck(False)
112
- @cdivision(True)
113
- def beamformerCythonNOTparallel(np.ndarray[DTYPEComplex_t, ndim=3] csm, np.ndarray[DTYPEReal_t] r0, np.ndarray[DTYPEReal_t, ndim=2] rm, np.ndarray[DTYPEComplex_t] kj):
114
- """ Dies ist eine Implementierung der Methode 'r_beamfull_inverse' der
115
- mit scipy.weave erzeugten 'beamformer.so', OHNE Parallelisierung.
116
- """
117
- cdef int nFreqs = csm.shape[0]
118
- cdef int nGridPoints = len(r0)
119
- cdef int nMics = csm.shape[1]
120
-
121
- cdef double[:,:] beamformOutput = np.zeros([nFreqs, nGridPoints], dtype=DTYPEReal)
122
- cdef complex[:] steerVec = np.zeros([nMics], dtype=DTYPEComplex)
123
-
124
- cdef int cntFreqs, cntGrid, cntMics, cntMics2
125
- cdef double rs, r01, kjj, rm1, temp1, temp3
126
- cdef complex temp2
127
- # cdef float temp3
128
-
129
- for cntFreqs in range(nFreqs):
130
- kjj = kj[cntFreqs].imag
131
- for cntGrid in range(nGridPoints):
132
- rs = 0
133
- r01 = r0[cntGrid]
134
- for cntMics in range(nMics):
135
- rm1 = rm[cntGrid, cntMics]
136
- rs += 1.0 / (rm1 ** 2)
137
- temp3 = (kjj * (rm1 - r01))
138
- steerVec[cntMics] = (c_cos(temp3) - 1j * c_sin(temp3)) * rm1
139
- rs = r01 ** 2
140
-
141
- temp1 = 0.0
142
- for cntMics in range(nMics):
143
- temp2 = 0.0
144
- for cntMics2 in range(cntMics):
145
- temp2 += csm[cntFreqs, cntMics2, cntMics] * steerVec[cntMics2] # Falls nicht mit prange gearbeitet wird, kann man "+= etc" wie sonst benutzen
146
- temp1 += 2 * (temp2 * steerVec[cntMics].conjugate()).real
147
- temp1 += (csm[cntFreqs, cntMics, cntMics] * (steerVec[cntMics]).conjugate() * steerVec[cntMics]).real
148
- beamformOutput[cntFreqs, cntGrid] = (temp1 / rs)
149
- return beamformOutput
150
-
151
- @nonecheck(False)
152
- @boundscheck(False)
153
- @wraparound(False)
154
- @cdivision(True)
155
- def beamformerCythonCorrectButSlow(np.ndarray[DTYPEComplex_t, ndim=3] csm, np.ndarray[DTYPEReal_t] r0, np.ndarray[DTYPEReal_t, ndim=2] rm, np.ndarray[DTYPEComplex_t] kj):
156
- #def beamformerCython(complex[:,:,:] csm, double[:] r0, double[:,:] rm, complex[:] kj): # Standard Methodenkopf (laut Doku etwas langsamer)
157
- """ Dies ist eine Implementierung der Methode 'r_beamfull_inverse' der
158
- mit scipy.weave erzeugten 'beamformer.so'. Benutzt Parallelisierung via
159
- cythons 'prange' und Kompilierung mit OpenMP.
160
- """
161
- cdef int nFreqs = csm.shape[0]
162
- cdef int nGridPoints = len(r0)
163
- cdef int nMics = csm.shape[1]
164
-
165
- cdef double[:,:] beamformOutput = np.zeros([nFreqs, nGridPoints], dtype=DTYPEReal)
166
-
167
- cdef int cntFreqs, cntGrid, cntMics, cntMics2, cntMics1
168
- cdef double r01, kjj, rm1, temp1, rs, temp3
169
- cdef complex temp2, steerVec1, steerVec
170
- # cdef float temp3
171
-
172
- for cntFreqs in range(nFreqs):
173
- kjj = kj[cntFreqs].imag
174
- for cntGrid in prange(nGridPoints, nogil=True, schedule='static'): # Parallelisierung
175
- r01 = r0[cntGrid]
176
- rs = r01 ** 2
177
-
178
- # Im ursprünglichen Code wurde hier erstmal in einer Schleife
179
- # ueber die Mics der Steering-Vektor erstellt und später verarbeitet.
180
- # Cython verhaut aber beim späteren Auslesen dieses Vektors, falls
181
- # mit prange parallelisiert wird (siehe 2. im Kommentar ganz oben).
182
- # Deshalb wurde hier der Code ein wenig geändert (Wirkung bleibt aber erhalten,
183
- # allerdings werdfen redundante Operationen ausgeführt -->langsamer)
184
- # Siehe Methode "beamformerCythonNOTparallel" für den ursprünglichen Code.
185
-
186
- temp1 = 0.0
187
- for cntMics in range(nMics):
188
- temp2 = 0.0
189
- rm1 = rm[cntGrid, cntMics]
190
- temp3 = (kjj * (rm1 - r01))
191
- steerVec = (c_cos(temp3) - 1j * c_sin(temp3)) * rm1
192
-
193
- for cntMics2 in range(cntMics):
194
- rm1 = rm[cntGrid, cntMics2]
195
- temp3 = (kjj * (rm1 - r01))
196
- steerVec1 = (c_cos(temp3) - 1j * c_sin(temp3)) * rm1
197
- temp2 = temp2 + csm[cntFreqs, cntMics2, cntMics] * steerVec1
198
- temp1 = temp1 + 2 * (temp2 * steerVec.conjugate()).real
199
- temp1 = temp1 + (csm[cntFreqs, cntMics, cntMics] * steerVec.conjugate() * steerVec).real
200
- beamformOutput[cntFreqs, cntGrid] = (temp1 / rs) # Hier gibt es keine Schwierigkeiten bzgl des Stichpkts 2. von oben. Nur falls "beamformOutput" nochmal in derselben Methode ausgelesen werden sollte.
201
- return beamformOutput
202
-
203
-
204
- #==============================================================================
205
- # BSP, FÜR DIE DIE PARALLELISIERUNG MIT PRANGE LAUFZEITVERBESSERUNGEN BRINGT:
206
- #---------------------------------------------------------------------------
207
- #
208
- # Die nachfolgenden 2 Fkt. machen das gleiche. Allerdings ist "c_arrayOpenMP" mit 'prange' parallelisiert.
209
- # Macht man von ausserhalb einen Laufzeitvergleich, ist zu erkennen, dass das
210
- # Parallelisieren hier tatsächlich was bringt (bei mir ungefähr 2x schneller).
211
- @boundscheck(False)
212
- @wraparound(False)
213
- @nonecheck(False)
214
- def c_array(double[:] X):
215
- cdef int N = X.shape[0]
216
- cdef double[:] Y = np.zeros(N)
217
- cdef int i
218
- for i in range(N): # NICHT parallelisiert
219
- if X[i] > 0.5:
220
- Y[i] = c_exp(X[i])
221
- else:
222
- Y[i] = 0
223
- return Y
224
-
225
- @boundscheck(False)
226
- @wraparound(False)
227
- @nonecheck(False)
228
- def c_arrayOpenMP(double[:] X):
229
- cdef int N = X.shape[0]
230
- cdef double[:] Y = np.zeros(N)
231
- cdef int i
232
- for i in prange(N, nogil=True): # parallelisiert
233
- if X[i] > 0.5:
234
- Y[i] = c_exp(X[i])
235
- else:
236
- Y[i] = 0
237
- return Y
@@ -1,103 +0,0 @@
1
- #!/usr/bin/env python2
2
- # -*- coding: utf-8 -*-
3
- """
4
- Created on Thu Jul 6 16:16:03 2017
5
-
6
- @author: tomgensch
7
- """
8
- #import os
9
- #print(os.path.dirname(os.path.realpath(__file__)))
10
-
11
- import numpy as np
12
- from cythonBeamformer import beamformerCython, beamformerCythonNOTparallel
13
-
14
- nMics = 32
15
- nGridPoints = 100
16
- nFreqs = 10
17
-
18
- csm = np.random.rand(nFreqs, nMics, nMics) + 1j*np.random.rand(nFreqs, nMics, nMics)
19
- for cntFreqs in range(nFreqs):
20
- csm[cntFreqs, :, :] += csm[cntFreqs, :, :].T.conj() # zu Hermitischer Matrix machen
21
- r0 = np.random.rand(nGridPoints) #abstand aufpunkte-arraymittelpunkt
22
- rm = np.random.rand(nGridPoints, nMics) #abstand aufpunkte-arraymikrofone
23
- kj = np.zeros(nFreqs) + 1j*np.random.rand(nFreqs) #
24
-
25
-
26
- #csm = np.ones((nFreqs, nMics, nMics), 'D')
27
- #r0 = np.ones(nGridPoints) * .2
28
- #rm = np.array([[.2, .3]])#rm = np.ones((nGridPoints, nMics)) * .24
29
- #kj = np.zeros(nFreqs) + 1j
30
-
31
-
32
- print('Sequentiel')
33
- outputWithoutMP = beamformerCythonNOTparallel(csm, r0, rm, kj)
34
-
35
- print('Parallel')
36
- outputMP = beamformerCython(csm, r0, rm, kj)
37
-
38
- outputMit = np.array(outputMP)
39
- outputOhne = np.array(outputWithoutMP)
40
-
41
-
42
-
43
-
44
- #==============================================================================
45
- # Bei Intel gibt es mit dem setuo-file aus der Doku keine probleme.
46
- # Die differenz zwischen den methoden und der referenz ist dann 0 (also wirklich 0, nicht e-12)
47
- # Allerdings ist parallel viel lamngsamer!
48
- #==============================================================================
49
-
50
-
51
-
52
-
53
-
54
- #e1Mit = np.array(e1MP)
55
- #e1Ohne = np.array(e1OhneMP)
56
-
57
-
58
- ## Referenz
59
- beamformOutput = np.zeros((nFreqs, nGridPoints), np.float64)
60
- e1 = np.zeros((nMics), np.complex128)
61
-
62
- for cntFreqs in xrange(nFreqs): # laeuft z.Z. nur einmal durch
63
- kjj = kj[cntFreqs].imag ### könnte man vielleicht reinnehmen um unten nicht immer den realteilnehmen zu müssen
64
- for cntGrid in xrange(nGridPoints):
65
- rs = 0
66
- r01 = r0[cntGrid]
67
-
68
- # Erzeugen der Steering-Vectoren
69
- for cntMics in xrange(nMics):
70
- rm1 = rm[cntGrid, cntMics]
71
- rs += 1.0 / (rm1**2)
72
- temp3 = (kjj * (rm1 - r01)) # der Float bewirkt die Abweichung vom Originalergebnis um ca 10^-8
73
- e1[cntMics] = (np.cos(temp3) - 1j * np.sin(temp3)) * rm1
74
- rs = r01 ** 2
75
-
76
- # Berechnen der Matrix multiplikation
77
- temp1 = 0.0
78
- for cntMics in xrange(nMics):
79
- temp2 = 0.0
80
- for cntMics2 in xrange(cntMics):
81
- temp2 += csm[cntFreqs, cntMics2, cntMics] * e1[cntMics2] # nicht ganz sicher ob richtig
82
- temp1 += 2 * (temp2 * e1[cntMics].conjugate()).real
83
- temp1 += (csm[cntFreqs, cntMics, cntMics] * np.conjugate(e1[cntMics]) * e1[cntMics]).real
84
-
85
- beamformOutput[cntFreqs, cntGrid] = (temp1 / rs).real
86
-
87
-
88
- #diffE1MitOpenMP = max(abs(e1 - e1Mit))
89
- #diffE1OhneOpenMP = max(abs(e1 - e1Ohne))
90
- ##diffE1BothCythonMethods = max([abs(e1Mit[cnt] - e1Ohne[cnt]) for cnt in range(len(e1Ohne))])
91
- #diffE1BothCythonMethods = np.amax(abs(e1Mit - e1Ohne), axis=0)
92
- #diffE1BothCythonMethods = np.amax(diffE1BothCythonMethods, axis=0)
93
-
94
- diffOutputBothMethods = np.amax(abs(outputMit - outputOhne), axis=0)
95
- diffOutputBothMethods = np.amax(abs(diffOutputBothMethods), axis=0)
96
-
97
- diffOutputOpenMP = np.amax(abs(outputMit - beamformOutput), axis=0)
98
- diffOutputOpenMP = np.amax(abs(diffOutputOpenMP), axis=0)
99
-
100
- diffOutputWithoutOpenMP = np.amax(abs(outputOhne - beamformOutput), axis=0)
101
- diffOutputWithoutOpenMP = np.amax(abs(diffOutputWithoutOpenMP), axis=0)
102
-
103
- print(diffOutputBothMethods)
@@ -1,143 +0,0 @@
1
- #!/usr/bin/env python2
2
- # -*- coding: utf-8 -*-
3
- """
4
- Created on Thu Jul 20 14:06:46 2017
5
-
6
- @author: tomgensch
7
-
8
- This script was for getting to know the mechanisms of the new prange function
9
- of jit (numba version 0.34). As it turns out the automatic parallelization is
10
- as faulty as in cython (same errors).
11
- """
12
-
13
- import numpy as np
14
- from numba import njit, float64, complex128, prange
15
-
16
- nMics = 4
17
- nGridPoints = 5
18
- nFreqs = 1
19
-
20
- csm = np.random.rand(nFreqs, nMics, nMics) + 1j*np.random.rand(nFreqs, nMics, nMics)
21
- for cntFreqs in range(nFreqs):
22
- csm[cntFreqs, :, :] += csm[cntFreqs, :, :].T.conj() # zu Hermitischer Matrix machen
23
- r0 = np.random.rand(nGridPoints) #abstand aufpunkte-arraymittelpunkt
24
- rm = np.random.rand(nGridPoints, nMics) #abstand aufpunkte-arraymikrofone
25
- kj = np.zeros(nFreqs) + 1j*np.random.rand(nFreqs)
26
-
27
- @njit(float64[:,:](complex128[:,:,:], float64[:], float64[:,:], complex128[:]), parallel=True)
28
- def loops_NumbaJit_parallelSlow(csm, r0, rm, kj):
29
- nFreqs = csm.shape[0]
30
- nGridPoints = len(r0)
31
- nMics = csm.shape[1]
32
- beamformOutput = np.zeros((nFreqs, nGridPoints), np.float64)
33
-
34
- for cntFreqs in xrange(nFreqs):
35
- kjj = kj[cntFreqs].imag
36
- for cntGrid in prange(nGridPoints):
37
- r01 = r0[cntGrid]
38
- rs = r01 ** 2
39
-
40
- temp1 = 0.0
41
- for cntMics in xrange(nMics):
42
- temp2 = 0.0
43
- rm1 = rm[cntGrid, cntMics]
44
- temp3 = np.float32(kjj * (rm1 - r01))
45
- steerVec = (np.cos(temp3) - 1j * np.sin(temp3)) * rm1
46
-
47
- for cntMics2 in xrange(cntMics):
48
- rm1 = rm[cntGrid, cntMics2]
49
- temp3 = np.float32(kjj * (rm1 - r01))
50
- steerVec1 = (np.cos(temp3) - 1j * np.sin(temp3)) * rm1
51
- temp2 += csm[cntFreqs, cntMics2, cntMics] * steerVec1
52
- temp1 += 2 * (temp2 * steerVec.conjugate()).real
53
- temp1 += (csm[cntFreqs, cntMics, cntMics] * steerVec.conjugate() * steerVec).real
54
-
55
- beamformOutput[cntFreqs, cntGrid] = (temp1 / rs).real
56
- return beamformOutput
57
-
58
- @njit(float64[:,:](complex128[:,:,:], float64[:], float64[:,:], complex128[:]), parallel=True)
59
- def loops_NumbaJit_parallelFast(csm, r0, rm, kj):
60
- """ This method implements the prange over the Gridpoints, which is a direct
61
- implementation of the currently used c++ methods created with scipy.wave.
62
-
63
- Very strange: Just like with Cython, this implementation (prange over Gridpoints)
64
- produces wrong results. If one doesn't parallelize -> everything is good
65
- (just like with Cython). Maybe Cython and Numba.jit use the same interpreter
66
- to generate OpenMP-parallelizable code.
67
-
68
- BUT: If one uncomments the 'steerVec' declaration in the prange-loop over the
69
- gridpoints an error occurs. After commenting the line again and executing
70
- the script once more, THE BEAMFORMER-RESULTS ARE CORRECT (for repeated tries).
71
- Funny enough the method is now twice as slow in comparison to the
72
- 'wrong version' (before invoking the error).
73
- """
74
- # init
75
- nFreqs = csm.shape[0]
76
- nGridPoints = len(r0)
77
- nMics = csm.shape[1]
78
- beamformOutput = np.zeros((nFreqs, nGridPoints), np.float64)
79
- steerVec = np.zeros((nMics), np.complex128)
80
-
81
- for cntFreqs in xrange(nFreqs):
82
- kjj = kj[cntFreqs].imag
83
- for cntGrid in prange(nGridPoints):
84
- # steerVec = np.zeros((nMics), np.complex128) # This is the line that has to be uncommented (see this methods documentation comment)
85
- rs = 0
86
- r01 = r0[cntGrid]
87
-
88
- for cntMics in xrange(nMics):
89
- rm1 = rm[cntGrid, cntMics]
90
- rs += 1.0 / (rm1**2)
91
- temp3 = np.float32(kjj * (rm1 - r01))
92
- steerVec[cntMics] = (np.cos(temp3) - 1j * np.sin(temp3)) * rm1
93
- rs = r01 ** 2
94
-
95
- temp1 = 0.0
96
- for cntMics in xrange(nMics):
97
- temp2 = 0.0
98
- for cntMics2 in xrange(cntMics):
99
- temp2 = temp2 + csm[cntFreqs, cntMics2, cntMics] * steerVec[cntMics2]
100
- temp1 = temp1 + 2 * (temp2 * steerVec[cntMics].conjugate()).real
101
- temp1 = temp1 + (csm[cntFreqs, cntMics, cntMics] * np.conjugate(steerVec[cntMics]) * steerVec[cntMics]).real
102
-
103
- beamformOutput[cntFreqs, cntGrid] = (temp1 / rs).real
104
- return beamformOutput
105
-
106
- beamformOutputFast = loops_NumbaJit_parallelFast(csm, r0, rm, kj)
107
- beamformOutputSlow = loops_NumbaJit_parallelSlow(csm, r0, rm, kj)
108
-
109
- #%% Referenz
110
- beamformOutputRef = np.zeros((nFreqs, nGridPoints), np.float64)
111
- e1 = np.zeros((nMics), np.complex128)
112
-
113
- for cntFreqs in xrange(nFreqs):
114
- kjj = kj[cntFreqs].imag
115
- for cntGrid in xrange(nGridPoints):
116
- rs = 0
117
- r01 = r0[cntGrid]
118
-
119
- for cntMics in xrange(nMics):
120
- rm1 = rm[cntGrid, cntMics]
121
- rs += 1.0 / (rm1**2)
122
- temp3 = np.float32(kjj * (rm1 - r01))
123
- e1[cntMics] = (np.cos(temp3) - 1j * np.sin(temp3)) * rm1
124
- rs = r01 ** 2
125
-
126
- temp1 = 0.0
127
- for cntMics in xrange(nMics):
128
- temp2 = 0.0
129
- for cntMics2 in xrange(cntMics):
130
- temp2 += csm[cntFreqs, cntMics2, cntMics] * e1[cntMics2]
131
- temp1 += 2 * (temp2 * e1[cntMics].conjugate()).real
132
- temp1 += (csm[cntFreqs, cntMics, cntMics] * np.conjugate(e1[cntMics]) * e1[cntMics]).real
133
-
134
- beamformOutputRef[cntFreqs, cntGrid] = (temp1 / rs).real
135
-
136
- diffFast = np.amax(abs(beamformOutputFast - beamformOutputRef), axis=0)
137
- diffFast= np.amax(abs(diffFast), axis=0)
138
-
139
- diffSlow = np.amax(abs(beamformOutputSlow - beamformOutputRef), axis=0)
140
- diffSlow= np.amax(abs(diffSlow), axis=0)
141
-
142
- print(diffFast)
143
- print(diffSlow)