def test_sparam_conversion_vs_sdefinition(self): ''' Check that power-wave or pseudo-waves scattering parameters definitions give same results for real characteristic impedances ''' f0 = rf.Frequency(75.8, npoints=1, unit='GHz') s_ref = npy.array([[ # random values [-0.1000 -0.2000j, -0.3000 +0.4000j], [-0.3000 +0.4000j, 0.5000 -0.6000j]]]) ntw = rf.Network(frequency=f0, s=s_ref, z0=50, name='dut') # renormalize s parameter according one of the definition. # As characteristic impedances are all real, should be all equal npy.testing.assert_allclose(ntw.s, s_ref) npy.testing.assert_allclose(rf.renormalize_s(ntw.s, 50, 50, s_def='power'), s_ref) npy.testing.assert_allclose(rf.renormalize_s(ntw.s, 50, 50, s_def='pseudo'), s_ref) npy.testing.assert_allclose(rf.renormalize_s(ntw.s, 50, 50, s_def='traveling'), s_ref) # also check Z and Y matrices, just in case z_ref = npy.array([[ [18.0000 -16.0000j, 20.0000 + 40.0000j], [20.0000 +40.0000j, 10.0000 -80.0000j]]]) npy.testing.assert_allclose(ntw.z, z_ref, atol=1e-4) y_ref = npy.array([[ [0.0251 +0.0023j, 0.0123 -0.0066j], [0.0123 -0.0066j, 0.0052 +0.0055j]]]) npy.testing.assert_allclose(ntw.y, y_ref, atol=1e-4) # creating network by specifying s-params definition ntw_power = rf.Network(frequency=f0, s=s_ref, z0=50, s_def='power') ntw_pseudo = rf.Network(frequency=f0, s=s_ref, z0=50, s_def='pseudo') ntw_legacy = rf.Network(frequency=f0, s=s_ref, z0=50, s_def='traveling') self.assertTrue(ntw_power == ntw_pseudo) self.assertTrue(ntw_power == ntw_legacy)
def test_sparam_conversion_with_complex_char_impedance(self): ''' Renormalize a 2-port network wrt to complex characteristic impedances using power-waves definition of s-param Example based on scikit-rf issue #313 ''' f0 = rf.Frequency(75.8, npoints=1, unit='GHz') s0 = npy.array([[-0.194 - 0.228j, -0.721 + 0.160j], [-0.721 + 0.160j, +0.071 - 0.204j]]) ntw = rf.Network(frequency=f0, s=s0, z0=50, name='dut') # complex characteristic impedance to renormalize to zdut = 100 + 10j # reference solutions obtained from ANSYS Circuit or ADS (same res) # case 1: z0=[50, zdut] s_ref = npy.array( [[[-0.01629813 - 0.29764199j, -0.6726785 + 0.24747539j], [-0.6726785 + 0.24747539j, -0.30104687 - 0.10693578j]]]) npy.testing.assert_allclose(rf.z2s(ntw.z, z0=[50, zdut]), s_ref) npy.testing.assert_allclose( rf.renormalize_s(ntw.s, [50, 50], [50, zdut]), s_ref) # case 2: z0=[zdut, zdut] s_ref = npy.array([[[ -0.402829859501534 - 0.165007172677339j, -0.586542065592524 + 0.336098534178339j ], [ -0.586542065592524 + 0.336098534178339j, -0.164707376748782 - 0.21617153431756j ]]]) npy.testing.assert_allclose(rf.z2s(ntw.z, z0=[zdut, zdut]), s_ref) npy.testing.assert_allclose( rf.renormalize_s(ntw.s, [50, 50], [zdut, zdut]), s_ref) # Compararing Z and Y matrices from reference ones (from ADS) # Z or Y matrices do not depend of characteristic impedances. # Precision is 1e-4 due to rounded results in ADS export files z_ref = npy.array([[[34.1507 - 65.6786j, -37.7994 + 73.7669j], [-37.7994 + 73.7669j, 55.2001 - 86.8618j]]]) npy.testing.assert_allclose(ntw.z, z_ref, atol=1e-4) y_ref = npy.array([[[0.0926 + 0.0368j, 0.0770 + 0.0226j], [0.0770 + 0.0226j, 0.0686 + 0.0206j]]]) npy.testing.assert_allclose(ntw.y, y_ref, atol=1e-4)
def setUp(self): self.f0 = rf.Frequency(75.8, npoints=1, unit='GHz') # initial s-param values of A 2 ports network self.s0 = np.array([ # dummy values [-0.1000 -0.2000j, -0.3000 +0.4000j], [-0.3000 +0.4000j, 0.5000 -0.6000j]]).reshape(-1,2,2) # build initial network (under z0=50) self.ntw0 = rf.Network(frequency=self.f0, s=self.s0, z0=50, name='dut') # complex characteristic impedance to renormalize to self.zdut = 100 + 10j # reference solutions obtained from ANSYS Circuit or ADS (same res) # when z0=[50, zdut] self.z_ref = np.array([ # not affected by z0 [18.0000 -16.0000j, 20.0000 +40.0000j], [20.0000 +40.0000j, 10.0000 -80.0000j]]).reshape(-1,2,2) self.y_ref = np.array([ # not affected by z0 [0.0251 +0.0023j, 0.0123 -0.0066j], [0.0123 -0.0066j, 0.0052 +0.0055j]]).reshape(-1,2,2) self.s_ref = np.array([ # renormalized s (power-waves) [-0.1374 -0.2957j, -0.1995 +0.5340j], [-0.1995 +0.5340j, -0.0464 -0.7006j]]).reshape(-1,2,2) # Creating equivalent reference circuit port1 = rf.Circuit.Port(self.f0, z0=50, name='port1') port2 = rf.Circuit.Port(self.f0, z0=50, name='port2') ntw0 = rf.Network(frequency=self.f0, z0=50, s=self.s0, name='dut') cnx = [ # z0=[50,50] [(port1, 0), (ntw0, 0)], [(ntw0, 1), (port2, 0)] ] self.cir = rf.Circuit(cnx) # Creating equivalent circuit with z0 real port2_real = rf.Circuit.Port(self.f0, z0=100, name='port2') cnx_real = [ # z0=[50,100] [(port1, 0), (ntw0, 0)], [(ntw0, 1), (port2_real, 0)] ] self.cir_real = rf.Circuit(cnx_real) # Creating equivalent circuit with z0 complex port2_complex = rf.Circuit.Port(self.f0, z0=self.zdut, name='port2') cnx_complex = [ # z0=[50,zdut] [(port1, 0), (ntw0, 0)], [(ntw0, 1), (port2_complex, 0)] ] self.cir_complex = rf.Circuit(cnx_complex) # references for each s-param definition self.s_legacy = rf.renormalize_s(self.s0, [50,50], [50,self.zdut], s_def='traveling') self.s_power = rf.renormalize_s(self.s0, [50,50], [50,self.zdut], s_def='power') self.s_pseudo = rf.renormalize_s(self.s0, [50,50], [50,self.zdut], s_def='pseudo') # for real values, should be = whatever s-param definition self.s_real = rf.renormalize_s(self.s0, [50,50], [50,100])