# sfs.array¶

Compute positions of various secondary source distributions.

import sfs
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = 8, 4.5  # inch
plt.rcParams['axes.grid'] = True


Functions

 as_secondary_source_distribution(arg, **kwargs) Create a SecondarySourceDistribution. circular(N, R, *[, center]) Return circular secondary source distribution parallel to the xy-plane. concatenate(*arrays) Concatenate SecondarySourceDistribution objects. cube(N, spacing, *[, center, orientation]) Return cube-shaped secondary source distribtion. edge(Nxy, dx, *[, center, orientation]) Return SSD along the xy-axis with sharp edge at the origin. linear(N, spacing, *[, center, orientation]) Return linear, equidistantly sampled secondary source distribution. linear_diff(distances, *[, center, orientation]) Return linear secondary source distribution from a list of distances. linear_random(N, min_spacing, max_spacing, *) Return randomly sampled linear array. load(file, *[, center, orientation]) Load secondary source distribution from file. planar(N, spacing, *[, center, orientation]) Return planar secondary source distribtion. rectangular(N, spacing, *[, center, orientation]) Return rectangular secondary source distribution. rounded_edge(Nxy, Nr, dx, *[, center, …]) Return SSD along the xy-axis with rounded edge at the origin. sphere_load(file, radius, *[, center]) Load spherical secondary source distribution from file. weights_midpoint(positions, *, closed) Calculate loudspeaker weights for a simply connected array.

Classes

 SecondarySourceDistribution Create new instance of SecondarySourceDistribution(x, n, a)
class sfs.array.SecondarySourceDistribution[source]

Create new instance of SecondarySourceDistribution(x, n, a)

take(indices)[source]

Return a sub-array given by indices.

sfs.array.as_secondary_source_distribution(arg, **kwargs)[source]
Parameters: arg (sequence of between 1 and 3 array_like objects) – All elements are converted to NumPy arrays. If only 1 element is given, all normal vectors are set to NaN. If only 1 or 2 elements are given, all weights are set to 1.0. **kwargs – All keyword arguments are forwarded to numpy.asarray(). SecondarySourceDistribution – A named tuple consisting of three numpy.ndarrays containing positions, normal vectors and weights.
sfs.array.linear(N, spacing, *, center=[0, 0, 0], orientation=[1, 0, 0])[source]

Return linear, equidistantly sampled secondary source distribution.

Parameters: N (int) – Number of secondary sources. spacing (float) – Distance (in metres) between secondary sources. center ((3,) array_like, optional) – Coordinates of array center. orientation ((3,) array_like, optional) – Orientation of the array. By default, the loudspeakers have their main axis pointing into positive x-direction. SecondarySourceDistribution – Positions, orientations and weights of secondary sources.

Examples

x0, n0, a0 = sfs.array.linear(16, 0.2, orientation=[0, -1, 0])
sfs.plot2d.loudspeakers(x0, n0, a0)
plt.axis('equal')
plt.xlabel('x / m')
plt.ylabel('y / m')

sfs.array.linear_diff(distances, *, center=[0, 0, 0], orientation=[1, 0, 0])[source]

Return linear secondary source distribution from a list of distances.

Parameters: distances ((N-1,) array_like) – Sequence of secondary sources distances in metres. center, orientation – See linear(). SecondarySourceDistribution – Positions, orientations and weights of secondary sources.

Examples

x0, n0, a0 = sfs.array.linear_diff(4 * [0.3] + 6 * [0.15] + 4 * [0.3],
orientation=[0, -1, 0])
sfs.plot2d.loudspeakers(x0, n0, a0)
plt.axis('equal')
plt.xlabel('x / m')
plt.ylabel('y / m')

sfs.array.linear_random(N, min_spacing, max_spacing, *, center=[0, 0, 0], orientation=[1, 0, 0], seed=None)[source]

Return randomly sampled linear array.

Parameters: N (int) – Number of secondary sources. min_spacing, max_spacing (float) – Minimal and maximal distance (in metres) between secondary sources. center, orientation – See linear(). seed ({None, int, array_like}, optional) – Random seed. See numpy.random.RandomState. SecondarySourceDistribution – Positions, orientations and weights of secondary sources.

Examples

x0, n0, a0 = sfs.array.linear_random(
N=12,
min_spacing=0.15, max_spacing=0.4,
orientation=[0, -1, 0])
sfs.plot2d.loudspeakers(x0, n0, a0)
plt.axis('equal')
plt.xlabel('x / m')
plt.ylabel('y / m')

