Ejemplo n.º 1
0
def dipole():
    s1p_file = './resource/single_dipole.s1p'
    freq, n, z_data, s_data, z0_data = vecfit.read_snp(s1p_file)
    cs = freq * 2j * np.pi

    # Try to fit S
    # f_out = vecfit.fit_s(s_data, cs, n_pole=3, n_iter=20, s_inf=-1)
    # f_out = vecfit.fit_s(s_data, cs, n_pole=6, n_iter=20, s_inf=-1, bound_wt=0.3)
    # f_out = vecfit.bound_tightening(s_data, cs)  # np.inf, -1
    f_out, log = vecfit.bound_tightening_sweep(s_data, cs)

    bound, bw = f_out.bound(np.inf, f0=2.4e9)
    bound_error = f_out.bound_error(s_data, cs, reflect=np.inf)
    # ant_integral = f_out.bound_integral(cs, reflect=np.inf)
    ant_integral = vecfit.bound_integral(s_data, cs, np.inf)
    print(
        'Bound is {:.5e}, BW is {:.5e}, Bound error is {:.5e}, The integral of the antenna is {:.5e}'
        .format(bound, bw, bound_error, ant_integral))

    ax1 = vecfit.plot_freq_resp(cs, s_data, y_scale='db')
    f_out.plot(cs, ax=ax1, y_scale='db', linestyle='--')
    vecfit.plot_freq_resp(cs,
                          s_data - f_out.model(cs),
                          ax=ax1,
                          y_scale='db',
                          linestyle='--')
    ax2 = f_out.plot_improved_bound(1e11, 4e10)
Ejemplo n.º 2
0
def coupled_siw():
    s2p_file = './resource/two_SIW_antenna_39GHz_50mil.s2p'
    freq, n, z, s, z0 = vecfit.read_snp(s2p_file)
    s_z0 = np.zeros(z.shape, dtype=z.dtype)
    cs = freq * 2j * np.pi
    # z0 = 50
    z0 = 190
    for i in range(len(freq)):
        s_z0[:, :,
             i] = np.matrix(z[:, :, i] / z0 - np.identity(n)) * np.linalg.inv(
                 np.matrix(z[:, :, i] / z0 + np.identity(n)))

    s_model, bound = vecfit.mode_fitting(s_z0, cs, True)
    bound_error = s_model.bound_error(s_z0, cs, reflect=np.inf)
    ant_integral = vecfit.bound_integral(s_z0, cs, np.inf)
    print(
        'Bound is {:.5e}, Bound error is {:.5e}, The integral of the antenna is {:.5e}'
        .format(bound, bound_error, ant_integral))

    # plots
    axs = vecfit.plot_freq_resp_matrix(cs, s_z0, y_scale='db')
    s_model.plot(cs, axs=axs, y_scale='db', linestyle='--')
    vecfit.plot_freq_resp_matrix(cs,
                                 s_z0 - s_model.model(cs),
                                 axs=axs,
                                 y_scale='db',
                                 linestyle='--')
Ejemplo n.º 3
0
def single_siw():
    s1p_file = './resource/single_SIW_antenna_39GHz_50mil.s1p'
    freq, n, z_data, s_data, z0_data = vecfit.read_snp(s1p_file)
    z0 = 190
    s_data = (z_data - z0) / (z_data + z0)
    cs = freq * 2j * np.pi

    # Try to fit S
    # f_out = vecfit.fit_s(s_data, cs, n_pole=18, n_iter=20, s_dc=0, s_inf=1, bound_wt=0.27)
    f_out = vecfit.bound_tightening(s_data, cs)

    bound, bw = f_out.bound(np.inf, f0=39e9)
    bound_error = f_out.bound_error(s_data, cs, reflect=np.inf)
    # ant_integral = f_out.bound_integral(cs, reflect=np.inf)
    ant_integral = vecfit.bound_integral(s_data, cs, np.inf)
    print(
        'Bound is {:.5e}, BW is {:.5e}, Bound error is {:.5e}, The integral of the antenna is {:.5e}'
        .format(bound, bw, bound_error, ant_integral))

    ax1 = vecfit.plot_freq_resp(cs, s_data, x_scale='log', y_scale='db')
    f_out.plot(cs, ax=ax1, x_scale='log', y_scale='db', linestyle='--')
    vecfit.plot_freq_resp(cs,
                          s_data - f_out.model(cs),
                          ax=ax1,
                          x_scale='log',
                          y_scale='db',
                          linestyle='--')
    ax2 = f_out.plot_improved_bound(1.2e10, 4e11)
