*Matrix multiplication *is needed, for example, in the calculation of electrical networks. Python can perform these multiplications for you.

If several two-port networks are connected in series (catenary circuit), then the catenary shape (A parameter) can be used to calculate the required input voltage and current for a given output voltage and current by matrix multiplication.

Two matrices are multiplied with each other by multiplying the rows of the first matrix by the columns of the second matrix, element by element, and adding the individual products (according to *Falk’s scheme*):

A simple example will demonstrate the matrix multiplication using a schema (see the table below). The following two matrices are to be multiplied:

The first matrix is entered in the first and second columns and the third and fourth rows of a table. The second matrix is entered in the third and fourth columns and in the first and second rows of the table.

The first row of the first matrix is multiplied element by element by the first column of the second matrix. The two products are added up. The second row of the first matrix is multiplied by the first column of the second matrix. The two products are added up again. The second column is calculated according to the same schema.

NumPy provides the array([[a11,a12],[a21,a22]]) function for generating the matrices. You can adjust the number of rows and columns as needed.

The easiest way to perform matrix multiplication is to use the infix operator @. Alternatives are matmul(A,B) or multi_dot([A,B,C,...]).

The listing below shows how you can perform matrix multiplication using the numbers from our earlier example.

`01 #12_mulmatrix1.py`

`02 import numpy as np`

`03 A=np.array ([[1, 2],`

`04 [3, 4]])`

`05 B=np.array ([[5, 6],`

`06 [7, 8]])`

`07 C=A@B`

`08 D=B@A`

`09 #Output`

`10 print(type(A))`

`11 print("Matrix A\n",A)`

`12 print("Matrix B\n",B)`

`13 print("Product A*B\n",C)`

`14 print("Product B*A\n",D)`

** **

**Output**

** **

`<class 'numpy.ndarray'>`

`Matrix A`

` [[1 2]`

` [3 4]]`

`Matrix B`

` [[5 6]`

` [7 8]]`

`Product A*B`

` [[19 22]`

` [43 50]]`

`Product B*A`

` [[23 34]`

` [31 46]]`

** **

**Analysis: **Lines 03 to 06 define matrices with two rows and two columns each. The values of the individual coefficients are stored in variables A and B.

Line 07 performs the matrix multiplication C=A@B, while line 08 performs the multiplication with an interchanged order of factors D=B@A.

The product for C is correctly output line 13 and matches the value that was manually calculated in the table. The result from line 14, on the other hand, deviates from this. This result is also correct, as you can easily check by recalculation. (You thus learn from this that the commutative law does not apply to a matrix product.)

## Usage Example: Analysis of a π-Substitute Circuit

Let’s say a Python program needs to calculate the matrix of catenary parameters and the required input variables *U*1 and *I*1 for given output variables *U*2 and *I*2 for a π-substitute circuit, as shown in this figure.

** **

Any passive two-port network can be described in general terms by a linear system of equations with a matrix of four parameters and the column vectors from voltages or currents.

** **

## Catenary Shape with A Parameters

For this problem, the catenary shape must be chosen. On the left-hand side of the equation system, a column vector contains the input variables we are looking for. On the right-hand side, we have a catenary matrix with the four coefficients ** A**11 to

**22. The catenary matrix is multiplied by the column vector of the output variables. If the coefficients of the catenary matrix and the column vector of the output variables are known, the input variables**

*A**U*1 and

*I*1 can be calculated:

For the transverse resistors *R*1 and *R*3, the following *A *parameters can be determined from the circuit shown earlier:

For the series resistance R2, the following matrix results:

To obtain the system matrix of the entire circuit, you need to multiply all three partial matrices with each other.

This listing performs the matrix multiplication from the three partial matrices for the π-substitution circuit. You can of course change the values of the resistors for further testing.

`01 #13_mulmatrix2.py`

`02 import numpy as np`

`03 R1=1`

`04 R2=2`

`05 R3=1`

`06 U2=1`

`07 I2=1`

`08 A1q=np.array([[1, 0],`

`09 [1/R1, 1]])`

`10 Al=np.array([[1, R2],`

`11 [0, 1]])`

`12 A2q=np.array([[1, 0],`

`13 [1/R3, 1]])`

`14 A=A1q@Al@A2q`

`15 b=np.array([[U2],[I2]])`

`16 E=A@b`

`17 U1,I1=E[0,0],E[1,0]`

`18 print("Chain shape A\n",A)`

`19 print("Input variables\n",E)`

`20 print("Input voltage U1=%3.2f V" %U1)`

`21 print("Input current I1=%3.2f A" %I1)`

** **

**Output**

** **

`Chain shape A`

` [[3. 2.]`

` [4. 3.]]`

`Input variables`

` [[5.]`

` [7.]]`

`Input voltage U1=5.00 V`

`Input current I1=7.00 A`

** **

**Analysis: **The values for the output voltage *U*2; the output current *I*2; and the three resistors *R*1, *R*2, and *R*3 were taken from the specifications of the circuit.

**3**

