# Work with balanced circuits

Balancing is a powerful design technique. Apply balancing to:

1. Create four-terminal networks from three-terminal networks using anti-series connection

2. Create odd transfer characteristics with voltage-limiting or current-limiting characteristics using complementary-parallel connection or anti-series connection of nonlinear devices, respectively.

The signal transfer of balanced circuits is often decomposed in a differential-mode, and a common-mode transfer. In many applications of balanced networks, the differential-mode voltages and currents are of interest, while common-mode voltages and currents are either zero, or should not affect the differential-mode transfer.

SLiCAP has a built-in method to convert nodal voltages and branch currents into differential voltages, differential currents, common-mode voltages, and common-mode currents (for theory see: Structured Electronics Design).

In a fully balanced network, differential-mode and common-mode quantities are orthogonal, and balanced circuits are decomposed into two independent network models: one modeling the differential-mode behavior and the other the common-mode behavior.

Using two independent network models helps to design the desired common-mode and differential-mode behavior with minimized network models.

## Settings for CM and DM decompositon

SLiCAP balanced network decomposition is based upon pairing nodes, branches and parameters.

The decomposition itself is initiated by setting the argument `convtype` in an instruction to:

1. “all”: SLiCAP decomposes paired node voltages and paired branch currents into pairs of common-mode and differential-mode voltages and currents. Convertion type `all` can only be used for displaying the matrix equations; performing analysis is not implemented.

2. “dd”: After the above decomposition, SLiCAP can perform all types of analysis using the differential-mode matrix equation.

3. “dc” SLiCAP returns the differential-mode to common-mode matrix equation. Generally this involves a non-square matrix.

4. “cd”: SLiCAP returns the common-mode to differential-mode matrix equation. Generally this involves a non-square matrix.

5. “cc” After the above decomposition, SLiCAP can perform all types of analysis using the common-mode matrix equation.

## Pairing nodes, branches, and parameters

The decomposition settings for balanced networks are stored in the file `SLiCAP.ini` in the project directory.

    >>> import SLiCAP as sl
    >>> sl.ini.dump("balancing")

    BALANCING
    ---------
    ini.pair_ext               = ['P', 'N']
    ini.update_srcnames        = True
    ini.remove_param_pair_ext  = True

1. `ini.pair_ext`: List with two strings. These strings (pair extensions) are the last part of node names, element reference designators, and parameter names of paired nodes, elements, and parameters, respectively. The first part of these names must be equal.

2. `ini.update_srcnames`: True will update the names of noise sources and dcvar sources in the results of noise and dcvar analysis, respectively.

3. `ini.remove_param_pair_ext`: True will remove the pair extensions from the parameter names after pairing. This is useful when using paired sub circuits. Local parameters of paired sub circuits are also paired: they obtain the same name, without pair extension.

## Create balanced circuits

SLiCAP output displayed on this manual page, is generated with the script: `balanced.py`, imported by `Manual.py`.

     1#!/usr/bin/env python3
     2# -*- coding: utf-8 -*-
     3
     4"""
     5balanced.py: SLiCAP scripts for the HTML help file
     6"""
     7import SLiCAP as sl
     8import sympy as sp
     9sl.initProject("balanced")
    10###############################################################################
    11# work with balanced circuits
    12###############################################################################

### Balanced passive network

    14balancedNetwork = sl.makeCircuit("kicad/balancedNetwork/balancedNetwork.kicad_sch")
    15noneM = sl.doMatrix(balancedNetwork)
    16allM  = sl.doMatrix(balancedNetwork, convtype="all")
    17ddM   = sl.doMatrix(balancedNetwork, convtype="dd")
    18dcM   = sl.doMatrix(balancedNetwork, convtype="dc")
    19cdM   = sl.doMatrix(balancedNetwork, convtype="cd")
    20ccM   = sl.doMatrix(balancedNetwork, convtype="cc")

Important

1. Notice the orientation of the components in both halves of the balanced circuit:

   Components of the two parts of a balanced circuit must have the same orientation in each part! This is particaluarly important for components that have a branch current in their MNA stamp.

2. Notice the naming of components and nodes:

   Paired nodes and components of the two parts of a balanced circuit have the same name plus an individual pair extension! This is particaluarly important for components that have a branch current in their MNA stamp.

#### Matrix equation convtype=None

\[\begin{split}\left[\begin{matrix}0\\0\\V_{b}\\V_{a}\\I_{s}\\0\\0\\0\\0\\0\\0\\0\end{matrix}\right]=\left[\begin{array}{cccccccccccc}- L_{a} s & - L_{a} k_{c} s & 0 & 0 & 0 & -1 & 1 & 0 & 0 & 0 & 0 & 0\\- L_{a} k_{c} s & - L_{a} s & 0 & 0 & 0 & -1 & 0 & 1 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 1 & 0 & 0\\0 & 0 & -1 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\-1 & -1 & 0 & 0 & 0 & C_{a} s + \frac{1}{R_{c}} & 0 & 0 & 0 & 0 & 0 & 0\\1 & 0 & 0 & 0 & 0 & 0 & \frac{1}{R_{b}} & 0 & 0 & 0 & - \frac{1}{R_{b}} & 0\\0 & 1 & 0 & 0 & 0 & 0 & 0 & \frac{1}{R_{b}} & 0 & 0 & 0 & - \frac{1}{R_{b}}\\0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & \frac{1}{R_{a}} & 0 & - \frac{1}{R_{a}} & 0\\0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & \frac{1}{R_{a}} & 0 & - \frac{1}{R_{a}}\\0 & 0 & 0 & 0 & 0 & 0 & - \frac{1}{R_{b}} & 0 & - \frac{1}{R_{a}} & 0 & \frac{R_{a} + R_{b}}{R_{a} R_{b}} & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & - \frac{1}{R_{b}} & 0 & - \frac{1}{R_{a}} & 0 & \frac{R_{a} + R_{b}}{R_{a} R_{b}}\end{array}\right]\cdot \left[\begin{matrix}I_{L1N}\\I_{L1P}\\I_{V1N}\\I_{V1P}\\V_{1}\\V_{2}\\V_{LN}\\V_{LP}\\V_{inN}\\V_{inP}\\V_{outN}\\V_{outP}\end{matrix}\right]\end{split}\]

#### Matrix equation convtype=’all’