Ejemplo n.º 4
0
def coupled_siw_even_odd():
    s2p_file = './resource/two_SIW_antenna_39GHz_50mil.s2p'
    freq, n, z, s, z0 = vecfit.read_snp(s2p_file)
    s_z0 = np.zeros(z.shape, dtype=z.dtype)
    cs = freq * 2j * np.pi
    # z0 = 50
    z0 = 190
    for i in range(len(freq)):
        s_z0[:, :,
             i] = np.matrix(z[:, :, i] / z0 - np.identity(n)) * np.linalg.inv(
                 np.matrix(z[:, :, i] / z0 + np.identity(n)))

    # Fit even and odd mode separately
    s_even = ((s_z0[0, 0, :] + s_z0[0, 1, :] + s_z0[1, 0, :] + s_z0[1, 1, :]) /
              2).reshape(len(freq))
    s_odd = ((s_z0[0, 0, :] - s_z0[0, 1, :] - s_z0[1, 0, :] + s_z0[1, 1, :]) /
             2).reshape(len(freq))

    # Even mode
    # f_even = vecfit.fit_s(s_even, cs, n_pole=19, n_iter=20, s_inf=1, bound_wt=1.1)
    f_even = vecfit.bound_tightening(s_even, cs)
    bound_even, bw_even = f_even.bound(np.inf, f0=39e9)
    bound_error_even = f_even.bound_error(s_even, cs, reflect=np.inf)
    # integral_even = f_even.bound_integral(cs, reflect=np.inf)
    integral_even = vecfit.bound_integral(s_even, cs, np.inf)

    # Odd mode
    # f_odd = vecfit.fit_s(s_odd, cs, n_pole=17, n_iter=20, s_inf=1, bound_wt=0.62)
    f_odd = vecfit.bound_tightening(s_odd, cs)
    bound_odd, bw_odd = f_odd.bound(np.inf, f0=39e9)
    bound_error_odd = f_odd.bound_error(s_odd, cs, reflect=np.inf)
    # integral_odd = f_odd.bound_integral(cs, reflect=np.inf)
    integral_odd = vecfit.bound_integral(s_odd, cs, np.inf)

    print(
        'Even mode: bound is {:.5e}, BW is {:.5e}, Bound error is {:.5e}, The integral of the antenna is {:.5e}'
        .format(bound_even, bw_even, bound_error_even, integral_even))
    print(
        'Odd mode: bound is {:.5e}, BW is {:.5e}, Bound error is {:.5e}, The integral of the antenna is {:.5e}'
        .format(bound_odd, bw_odd, bound_error_odd, integral_odd))

    # plots
    ax1 = vecfit.plot_freq_resp(cs, s_even, y_scale='db')
    f_even.plot(cs, ax=ax1, y_scale='db', linestyle='--')
    vecfit.plot_freq_resp(cs,
                          s_even - f_even.model(cs),
                          ax=ax1,
                          y_scale='db',
                          linestyle='--')
    ax2 = f_even.plot_improved_bound(2e10, 4e11)

    ax3 = vecfit.plot_freq_resp(cs, s_odd, y_scale='db')
    f_odd.plot(cs, ax=ax3, y_scale='db', linestyle='--')
    vecfit.plot_freq_resp(cs,
                          s_odd - f_odd.model(cs),
                          ax=ax3,
                          y_scale='db',
                          linestyle='--')
    ax4 = f_odd.plot_improved_bound(2e10, 4e11)