In lines 08 to 13, the three partial matrices A1q, Al, and A2q are defined for the transverse resistances *R*1 and *R*3 and the series resistance *R*2. Line 14 performs the matrix multiplication A=A1q@Al@A2q. Pay attention to the correct sequence of factors. As shown earlier in Listing 3.12, the commutative law does not apply to matrix multiplication! Changing the order of the partial matrices would also represent a different circuit structure.

Line 15 creates the column vector b=np.array([[U2],[I2]]) for the output variables. In line 16, system matrix A is multiplied by column vector b. The result of the matrix multiplication is assigned to column vector E.

The input voltage must be 5 V so that a voltage of *U*2 = 1 V is present at the output of the π-substitute circuit. A current of *I*1 = 7 A must flow at the input of the circuit so that a current of *I*2 = 1 A flows at the output. You can check the results using the circuit.

** **

## Chain Shape with B Parameters

The output variables *U*2 and *I*2 of a two-port network are calculated using the *B *catenary parameters. The following two-port equations are then obtained for a π-substitute circuit:

For the transverse resistors *R*1 and *R*3, the *B *parameters can be determined from the circuit shown in as follows:

For the series resistance *R*2, the following matrix is obtained:

In general, the *B *parameters can be determined from the inverse matrix of *A*. The following applies:

The listing below calculates the output voltage *U*2 and output current *I*2 of a π-substitute circuit with the B catenary parameters.

`01 #14_mulmatrix3.py`

`02 import numpy as np`

`03 R1=1`

`04 R2=2`

`05 R3=1`

`06 U1=5`

`07 I1=7`

`08 B1q=np.array([[1, 0],`

`09 [-1/R1, 1]])`

`10 B2l=np.array([[1, -R2],`

`11 [0, 1]])`

`12 B3q=np.array([[1, 0],`

`13 [-1/R3, 1]])`

`14 B=B1q@B2l@B3q`

`15 b=np.array([[U1],[I1]])`

`16 E=B@b`

`17 U2,I2=E[0,0],E[1,0]`

`18 print("Chain shape B\n",B)`

`19 print("Output variables\n",E)`

`20 print("Output voltage U2=%3.2fV" %U2)`

`21 print("Output current I2=%3.2fA" %I2)`

** **

**Output**

`Chain shape B`

` [[ 3. -2.]`

` [-4. 3.]]`

`Output variables`

` [[1.]`

` [1.]]`

`Output voltage U2=1.00V`

`Output current I2=1.00A`

** **

**Analysis: **Basically, the program is structured in the same way as shown in earlier, except that the parameters in the secondary diagonal have a negative sign. The result for the output voltage *U*2 and the output current *I*2 matches the values determined using Kirchhoff’s circuit laws in the circuit shown.

** **

## Usage Example: Calculating the Energy of a Rotating Rigid Body in Space

The next example shows the multiplication of the row vector of an angular velocity with an inertia tensor *I *(3×3 matrix) and the column vector of an angular velocity.

For the rotational energy, the following applies:

** **

The superscript *T *means that the vector of angular velocity must be *transposed*, that is, the column vector is converted into a row vector. In component notation, you obtain the following:

For the inertia tensor of a point mass *m*, the following applies:

The product of the mass *m *and the matrix with the location coordinates is referred to as the inertia tensor. If you perform the matrix multiplication, you’ll get the rotational energy, which is stored in the rotating body.

For a case where mass *m *with radius *x = r *rotates around the z-axis in the x-y-plane, the following applies in a simplified way:

This listing calculates the rotational energy of a point mass of mass *m *= 6 kg rotating in space around the z-axis with an angular velocity of .

`01 #15_mulmatrix4.py`

`02 import numpy as np`

`03 x=1 #distance in m`

`04 y=0`

`05 z=0`

`06 wx=0`

`07 wy=0`

`08 wz=1 #angular velocity`

`09 m=6 #mass in kg`

`10 w_Z=np.array([wx,wy,wz])`

`11 I=m*np.array([[y**2+z**2, -x*y, -x*z],`

`12 [-x*y, x**2+z**2, -y*z],`

`13 [-x*z, -y*z, x**2+y**2]])`

`14 w_S=np.array([[wx],`

`15 [wy],`

`16 [wz]])`

`17 #Calculation of the rotational energy`

`18 Erot=0.5*w_Z@I@w_S`

`19 #Erot=0.5*w_S.T@I@w_S`

`20 Er=Erot[0]`

`21 #Output`

`22 print("Rotational energy: %3.2f joules" %Er)`

** **

**Output**

`Rotational energy: 3.00 joules`

** **

**Analysis: **The rotational energy is calculated according to the rule: “row vector multiplied by 3×3 matrix multiplied by column vector.” Following this sequence is mandatory because the commutative law does not apply with matrices! Line 10 contains the row vector of angular velocity, lines 11 to 13 contain the 3×3 matrix of the inertia tensor, and lines 14 to 16 contain the column vector of the angular velocity.

The statement in line 18 performs the matrix multiplication and stores the result in the Erot variable. Alternatively, you can comment out lines 10 and 18 and remove the comment in line 19. In this line, the column vector from line 14 is transposed into a row vector using the T property.

Editor’s note: This post has been adapted from a section of the book *Python for Engineering and Scientific Computing *by Veit Steinkamp.

## Comments