\[\begin{split}\left[\begin{matrix}0\\V_{a} - V_{b}\\0\\0\\0\\0\\0.5 V_{a} + 0.5 V_{b}\\0\\0\\0\\I_{s}\\0\end{matrix}\right]=\left[\begin{array}{cccccccccccc}2 L_{a} s \left(k_{c} - 1\right) & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\1 & 0 & \frac{0.5}{R_{b}} & 0 & - \frac{0.5}{R_{b}} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 1 & 0 & \frac{0.5}{R_{a}} & - \frac{0.5}{R_{a}} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & - \frac{0.5}{R_{b}} & - \frac{0.5}{R_{a}} & \frac{0.5}{R_{b}} + \frac{0.5}{R_{a}} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0.5 L_{a} s \left(- k_{c} - 1\right) & 0 & 1 & 0 & 0 & 0 & -1\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & -1 & 0\\0 & 0 & 0 & 0 & 0 & 1 & 0 & \frac{2}{R_{b}} & 0 & - \frac{2}{R_{b}} & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & \frac{2}{R_{a}} & - \frac{2}{R_{a}} & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & - \frac{2}{R_{b}} & - \frac{2}{R_{a}} & \frac{2}{R_{b}} + \frac{2}{R_{a}} & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & C_{a} s + \frac{1}{R_{c}}\end{array}\right]\cdot \left[\begin{matrix}I_{L1 D}\\I_{V1 D}\\V_{L D}\\V_{in D}\\V_{out D}\\I_{L1 C}\\I_{V1 C}\\V_{L C}\\V_{in C}\\V_{out C}\\V_{1}\\V_{2}\end{matrix}\right]\end{split}\]

Important

After pairing, pair extensions in the vector with nodal voltages and branch currents have been replaced with `_D` and `_C` for differential-mode and common-mode, respectively.

#### Matrix equation convtype=’dd’

\[\begin{split}\left[\begin{matrix}0\\V_{a} - V_{b}\\0\\0\\0\end{matrix}\right]=\left[\begin{matrix}2 L_{a} s \left(k_{c} - 1\right) & 0 & 1 & 0 & 0\\0 & 0 & 0 & 1 & 0\\1 & 0 & \frac{0.5}{R_{b}} & 0 & - \frac{0.5}{R_{b}}\\0 & 1 & 0 & \frac{0.5}{R_{a}} & - \frac{0.5}{R_{a}}\\0 & 0 & - \frac{0.5}{R_{b}} & - \frac{0.5}{R_{a}} & \frac{0.5}{R_{b}} + \frac{0.5}{R_{a}}\end{matrix}\right]\cdot \left[\begin{matrix}I_{L1 D}\\I_{V1 D}\\V_{L D}\\V_{in D}\\V_{out D}\end{matrix}\right]\end{split}\]

`convtype='dd'` gives the uppper-left matrix of the square matrix from `convtype='all'`

#### Matrix equation convtype=’dc’

\[\begin{split}\left[\begin{matrix}0\\V_{a} - V_{b}\\0\\0\\0\end{matrix}\right]=\left[\begin{matrix}0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0\end{matrix}\right]\cdot \left[\begin{matrix}I_{L1 C}\\I_{V1 C}\\V_{L C}\\V_{in C}\\V_{out C}\\V_{1}\\V_{2}\end{matrix}\right]\end{split}\]

`convtype='dc'` gives the uppper-right matrix of the square matrix from `convtype='all'`

#### Matrix equation convtype=’cd’

\[\begin{split}\left[\begin{matrix}0\\0.5 V_{a} + 0.5 V_{b}\\0\\0\\0\\I_{s}\\0\end{matrix}\right]=\left[\begin{matrix}0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0\end{matrix}\right]\cdot \left[\begin{matrix}I_{L1 D}\\I_{V1 D}\\V_{L D}\\V_{in D}\\V_{out D}\end{matrix}\right]\end{split}\]

`convtype='cd'` gives the lower-left matrix of the square matrix from `convtype='all'`

#### Matrix equation convtype=’cc’

\[\begin{split}\left[\begin{matrix}0\\0.5 V_{a} + 0.5 V_{b}\\0\\0\\0\\I_{s}\\0\end{matrix}\right]=\left[\begin{matrix}0.5 L_{a} s \left(- k_{c} - 1\right) & 0 & 1 & 0 & 0 & 0 & -1\\0 & 0 & 0 & 1 & 0 & -1 & 0\\1 & 0 & \frac{2}{R_{b}} & 0 & - \frac{2}{R_{b}} & 0 & 0\\0 & 1 & 0 & \frac{2}{R_{a}} & - \frac{2}{R_{a}} & 0 & 0\\0 & 0 & - \frac{2}{R_{b}} & - \frac{2}{R_{a}} & \frac{2}{R_{b}} + \frac{2}{R_{a}} & 0 & 0\\0 & -1 & 0 & 0 & 0 & 0 & 0\\-1 & 0 & 0 & 0 & 0 & 0 & C_{a} s + \frac{1}{R_{c}}\end{matrix}\right]\cdot \left[\begin{matrix}I_{L1 C}\\I_{V1 C}\\V_{L C}\\V_{in C}\\V_{out C}\\V_{1}\\V_{2}\end{matrix}\right]\end{split}\]

`convtype='cc'` gives the lower-right matrix of the square matrix from `convtype='all'`

#### Check common-mode and differential-mode orthogonality

A circuit is fully balanced if the the matrices obtained with `convtype='dc'` and `convtype='cd'` are zero:

    22if cdM.M.is_zero_matrix and dcM.M.is_zero_matrix:
    23    print("The CM-DM decomposition is orthogonal!")
    24else:
    25    print("Warning: the CM-DM decomposition is NOT orthogonal!")

This yields:

    The CM-DM decomposition is orthogonal!

#### Get the conversion matrix

The MNA equation (`convtype=None`) has the form:

\[\mathbf{I_{n,b} = M \cdot D_{n,b}}\]

where \(\mathbf{I_{n,b}}\) is the vector with independent nodal currents and branch voltages (independent sources), \(\mathbf{M}\) is the MNA matrix, and \(\mathbf{D_{n,b}}\) is the vector with unknown nodal voltages and branch currents.

The matrix equation for `convtype='all'` is:

\[\mathbf{I_{d,c}} = \mathbf{M^{\prime} \cdot D_{d,c}}\]

where \(\mathbf{I_{d,c}}\) is the vector with independent differential-mode and common-mode voltage and current sources, \(\mathbf{D_{d,c}}\) the vector with unknown differential-mode and common-mode voltages and currents, and math:mathbf{M^{prime}} the converted MNA matrix.

The converted matrices are obtained as:

\[\begin{split}\begin{align} \mathbf{I_{d,c}} &=\mathbf{A^T}\cdot\mathbf{I_{n,b}}\\ \mathbf{M^{\prime}} &=\mathbf{A^T \cdot M \cdot A}\\ \mathbf{D_{d,c}} &=\mathbf{A^{-1} \cdot D_{n,b}} \end{align}\end{split}\]

Where \(\mathbf{A}\) is the conversion matrix, constricted such that:

\[\mathbf{D_{n,b} = A \cdot D_{d,c}}\]

For theory see: Structured Electronics Design.