sfs.array.circular(N, R, *, center=[0, 0, 0])[source]

Return circular secondary source distribution parallel to the xy-plane.

Parameters: N (int) – Number of secondary sources. R (float) – Radius in metres. center – See linear(). SecondarySourceDistribution – Positions, orientations and weights of secondary sources.

Examples

x0, n0, a0 = sfs.array.circular(16, 1)
sfs.plot2d.loudspeakers(x0, n0, a0, size=0.2, show_numbers=True)
plt.axis('equal')
plt.xlabel('x / m')
plt.ylabel('y / m')

sfs.array.rectangular(N, spacing, *, center=[0, 0, 0], orientation=[1, 0, 0])[source]

Return rectangular secondary source distribution.

Parameters: N (int or pair of int) – Number of secondary sources on each side of the rectangle. If a pair of numbers is given, the first one specifies the first and third segment, the second number specifies the second and fourth segment. spacing (float) – Distance (in metres) between secondary sources. center, orientation – See linear(). The orientation corresponds to the first linear segment. SecondarySourceDistribution – Positions, orientations and weights of secondary sources.

Examples

x0, n0, a0 = sfs.array.rectangular((4, 8), 0.2)
sfs.plot2d.loudspeakers(x0, n0, a0, show_numbers=True)
plt.axis('equal')
plt.xlabel('x / m')
plt.ylabel('y / m')

sfs.array.rounded_edge(Nxy, Nr, dx, *, center=[0, 0, 0], orientation=[1, 0, 0])[source]

Return SSD along the xy-axis with rounded edge at the origin.

Parameters: Nxy (int) – Number of secondary sources along x- and y-axis. Nr (int) – Number of secondary sources in rounded edge. Radius of edge is adjusted to equdistant sampling along entire array. center ((3,) array_like, optional) – Position of edge. orientation ((3,) array_like, optional) – Normal vector of array. Default orientation is along xy-axis. SecondarySourceDistribution – Positions, orientations and weights of secondary sources.

Examples

x0, n0, a0 = sfs.array.rounded_edge(8, 5, 0.2)
sfs.plot2d.loudspeakers(x0, n0, a0)
plt.axis('equal')
plt.xlabel('x / m')
plt.ylabel('y / m')

sfs.array.edge(Nxy, dx, *, center=[0, 0, 0], orientation=[1, 0, 0])[source]

Return SSD along the xy-axis with sharp edge at the origin.

Parameters: Nxy (int) – Number of secondary sources along x- and y-axis. center ((3,) array_like, optional) – Position of edge. orientation ((3,) array_like, optional) – Normal vector of array. Default orientation is along xy-axis. SecondarySourceDistribution – Positions, orientations and weights of secondary sources.

Examples

x0, n0, a0 = sfs.array.edge(8, 0.2)
sfs.plot2d.loudspeakers(x0, n0, a0)
plt.axis('equal')
plt.xlabel('x / m')
plt.ylabel('y / m')

sfs.array.planar(N, spacing, *, center=[0, 0, 0], orientation=[1, 0, 0])[source]

Return planar secondary source distribtion.

Parameters: N (int or pair of int) – Number of secondary sources along each edge. If a pair of numbers is given, the first one specifies the number on the horizontal edge, the second one specifies the number on the vertical edge. spacing (float) – Distance (in metres) between secondary sources. center, orientation – See linear(). SecondarySourceDistribution – Positions, orientations and weights of secondary sources.

Examples

x0, n0, a0 = sfs.array.planar(
(4,3), 0.5, orientation=[0, 0, 1])  # 4 sources along y, 3 sources along x
x0, n0, a0 = sfs.array.planar(
(4,3), 0.5, orientation=[1, 0, 0])  # 4 sources along y, 3 sources along z

x0, n0, a0 = sfs.array.planar(
(4,3), 0.5, orientation=[0, 1, 0])  # 4 sources along x, 3 sources along z
sfs.plot2d.loudspeakers(x0, n0, a0)  # plot the last ssd in 2D
plt.axis('equal')
plt.xlabel('x / m')
plt.ylabel('y / m')

sfs.array.cube(N, spacing, *, center=[0, 0, 0], orientation=[1, 0, 0])[source]