Ejemplo n.º 5
0
def coupled_dipole():
    s2p_file = './resource/coupled_dipoles.s2p'
    freq, n, z_data, s_data, z0_data = vecfit.read_snp(s2p_file)
    cs = freq * 2j * np.pi

    # Fit even and odd mode separately
    s_even = ((s_data[0, 0, :] + s_data[0, 1, :] + s_data[1, 0, :] +
               s_data[1, 1, :]) / 2).reshape(len(freq))
    s_odd = ((s_data[0, 0, :] - s_data[0, 1, :] - s_data[1, 0, :] +
              s_data[1, 1, :]) / 2).reshape(len(freq))
    # Even and odd mode
    # f_even = vecfit.fit_s(s_even, cs, n_pole=3, n_iter=20, s_inf=-1)
    # f_odd = vecfit.fit_s(s_odd, cs, n_pole=3, n_iter=20, s_inf=-1)
    # f_even = vecfit.bound_tightening(s_even, cs)
    # f_odd = vecfit.bound_tightening(s_odd, cs)
    f_even, log_even = vecfit.bound_tightening_sweep(s_even, cs, np.inf)
    f_odd, log_odd = vecfit.bound_tightening_sweep(s_odd, cs, np.inf)

    bound_even, bw_even = f_even.bound(np.inf, f0=2.4e9)
    bound_error_even = f_even.bound_error(s_even, cs, reflect=np.inf)
    bound_odd, bw_odd = f_odd.bound(np.inf, f0=2.4e9)
    bound_error_odd = f_odd.bound_error(s_odd, cs, reflect=np.inf)
    print('Manual even/odd mode decomposition:')
    print(
        'Even mode, # poles {}, bound {:.5e}, bound error {:.5e}, sum {:.5e}'.
        format(len(f_even.pole), bound_even, bound_error_even,
               bound_even + bound_error_even))
    print('Odd mode, # poles {}, bound {:.5e}, bound error {:.5e}, sum {:.5e}'.
          format(len(f_odd.pole), bound_odd, bound_error_odd,
                 bound_odd + bound_error_odd))
    fig = plt.figure(figsize=(8, 5.5))
    ax1 = fig.add_subplot(211)
    ax2 = fig.add_subplot(212)
    vecfit.plot_freq_resp(cs, s_even, ax=ax1, y_scale='db')
    f_even.plot(cs, ax=ax1, y_scale='db', linestyle='--')
    vecfit.plot_freq_resp(cs, s_odd, ax=ax2, y_scale='db')
    f_odd.plot(cs, ax=ax2, y_scale='db', linestyle='--')

    # Try to fit S
    # fixed_pole = np.concatenate([f_even.pole, f_odd.pole])
    # s_model = vecfit.matrix_fitting_rescale(s_data, cs, n_pole=6, n_iter=20, has_const=True, has_linear=False, fixed_pole=fixed_pole)
    # s_model = s_model.rank_one()
    # s_model = vecfit.matrix_fitting_rank_one_rescale(s_data, cs, n_pole=6, n_iter=50, has_const=True, has_linear=True)
    s_model, bound = vecfit.mode_fitting(s_data, cs, True)
    bound_error = s_model.bound_error(s_data, cs, reflect=np.inf)
    ant_integral = vecfit.bound_integral(s_data, cs, np.inf)
    print(
        'Bound is {:.5e}, Bound error is {:.5e}, The integral of the antenna is {:.5e}'
        .format(bound, bound_error, ant_integral))

    axs = vecfit.plot_freq_resp_matrix(cs, s_data, y_scale='db')
    s_model.plot(cs, axs=axs, y_scale='db', linestyle='--')
Ejemplo n.º 6
0
def four_ifa():
    snp_file = './resource/4Port_IFA_Free_Space.s4p'
    freq, n, z_data, s_data, z0_data = vecfit.read_snp(snp_file)
    cs = freq * 2j * np.pi

    # Fit modes separately
    s_matrix, bound = vecfit.mode_fitting(s_data, cs, True)
    bound_error = s_matrix.bound_error(s_data, cs, reflect=np.inf)
    ant_integral = vecfit.bound_integral(s_data, cs, np.inf)
    print(
        'Bound is {:.5e}, Bound error is {:.5e}, The integral of the antenna is {:.5e}'
        .format(bound, bound_error, ant_integral))

    # plot the s_matrix
    axs = vecfit.plot_freq_resp_matrix(cs, s_data, y_scale='db')
    s_matrix.plot(cs, axs=axs, y_scale='db', linestyle='--')
Ejemplo n.º 7
0
def skycross_antennas():
    snp_file = './resource/Skycross_4_parallel_fine2.s4p'
    freq, n, z_data, s_data, z0_data = vecfit.read_snp(snp_file)
    cs = freq * 2j * np.pi

    s_matrix, bound = vecfit.mode_fitting(s_data, cs, True)
    bound_error = s_matrix.bound_error(s_data, cs, reflect=np.inf)
    ant_integral = vecfit.bound_integral(s_data, cs, np.inf)
    print(
        'Bound is {:.5e}, Bound error is {:.5e}, The integral of the antenna is {:.5e}'
        .format(bound, bound_error, ant_integral))

    # plot per mode response
    # calculate the bound error
    s_fit = s_matrix.model(cs)
    s_error = s_fit - s_data

    u, sigma, vh = np.linalg.svd(np.moveaxis(s_error, -1, 0))
    sigma_error = sigma[:, 0].flatten()
    u, sigma, vh = np.linalg.svd(np.moveaxis(s_data, -1, 0))
    sigma_max = sigma[:, 0].flatten()
    sigma_min = sigma[:, -1].flatten()

    rho = (2 * sigma_error) / (
        1 - np.power(sigma_max, 2)) * np.sqrt(1 +
                                              (sigma_max**2 - sigma_min**2) /
                                              (1 - sigma_max)**2)

    tau = 0.3162278
    int_fct = vecfit.f_integral(
        cs.imag, 0) / 2 * np.log(1 + (1 - tau**2) / tau**2 * rho)
    delta_b = vecfit.num_integral(cs.imag, int_fct)
    print('Bound error is {:.2e}'.format(delta_b))

    int_fct = vecfit.f_integral(cs.imag, 0) * (1 - np.sum(sigma**2, 1) / n)
    unmatched_integral = vecfit.num_integral(cs.imag, int_fct)
    print('Unmatched integral is {:.2e}'.format(unmatched_integral))

    # plot the s_matrix
    axs = vecfit.plot_freq_resp_matrix(cs, s_data, y_scale='db')
    s_matrix.plot(cs, axs=axs, y_scale='db', linestyle='--')