for this example:

    27# Conversion matrix:
    28print(allM.A)

This yields:

    Matrix([[-1, 0, 0, 0, 0, 0.500000000000000, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0.500000000000000, 0, 0, 0, 0, 0, 0], [0, -1, 0, 0, 0, 0, 0.500000000000000, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0.500000000000000, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, -0.500000000000000, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0.500000000000000, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, -0.500000000000000, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0.500000000000000, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, -0.500000000000000, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0.500000000000000, 0, 0, 0, 0, 1, 0, 0]])

Typesetted:

\[\begin{split}A = \left[\begin{array}{cccccccccccc}-1 & 0 & 0 & 0 & 0 & 0.5 & 0 & 0 & 0 & 0 & 0 & 0\\1 & 0 & 0 & 0 & 0 & 0.5 & 0 & 0 & 0 & 0 & 0 & 0\\0 & -1 & 0 & 0 & 0 & 0 & 0.5 & 0 & 0 & 0 & 0 & 0\\0 & 1 & 0 & 0 & 0 & 0 & 0.5 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\0 & 0 & -0.5 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\0 & 0 & 0.5 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\0 & 0 & 0 & -0.5 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\0 & 0 & 0 & 0.5 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\0 & 0 & 0 & 0 & -0.5 & 0 & 0 & 0 & 0 & 1 & 0 & 0\\0 & 0 & 0 & 0 & 0.5 & 0 & 0 & 0 & 0 & 1 & 0 & 0\end{array}\right]\end{split}\]

### Balanced circuit with models

    30# Use models
    31# OpAmp circuit
    32Vamp = sl.makeCircuit("kicad/balancedAmp/balancedAmp.kicad_sch")

Important

The scope of parameters defined in a (sub) circuit `.model` statement is the (sub) circuit in which they are defined.

n this example model parameters are defined in the main circuit. Hence, no extensions `P` or `N` wil be added to the parameter names:

    34print(Vamp.elements['E_O1N'].params)
    35print(Vamp.elements['E_O1P'].params)

    {'value': A_0/(1 + s/(2*pi*f_p1)), 'zo': 1000}
    {'value': A_0/(1 + s/(2*pi*f_p1)), 'zo': 1000}

The matrix equation with `convtype='all'`:

    35# Matrix equation
    36VampAll = sl.doMatrix(Vamp, pardefs="circuit", numeric=True, convtype="all")

\[\begin{split}\left[\begin{matrix}0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\end{matrix}\right]=\left[\begin{array}{cccccccccccc}0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\0 & - 6.366 \cdot 10^{17} s - 2.0 \cdot 10^{20} & 1.0 \cdot 10^{17} A_{0} & - 1.0 \cdot 10^{17} A_{0} & 3.183 \cdot 10^{14} s + 1.0 \cdot 10^{17} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 3.0 \cdot 10^{-12} s + 0.01 & - 2.5 \cdot 10^{-12} s & -5.0 \cdot 10^{-6} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & - 2.5 \cdot 10^{-12} s & 3.0 \cdot 10^{-12} s + 0.0005 & 0 & -0.0005 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 1 & -5.0 \cdot 10^{-6} & 0 & 0.005005 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\1 & 0 & 0 & -0.0005 & 0 & 0.0005 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\0 & 0 & 0 & 0 & 0 & 0 & 0 & - 1.592 \cdot 10^{17} s - 5.0 \cdot 10^{19} & 1.0 \cdot 10^{17} A_{0} & - 1.0 \cdot 10^{17} A_{0} & 3.183 \cdot 10^{14} s + 1.0 \cdot 10^{17} & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1.2 \cdot 10^{-11} s + 2.0 \cdot 10^{-5} & - 1.0 \cdot 10^{-11} s & -2.0 \cdot 10^{-5} & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 1.0 \cdot 10^{-11} s & 1.2 \cdot 10^{-11} s + 0.002 & 0 & -0.002\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & -2.0 \cdot 10^{-5} & 0 & 2.0 \cdot 10^{-5} & 0\\0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & -0.002 & 0 & 0.002\end{array}\right]\cdot \left[\begin{matrix}I_{V1 D}\\I_{E O1 D}\\V_{fb D}\\V_{in D}\\V_{out D}\\V_{src D}\\I_{V1 C}\\I_{E O1 C}\\V_{fb C}\\V_{in C}\\V_{out C}\\V_{src C}\end{matrix}\right]\end{split}\]

### Balanced circuit with sub circuits

Below a balanced circuit built-up from two equal sub circuits.

The figure below shows the sub circuit diagram.

    38# Use sub circuits
    39subckt = sl.makeCircuit("kicad/myBJTamp/myBJTamp.kicad_sch")
    40BJTdiffAmp = sl.makeCircuit("kicad/BJTdiffAmp/BJTdiffAmp.kicad_sch")

The scope of the model parameters is now limited to the sub circuit.

    42# Disable parameter pairing
    43sl.ini.remove_param_pair_ext = False
    44BJTampAllF = sl.doMatrix(BJTdiffAmp, pardefs="circuit", numeric=True, convtype="all")

Typesetted result:

\[\begin{split}\left[\begin{matrix}0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\end{matrix}\right]=\left[\begin{array}{cccccccccccccc}0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & -1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & -1 & \frac{0.25 g_{m X1P}}{\beta_{AC X1P}} + \frac{0.25 g_{m X1N}}{\beta_{AC X1N}} & - \frac{0.25 g_{m X1P}}{\beta_{AC X1P}} - \frac{0.25 g_{m X1N}}{\beta_{AC X1N}} & 0 & 0 & 0 & 0 & 0 & \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} - \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & - \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} + \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & 0 & 0 & 0\\0 & 0 & - 0.25 g_{m X1N} - 0.25 g_{m X1P} - \frac{0.25 g_{m X1P}}{\beta_{AC X1P}} - \frac{0.25 g_{m X1N}}{\beta_{AC X1N}} & 0.25 g_{m X1N} + 0.25 g_{m X1P} + 0.25 g_{o X1N} + 0.25 g_{o X1P} + \frac{0.25 g_{m X1P}}{\beta_{AC X1P}} + \frac{0.25 g_{m X1N}}{\beta_{AC X1N}} + \frac{1}{R_{a}} & 0 & - 0.25 g_{o X1N} - 0.25 g_{o X1P} & 0 & 0 & 0 & 0.5 g_{m X1N} - 0.5 g_{m X1P} - \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} + \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & - 0.5 g_{m X1N} + 0.5 g_{m X1P} - 0.5 g_{o X1N} + 0.5 g_{o X1P} + \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} - \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & 0 & 0.5 g_{o X1N} - 0.5 g_{o X1P} & 0\\0 & 1 & 0 & 0 & \frac{0.5}{R_{s}} + \frac{0.25}{R_{f X1P}} + \frac{0.25}{R_{f X1N}} & - \frac{0.25}{R_{f X1P}} - \frac{0.25}{R_{f X1N}} & - \frac{0.5}{R_{s}} & 0 & 0 & 0 & 0 & \frac{0.5}{R_{f X1P}} - \frac{0.5}{R_{f X1N}} & - \frac{0.5}{R_{f X1P}} + \frac{0.5}{R_{f X1N}} & 0\\0 & 0 & 0.25 g_{m X1N} + 0.25 g_{m X1P} & - 0.25 g_{m X1N} - 0.25 g_{m X1P} - 0.25 g_{o X1N} - 0.25 g_{o X1P} & - \frac{0.25}{R_{f X1P}} - \frac{0.25}{R_{f X1N}} & 0.25 g_{o X1N} + 0.25 g_{o X1P} + \frac{0.25}{R_{f X1P}} + \frac{0.25}{R_{f X1N}} & 0 & 0 & 0 & - 0.5 g_{m X1N} + 0.5 g_{m X1P} & 0.5 g_{m X1N} - 0.5 g_{m X1P} + 0.5 g_{o X1N} - 0.5 g_{o X1P} & - \frac{0.5}{R_{f X1P}} + \frac{0.5}{R_{f X1N}} & - 0.5 g_{o X1N} + 0.5 g_{o X1P} + \frac{0.5}{R_{f X1P}} - \frac{0.5}{R_{f X1N}} & 0\\1 & 0 & 0 & 0 & - \frac{0.5}{R_{s}} & 0 & \frac{0.5}{R_{s}} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 1 & 0 & 0\\0 & 0 & \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} - \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & - \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} + \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & 0 & 0 & 0 & 0 & -1 & \frac{g_{m X1P}}{\beta_{AC X1P}} + \frac{g_{m X1N}}{\beta_{AC X1N}} & - \frac{g_{m X1P}}{\beta_{AC X1P}} - \frac{g_{m X1N}}{\beta_{AC X1N}} & 0 & 0 & 0\\0 & 0 & 0.5 g_{m X1N} - 0.5 g_{m X1P} - \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} + \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & - 0.5 g_{m X1N} + 0.5 g_{m X1P} - 0.5 g_{o X1N} + 0.5 g_{o X1P} + \frac{0.5 g_{m X1P}}{\beta_{AC X1P}} - \frac{0.5 g_{m X1N}}{\beta_{AC X1N}} & 0 & 0.5 g_{o X1N} - 0.5 g_{o X1P} & 0 & 0 & 0 & - g_{m X1N} - g_{m X1P} - \frac{g_{m X1P}}{\beta_{AC X1P}} - \frac{g_{m X1N}}{\beta_{AC X1N}} & g_{m X1N} + g_{m X1P} + g_{o X1N} + g_{o X1P} + \frac{g_{m X1P}}{\beta_{AC X1P}} + \frac{g_{m X1N}}{\beta_{AC X1N}} & 0 & - g_{o X1N} - g_{o X1P} & 0\\0 & 0 & 0 & 0 & \frac{0.5}{R_{f X1P}} - \frac{0.5}{R_{f X1N}} & - \frac{0.5}{R_{f X1P}} + \frac{0.5}{R_{f X1N}} & 0 & 0 & 1 & 0 & 0 & \frac{2}{R_{s}} + \frac{1}{R_{f X1P}} + \frac{1}{R_{f X1N}} & - \frac{1}{R_{f X1P}} - \frac{1}{R_{f X1N}} & - \frac{2}{R_{s}}\\0 & 0 & - 0.5 g_{m X1N} + 0.5 g_{m X1P} & 0.5 g_{m X1N} - 0.5 g_{m X1P} + 0.5 g_{o X1N} - 0.5 g_{o X1P} & - \frac{0.5}{R_{f X1P}} + \frac{0.5}{R_{f X1N}} & - 0.5 g_{o X1N} + 0.5 g_{o X1P} + \frac{0.5}{R_{f X1P}} - \frac{0.5}{R_{f X1N}} & 0 & 0 & 0 & g_{m X1N} + g_{m X1P} & - g_{m X1N} - g_{m X1P} - g_{o X1N} - g_{o X1P} & - \frac{1}{R_{f X1P}} - \frac{1}{R_{f X1N}} & g_{o X1N} + g_{o X1P} + \frac{1}{R_{f X1P}} + \frac{1}{R_{f X1N}} & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & - \frac{2}{R_{s}} & 0 & \frac{2}{R_{s}}\end{array}\right]\cdot \left[\begin{matrix}I_{V1 D}\\I_{Rb Q1 X1 D}\\V_{1 Q1 X1 D}\\V_{fb D}\\V_{in D}\\V_{out D}\\V_{src D}\\I_{V1 C}\\I_{Rb Q1 X1 C}\\V_{1 Q1 X1 C}\\V_{fb C}\\V_{in C}\\V_{out C}\\V_{src C}\end{matrix}\right]\end{split}\]

    45# The circuit parameters are not altered
    46print(BJTdiffAmp.params)
    47print(BJTdiffAmp.parDefs)
    48# The instruction parameters are not altered
    49print(BJTampAllF.circuit.params)
    50print(BJTampAllF.circuit.parDefs)

This yields:

    [g_o_X1P, R_f_X1N, g_o_X1N, R_f_X1P, R_s, g_m_X1N, R_a, beta_AC_X1N, beta_AC_X1P, g_m_X1P]
    {}
    [g_o_X1P, R_f_X1N, g_o_X1N, R_f_X1P, R_s, g_m_X1N, R_a, beta_AC_X1N, beta_AC_X1P, g_m_X1P]
    {}

The default value of `ini.remove_param_pair_ext` is `True`:

    51# Enable parameter pairing (default setting)
    52sl.ini.remove_param_pair_ext = True
    53BJTampAllT = sl.doMatrix(BJTdiffAmp, pardefs="circuit", numeric=True, convtype="all")
    54# The circuit parameters are not altered
    55print(BJTdiffAmp.params)
    56print(BJTdiffAmp.parDefs)
    57# The instruction parameters are altered
    58print(BJTampAllT.circuit.params)
    59print(BJTampAllT.circuit.parDefs)

This yields:

    [g_o_X1P, R_f_X1N, g_o_X1N, R_f_X1P, R_s, g_m_X1N, R_a, beta_AC_X1N, beta_AC_X1P, g_m_X1P]
    {}
    [g_m_X1, R_s, R_a, g_o_X1, R_f_X1, beta_AC_X1]
    {}

Typesetted result:

\[\begin{split}\left[\begin{matrix}0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\end{matrix}\right]=\left[\begin{array}{cccccccccccccc}0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & -1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & -1 & \frac{0.5 g_{m X1}}{\beta_{AC X1}} & - \frac{0.5 g_{m X1}}{\beta_{AC X1}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & - 0.5 g_{m X1} - \frac{0.5 g_{m X1}}{\beta_{AC X1}} & 0.5 g_{m X1} + 0.5 g_{o X1} + \frac{0.5 g_{m X1}}{\beta_{AC X1}} + \frac{1}{R_{a}} & 0 & - 0.5 g_{o X1} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 1 & 0 & 0 & \frac{0.5}{R_{s}} + \frac{0.5}{R_{f X1}} & - \frac{0.5}{R_{f X1}} & - \frac{0.5}{R_{s}} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0.5 g_{m X1} & - 0.5 g_{m X1} - 0.5 g_{o X1} & - \frac{0.5}{R_{f X1}} & 0.5 g_{o X1} + \frac{0.5}{R_{f X1}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\1 & 0 & 0 & 0 & - \frac{0.5}{R_{s}} & 0 & \frac{0.5}{R_{s}} & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 1 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & \frac{2 g_{m X1}}{\beta_{AC X1}} & - \frac{2 g_{m X1}}{\beta_{AC X1}} & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 2 g_{m X1} - \frac{2 g_{m X1}}{\beta_{AC X1}} & 2 g_{m X1} + 2 g_{o X1} + \frac{2 g_{m X1}}{\beta_{AC X1}} & 0 & - 2 g_{o X1} & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & \frac{2}{R_{s}} + \frac{2}{R_{f X1}} & - \frac{2}{R_{f X1}} & - \frac{2}{R_{s}}\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 2 g_{m X1} & - 2 g_{m X1} - 2 g_{o X1} & - \frac{2}{R_{f X1}} & 2 g_{o X1} + \frac{2}{R_{f X1}} & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & - \frac{2}{R_{s}} & 0 & \frac{2}{R_{s}}\end{array}\right]\cdot \left[\begin{matrix}I_{V1 D}\\I_{Rb Q1 X1 D}\\V_{1 Q1 X1 D}\\V_{fb D}\\V_{in D}\\V_{out D}\\V_{src D}\\I_{V1 C}\\I_{Rb Q1 X1 C}\\V_{1 Q1 X1 C}\\V_{fb C}\\V_{in C}\\V_{out C}\\V_{src C}\end{matrix}\right]\end{split}\]

### Auto-rename detector

With the conversion type set to `dd`, `dc`, `cd`, or `cc`, SLiCAP automatically redefines the differential voltage or current detector as the corresponding differential-mode or common-mode detector.

    61# Adapt detector
    62BJTampDD = sl.doLaplace(BJTdiffAmp, source=["V1P", "V1N"], detector=["V_outP", "V_outN"], convtype='dd').laplace
    63numer, denom = BJTampDD.as_numer_denom()
    64BJTampDD = 8*numer/(8*denom)

This prints:

    Detector changed to: V_out_D

\[A_{vdd} = \frac{8 R_{a} R_{f X1} g_{m X1} g_{o X1} + 8 R_{a} \beta_{AC X1} g_{m X1} + 8 R_{a} \beta_{AC X1} g_{o X1} + 8 R_{a} g_{m X1} - 16 R_{f X1} \beta_{AC X1} g_{m X1} + 16 \beta_{AC X1}}{8 R_{a} R_{f X1} g_{m X1} g_{o X1} + 8 R_{a} \beta_{AC X1} g_{m X1} + 8 R_{a} \beta_{AC X1} g_{o X1} + 8 R_{a} g_{m X1} + 16 R_{f X1} R_{s} g_{m X1} g_{o X1} + 16 R_{f X1} \beta_{AC X1} g_{o X1} + 16 R_{s} \beta_{AC X1} g_{m X1} + 16 R_{s} \beta_{AC X1} g_{o X1} + 16 R_{s} g_{m X1} + 16 \beta_{AC X1}}\]

    65BJTampCC = sl.doLaplace(BJTdiffAmp, source=["V1P", "V1N"], detector=["V_outP", "V_outN"], convtype='cc').laplace

This prints:

    Detector changed to: V_out_C

\[A_{vcc} = 1\]

## Balanced feedback

    67# Balanced Feedback
    68# Define parameters
    69par_dict = {"A_0": 1e6, "f_p1": 100}
    70Vamp.defPars(par_dict)

### Differential amplifier

    72# Poles and zeros
    73poles = sl.doPoles(Vamp, pardefs="circuit", numeric=True)
    74zeros = sl.doZeros(Vamp, pardefs="circuit", numeric=True)
    75pz    = sl.doPZ(Vamp, pardefs="circuit", numeric=True)

The table below shows all the poles of the circuit.

# | Re [Hz] | Im [Hz] | \(f\) [Hz] | Q
--- | --- | --- | --- | ---
\(p_{0}\) | \(-4640.0\) | \(0\) | \(4640.0\) |
\(p_{0}\) | \(-6.334 \cdot 10^{4}\) | \(5.103 \cdot 10^{6}\) | \(5.103 \cdot 10^{6}\) | \(40.28\)
\(p_{0}\) | \(-6.334 \cdot 10^{4}\) | \(-5.103 \cdot 10^{6}\) | \(5.103 \cdot 10^{6}\) | \(40.28\)
\(p_{0}\) | \(-2.562 \cdot 10^{7}\) | \(0\) | \(2.562 \cdot 10^{7}\) |
\(p_{0}\) | \(-8.754 \cdot 10^{7}\) | \(0\) | \(8.754 \cdot 10^{7}\) |
\(p_{0}\) | \(-1.798 \cdot 10^{9}\) | \(0\) | \(1.798 \cdot 10^{9}\) |

The table below shows all the zeros of the differential voltage transfer.

# | Re [Hz] | Im [Hz] | \(f\) [Hz] | Q
--- | --- | --- | --- | ---
\(z_{0}\) | \(-6.334 \cdot 10^{4}\) | \(5.103 \cdot 10^{6}\) | \(5.103 \cdot 10^{6}\) | \(40.28\)
\(z_{0}\) | \(-6.334 \cdot 10^{4}\) | \(-5.103 \cdot 10^{6}\) | \(5.103 \cdot 10^{6}\) | \(40.28\)
\(z_{0}\) | \(-8.754 \cdot 10^{7}\) | \(0\) | \(8.754 \cdot 10^{7}\) |
\(z_{0}\) | \(-1.0 \cdot 10^{9}\) | \(2.317 \cdot 10^{9}\) | \(2.524 \cdot 10^{9}\) | \(1.262\)
\(z_{0}\) | \(-1.0 \cdot 10^{9}\) | \(-2.317 \cdot 10^{9}\) | \(2.524 \cdot 10^{9}\) | \(1.262\)

The table below shows all the observable and controllable poles and zeros of the differential voltage transfer.

DC value of gain: \(1958.0\)

# | Re [Hz] | Im [Hz] | \(f\) [Hz] | Q
--- | --- | --- | --- | ---
\(p_{0}\) | \(-4640.0\) | \(0\) | \(4640.0\) |
\(p_{0}\) | \(-2.562 \cdot 10^{7}\) | \(0\) | \(2.562 \cdot 10^{7}\) |
\(p_{0}\) | \(-1.798 \cdot 10^{9}\) | \(0\) | \(1.798 \cdot 10^{9}\) |
\(z_{0}\) | \(-1.0 \cdot 10^{9}\) | \(2.317 \cdot 10^{9}\) | \(2.524 \cdot 10^{9}\) | \(1.262\)
\(z_{0}\) | \(-1.0 \cdot 10^{9}\) | \(-2.317 \cdot 10^{9}\) | \(2.524 \cdot 10^{9}\) | \(1.262\)

### Differential-mode circuit

    77# Differential-mode poles and zeros
    78pzdd  = sl.doPZ(Vamp, pardefs="circuit", numeric=True, convtype="dd")

The observable and controllable poles and zeros of the voltage transfer of the differential-mode equivalent circuit:

DC value of gain: \(1958.0\)

# | Re [Hz] | Im [Hz] | \(f\) [Hz] | Q
--- | --- | --- | --- | ---
\(p_{0}\) | \(-4640.0\) | \(0\) | \(4640.0\) |
\(p_{0}\) | \(-2.562 \cdot 10^{7}\) | \(0\) | \(2.562 \cdot 10^{7}\) |
\(p_{0}\) | \(-1.798 \cdot 10^{9}\) | \(0\) | \(1.798 \cdot 10^{9}\) |
\(z_{0}\) | \(-1.0 \cdot 10^{9}\) | \(2.317 \cdot 10^{9}\) | \(2.524 \cdot 10^{9}\) | \(1.262\)
\(z_{0}\) | \(-1.0 \cdot 10^{9}\) | \(-2.317 \cdot 10^{9}\) | \(2.524 \cdot 10^{9}\) | \(1.262\)

    80# Differential-mode aysmptotic-gain model Bode plots
    81Add = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="dd",
    82                   transfer="asymptotic")
    83Ldd = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="dd",
    84                   transfer="loopgain")
    85Sdd = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="dd",
    86                   transfer="servo")
    87Ddd = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="dd",
    88                   transfer="direct")
    89Gdd = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="dd",
    90                   transfer="gain")
    91# dB magnitude plots
    92sl.plotSweep("Vamp_dd_fb_dB", "Balanced voltage amplifier, differential-mode",
    93             [Add, Ldd, Sdd, Ddd, Gdd], 0.1, 1e5, 200, sweepScale="k",
    94             funcType="dBmag")
    95# Phase plots
    96sl.plotSweep("Vamp_dd_fb_phs", "Balanced voltage amplifier, differential-mode",
    97             [Add, Ldd, Sdd, Ddd, Gdd], 0.1, 1e5, 200, sweepScale="k",
    98             funcType="phase")