Return cube-shaped secondary source distribtion.

Parameters: N (int or triple of int) – Number of secondary sources along each edge. If a triple of numbers is given, the first two specify the edges like in rectangular(), the last one specifies the vertical edge. spacing (float) – Distance (in metres) between secondary sources. center, orientation – See linear(). The orientation corresponds to the first planar segment. SecondarySourceDistribution – Positions, orientations and weights of secondary sources.

Examples

x0, n0, a0 = sfs.array.cube(
N=2, spacing=0.5,
center=[0, 0, 0], orientation=[1, 0, 0])
sfs.plot2d.loudspeakers(x0, n0, a0)
plt.axis('equal')
plt.xlabel('x / m')
plt.ylabel('y / m')
plt.title('view onto xy-plane')

sfs.array.sphere_load(file, radius, *, center=[0, 0, 0])[source]

Load spherical secondary source distribution from file.

ASCII Format (see MATLAB SFS Toolbox) with 4 numbers (3 for the cartesian position vector, 1 for the integration weight) per secondary source located on the unit circle which is resized by the given radius and shifted to the given center.

Returns: SecondarySourceDistribution – Positions, orientations and weights of secondary sources.

Examples

content of example_array_6LS_3D.txt:

1 0 0 1
-1 0 0 1
0 1 0 1
0 -1 0 1
0 0 1 1
0 0 -1 1


corresponds to the 3-dimensional 6-point spherical 3-design.

x0, n0, a0 = sfs.array.sphere_load(
'../data/arrays/example_array_6LS_3D.txt',
center=[0, 0, 0])
sfs.plot2d.loudspeakers(x0, n0, a0, size=0.25)
plt.axis('equal')
plt.xlabel('x / m')
plt.ylabel('y / m')
plt.title('view onto xy-plane')

sfs.array.load(file, *, center=[0, 0, 0], orientation=[1, 0, 0])[source]

Load secondary source distribution from file.

Comma Separated Values (CSV) format with 7 values (3 for the cartesian position vector, 3 for the cartesian inward normal vector, 1 for the integration weight) per secondary source.

Returns: SecondarySourceDistribution – Positions, orientations and weights of secondary sources.

Examples

content of example_array_4LS_2D.csv:

1,0,0,-1,0,0,1
0,1,0,0,-1,0,1
-1,0,0,1,0,0,1
0,-1,0,0,1,0,1


corresponds to 4 sources at 1, j, -1, -j in the complex plane. This setup is typically used for Quadraphonic audio reproduction.

x0, n0, a0 = sfs.array.load('../data/arrays/example_array_4LS_2D.csv')
sfs.plot2d.loudspeakers(x0, n0, a0)
plt.axis('equal')
plt.xlabel('x / m')
plt.ylabel('y / m')

x0, n0, a0 = sfs.array.load(
'../data/arrays/wfs_university_rostock_2018.csv')
sfs.plot2d.loudspeakers(x0, n0, a0)
plt.axis('equal')
plt.xlabel('x / m')
plt.ylabel('y / m')
plt.title('top view of 64 channel WFS system at university of Rostock')

sfs.array.weights_midpoint(positions, *, closed)[source]

Calculate loudspeaker weights for a simply connected array.

The weights are calculated according to the midpoint rule.

Parameters: positions ((N, 3) array_like) – Sequence of secondary source positions. Note The loudspeaker positions have to be ordered along the contour. closed (bool) – True if the loudspeaker contour is closed. (N,) numpy.ndarray – Weights of secondary sources.

Examples

>>> import sfs
>>> x0, n0, a0 = sfs.array.circular(2**5, 1)
>>> a = sfs.array.weights_midpoint(x0, closed=True)
>>> max(abs(a0-a))
0.0003152601902411123

sfs.array.concatenate(*arrays)[source]

Concatenate SecondarySourceDistribution objects.

Returns: SecondarySourceDistribution – Positions, orientations and weights of the concatenated secondary sources.

Examples

ssd1 = sfs.array.edge(10, 0.2)
ssd2 = sfs.array.edge(20, 0.1, center=[2, 2, 0], orientation=[-1, 0, 0])
x0, n0, a0 = sfs.array.concatenate(ssd1, ssd2)
sfs.plot2d.loudspeakers(x0, n0, a0)
plt.axis('equal')
plt.xlabel('x / m')
plt.ylabel('y / m')