Ejemplo n.º 8
0
def skycross_antennas_old():
    snp_file = './resource/Skycross_4_parallel_fine2.s4p'
    freq, n, z_data, s_data, z0_data = vecfit.read_snp(snp_file)
    # z0 = 50
    # s_data = (z_data-z0) / (z_data+z0)
    cs = freq * 2j * np.pi
    cs_all = np.logspace(0, 15, 10000) * 2j * np.pi

    # Fit modes separately
    s_inf = 1
    inf_weight = 1e6
    s_data = np.concatenate(
        [s_data, np.reshape(inf_weight * np.identity(n), [n, n, 1])], 2)
    u_a, Lambda_A, vh_a, A_remain, err_norm, orig_norm = vecfit.joint_svd(
        s_data)
    s_data = s_data[:, :, :-1]
    Lambda_A = Lambda_A[:, :, :-1]
    A_remain = A_remain[:, :, :-1]

    # poles_by_mode = [5, 7, 9, 6]
    poles_by_mode = [5, 8, 5, 7]  # s_inf = 1
    f_by_mode = []
    total_bound = 0.0
    for i in range(n):
        s_mode = Lambda_A[i, i, :]
        f_mode = vecfit.fit_s(s_mode * np.exp(1j * np.pi * 0),
                              cs,
                              n_pole=poles_by_mode[i],
                              n_iter=20,
                              s_dc=s_inf)
        mode_bound = f_mode.bound(0)
        print('Mode {} bound is {:.2e}'.format(i, mode_bound[0]))
        total_bound += mode_bound[0]
        f_by_mode.append(f_mode)
        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.plot(np.abs(cs) / 2 / np.pi, 20 * np.log10(np.abs(s_mode)), 'b-')
        ax.semilogx(
            np.abs(cs_all) / 2 / np.pi,
            20 * np.log10(np.abs(f_mode.model(cs_all))), 'r--')
        ax.grid(True)
        ax.set_xlabel('Frequency (Hz)')
        ax.set_ylabel('S even Amplitude (dB)')
    total_bound /= n
    print('Total bound is {:.2e}'.format(total_bound))
    # Put the modes back to matrix
    pole = np.zeros([np.sum(poles_by_mode)], dtype=np.complex128)
    residue = np.zeros([n, n, np.sum(poles_by_mode)], dtype=np.complex128)
    const = np.zeros([n, n], dtype=np.complex128)
    idx = 0
    for i in range(n):
        tmp_matrix = np.zeros([n, n], dtype=np.complex128)
        tmp_matrix[i, i] = 1
        pole_range = np.array(range(idx, idx + poles_by_mode[i]))

        pole[pole_range] = f_by_mode[i].pole
        for j in range(poles_by_mode[i]):
            residue_matrix = np.dot(
                np.dot(u_a, f_by_mode[i].residue[j] * tmp_matrix), vh_a)
            residue[:, :, pole_range[j]] = residue_matrix
        const += np.dot(np.dot(u_a, f_by_mode[i].const * tmp_matrix), vh_a)
        idx += poles_by_mode[i]
    s_matrix = vecfit.RationalMtx(pole, residue, const)

    # # do another fit for the remaining errors
    # s_inf = -1
    # inf_weight = 1e6
    # s_remain = np.concatenate([A_remain, np.reshape(inf_weight * np.identity(n), [n, n, 1])], 2)
    # u_a, Lambda_A, vh_a, A_remain, err_norm, orig_norm = vecfit.joint_svd(s_remain)
    # s_remain = s_remain[:, :, :-1]
    # Lambda_A = Lambda_A[:, :, :-1]
    # A_remain = A_remain[:, :, :-1]
    #
    # poles_by_mode = [7, 11, 8, 9]
    # f_by_mode = []
    # total_bound = 0.0
    # for i in range(n):
    #     s_mode = Lambda_A[i, i, :]
    #     f_mode = vecfit.fit_s(s_mode * np.exp(1j*np.pi*0), cs, n_pole=poles_by_mode[i], n_iter=20, s_inf=s_inf)
    #     mode_bound = f_mode.bound(np.inf)
    #     print('Mode {} bound is {:.2e}'.format(i, mode_bound[0]))
    #     total_bound += mode_bound[0]
    #     f_by_mode.append(f_mode)
    #     fig = plt.figure()
    #     ax = fig.add_subplot(111)
    #     ax.plot(np.abs(cs) / 2 / np.pi, 20 * np.log10(np.abs(s_mode)), 'b-')
    #     ax.semilogx(np.abs(cs_all) / 2 / np.pi, 20 * np.log10(np.abs(f_mode.model(cs_all))), 'r--')
    #     ax.grid(True)
    #     ax.set_xlabel('Frequency (Hz)')
    #     ax.set_ylabel('S even Amplitude (dB)')
    # total_bound /= n
    # print('Total bound is {:.2e}'.format(total_bound))
    # # Put the modes back to matrix
    # pole = np.zeros([np.sum(poles_by_mode)], dtype=np.complex128)
    # residue = np.zeros([n, n, np.sum(poles_by_mode)], dtype=np.complex128)
    # const = np.zeros([n, n], dtype=np.complex128)
    # idx = 0
    # for i in range(n):
    #     tmp_matrix = np.zeros([n, n], dtype=np.complex128)
    #     tmp_matrix[i, i] = 1
    #     pole_range = np.array(range(idx, idx+poles_by_mode[i]))
    #
    #     pole[pole_range] = f_by_mode[i].pole
    #     for j in range(poles_by_mode[i]):
    #         residue_matrix = np.dot(np.dot(u_a, f_by_mode[i].residue[j]*tmp_matrix), vh_a)
    #         residue[:, :, pole_range[j]] = residue_matrix
    #     const += np.dot(np.dot(u_a, f_by_mode[i].const*tmp_matrix), vh_a)
    #     idx += poles_by_mode[i]
    # s_matrix = vecfit.RationalMtx(pole, residue, const) + s_matrix

    # calculate the bound error
    s_fit = s_matrix.model(cs)
    s_error = s_fit - s_data

    u, sigma, vh = np.linalg.svd(np.moveaxis(s_error, -1, 0))
    sigma_error = sigma[:, 0].flatten()
    u, sigma, vh = np.linalg.svd(np.moveaxis(s_data, -1, 0))
    sigma_max = sigma[:, 0].flatten()
    sigma_min = sigma[:, -1].flatten()

    rho = (2 * sigma_error) / (
        1 - np.power(sigma_max, 2)) * np.sqrt(1 +
                                              (sigma_max**2 - sigma_min**2) /
                                              (1 - sigma_max)**2)

    tau = 0.3162278
    int_fct = vecfit.f_integral(
        cs.imag, 0) / 2 * np.log(1 + (1 - tau**2) / tau**2 * rho)
    delta_b = vecfit.num_integral(cs.imag, int_fct)
    print('Bound error is {:.2e}'.format(delta_b))

    int_fct = vecfit.f_integral(cs.imag, 0) * (1 - np.sum(sigma**2, 1) / n)
    unmatched_integral = vecfit.num_integral(cs.imag, int_fct)
    print('Unmatched integral is {:.2e}'.format(unmatched_integral))

    # plot the s_matrix
    s = 2j * np.pi * freq
    s_model = s_matrix.model(s)
    fig1 = plt.figure()
    ax1 = fig1.add_subplot(321)
    ax1.plot(freq, 20 * np.log10(np.abs(s_model[0, 0, :].flatten())), 'b-')
    ax1.plot(freq, 20 * np.log10(np.abs(s_data[0, 0, :].flatten())), 'r--')
    # ax1.plot(freq, 20 * np.log10(np.abs((s_data - s_model)[0, 0, :].flatten())), 'k--')

    ax1 = fig1.add_subplot(322)
    ax1.plot(freq, 20 * np.log10(np.abs(s_model[0, 1, :].flatten())), 'b-')
    ax1.plot(freq, 20 * np.log10(np.abs(s_data[0, 1, :].flatten())), 'r--')

    ax1 = fig1.add_subplot(323)
    ax1.plot(freq, 20 * np.log10(np.abs(s_model[0, 2, :].flatten())), 'b-')
    ax1.plot(freq, 20 * np.log10(np.abs(s_data[0, 2, :].flatten())), 'r--')

    ax1 = fig1.add_subplot(324)
    ax1.plot(freq, 20 * np.log10(np.abs(s_model[0, 3, :].flatten())), 'b-')
    ax1.plot(freq, 20 * np.log10(np.abs(s_data[0, 3, :].flatten())), 'r--')

    ax1 = fig1.add_subplot(325)
    ax1.plot(freq, 20 * np.log10(np.abs(s_model[1, 1, :].flatten())), 'b-')
    ax1.plot(freq, 20 * np.log10(np.abs(s_data[1, 1, :].flatten())), 'r--')

    ax1 = fig1.add_subplot(326)
    ax1.plot(freq, 20 * np.log10(np.abs(s_model[1, 2, :].flatten())), 'b-')
    ax1.plot(freq, 20 * np.log10(np.abs(s_data[1, 2, :].flatten())), 'r--')

    plt.show()