Bode plots of the feedback transfers of the differential-mode equivalent circuit.

### Common-mode circuit

    100# Common-mode poles and zeros
    101pzcc  = sl.doPZ(Vamp, pardefs="circuit", numeric=True, convtype="cc")

The observable and controllable poles and zeros of the voltage transfer of the common-mode equivalent circuit:

DC value of gain: \(1\)

# | Re [Hz] | Im [Hz] | \(f\) [Hz] | Q
--- | --- | --- | --- | ---
\(p_{0}\) | \(-6.334 \cdot 10^{4}\) | \(5.103 \cdot 10^{6}\) | \(5.103 \cdot 10^{6}\) | \(40.28\)
\(p_{0}\) | \(-6.334 \cdot 10^{4}\) | \(-5.103 \cdot 10^{6}\) | \(5.103 \cdot 10^{6}\) | \(40.28\)
\(p_{0}\) | \(-8.754 \cdot 10^{7}\) | \(0\) | \(8.754 \cdot 10^{7}\) |
\(z_{0}\) | \(-1.593 \cdot 10^{6}\) | \(0\) | \(1.593 \cdot 10^{6}\) |
\(z_{0}\) | \(-1.998 \cdot 10^{9}\) | \(0\) | \(1.998 \cdot 10^{9}\) |

    103# Common-mode aysmptotic-gain model Bode plots
    104Acc = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="cc",
    105                   transfer="asymptotic")
    106Lcc = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="cc",
    107                   transfer="loopgain")
    108Scc = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="cc",
    109                   transfer="servo")
    110Dcc = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="cc",
    111                   transfer="direct")
    112Gcc = sl.doLaplace(Vamp, pardefs="circuit", numeric=True, convtype="cc",
    113                   transfer="gain")
    114# dB magnitude plots
    115sl.plotSweep("Vamp_cc_fb_dB", "Balanced voltage amplifier, common-mode",
    116             [Acc, Lcc, Scc, Dcc, Gcc], 0.1, 1e5, 200, sweepScale="k",
    117             funcType="dBmag")
    118# Phase plots
    119sl.plotSweep("Vamp_cc_fb_phs", "Balanced voltage amplifier, common-mode",
    120             [Acc, Lcc, Scc, Dcc, Gcc], 0.1, 1e5, 200, sweepScale="k",
    121             funcType="phase")

Bode plots of the feedback transfers of the common-mode equivalent circuit.

## Balanced noise

    123# Balanced noise
    124noisyCircuit = sl.makeCircuit("kicad/balancedNoisyNetwork/balancedNoisyNetwork.kicad_sch")

### Differential output noise

    126# Differential-mode output noise (complete circuit)
    127noiseResultD = sl.doNoise(noisyCircuit)

\[\begin{split}\begin{align} S_{vD} = & \frac{8 R_{a}^{2} R_{b} T k}{16 \pi^{2} C_{a}^{2} R_{a}^{2} R_{b}^{2} f^{2} + R_{a}^{2} + 2 R_{a} R_{b} + R_{b}^{2}} \nonumber \\ & + \frac{8 R_{a} R_{b}^{2} T k}{16 \pi^{2} C_{a}^{2} R_{a}^{2} R_{b}^{2} f^{2} + R_{a}^{2} + 2 R_{a} R_{b} + R_{b}^{2}} \nonumber \\ & + \frac{R_{b}^{2} S_{va}}{16 \pi^{2} C_{a}^{2} R_{a}^{2} R_{b}^{2} f^{2} + R_{a}^{2} + 2 R_{a} R_{b} + R_{b}^{2}} \nonumber \\ & + \frac{R_{b}^{2} S_{vb}}{16 \pi^{2} C_{a}^{2} R_{a}^{2} R_{b}^{2} f^{2} + R_{a}^{2} + 2 R_{a} R_{b} + R_{b}^{2}} \,\left[\mathrm{\frac{V^2}{Hz}}\right] \end{align}\end{split}\]

