TransmissionMatrix#
The following introduces the TransmissionMatrix
class available
in pyfar.
Transmission matrices (short T-matrices) are a convenient representation of Two-ports or Quadrupoles. These can represent systems from various fields, e.g. electrical circuits, mechanical vibration, (acoustic) transmission lines.
System properties like input impedance or transfer functions can directly be
derived from a T-matrix. Furthermore, systems can be cascaded my multiplying
consecutive T-matrices simply using the @
operator:
>>> import numpy as np
>>> import pyfar as pf
>>> frequencies = (100,200,300)
>>>
>>> # T-matrix with arbitrary data
>>> A = np.ones(len(frequencies))
>>> (B,C,D) = (A+1,A+2,A+3)
>>> tmat = pf.TransmissionMatrix.from_abcd(A,B,C,D,frequencies)
>>>
>>> # T-matrix of a bypass system
>>> tmat_bypass = pf.TransmissionMatrix.create_identity(frequencies)
>>>
>>> # Cascade
>>> tmat_out = tmat @ tmat_bypass
>>> tmat_out.freq == tmat.freq
Classes:
|
Class representing a transmission matrix. |
- class pyfar.classes.transmission_matrix.TransmissionMatrix(data, frequencies, comment='')[source]#
Class representing a transmission matrix.
This implementation is based on a paper by Lampton [1] and uses the ABCD- representation. A single T-matrix is a (2x2)-matrix of the form:
\[\begin{split}T = \begin{bmatrix} A & B \\ C & D \end{bmatrix}\end{split}\]This class is derived from
FrequencyData
, representing a frequency-dependent matrix of a multi-dimensional form In the easiest case, each matrix entry (A,B,C,D) is a single-channel FrequencyData object (i.e. a vector depending on frequency). However, additional dimensions can be used to represent additional variables (e.g. multiple layouts of an electrical circuit).Notes
This class is derived from
FrequencyData
but has a special constraint: The underlying frequency domain data must match a shape like (…, 2, 2, N). The last axis refers to the frequency, and the two axes before to the ABCD-Matrix (which is a 2x2 matrix), so the resulting cshape is (…,2,2).Another point is the numerical handling when deriving input/output impedance or transfer functions (see
input_impedance
,output_impedance
,transfer_function
): In the respective equations, the load impedance Zl is usually multiplied. However, Zl is applied in the form of 1/Zl (as admittance) for Zl = inf to avoid numerical problems. There are additional cases where certain entries of the T-matrix being zero might still lead to the main denominator becoming zero. For these cases, the denominator is set to eps.References
Attributes:
A entry of the transmission matrix.
B entry of the transmission matrix.
C entry of the transmission matrix.
D entry of the transmission matrix.
Shorthand for Signal.transpose().
The indices of the channel axes referring to the transmission matrix, namely (-2, -1)
The channel shape of the transmission matrix entries (A, B, C, D)
Return channel dimension.
Get comment.
Return channel shape.
The domain the data is stored in.
Return or set the data in the frequency domain.
Frequencies of the discrete signal spectrum.
Number of frequency bins.
Methods:
copy
()Return a copy of the audio object.
create_gyrator
(transducer_constant)Creates a transmission matrix representing a gyrator.
create_identity
([frequencies])Creates an object with identity matrix entries (bypass).
create_series_impedance
(impedance)Creates a transmission matrix representing a series impedance.
create_shunt_admittance
(admittance)Creates a transmission matrix representing a shunt admittance (parallel connection).
create_transformer
(transducer_constant)Creates a transmission matrix representing a transformer.
find_nearest_frequency
(value)Return the index that is closest to the query frequency.
flatten
()Return flattened copy of the audio object.
from_abcd
(A, B, C, D[, frequencies])Create a TransmissionMatrix object from A-, B-, C-, D-data, and frequencies.
from_tmatrix
(data, frequencies[, comment])Create TransmissionMatrix using data in T-matrix shape and frequencies.
input_impedance
(Zl)Calculates the input impedance given the load impedance Zl at the output.
Returns true if ABCD-entries have more than one channel and are therefore indexable.
output_impedance
(Zl)Calculates the output impedance given the load impedance Zl at the input.
reshape
(newshape)Return reshaped copy of the audio object.
transfer_function
(quantity_indices, Zl)Returns the transfer function (output/input) for specified quantities and a given load impedance.
transpose
(*axes)Transpose time/frequency data and return copy of the audio object.
- property A: FrequencyData#
A entry of the transmission matrix.
- property B: FrequencyData#
B entry of the transmission matrix.
- property C: FrequencyData#
C entry of the transmission matrix.
- property D: FrequencyData#
D entry of the transmission matrix.
- property T#
Shorthand for Signal.transpose().
- property abcd_caxes#
The indices of the channel axes referring to the transmission matrix, namely (-2, -1)
- property abcd_cshape#
The channel shape of the transmission matrix entries (A, B, C, D)
This is the same as ‘cshape’ without the last two elements. As an exception, a matrix with cshape (2,2) will return (1,) as abcd_cshape.
- property cdim#
Return channel dimension.
The channel dimension (cdim) gives the number of dimensions of the audio data excluding the last dimension, which is n_samples for time domain objects and n_bins for frequency domain objects. Therefore it is equivalent to the length of the channel shape (cshape) (e.g.
self.cshape = (2, 3)
;self.cdim = 2
).
- property comment#
Get comment.
- copy()#
Return a copy of the audio object.
- static create_gyrator(transducer_constant: complex | FrequencyData) ndarray | TransmissionMatrix [source]#
Creates a transmission matrix representing a gyrator.
The T-matrix is defined by a transducer constant (\(M\)), see Equation (2-14) in Table I of Reference [1]:
\[\begin{split}T = \begin{bmatrix} 0 & M \\ 1/M & 0 \end{bmatrix}\end{split}\]\(M\) connects the first input and second output quantity (e.g., \(U_\mathrm{out} = I_\mathrm{in} \cdot M\)). A respective system with load \(Z_L\) has the input impedance \(Z_\mathrm{in} = M^2 / Z_L\).
- Parameters:
transducer_constant (scalar | FrequencyData) – The transducer constant \(M\). If a scalar is given, i.e. a frequency-independent transformer matrix is requested, the return value will be a 2x2 np.ndarray instead.
- Returns:
tmat – A the transmission matrix representing the gyrator and can be cascaded with TransmissionMatrix objects. If a scalar was used as input a frequency-independent matrix is returned, namely an np.ndarray of shape (2,2).
- Return type:
np.ndarray | TransmissionMatrix
- static create_identity(frequencies=None)[source]#
Creates an object with identity matrix entries (bypass).
See Equation (2-7) in Table I of Reference [1]:
\[\begin{split}T = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix}\end{split}\]- Parameters:
frequencies (None | array_like, optional) – The frequency sampling points in Hz. The default is None which will result in this function to return an np.ndarray instead of an TransmissionMatrix object.
- Returns:
tmat – If frequencies are specified, a TransmissionMatrix object that contains one 2x2 identity matrix per bin is returned. Otherwise, this returns a 2x2 np.ndarray.
- Return type:
np.ndarray | TransmissionMatrix
- static create_series_impedance(impedance: complex | FrequencyData) ndarray | TransmissionMatrix [source]#
Creates a transmission matrix representing a series impedance.
This means the impedance is connected in series with a potential load impedance. See Equation (2-8) in Table I of Reference [1]:
\[\begin{split}T = \begin{bmatrix} 1 & Z \\ 0 & 1 \end{bmatrix}\end{split}\]- Parameters:
impedance (scalar | FrequencyData) – The impedance data of the series impedance.
- Returns:
tmat – A transmission matrix representing the series connection and can be cascaded with TransmissionMatrix objects. If a scalar was used as input a frequency-independent matrix is returned, namely an np.ndarray of shape (2,2).
- Return type:
np.ndarray | TransmissionMatrix
- static create_shunt_admittance(admittance: complex | FrequencyData) ndarray | TransmissionMatrix [source]#
Creates a transmission matrix representing a shunt admittance (parallel connection).
In this case, the impedance (= 1 / admittance) is connected in parallel with a potential load impedance. See Equation (2-9) in Table I of Reference [1]:
\[\begin{split}T = \begin{bmatrix} 1 & 0 \\ Y & 1 \end{bmatrix}\end{split}\]- Parameters:
admittance (scalar | FrequencyData) – The admittance data of the element connected in parallel.
- Returns:
tmat – A transmission matrix representing a parallel connection and can be cascaded with TransmissionMatrix objects. If a scalar was used as input a frequency-independent matrix is returned, namely an np.ndarray of shape (2,2).
- Return type:
np.ndarray | TransmissionMatrix
- static create_transformer(transducer_constant: float | int | FrequencyData) ndarray | TransmissionMatrix [source]#
Creates a transmission matrix representing a transformer.
See Equation (2-12) in Table I of Reference [1]:
\[\begin{split}T = \begin{bmatrix} N & 0 \\ 0 & 1/N \end{bmatrix}\end{split}\]- Parameters:
transducer_constant (scalar | FrequencyData) – The transmission ratio with respect to voltage-like quantity, i.e. \(N=U_\mathrm{out}/U_\mathrm{in}\). If a scalar is given, i.e. a frequency-independent transformer matrix is requested, the return value will be a 2x2 np.ndarray instead.
- Returns:
tmat – A transmission matrix representing the transformer and can be cascaded with TransmissionMatrix objects. If a scalar was used as input a frequency-independent matrix is returned, namely an np.ndarray of shape (2,2).
- Return type:
np.ndarray | TransmissionMatrix
- property cshape#
Return channel shape.
The channel shape gives the shape of the audio data excluding the last dimension, which is n_samples for time domain objects and n_bins for frequency domain objects.
- property domain#
The domain the data is stored in.
- find_nearest_frequency(value)#
Return the index that is closest to the query frequency.
- Parameters:
value (float, array-like) – The frequencies for which the indices are to be returned
- Returns:
indices – The index for the given frequency. If the input was an array like, a numpy array of indices is returned.
- Return type:
int, array-like
- flatten()#
Return flattened copy of the audio object.
- Returns:
flat – Flattened copy of audio object with
flat.cshape = np.prod(audio.cshape)
- Return type:
Notes
The number of samples and frequency bins always remains the same, e.g., an audio object of
cshape=(4,3)
andn_samples=512
will havecshape=(12, )
andn_samples=512
after flattening.
- property freq#
Return or set the data in the frequency domain.
- property frequencies#
Frequencies of the discrete signal spectrum.
- classmethod from_abcd(A, B, C, D, frequencies=None)[source]#
Create a TransmissionMatrix object from A-, B-, C-, D-data, and frequencies.
- Parameters:
A (FrequencyData, array_like, double) – Raw data for the matrix entries A. The data need to match the B, C and D entry or be broadcastable into one
shape
.B (FrequencyData, array_like, double) – See A.
C (FrequencyData, array_like, double) – See A.
D (FrequencyData, array_like, double) – See A.
frequencies (array, double, None) – Frequencies of the data in Hz. This is optional if using the FrequencyData type for A, B, C, D.
Examples
>>> import numpy as np >>> import pyfar as pf >>> frequencies = (100,200,300)
>>> # From np.array >>> A = np.ones(len(frequencies)) >>> (B,C,D) = (A+1, A+2, A+3) >>> tmat = pf.TransmissionMatrix.from_abcd(A,B,C,D, frequencies) >>> tmat
>>> # From FrequencyData objects >>> A = pf.FrequencyData( A, frequencies ) >>> (B,C,D) = (A+1, A+2, A+3) >>> tmat = pf.TransmissionMatrix.from_abcd(A,B,C,D) >>> tmat
>>> # Data with higher abcd dimension >>> A = np.ones( (3, 4, len(frequencies)) ) >>> (B,C,D) = (A+1, A+2, A+3) >>> tmat = pf.TransmissionMatrix.from_abcd(A,B,C,D, frequencies) >>> tmat
- classmethod from_tmatrix(data, frequencies, comment='')[source]#
Create TransmissionMatrix using data in T-matrix shape and frequencies.
For using individual objects for A, B, C, D matrix entries, see
from_abcd
.- Parameters:
data (array_like, double) – Raw data in the frequency domain. In contrast to the
FrequencyData
class, data must have a shape of the form (…, 2, 2, N), e.g. (2, 2, 1024) or (3, 2, 2, 1024). In those examples 1024 refers to the number of frequency bins and the two dimensions before that to the (2x2) ABCD matrices. Supported data types areint
,float
orcomplex
, whereint
is converted tofloat
.frequencies (array_like, double) – Frequencies of the data in Hz. The number of frequencies must match the size of the last dimension of data.
comment (str, optional) – A comment related to the data. The default is
""
, which initializes an empty string.
Examples
>>> import pyfar as pf >>> frequencies = (100,200,300) >>> data = np.ones( (2, 2, len(frequencies)) ) >>> tmat = pf.TransmissionMatrix.from_tmatrix(data, frequencies)
>>> data = np.ones( (3, 2, 2, len(frequencies)) ) >>> tmat = pf.TransmissionMatrix.from_tmatrix(data, frequencies)
- input_impedance(Zl: complex | FrequencyData) FrequencyData [source]#
Calculates the input impedance given the load impedance Zl at the output.
Two-port representation:
o---xxxxxxxxx---o x x | Zin--> x x Zl x x | o---xxxxxxxxx---o
See Equation (2-6) in Reference [1]: \(Z_\mathrm{in} = \frac{AZ_L + B}{CZ_L + D}\)
- Parameters:
Zl (scalar | FrequencyData) – The load impedance data as scalar or FrequencyData. In latter case, the shape must match the entries of the T-matrix, i.e. shape(tmat.A.freq) == shape(Zl.freq), or must be broadcastable.
- Returns:
Zout – A FrequencyData object with the resulting output impedance. The cshape is identical to the entries of the T-matrix, i.e. tmat.A.cshape == Zout.cshape.
- Return type:
Example
>>> import numpy as np >>> import pyfar as pf >>> >>> # Frequency-dependent load impedance >>> frequencies = (100,200,300) >>> load_impedance = pf.FrequencyData((0, 1, np.inf), frequencies) >>> >>> # T-Matrix for frequency-independent series impedance R = 1 Ohm >>> R = pf.FrequencyData((1,1,1), frequencies) >>> tmat = pf.TransmissionMatrix.create_series_impedance(R) >>> >>> # Expected result: (1+0, 1+1, 1+inf) = (1, 2, inf) >>> # Note, that due to numerical limitations infinite load will >>> # result in Zin > 1e15. >>> Zin = tmat.input_impedance(load_impedance) >>> Zin.freq
- is_indexable() bool [source]#
Returns true if ABCD-entries have more than one channel and are therefore indexable.
- property n_bins#
Number of frequency bins.
- output_impedance(Zl: complex | FrequencyData) FrequencyData [source]#
Calculates the output impedance given the load impedance Zl at the input.
Two-port representation:
o---xxxxxxxxx---o | x x Zl x x <--Zout | x x o---xxxxxxxxx---o
See Equation (2-6) in Reference [1]: \(Z_\mathrm{out} = \frac{DZ_L + B}{CZ_L + A}\)
For a code example, see
input_impedance
and exchange respective method call with output_impedance.- Parameters:
Zl (scalar | FrequencyData) – The load impedance data as scalar or FrequencyData. In latter case, the shape must match the entries of the T-matrix, i.e. shape(tmat.A.freq) == shape(Zl.freq), or must be broadcastable.
- Returns:
Zout – A FrequencyData object with the resulting output impedance. The cshape is identical to the entries of the T-matrix, i.e. tmat.A.cshape == Zout.cshape.
- Return type:
- reshape(newshape)#
Return reshaped copy of the audio object.
- Parameters:
newshape (int, tuple) – new cshape of the audio object. One entry of newshape dimension can be
-1
. In this case, the value is inferred from the remaining dimensions.- Returns:
reshaped – reshaped copy of the audio object.
- Return type:
Notes
The number of samples and frequency bins always remains the same.
- transfer_function(quantity_indices, Zl: complex | FrequencyData) FrequencyData [source]#
Returns the transfer function (output/input) for specified quantities and a given load impedance.
The transfer function is the relation between an output and input quantity of modelled two-port and depends on the load impedance at the output. Since there are two quantities at input and output respectively, four transfer functions exist in total. The first usually refers to the “voltage-like” quantity (\(Q_1\)) whereas the second refers to the “current-like” quantity (\(Q_2\)).
The transfer functions can be derived from Equation (2-1) in Reference [1]:
\[ \begin{align}\begin{aligned}Q_{1,\mathrm{in}} = AQ_{1,\mathrm{out}} + BQ_{2,\mathrm{in}}\\Q_{2,\mathrm{in}} = CQ_{1,\mathrm{out}} + DQ_{2,\mathrm{in}}\end{aligned}\end{align} \]The four transfer functions are defined as:
\(Q_{1,\mathrm{out}} / Q_{1,\mathrm{in}}\) using \(Q_{2,\mathrm{out}} = Q_{1,\mathrm{out}}/Z_L\)
\(Q_{2,\mathrm{out}} / Q_{1,\mathrm{in}} = Q_{1,\mathrm{out}} / Q_{1,\mathrm{in}} \cdot \frac{1}{Z_L}\)
\(Q_{2,\mathrm{out}} / Q_{2,\mathrm{in}}\) using \(Q_{1,\mathrm{out}} = Q_{2,\mathrm{out}}\cdot Z_L\)
\(Q_{1,\mathrm{out}} / Q_{2,\mathrm{in}} = Q_{2,\mathrm{out}} / Q_{2,\mathrm{in}} \cdot Z_L\)
- Parameters:
quantity_indices (array_like (int, int)) – Array-like object with two integer elements referring to the indices of the utilized quantity at the output (first integer) and input (second integer). For example, (1,0) refers to the transfer function \(Q_{2,\mathrm{out}} / Q_{1,\mathrm{in}}\).
Zl (scalar | FrequencyData) – The load impedance data as scalar or FrequencyData. In latter case, the shape must match the entries of the T-matrix, i.e. shape(tmat.A.freq) == shape(Zl.freq), or must be broadcastable.
- Returns:
transfer_function – A FrequencyData object with the resulting transfer function. The cshape is identical to the entries of the T-matrix, i.e. tmat.A.cshape == transfer_function.cshape.
- Return type:
- transpose(*axes)#
Transpose time/frequency data and return copy of the audio object.
- Parameters:
caxes (empty,
None
, iterable of ints, or n ints) –Define how the :py:mod:` caxes <pyfar._concepts.audio_classes>` are ordered in the transposed audio object. Note that the last dimension of the data in the audio object always contains the time samples or frequency bins and can not be transposed.
- empty (default) or
None
reverses the order of
self.caxes
.- iterable of ints
i in the j-th place of the interable means that the i-th caxis becomes transposed object’s j-th caxis.
- n ints
same as ‘iterable of ints’.
- empty (default) or