Ejemplo n.º 9
0
def long_dipole_bound_vs_pole():
    s1p_file = './resource/single_dipole_wideband.s1p'
    freq, n, z_data, s_data, z0_data = vecfit.read_snp(s1p_file)
    cs = freq * 2j * np.pi
    s_all = np.logspace(
        np.log10(np.min(np.abs(cs))) - 3,
        np.log10(np.max(np.abs(cs))) + 3, int(1e5)) * 1j

    # plot 1: bound vs pole with reflection inf
    # ax1 = vecfit.plot_freq_resp(cs, s_data, y_scale='db')
    pole_list = []
    bound_list = []
    bound_error_list = []
    for i in range(1, 15):
        f_out = vecfit.fit_s_v2(s_data, cs, n_pole=i, n_iter=20, s_inf=-1)
        passive = np.all(np.abs(f_out.model(s_all)) <= 1)
        print('Pole {}, passive {}, stable {}'.format(i, passive,
                                                      f_out.stable))
        bound, bw = f_out.bound(np.inf, f0=2.4e9)
        bound_error = f_out.bound_error(s_data, cs, reflect=np.inf)
        pole_list.append(i)
        bound_list.append(bound)
        bound_error_list.append(bound_error)
        # f_out.plot(cs, ax=ax1, y_scale='db', linestyle='--')
        # vecfit.plot_freq_resp(cs, s_data - f_out.model(cs), ax=ax1, y_scale='db', linestyle='--')

    fig = plt.figure(figsize=(8, 5.5))
    ax = fig.add_subplot(111)
    ax.plot(pole_list, bound_list, '--')
    ax.plot(pole_list, bound_error_list, '--')
    ax.plot(pole_list, np.array(bound_list) + np.array(bound_error_list))
    ax.set_xlabel(r'Number of poles $N_p$')
    ax.set_ylabel(r'Bound ($s_0=\infty$)')
    ax.legend([r'$B$', r'$\delta B$', r'$B+\delta B$'])
    ax.grid(True, which='both', linestyle='--')

    # plot 2: bound vs weight with reflection inf
    wt_list = []
    bound_list = []
    bound_error_list = []
    wt = 0
    wt_step = 0.2
    while wt <= 20:
        f_out = vecfit.fit_s_v2(s_data,
                                cs,
                                n_pole=7,
                                n_iter=20,
                                s_inf=-1,
                                bound_wt=wt)
        passive = np.all(np.abs(f_out.model(s_all)) <= 1)
        if passive and f_out.stable:
            bound, bw = f_out.bound(np.inf, f0=2.4e9)
            bound_error = f_out.bound_error(s_data, cs, reflect=np.inf)
            wt_list.append(wt)
            bound_list.append(bound)
            bound_error_list.append(bound_error)
            wt += wt_step
        else:
            print('Stop at weight {:g}, passive {}, stable {}'.format(
                wt, passive, f_out.stable))
            break

    fig = plt.figure(figsize=(8, 5.5))
    ax = fig.add_subplot(111)
    ax.plot(wt_list, bound_list, '--')
    ax.plot(wt_list, bound_error_list, '--')
    ax.plot(wt_list, np.array(bound_list) + np.array(bound_error_list))
    ax.set_xlabel(r'Weight $\alpha$')
    ax.set_ylabel(r'Bound ($s_0=\infty$)')
    ax.legend([r'$B$', r'$\delta B$', r'$B+\delta B$'])
    ax.grid(True, which='both', linestyle='--')