### Common-mode ouput noise

\[\begin{split}\begin{align} S_{vC} = & \frac{2 \pi^{2} C_{b}^{2} R_{a} T f^{2} k \left(R_{b} + 2 R_{c}\right)^{2}}{\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 2 \pi^{2} C_{b}^{2} R_{a} R_{b} f^{2} + 4 \pi^{2} C_{b}^{2} R_{a} R_{c} f^{2} + \pi^{2} C_{b}^{2} R_{b}^{2} f^{2} + 4 \pi^{2} C_{b}^{2} R_{b} R_{c} f^{2} + 4 \pi^{2} C_{b}^{2} R_{c}^{2} f^{2} + 1} \nonumber \\ & + \frac{0.25 \pi^{2} C_{b}^{2} S_{va} f^{2} \left(R_{b} + 2 R_{c}\right)^{2}}{\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 2 \pi^{2} C_{b}^{2} R_{a} R_{b} f^{2} + 4 \pi^{2} C_{b}^{2} R_{a} R_{c} f^{2} + \pi^{2} C_{b}^{2} R_{b}^{2} f^{2} + 4 \pi^{2} C_{b}^{2} R_{b} R_{c} f^{2} + 4 \pi^{2} C_{b}^{2} R_{c}^{2} f^{2} + 1} \nonumber \\ & + \frac{0.25 \pi^{2} C_{b}^{2} S_{vb} f^{2} \left(R_{b} + 2 R_{c}\right)^{2}}{\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 2 \pi^{2} C_{b}^{2} R_{a} R_{b} f^{2} + 4 \pi^{2} C_{b}^{2} R_{a} R_{c} f^{2} + \pi^{2} C_{b}^{2} R_{b}^{2} f^{2} + 4 \pi^{2} C_{b}^{2} R_{b} R_{c} f^{2} + 4 \pi^{2} C_{b}^{2} R_{c}^{2} f^{2} + 1} \nonumber \\ & + \frac{2 R_{b} T k \left(\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 1\right)}{\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 2 \pi^{2} C_{b}^{2} R_{a} R_{b} f^{2} + 4 \pi^{2} C_{b}^{2} R_{a} R_{c} f^{2} + \pi^{2} C_{b}^{2} R_{b}^{2} f^{2} + 4 \pi^{2} C_{b}^{2} R_{b} R_{c} f^{2} + 4 \pi^{2} C_{b}^{2} R_{c}^{2} f^{2} + 1} \nonumber \\ & + \frac{4 R_{c} T k \left(\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 1\right)}{\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 2 \pi^{2} C_{b}^{2} R_{a} R_{b} f^{2} + 4 \pi^{2} C_{b}^{2} R_{a} R_{c} f^{2} + \pi^{2} C_{b}^{2} R_{b}^{2} f^{2} + 4 \pi^{2} C_{b}^{2} R_{b} R_{c} f^{2} + 4 \pi^{2} C_{b}^{2} R_{c}^{2} f^{2} + 1} \nonumber \\ & + \frac{0.25 S_{i} \left(R_{b} + 2 R_{c}\right)^{2}}{\pi^{2} C_{b}^{2} R_{a}^{2} f^{2} + 2 \pi^{2} C_{b}^{2} R_{a} R_{b} f^{2} + 4 \pi^{2} C_{b}^{2} R_{a} R_{c} f^{2} + \pi^{2} C_{b}^{2} R_{b}^{2} f^{2} + 4 \pi^{2} C_{b}^{2} R_{b} R_{c} f^{2} + 4 \pi^{2} C_{b}^{2} R_{c}^{2} f^{2} + 1} \,\left[\mathrm{\frac{V^2}{Hz}}\right] \end{align}\end{split}\]

### Output noise of the differential-mode equivalent circuit

    132# DM equivalent circuit
    133DnoiseResult = sl.doNoise(noisyCircuit, convtype="dd")
    134
    135# Show difference (should be zero!)
    136diffD = sp.simplify(sl.assumePosParams(noiseResultD.onoise - DnoiseResult.onoise))
    137print("Difference onoise full circuit and DM equivalent network:", diffD)
    138# Display the noise source names
    139print("Noise sources:")
    140for src in noiseResultD.onoiseTerms:
    141    print(src, ":", noiseResultD.snoiseTerms[src])
    142print("Differential-mode noise sources contribution to DM onoise:")
    143for src in DnoiseResult.onoiseTerms:
    144    print(src, ":", DnoiseResult.snoiseTerms[src])

The console output:

    Detector changed to: V_out_D
    Difference onoise full circuit and DM equivalent network: 0
    Noise sources:
    I1 : S_i
    V1N : S_vb
    V1P : S_va
    I_noise_R1N : 4*T*k/R_a
    I_noise_R1P : 4*T*k/R_a
    I_noise_R2N : 4*T*k/R_b
    I_noise_R2P : 4*T*k/R_b
    I_noise_R3 : 4*T*k/R_c
    Differential-mode noise sources contribution to DM onoise:
    V1_D : S_va + S_vb
    I_noise_R1_D : 2*T*k/R_a
    I_noise_R2_D : 2*T*k/R_b

### Output noise of the common-mode equivalent circuit

    146# CM equivalent circuit
    147CnoiseResult = sl.doNoise(noisyCircuit, detector="circuit", convtype="cc")
    148
    149# Show difference (should be zero!)
    150diffC = sp.simplify(sl.assumePosParams(noiseResultC.onoise - CnoiseResult.onoise))
    151print("Difference onoise full circuit and CM equivalent network:", diffC)
    152# Display the noise source names
    153print("Noise sources:")
    154for src in noiseResultC.onoiseTerms:
    155    print(src, ":", noiseResultC.snoiseTerms[src])
    156print("Common-mode noise sources contribution to CM onoise:")
    157for src in CnoiseResult.onoiseTerms:
    158    print(src, ":", CnoiseResult.snoiseTerms[src])

The console output:

    Detector changed to: V_out_C
    Difference onoise full circuit and CM equivalent network: 0
    Noise sources:
    I1 : S_i
    V1N : S_vb
    V1P : S_va
    I_noise_R1N : 4*T*k/R_a
    I_noise_R1P : 4*T*k/R_a
    I_noise_R2N : 4*T*k/R_b
    I_noise_R2P : 4*T*k/R_b
    I_noise_R3 : 4*T*k/R_c
    Common-mode noise sources contribution to CM onoise:
    I1 : S_i
    V1_C : S_va/4 + S_vb/4
    I_noise_R1_C : 8*T*k/R_a
    I_noise_R2_C : 8*T*k/R_b
    I_noise_R3 : 4*T*k/R_c

