Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix n-port mismatch junction issue in Circuit #1028

Merged
merged 10 commits into from
Feb 18, 2024
Merged

Conversation

mhuser
Copy link
Collaborator

@mhuser mhuser commented Feb 17, 2024

Fix issue #1022
It appears that formula (3) in P. Hallbjörner, Microw. Opt. Technol. Lett. 38, 99 (2003). does not work for mismatched intersections.
This was temporarily fixed for 2-connection intersections and is now generalized to n-connection intersections with mismatched port impedances.

  • Fix circuit
  • Optimize
  • Update test_circuit
  • Add mismatched splitter to media and a test case

@mhuser mhuser added fix Bug Fix Circuit labels Feb 17, 2024
@mhuser mhuser linked an issue Feb 17, 2024 that may be closed by this pull request
@github-actions github-actions bot added the Media label Feb 17, 2024
@mhuser mhuser changed the title Fix1022 fix n-port mismatch junction issue in Circuit Feb 18, 2024
@mhuser mhuser marked this pull request as ready for review February 18, 2024 00:43
@mhuser
Copy link
Collaborator Author

mhuser commented Feb 18, 2024

I wrote the equations in Media.splitter doc as a reminder.

Copy link
Member

@jhillairet jhillairet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work @mhuser !

skrf/circuit.py Show resolved Hide resolved
@jhillairet
Copy link
Member

It's no more relevant, but for info here is another implementation of the S-matrix renormalization from a given Z0 to Z0'. The numerical precision is better than the current implementation using s2z(z2s()) but it only works for power waves.

def renormalize_s2(
        s: npy.ndarray, z_old: NumberLike, z_new: NumberLike,
        ) -> npy.ndarray:
    """
    Renormalize a s-parameter matrix given old and new port impedances.
    
    Use equations from [#Reveyrand]_. 
    The numerical precision of this method is better than `renormalize_s`, 
    however, it only supports the power-wave definition.
   
    Parameters
    ----------
    s : complex array of shape `fxnxn`
        s-parameter matrix

    z_old : complex array of shape `fxnxn` or a scalar
        old (original) port impedances

    z_new : complex array of shape `fxnxn` or a scalar
        new port impedances

    Returns
    -------
    :class:`numpy.ndarray`
        renormalized s-parameter matrix (shape `fxnxn`)

    See Also
    --------
    Network.renormalize : method of Network to renormalize s
    renormalize_s
    fix_z0_shape
    s2s

    References
    ----------
    .. [#Reveyrand] T. Reveyrand, "Multiport conversions between S, Z, Y, h, 
        ABCD, and T parameters’, in 2018 International Workshop on Integrated 
        Nonlinear Microwave and Millimetre-wave Circuits (INMMIC)"",
        Brive La Gaillarde: IEEE, Jul. 2018, pp. 1–3.
        doi: 10.1109/INMMIC.2018.8430023.

    """
    nfreqs, nports, nports = s.shape
    z_old = fix_z0_shape(z_old, nfreqs, nports)
    z_new = fix_z0_shape(z_new, nfreqs, nports)
   
    Id = npy.zeros_like(s, dtype='complex')
    R = npy.zeros_like(s, dtype='complex')
    Gold = npy.zeros_like(s, dtype='complex')
    Gnew = npy.zeros_like(s, dtype='complex')
    
    npy.einsum('ijj->ij', Id)[...] = 1
    npy.einsum('ijj->ij', R)[...] = (z_new - z_old)/(z_new + z_old.conj())
    npy.einsum('ijj->ij', Gold)[...] = 1/npy.sqrt(npy.abs(z_old.real))
    npy.einsum('ijj->ij', Gnew)[...] = 1/npy.sqrt(npy.abs(z_new.real))

    A = npy.linalg.inv(Gnew) @ Gold @ (Id - R.conj())

    return npy.linalg.inv(A) @ (s - R.conj()) @ npy.linalg.inv(Id - R@s) @ A.conj()

@mhuser
Copy link
Collaborator Author

mhuser commented Feb 18, 2024

It's no more relevant, but for info here is another implementation of the S-matrix renormalization from a given Z0 to Z0'. The numerical precision is better than the current implementation using s2z(z2s()) but it only works for power waves.

Very interesting. Maybe we could use this in renormalize_s and fallback to z2s(s2z() if s_def is not power-wave?
We know that current renormalize_s is weak when transformation between $S$ and $Z$ would yeld the inverse of a singular matrix.

@jhillairet
Copy link
Member

It's no more relevant, but for info here is another implementation of the S-matrix renormalization from a given Z0 to Z0'. The numerical precision is better than the current implementation using s2z(z2s()) but it only works for power waves.

Very interesting. Maybe we could use this in renormalize_s and fallback to z2s(s2z() if s_def is not power-wave? We know that current renormalize_s is weak when transformation between S and Z would yeld the inverse of a singular matrix.

Eventually... Let's see that in another PR.

@mhuser mhuser merged commit 22aba87 into scikit-rf:master Feb 18, 2024
12 checks passed
@mhuser mhuser deleted the fix1022 branch February 18, 2024 16:20
@jhillairet jhillairet mentioned this pull request Feb 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

S-parameter calculation incorrect for 3-port circuit
2 participants