Ejemplo n.º 10
0
def long_dipole_paper():
    s1p_file = './resource/single_dipole_wideband.s1p'
    freq, n, z_data, s_data, z0_data = vecfit.read_snp(s1p_file)
    cs = freq * 2j * np.pi
    z0 = 50
    z_data = (1 + s_data) / (1 - s_data) * z0
    fz = interp1d(freq, z_data)
    fr = interp1d(freq, np.real(z_data))
    fx = interp1d(freq, np.imag(z_data))
    f0 = 2.4e9
    f1 = optimize.bisect(fx, 2e9, 2.5e9)
    f2 = optimize.bisect(fx, 4e9, 4.2e9)
    f3 = optimize.bisect(fx, 6.8e9, 7.2e9)
    f4 = optimize.bisect(fx, 8.5e9, 8.8e9)

    # Equivalent circuit of dipole antenna of arbitrary length
    # proposed structure: C0 + L0 + (R1 // L1 // C1) + (R2 // L2 // C2)
    C0 = -1 / (2 * np.pi * f0 / 10 * fx(f0 / 10))  # determined by 0.1 * lambda
    L0 = 1 / (2 * np.pi *
              (3 * f1))**2 / C0  # determined by 0.5 * lambda and C0
    R1 = fr(f2)  # determined by 1 * lambda
    C1 = 1e-13  # determined by 0.5 * lambda and 1 * lambda
    L1 = 1 / (2 * np.pi *
              f2)**2 / C1  # determined by 0.5 * lambda and 1 * lambda
    R2 = fr(f4)  # determined by 2 * lambda
    C2 = 1.2e-13  # determined by 1.5 * lambda and 2 * lambda
    L2 = 1 / (
        2 * np.pi *
        (1.018 * f4))**2 / C2  # determined by 1.5 * lambda and 2 * lambda

    p1 = (-1 / R1 / C1 + cmath.sqrt(1 / R1**2 / C1**2 - 4 / L1 / C1)) / 2
    p2 = (-1 / R1 / C1 - cmath.sqrt(1 / R1**2 / C1**2 - 4 / L1 / C1)) / 2
    r1 = 1 / C1 / (1 - p2 / p1)
    r2 = 1 / C1 / (1 - p1 / p2)
    p3 = (-1 / R2 / C2 + cmath.sqrt(1 / R2**2 / C2**2 - 4 / L2 / C2)) / 2
    p4 = (-1 / R2 / C2 - cmath.sqrt(1 / R2**2 / C2**2 - 4 / L2 / C2)) / 2
    r3 = 1 / C2 / (1 - p4 / p3)
    r4 = 1 / C2 / (1 - p3 / p4)
    pole_model = [0, p1, p2, p3, p4]
    zero_model = [1 / C0, r1, r2, r3, r4]
    z_model = vecfit.RationalFct(pole_model, zero_model, 0, L0)
    s_tmp = (z_model.model(cs) - z0) / (z_model.model(cs) + z0)
    s_model = vecfit.fit_s(s_tmp, cs, n_pole=6, n_iter=20, s_inf=1)
    paper_bound, paper_bw = s_model.bound(np.inf, f0=2.4e9)
    paper_bound_error = s_model.bound_error(s_data, cs, reflect=np.inf)

    zl = z_model.model(cs)
    zl2 = 1 / (cs * C0) + cs * L0 + 1 / (1 / R1 + 1 / (cs * L1) +
                                         cs * C1) + 1 / (1 / R2 + 1 /
                                                         (cs * L2) + cs * C2)
    # zl2 = 1/(cs*C0) + cs*L0 + 1/(1/R1 + 1/(cs*L1) + cs*C1)
    # zl2 = 1/(cs*C0) + cs*L0
    # zl2 = 1/(1/R1 + 1/(cs*L1) + cs*C1)

    # Use algorithm to fit S
    # f_out = vecfit.fit_s(s_data, cs, n_pole=6, n_iter=20, s_inf=1)
    # f_out = vecfit.bound_tightening(s_data, cs)
    f_out, log = vecfit.bound_tightening_sweep(s_data, cs, np.inf)  # -1
    z_fit = (1 + f_out.model(cs)) / (1 - f_out.model(cs)) * z0
    bound, bw = f_out.bound(np.inf, f0=2.4e9)
    bound_error = f_out.bound_error(s_data, cs, reflect=np.inf)

    # Use manual algorithm to fit S
    # f_out2 = vecfit.fit_s(s_data, cs, n_pole=6, n_iter=20, s_inf=1)
    f_out2 = vecfit.fit_s_v2(s_data, cs, n_pole=6, n_iter=20, s_inf=1)
    z_fit2 = (1 + f_out2.model(cs)) / (1 - f_out2.model(cs)) * z0
    bound2, bw2 = f_out2.bound(np.inf, f0=2.4e9)
    bound_error2 = f_out2.bound_error(s_data, cs, reflect=np.inf)

    # plots
    ax = vecfit.plot_freq_resp(cs, s_data, y_scale='db')
    vecfit.plot_freq_resp(cs, s_tmp, ax=ax, y_scale='db', linestyle='--')
    f_out.plot(cs, ax=ax, y_scale='db', linestyle='--')
    f_out2.plot(cs, ax=ax, y_scale='db', linestyle='--')
    ax.set_ylabel(r'Reflection coefficient $\Gamma$ (dB)')
    ax.legend(['Simulation', 'Paper [16?]', 'Algorithm 2', 'Impedance Method'])
    ax.grid(True, which='both', linestyle='--')

    # bound values
    print('Paper:')
    print('Poles {}, bound {:.5e}, error {:.5e}, sum {:.5e}'.format(
        len(s_model.pole), paper_bound, paper_bound_error,
        paper_bound + paper_bound_error))
    print('Algorithm:')
    print('Poles {}, bound {:.5e}, error {:.5e}, sum {:.5e}'.format(
        len(f_out.pole), bound, bound_error, bound + bound_error))
    print('Manual comparison:')
    print('Poles {}, bound {:.5e}, error {:.5e}, sum {:.5e}'.format(
        len(f_out2.pole), bound2, bound_error2, bound2 + bound_error2))