## Balanced dcvar

    160# Balanced dc variance analysis
    161dcvarAmp  = sl.makeCircuit("kicad/balancedAmpDCvar/balancedAmpDCvar.kicad_sch")

### Differential output dc variance

    163# Differential-mode output dc variance (complete circuit)
    164dcvarD    = sl.doDCvar(dcvarAmp)

\[\begin{split}\begin{align} var_{vD} = & 2 I_{b}^{2} R_{a}^{2} \sigma_{R}^{2} \nonumber \\ & + \frac{2 \sigma_{ib}^{2} \left(R_{a} R_{b} - 2 R_{a} R_{s} - R_{b} R_{s}\right)^{2}}{R_{b}^{2}} \nonumber \\ & + \frac{2 \sigma_{io}^{2} \left(R_{a} R_{b} + 2 R_{a} R_{s} + R_{b} R_{s}\right)^{2}}{R_{b}^{2}} \nonumber \\ & + \frac{2 \sigma_{vo}^{2} \left(2 R_{a} + R_{b}\right)^{2}}{R_{b}^{2}} \,\left[\mathrm{V^2}\right] \end{align}\end{split}\]

### Common-mode ouput dc variance

    166# Common-mode output dc variance (complete circuit)
    167dcvarC    = sl.doDCvar(dcvarAmp, detector="V_comm")

\[var_{vC} = I_{b}^{2} R_{a}^{2} \sigma_{L}^{2} + 0.5 I_{b}^{2} R_{a}^{2} \sigma_{R}^{2} + 0.5 \sigma_{ib}^{2} \left(R_{a} - R_{s}\right)^{2} + 0.5 \sigma_{io}^{2} \left(R_{a} + R_{s}\right)^{2} + 0.5 \sigma_{vo}^{2}\,\,\left[\mathrm{V^2}\right]\]

### Output dc variance of the differential-mode equivalent circuit

    169# DM equivalent circuit
    170Ddcvar    = sl.doDCvar(dcvarAmp, convtype="dd")
    171
    172# Show difference (should be zero!)
    173diffOvarD = sp.simplify(dcvarD.ovar - Ddcvar.ovar)
    174print("Difference ovar full circuit and DM equivalent network:", diffOvarD)
    175# Display the dc variance source names
    176print("DC variance sources:")
    177for src in dcvarD.ovarTerms:
    178    print(src, ":", dcvarD.ovarTerms[src])
    179print("Differential-mode dc variance sources contribution to DM dc variance:")
    180for src in Ddcvar.ovarTerms:
    181    print(src, ":", Ddcvar.ovarTerms[src])

The console output:

    Detector changed to: V_out_D
    Difference ovar full circuit and DM equivalent network: 0
    DCvar sources:
    V1N : 0
    V1P : 0
    Ib_X1N : sigma_ib**2*(R_a*R_b - 2*R_a*R_s - R_b*R_s)**2/R_b**2
    Vm_X1N : 0
    Io_X1N : sigma_io**2*(R_a*R_b + 2*R_a*R_s + R_b*R_s)**2/R_b**2
    Vo_X1N : sigma_vo**2*(2*R_a + R_b)**2/R_b**2
    Ib_X1P : sigma_ib**2*(R_a*R_b - 2*R_a*R_s - R_b*R_s)**2/R_b**2
    Vm_X1P : 0
    Io_X1P : sigma_io**2*(R_a*R_b + 2*R_a*R_s + R_b*R_s)**2/R_b**2
    Vo_X1P : sigma_vo**2*(2*R_a + R_b)**2/R_b**2
    I_dcvar_R1N : 0
    I_dcvar_R1P : 0
    I_dcvar_R2N : I_b**2*R_a**2*sigma_R**2
    V_dcvar_Lot_1 : 0
    I_dcvar_R2P : I_b**2*R_a**2*sigma_R**2
    Differential-mode dc variance sources contribution to DM onoise:
    V1_D : 0
    Ib_X1_D : 2*sigma_ib**2*(R_a*R_b - 2*R_a*R_s - R_b*R_s)**2/R_b**2
    Vm_X1_D : 0
    Io_X1_D : 2*sigma_io**2*(R_a*R_b + 2*R_a*R_s + R_b*R_s)**2/R_b**2
    Vo_X1_D : 2*sigma_vo**2*(2*R_a + R_b)**2/R_b**2
    I_dcvar_R1_D : 0
    I_dcvar_R2_D : 2*I_b**2*R_a**2*sigma_R**2

### Output dc variance of the common-mode equivalent circuit

    183# CM equivalent circuit
    184Cdcvar    = sl.doDCvar(dcvarAmp, convtype="cc")
    185
    186# Show difference (should be zero!)
    187diffOvarC = sp.simplify(dcvarC.ovar - Cdcvar.ovar)
    188print("Difference ovar full circuit and CM equivalent network:", diffOvarC)
    189# Display the dcvariance source names
    190print("DC variance sources:")
    191for src in dcvarC.ovarTerms:
    192    print(src, ":", dcvarC.ovarTerms[src])
    193print("Common-mode dc variance sources contribution to CM dc variance:")
    194for src in Cdcvar.ovarTerms:
    195    print(src, ":", Cdcvar.ovarTerms[src])

The console output:

    Detector changed to: V_out_C
    Difference ovar full circuit and CM equivalent network: 0
    DC variance sources:
    V1N : 0
    V1P : 0
    Ib_X1N : sigma_ib**2*(R_a - R_s)**2/4
    Vm_X1N : 0
    Io_X1N : sigma_io**2*(R_a + R_s)**2/4
    Vo_X1N : sigma_vo**2/4
    Ib_X1P : sigma_ib**2*(R_a - R_s)**2/4
    Vm_X1P : 0
    Io_X1P : sigma_io**2*(R_a + R_s)**2/4
    Vo_X1P : sigma_vo**2/4
    I_dcvar_R1N : 0
    I_dcvar_R1P : 0
    I_dcvar_R2N : I_b**2*R_a**2*sigma_R**2/4
    V_dcvar_Lot_1 : I_b**2*R_a**2*sigma_L**2
    I_dcvar_R2P : I_b**2*R_a**2*sigma_R**2/4
    Common-mode dc variance sources contribution to CM dc variance:
    V1_C : 0
    Ib_X1_C : sigma_ib**2*(R_a - R_s)**2/2
    Vm_X1_C : 0
    Io_X1_C : sigma_io**2*(R_a + R_s)**2/2
    Vo_X1_C : sigma_vo**2/2
    I_dcvar_R1_C : 0
    I_dcvar_R2_C : I_b**2*R_a**2*sigma_R**2/2
    V_dcvar_Lot_1 : I_b**2*R_a**2*sigma_L**2