Ejemplo n.º 11
0
def dipole_paper():
    # Equivalent circuit of a dipole antenna using frequency-independent lumped elements
    # https://ieeexplore.ieee.org/document/210122

    s1p_file = './resource/single_dipole.s1p'
    freq, n, z_data, s_data, z0_data = vecfit.read_snp(s1p_file)
    cs = freq * 2j * np.pi
    z0 = 50

    # [2] three-element
    # [3] four-element
    # proposed four-element: C1 + (C2 // L1 // R1)
    h = 62.5e-3 / 2
    a = 2.5e-3 / 2
    # h = 0.9
    # a = 0.00264
    C1 = 12.0674 * h / (np.log10(2 * h / a) - 0.7245) * 1e-12  # pF
    C2 = 2 * h * (0.89075 / (np.power(np.log10(2 * h / a), 0.8006) - 0.861) -
                  0.02541) * 1e-12  # pF
    L1 = 0.2 * h * (np.power(1.4813 * np.log10(2 * h / a), 1.012) -
                    0.6188) * 1e-6  # uH
    R1 = (0.41288 * np.power(np.log10(2 * h / a), 2) +
          7.40754 * np.power(2 * h / a, -0.02389) - 7.27408) * 1e3  # k Ohm

    C1 *= z0
    C2 *= z0
    L1 /= z0
    R1 /= z0
    p1 = (-1 / R1 / C2 + cmath.sqrt(1 / R1**2 / C2**2 - 4 / L1 / C2)) / 2
    p2 = (-1 / R1 / C2 - cmath.sqrt(1 / R1**2 / C2**2 - 4 / L1 / C2)) / 2
    r1 = 1 / C2 / (1 - p2 / p1)
    r2 = 1 / C2 / (1 - p1 / p2)
    pole_model = [0, p1, p2]
    zero_model = [1 / C1, r1, r2]
    z_model = vecfit.RationalFct(pole_model, zero_model, 0, 0)
    s_model = (z_model.model(cs) - 1) / (z_model.model(cs) + 1)

    # Try to fit S
    # f_out = vecfit.bound_tightening(s_data, cs)
    f_out, log = vecfit.bound_tightening_sweep(s_data, cs)

    bound, bw = f_out.bound(np.inf, f0=2.4e9)
    bound_error = f_out.bound_error(s_data, cs, reflect=np.inf)
    # ant_integral = f_out.bound_integral(cs, reflect=np.inf)
    ant_integral = vecfit.bound_integral(s_data, cs, np.inf)
    print(
        'Bound is {:.5e}, BW is {:.5e}, Bound error is {:.5e}, The integral of the antenna is {:.5e}'
        .format(bound, bw, bound_error, ant_integral))

    ax1 = vecfit.plot_freq_resp(cs, s_data, y_scale='db')
    f_out.plot(cs, ax=ax1, y_scale='db', linestyle='--')
    vecfit.plot_freq_resp(cs, s_model, ax=ax1, y_scale='db')
    vecfit.plot_freq_resp(cs,
                          s_data - f_out.model(cs),
                          ax=ax1,
                          y_scale='db',
                          linestyle='--')
    vecfit.plot_freq_resp(cs,
                          s_data - s_model,
                          ax=ax1,
                          y_scale='db',
                          linestyle='--')
    ax2 = f_out.plot_improved_bound(1e11, 4e10)