def test_postFiltering():
    size = 10000
    order = 4
    Ts = 0.1
    amplitude = 0.35
    frequency = 1e-2
    phase = np.pi * 7. / 8.
    vector = np.zeros(order)
    vector[0] = 1.
    inp = system.Sin(Ts,
                     amplitude=amplitude,
                     frequency=frequency,
                     phase=phase,
                     steeringVector=vector)

    A = np.eye(order, k=-1)
    c = np.eye(order)

    sys = system.System(A, c)

    mixingMatrix = -1e0 * np.eye(order)

    ctrl = system.Control(mixingMatrix, size)

    sim = simulator.Simulator(sys, ctrl)
    t = np.linspace(0., Ts * (size - 1), size)
    res = sim.simulate(t, [inp])
    plt.figure()
    plt.plot(res['t'], res['output'])
    plt.legend(["%s" % x for x in range(order)])

    bandwith = 2 * np.pi * frequency * 1e-2

    print("Bandwith = %s" % bandwith)

    postFilterTF = filters.TransferFunction()
    postFilterTF.butterWorth(2, (bandwith, ))
    print(postFilterTF.a, postFilterTF.b)
    postFilter = filters.Filter()
    postFilter.tf2lssObservableForm(postFilterTF.b, postFilterTF.a)
    print("Filter A = \n%s" % postFilter.A)
    print(postFilter.b)
    print(postFilter.c)

    recon = reconstruction.WienerFilterWithPostFiltering(
        t, sys, (inp, ), postFilter)

    u_hat, log = recon.filter(ctrl)

    plt.figure()
    plt.plot(t, inp.scalarFunction(t), label="u")
    plt.plot(t, u_hat, label="u_hat")
    plt.legend()
def test_lowering_order():
    size = 1000
    order = 8
    Ts = 0.1
    amplitude = 0.35
    frequency = 1e-2
    phase = np.pi * 7. / 8.
    vector = np.zeros(order)
    vector[0] = 1.
    inp = system.Sin(Ts,
                     amplitude=amplitude,
                     frequency=frequency,
                     phase=phase,
                     steeringVector=vector)

    A = np.eye(order, k=-1)
    c = np.eye(order)

    sys = system.System(A, c)

    mixingMatrix = -1e0 * np.eye(order)

    ctrl = system.Control(mixingMatrix, size)

    sim = simulator.Simulator(sys, ctrl)
    t = np.linspace(0., 99., size)
    res = sim.simulate(t, (inp, ))
    plt.figure()
    plt.plot(res['t'], res['output'])
    plt.legend(["%s" % x for x in range(order)])

    u_hats = []
    for index in range(1, order + 1):
        newSystem, newControl, newInput = system.LowerOrderSystem(
            sys, ctrl, inp, index)
        recon = reconstruction.WienerFilter(t, newSystem, (newInput, ))
        u_hat, log = recon.filter(newControl)
        u_hats.append(u_hat)

    plt.figure()
    plt.plot(t, inp.scalarFunction(t), label="u")
    for index in range(order):
        plt.plot(t, u_hats[index], label="u_hat_%i" % (index + 1))
    plt.legend()
def test_for_sinusodial_signal():
    size = 1000
    order = 8
    Ts = 0.1
    amplitude = 0.35
    frequency = 1e-2
    phase = np.pi * 7. / 8.
    vector = np.zeros(order)
    vector[0] = 1.
    inp = system.Sin(Ts,
                     amplitude=amplitude,
                     frequency=frequency,
                     phase=phase,
                     steeringVector=vector)

    A = np.eye(order, k=-1)
    c = np.eye(order)

    sys = system.System(A, c)

    mixingMatrix = -1e0 * np.eye(order)

    ctrl = system.Control(mixingMatrix, size)

    sim = simulator.Simulator(sys, ctrl)
    t = np.linspace(0., 99., size)
    res = sim.simulate(t, (inp, ))
    plt.figure()
    plt.plot(res['t'], res['output'])
    plt.legend(["%s" % x for x in range(order)])

    recon = reconstruction.WienerFilter(t, sys, (inp, ))

    u_hat, log = recon.filter(ctrl)

    plt.figure()
    plt.plot(t, inp.scalarFunction(t), label="u")
    plt.plot(t, u_hat, label="u_hat")
    plt.legend()
def test_for_noise_simulation():
    size = 1000
    order = 8
    Ts = 0.1
    amplitude = 0.35
    frequency = 1e-2
    phase = np.pi * 7. / 8.
    vector = np.zeros(order)
    vector[0] = 1.
    inp = system.Sin(Ts,
                     amplitude=amplitude,
                     frequency=frequency,
                     phase=phase,
                     steeringVector=vector)

    A = np.eye(order, k=-1)
    c = np.eye(order)

    sys = system.System(A, c)

    mixingMatrix = -1e0 * np.eye(order)

    ctrl = system.Control(mixingMatrix, size)

    noiseVariance = np.ones(order) * 1e-4
    noiseSources = []
    for index in range(order):
        if noiseVariance[index] > 0:
            vector = np.zeros(order)
            vector[index] = 1
            noiseSources.append({
                "std": np.sqrt(noiseVariance[index]),
                "steeringVector": vector,
                "name": "Noise Source %s" % index
            })

    options = {'noise': noiseSources}

    sim = simulator.Simulator(sys, ctrl, options=options)
    t = np.linspace(0., 99., size)
    res = sim.simulate(t, [inp])
    plt.figure()
    plt.plot(res['t'], res['output'])
    plt.legend(["%s" % x for x in range(order)])

    recon = reconstruction.WienerFilter(t, sys, (inp, ))
    recon_with_noise = reconstruction.WienerFilter(t,
                                                   sys, [inp],
                                                   options=options)
    recon_with_noise_Parallel = reconstruction.ParallelWienerFilter(
        t, sys, [inp], options=options)

    u_hat, log = recon.filter(ctrl)
    u_hat_with_noise, log_with_noise = recon_with_noise.filter(ctrl)
    u_hat_with_noise_Parallel = recon_with_noise_Parallel.filter(ctrl)

    plt.figure()
    plt.plot(t, inp.scalarFunction(t), label="u")
    plt.plot(t, u_hat, label="u_hat")
    plt.plot(t, u_hat_with_noise, label="u_hat_with_noise")
    plt.plot(t, u_hat_with_noise_Parallel, label="u_hat_with_noise_Parallel")
    plt.legend()
Beispiel #5
0
def piBlockSystem1():
    start_time = time.time()

    size = 20000  # Number of samples in the simulation
    M = (1 << 0)  # Number of parallel controlnverters
    N = 2  # Number of PI mixing submatrices
    Ts = 8e-5  # Sampling period
    num_inputs = 1
    t = np.linspace(0, (size - 1) * Ts, size)  # Time grid for control updates

    beta = 6250
    kappa = 1

    stability = Ts * beta * (1 / np.sqrt(M) + kappa) <= 1
    print("Stability margin: {}".format(1. - Ts * beta *
                                        (1 / np.sqrt(M) + kappa)))
    print("Stability criterion: {}".format(stability))

    H = hadamardMatrix(M)
    L = 1

    A = np.zeros(((N + 1) * M, (N + 1) * M))
    MixingPi = np.empty((N, M, M))
    for k in range(N):
        MixingPi[k] = beta * np.outer(H[:, 0], H[:, 0])
        # (beta)*(0.2*np.outer(H[:,0],H[:,0])
        #                        + 0.1*np.outer(H[:,1],H[:,1])
        #                        + 0.3*np.outer(H[:,2],H[:,2])
        #                        + 0.4*np.outer(H[:,3],H[:,3]))  # Index set = {0,0}
        A[(k + 1) * M:(k + 2) * M, (k) * M:(k + 1) * M] = MixingPi[k]

    nperseg = (1 << 16)
    selected_FFT_bin = 250.

    input_signals = []
    frequencies = []
    # sins = np.empty((M,size))
    for i in range(num_inputs):
        amplitude = 1
        frequency = (i + 1) * (selected_FFT_bin / (nperseg * Ts))
        print("{} Hz".format(frequency))
        # size =
        frequencies.append(frequency)
        phase = 0
        vector = np.zeros((N + 1) * M)
        vector[0:M] = beta * (H[:, i])
        input_signals.append(
            system.Sin(Ts,
                       amplitude=amplitude,
                       frequency=frequency,
                       phase=phase,
                       steeringVector=vector))

    input_signals = tuple(input_signals)

    print("A = \n%s\nb = \n%s" % (A, vector))
    checkCovarianceMatrixConvergence(A, vector)
    checkCovarianceMatrixConvergence(-A, vector)

    c = np.eye((N + 1) * M)
    sys = system.System(A, c)

    mixingMatrix = -kappa * beta * np.eye((N + 1) * M)
    ctrl = system.Control(mixingMatrix, size)

    sim = simulator.Simulator(sys,
                              ctrl,
                              options={
                                  'stateBound':
                                  (Ts * beta * kappa) / (1. - Ts * beta) + 1.,
                                  'noise': [{
                                      'std':
                                      1e-6,
                                      'steeringVector':
                                      beta * np.eye((N + 1) * M)[:, i],
                                      'name':
                                      'Bastard'
                                  } for i in range((N + 1) * M)]
                              })

    res = sim.simulate(t, input_signals)

    # plt.figure()
    # plt.plot(res['t'], res['output'])
    # plt.legend(["%s" % x for x in range(res['output'].shape[0])])
    # plt.show()

    eta2 = np.ones((N + 1) * M) * 1e5

    options = {
        'eta2':
        eta2,
        'sigmaU2': [1.],
        'noise': [{
            'std': 1e-6,
            'steeringVector': beta * np.eye((N + 1) * M)[:, i],
            'name': 'Bastard'
        } for i in range((N + 1) * M)]
    }

    recon = reconstruction.WienerFilter(t, sys, input_signals, options)
    input_estimates, recon_log = recon.filter(ctrl)

    print("Run Time: {} seconds".format(time.time() - start_time))

    nfft = (1 << 16)
    spectrums = np.empty((num_inputs, nfft // 2 + 1))
    for i in range(num_inputs):
        freq, spec = signal.welch(input_estimates[:, i],
                                  1. / Ts,
                                  axis=0,
                                  nperseg=nperseg,
                                  nfft=nfft,
                                  scaling='density')
        spectrums[i, :] = spec

    plt.figure()
    [
        plt.semilogx(freq, 10 * np.log10(np.abs(spec)), label="")
        for spec in spectrums
    ]
    plt.grid()
    plt.title("Block diagonal Pi System")
Beispiel #6
0
def test_evaluate_PlotTransferFunctions_For_PostFiltering():
    size = 10000
    order = 2
    postFilterOrder = 2
    Ts = 0.1
    eta2 = 1e-6
    filterEta2 = 1e-0


    amplitude = 1.
    frequency = 1e-1
    phase = np.pi * 7. / 8.
    vector = np.zeros(order)
    vector[0] = 1.
    inp = system.Sin(Ts, amplitude=amplitude, frequency=frequency, phase=phase, steeringVector=vector)


    # coef = np.random.rand(size) * 2. - 1.
    # vector = np.zeros(order)
    # vector[0] = 2.
    # inp = system.FirstOrderHold(Ts, coefficients=coef, steeringVector=vector)


    A = 2 * np.eye(order, k=-1, dtype=np.float)
    # make causal filter
    A +=  0. * np.eye(order, k=0)
    c = np.eye(order, dtype=np.float)

    sys = system.System(A, c)

    mixingMatrix = - 1e1 * np.eye(order)

    ctrl = system.Control(mixingMatrix, size)

    sim = simulator.Simulator(sys, ctrl)
    t = np.linspace(0., 99., size)
    res = sim.simulate(t, (inp,))
    plt.figure()
    plt.plot(res['t'], res['output'])
    plt.legend(["%s" % x for x in range(order)])

    # System 1
    recon = reconstruction.WienerFilter(t, sys, (inp,), {"eta2":eta2*np.ones(order)})

    u_hat, log = recon.filter(ctrl)

    ev = evaluation.Evaluation(sys, u_hat, (inp,))

    # Post Filtering
    bandwith = 2 * np.pi * 1e-1

    print("Bandwith = %s" % bandwith)

    postFilterTF = filters.TransferFunction()
    postFilterTF.butterWorth(postFilterOrder, (bandwith))
    postFilterElliptic = filters.TransferFunction()
    postFilterElliptic.iirFilter(postFilterOrder, (bandwith,), 'ellip')
    postFilterCheby1 = filters.TransferFunction()
    postFilterCheby1.iirFilter(postFilterOrder, (bandwith,), 'cheby1')
    postFilterCheby2 = filters.TransferFunction()
    postFilterCheby2.iirFilter(postFilterOrder, (bandwith,), 'cheby2')
    postFilterBessel = filters.TransferFunction()
    postFilterBessel.iirFilter(postFilterOrder, (bandwith,), 'bessel')


    plt.figure()
    w1, h1 = postFilterTF.frequencyResponse()
    w2, h2 = postFilterElliptic.frequencyResponse()
    w3, h3 = postFilterCheby1.frequencyResponse()
    w4, h4 = postFilterCheby2.frequencyResponse()
    w5, h5 = postFilterBessel.frequencyResponse()
    plt.semilogx(w1/np.pi/2., 20 * np.log10(abs(h1)), label="Butterworth")
    plt.semilogx(w2/np.pi/2., 20 * np.log10(abs(h2)), label="Elliptic")
    plt.semilogx(w3/np.pi/2., 20 * np.log10(abs(h3)), label="Cheby 1")
    plt.semilogx(w4/np.pi/2., 20 * np.log10(abs(h4)), label="Cheby 2")
    plt.semilogx(w5/np.pi/2., 20 * np.log10(abs(h5)), label="Bessel")
    plt.legend()
    plt.xlabel('Frequency [Hz]')
    plt.ylabel('Amplitude response [dB]')
    plt.grid()
    # plt.show()

    # print(postFilterTF.a, postFilterTF.b)
    postFilter1 = filters.Filter()
    postFilter2 = filters.Filter()
    postFilter3 = filters.Filter()
    postFilter4 = filters.Filter()
    postFilter5 = filters.Filter()
    postFilter1.tf2lssObservableForm(postFilterTF.b, postFilterTF.a)
    postFilter2.tf2lssObservableForm(postFilterElliptic.b, postFilterElliptic.a)
    postFilter3.tf2lssObservableForm(postFilterCheby1.b, postFilterCheby1.a)
    postFilter4.tf2lssObservableForm(postFilterCheby2.b, postFilterCheby2.a)
    postFilter5.tf2lssObservableForm(postFilterBessel.b, postFilterBessel.a)

    # eta2PostFilter = np.concatenate((eta2 * np.ones(order), filterEta2 * np.ones(postFilter.c.shape[1])))
    eta2PostFilter = eta2 * np.ones(order)
    reconstructionFiltered1 = reconstruction.WienerFilterWithPostFiltering(t, sys, (inp,), postFilter1, {"eta2":eta2PostFilter})
    reconstructionFiltered2 = reconstruction.WienerFilterWithPostFiltering(t, sys, (inp,), postFilter2, {"eta2":eta2PostFilter})
    reconstructionFiltered3 = reconstruction.WienerFilterWithPostFiltering(t, sys, (inp,), postFilter3, {"eta2":eta2PostFilter})
    reconstructionFiltered4 = reconstruction.WienerFilterWithPostFiltering(t, sys, (inp,), postFilter4, {"eta2":eta2PostFilter})
    reconstructionFiltered5 = reconstruction.WienerFilterWithPostFiltering(t, sys, (inp,), postFilter5, {"eta2":eta2PostFilter})

    print(ctrl.mixingMatrix)

    u_hatP_1, log_1 = reconstructionFiltered1.filter(ctrl)
    print(ctrl.mixingMatrix)

    print(postFilter2)
    u_hatP_2, log_2 = reconstructionFiltered2.filter(ctrl)
    u_hatP_3, log_3 = reconstructionFiltered3.filter(ctrl)
    u_hatP_4, log_4 = reconstructionFiltered4.filter(ctrl)
    u_hatP_5, log_5 = reconstructionFiltered5.filter(ctrl)

    evP1 = evaluation.Evaluation(sys, u_hatP_1, (inp,))
    evP2 = evaluation.Evaluation(sys, u_hatP_2, (inp,))
    evP3 = evaluation.Evaluation(sys, u_hatP_3, (inp,))
    evP4 = evaluation.Evaluation(sys, u_hatP_4, (inp,))
    evP5 = evaluation.Evaluation(sys, u_hatP_5, (inp,))

    freqsLim = [1e-2, 1e2]

    # figure1 = ev.PlotTransferFunctions(freqsLim)
    figure2 = ev.PlotPowerSpectralDensity(t)
    # figure3 = ev2.PlotTransferFunctions(freqsLim)
    figure4 = evP1.PlotPowerSpectralDensity(t)
    figure5 = evP2.PlotPowerSpectralDensity(t)
    figure6 = evP3.PlotPowerSpectralDensity(t)
    figure7 = evP4.PlotPowerSpectralDensity(t)
    figure8 = evP5.PlotPowerSpectralDensity(t)

    plt.figure()
    plt.plot(u_hat, label="u_hat")
    # plt.plot(u_hatP_1, label="Butter")
    # plt.plot(u_hatP_2, label="Elliptic")
    plt.plot(u_hatP_3, label="Chebyshev 1")
    # plt.plot(u_hatP_4, label="Chebychev 2")
    plt.plot(u_hatP_5, label="Bessel")
    # plt.plot(u_hat - u_hat2, label="diff")
    plt.legend()
Beispiel #7
0
def test_evaluate_WithNoise():
    size = 10000
    order = 5
    Ts = 0.0001
    eta2 = 1e-4
    beta = 1000.


    noiseVariance = np.ones(order) * 1e-12
    noiseSources = []
    for index in range(order):
        if noiseVariance[index]>0:
            vector = np.zeros(order)
            vector[index] = beta
            noiseSources.append(
            {
                "std": np.sqrt(noiseVariance[index]),
                "steeringVector": vector,
                "name": "Noise Source %s" % index
            }
            )


    options = {
        'noise': noiseSources,
        'eta2': eta2 * np.ones(order)
    }

    # options = {}

    # options2 = {
    #     # 'noise': {"standardDeviation": np.sqrt(noiseVariance) * np.array([1./(order - x)**3 for x in range(order)])},
    #     'noise': {"standardDeviation": 1e-4 * np.array([1. for x in range(order)])},
    #     'eta2': eta2 * np.ones(order)
    # }
    # options['noise']['standardDeviation'][5] = 1e-1

    amplitude = 1. * 1e-6
    frequency = 1e2 / (2. * np.pi)
    phase = np.pi * 7. / 8.
    vector = np.ones(order) * beta / 2.
    # vector = np.zeros(order)
    vector[0] = beta
    inp = system.Sin(Ts, amplitude=amplitude, frequency=frequency, phase=phase, steeringVector=vector)


    # coef = np.random.rand(size) * 2. - 1.
    # vector = np.zeros(order)
    # vector[0] = beta
    # inp = system.FirstOrderHold(Ts, coefficients=coef, steeringVector=vector)



    # T = 120
    # t = 10 ** (T/10.)
    # rho = np.power(t, 1./order)/beta * np.sqrt(2)
    rho = 0.

    A = beta/2. * np.eye(order, k=-1) - rho * np.eye(order, k=0)
    # A[0, :] =-np.ones(order) * beta/2.

    print(A)
    # A = 1e-2 * np.eye(order, k=-1) - rho * np.eye(order, k=0)
    # A = np.zeros((order, order))
    # A = np.random.randn(order, order)
    # A = np.dot(A, np.linalg.inv(np.diag(np.sum(np.abs(A), axis=1))))
    # print(A)

    # A = 9. * np.eye(order, k=-1, dtype=np.float)
    # make causal filter
    # A +=  0. * np.eye(order, k=0)
    c0 = np.zeros(order, dtype=np.float).reshape((order,1))
    c0[-1] = 1.
    c = np.eye(order, dtype=np.float)

    sys0 = system.System(A, c0)
    sys = system.System(A, c)

    mixingMatrix = - 10.5 * np.eye(order)

    ctrl = system.Control(mixingMatrix, size)
    ctrl0 = system.Control(mixingMatrix, size)


    sim0 = simulator.Simulator(sys0, ctrl0, options=options)
    sim = simulator.Simulator(sys, ctrl, options=options)
    t = np.linspace(0., Ts * (size - 1) , size)
    u = inp.scalarFunction(t)
    # res2 = sim0.simulate(t, (inp,))
    res = sim.simulate(t, (inp,))
    plt.figure()
    plt.plot(res['t'], res['output'])
    plt.legend(["%s" % x for x in range(order)])

    # System 1
    reconSISO = reconstruction.WienerFilter(t, sys0, (inp,), {"eta2":np.array(eta2)})
    reconSIMO = reconstruction.WienerFilter(t, sys, (inp,), {"eta2":eta2 * np.ones(order)})
    reconMIMO = reconstruction.WienerFilter(t, sys, [inp], options)

    u_hatSISO, log_SISO = reconSISO.filter(ctrl)
    u_hatSIMO, log_SIMO = reconSIMO.filter(ctrl)
    u_hatMIMO, log_MIMO = reconMIMO.filter(ctrl)

    print(reconSISO)


    ev_SISO = evaluation.Evaluation(sys, u_hatSISO, (inp,))
    ev_SIMO = evaluation.Evaluation(sys, u_hatSIMO, (inp,))
    ev_MIMO = evaluation.Evaluation(sys, u_hatMIMO, (inp,))


    freqsLim = [1e-2, 1e2]

    freq, SISOSPECTRUM, SIGNALSPECTRUM = ev_SISO.PowerSpectralDensity(t)
    _, SIMOSPECTRUM, _  = ev_SIMO.PowerSpectralDensity(t)
    _, MIMOSPECTRUM, _  = ev_MIMO.PowerSpectralDensity(t)

    plt.figure()
    plt.semilogx(freq, 10 * np.log10(np.abs(SIGNALSPECTRUM[0].flatten())), label="u_hatSISO")
    plt.semilogx(freq, 10 * np.log10(np.abs(SISOSPECTRUM.flatten())), label="u_hatSISO")
    plt.semilogx(freq, 10 * np.log10(np.abs(SIMOSPECTRUM.flatten())), label="u_hatSIMO")
    plt.semilogx(freq, 10 * np.log10(np.abs(MIMOSPECTRUM[:, 0].flatten())), label="u_hatMIMO")
    plt.legend()


    plt.figure()
    plt.plot(u, label="u")
    plt.plot(u_hatSISO, label="u_hatSISO")
    plt.plot(u_hatSIMO, label="u_hatSIMO")
    plt.plot(u_hatMIMO, label="u_hatMIMO")
    plt.legend()

    plt.figure()
    plt.plot(u_hatSISO.flatten() - u.flatten(), label="u_hatSISO")
    plt.plot(u_hatSIMO.flatten() - u.flatten(), label="u_hatSIMO")
    plt.plot(u_hatMIMO[:,0] - u.flatten(), label="u_hatMIMO")
    plt.legend()

    plt.figure()
    freq, u_hatSISOSP = signal.welch(u_hatSISO.flatten() - u.flatten(), 1./Ts)
    _, u_hatSIMOSP = signal.welch(u_hatSIMO.flatten() - u.flatten(), 1./Ts)
    _, u_hatMIMOSP = signal.welch(u_hatMIMO[:,0] - u.flatten(), 1./Ts)

    plt.semilogx(freq, 10 * np.log10(np.abs(u_hatSISOSP)), label="u_hatSISO")
    plt.semilogx(freq, 10 * np.log10(np.abs(u_hatSIMOSP)), label="u_hatSIMO")
    plt.semilogx(freq, 10 * np.log10(np.abs(u_hatMIMOSP)), label="u_hatMIMO")
    plt.legend()

    figure1 = ev_SISO.PlotTransferFunctions(freqsLim)
Beispiel #8
0
    def __init__(self,
                 experiment_id,
                 data_dir,
                 M,
                 N,
                 L,
                 input_phase,
                 input_amplitude,
                 input_frequency=None,
                 beta=6250,
                 sampling_period=8e-5,
                 primary_signal_dimension=0,
                 systemtype='ParallelIntegratorChain',
                 OSR=16,
                 eta2_magnitude=1,
                 kappa=1,
                 sigma2_thermal=1e-6,
                 sigma2_reconst=1e-6,
                 num_periods_in_simulation=100,
                 controller='subspaceController',
                 bitsPerControl=1):

        print("Initializing Experiment | ID: %s" % experiment_id)
        self.experiment_id = experiment_id
        self.data_dir = Path(data_dir)
        self.M = M
        self.N = N
        self.L = L
        self.input_phase = input_phase
        self.input_amplitude = input_amplitude
        self.input_frequency = input_frequency
        self.beta = beta
        self.sampling_period = sampling_period
        self.primary_signal_dimension = primary_signal_dimension
        self.systemtype = systemtype
        self.OSR = OSR
        self.kappa = kappa
        self.sigma2_thermal = sigma2_thermal
        self.sigma2_reconst = sigma2_reconst
        self.num_periods_in_simulation = num_periods_in_simulation
        self.size = round(num_periods_in_simulation / sampling_period)

        self.controller = controller
        self.bitsPerControl = bitsPerControl

        self.border = np.int(self.size // 100)
        self.all_input_signal_amplitudes = np.zeros(L)
        self.all_input_signal_amplitudes[
            primary_signal_dimension] = input_amplitude

        self.logstr = ("{0}: EXPERIMENT LOG\n{0}: Experiment ID: {1}\n".format(
            time.strftime("%d/%m/%Y %H:%M:%S"), experiment_id))

        self.finished_simulation = False
        self.finished_reconstruction = False
        if not self.data_dir.exists():
            self.data_dir.mkdir(parents=True)

        #################################################
        #     System and input signal specifications    #
        #################################################

        if self.primary_signal_dimension > self.M:
            self.log(
                "Primary Signal Dimension cannot be larger than M, setting to 0 (first dim)"
            )
            self.primary_signal_dimension = 0

        if self.input_frequency == None:
            self.input_frequency = 1. / (self.sampling_period * 2 * self.OSR)
            self.log(f'Setting f_sig = f_s/(2*OSR) = {self.input_frequency}')

        if self.systemtype == "ParallelIntegratorChain":

            self.A = np.zeros((self.N * self.M, self.N * self.M))
            mixingPi = np.zeros((self.N - 1, self.M, self.M))
            H = hadamardMatrix(self.M)

            if N > 1:
                # L=1 means just one of M dimensions is used and there is
                # only one input signal => We scale up the input vector by sqrt(M)
                if L == 1:
                    for k in range(N - 1):
                        mixingPi[k] = beta * np.sqrt(M) * (
                            np.outer(H[:, 0], H[:, 0])
                        )  # + beta * np.sqrt(M) * sum(np.outer(H[:,i],H[:,i]) for i in range(1,self.M)) * 1e-3
                        self.A[(k + 1) * self.M:(k + 2) * self.M,
                               (k) * self.M:(k + 1) * self.M] = mixingPi[k]
                # L=M means M input signals
                elif L == M:
                    for k in range(N - 1):
                        mixingPi[k] = self.beta * np.sqrt(M) * np.eye(
                            M
                        )  #(sum(np.outer(H[:,i],H[:,i]) for i in range(self.M)))
                        self.A[(k + 1) * self.M:(k + 2) * self.M,
                               (k) * self.M:(k + 1) * self.M] = mixingPi[k]
                else:
                    for k in range(N - 1):
                        mixingPi[k] = self.beta * np.sqrt(M / L) * (sum(
                            np.outer(H[:, i], H[:, i]) for i in range(self.L)))
                        self.A[(k + 1) * self.M:(k + 2) * self.M,
                               (k) * self.M:(k + 1) * self.M] = mixingPi[k]
                    # raise NotImplemented
                print("A = {}".format(self.A))
            else:
                mixingPi = [np.zeros((M, M))]

            # Limit the low frequency gain of the filter
            # at approximately the thermal noise level
            LeakyIntegrators = True
            if LeakyIntegrators == True:
                self.rho = beta / ((sigma2_thermal)**(-1 / N))
                self.A -= np.eye(N * M) * self.rho

            # Define input signals:
            self.input_signals = []
            self.all_input_signal_frequencies = np.zeros(L)
            self.all_input_signal_frequencies[
                self.primary_signal_dimension] = self.input_frequency
            allowed_signal_frequencies = self.input_frequency * (
                0.5**np.arange(1, 3 * M))
            for i in range(self.L):
                if i == self.primary_signal_dimension: continue
                k = np.random.randint(0, L - 1)
                self.all_input_signal_frequencies[
                    i] = allowed_signal_frequencies[i]
                self.all_input_signal_amplitudes[i] = input_amplitude

            # Define input steeringVectors
            if L == 1:
                inputVectorMatrix = beta * np.sqrt(M) * H
            elif L == 2:
                # The outer product sum results in a checkerboard matrix with 1/0 entries.
                # We pick input vectors from there and scale up by M (undoing the attenuation from the outer products)
                inputVectorMatrix = beta * (M / 2) * (np.outer(
                    H[:, 0], H[:, 0]) + np.outer(H[:, 1], H[:, 1])) * 2
            elif L == M:
                inputVectorMatrix = beta * np.sqrt(M) * (np.hstack(
                    (np.outer(H[:, i], H[:, i])[:, 0].reshape(-1, 1)
                     for i in range(L))))
            else:
                inputVectorMatrix = beta * np.sqrt(M / L) * H

            for i in range(self.L):
                vector = np.zeros(self.M * self.N)
                vector[0:self.M] = inputVectorMatrix[:, i]
                self.input_signals.append(
                    system.Sin(
                        self.sampling_period,
                        amplitude=self.all_input_signal_amplitudes[i],
                        frequency=self.all_input_signal_frequencies[i],
                        phase=self.input_phase,  #+ (np.pi/2)*i,
                        steeringVector=vector))
                print(f'b_{i} = {self.input_signals[i].steeringVector}')
            self.input_signals = tuple(self.input_signals)

        elif self.systemtype == "CyclicIntegratorChain":

            self.A = np.zeros((self.N * self.M, self.N * self.M))
            mixingPi = np.zeros((self.N, self.M, self.M))
            H = hadamardMatrix(self.M)

            self.all_input_signal_frequencies = np.zeros(L)
            self.all_input_signal_frequencies[
                self.primary_signal_dimension] = self.input_frequency
            self.all_input_signal_amplitudes[
                self.primary_signal_dimension] = self.input_amplitude

            if N > 1:
                if L == 1:
                    # Start with the Pi_N, in the top right corner
                    mixingPi[-1] = beta * np.sqrt(M) * sum(
                        np.outer(H[:, i], H[:, i]) for i in range(self.N - 1))
                    self.A[0:self.M, -self.M:self.M * self.N] = mixingPi[-1]

                    # Iterate just like before, down the first sub-diagonal, always summing over all but the k'th pi vector
                    for k in range(N - 1):
                        mixingPi[k] = beta * np.sqrt(M) * sum(
                            np.outer(H[:, i], H[:, i])
                            for i in range(self.N) if i != k)
                        self.A[(k + 1) * self.M:(k + 2) * self.M,
                               (k) * self.M:(k + 1) * self.M] = mixingPi[k]
                else:
                    raise NotImplemented
            else:
                mixingPi = [np.zeros((M, M))]
            # Define input signals:
            self.input_signals = []
            if self.L == 1:
                selector = np.zeros(self.M)
                selector[0] = 1
                vector = np.zeros(self.M * self.N)
                vector[0:self.M * self.N] = beta * np.sqrt(M) * np.dot(
                    np.vstack(
                        (np.outer(H[:, i], H[:, i]) for i in range(self.N))),
                    selector.reshape(-1, 1)).flatten()

                self.input_signals.append(
                    system.Sin(self.sampling_period,
                               amplitude=self.input_amplitude,
                               frequency=self.input_frequency,
                               phase=self.input_phase,
                               steeringVector=vector))
            else:
                raise NotImplemented

        else:
            raise NotImplemented

        # pd.DataFrame(self.A).to_csv('A_matrix.csv')
        # print("A = \n%s\nb = \n%s" % (self.A, self.input_signals[self.primary_signal_dimension].steeringVector))

        self.c = np.eye(self.N * self.M)
        self.sys = system.System(
            A=self.A,
            c=self.c,
            b=self.input_signals[primary_signal_dimension].steeringVector)

        systemResponse = lambda f: np.dot(self.sys.frequencyResponse(f), self.
                                          sys.b)
        self.eta2_magnitude = np.max(
            np.abs(systemResponse(1. / (2. * sampling_period * OSR)))**2)
        self.log("eta2_magnitude set to max(|G(s)b|^2) = {:.5e}".format(
            self.eta2_magnitude))
        print("eta2_magnitude set to max(|G(s)b|^2) = {:.5e}".format(
            self.eta2_magnitude))

        #################################################
        #           Controller specification            #
        #################################################
        dither = True
        """
          The subspace controller is only implemented for L=1 signal right now.
        """
        if controller == 'subspaceController':
            self.ctrlMixingMatrix = np.zeros((self.N * self.M, self.N))
            # if L>1:
            #   raise "Multi-Bit controller not implemented for L>1 input signals"
            if dither:
                self.ctrlMixingMatrix = (
                    np.random.randint(2, size=(N * M, N)) * 2 -
                    1) * beta * 1e-3

            if L == 1:
                for i in range(N):
                    self.ctrlMixingMatrix[
                        i * M:(i + 1) * M,
                        i] = -np.sqrt(self.M) * self.beta * H[:, 0]
            else:
                raise NotImplemented
                # self.ctrlMixingMatrix = np.zeros((N*M,N*M))
                # for i in range(N):
                #   self.ctrlMixingMatrix[i*M:(i+1)*M,i*M:(i+1)*M] = -np.sqrt(self.M) *  self.beta * H #

        elif controller == 'diagonalController':
            self.ctrlMixingMatrix = np.zeros((N * M, N * M))
            if dither:
                self.ctrlMixingMatrix = (np.random.randint(
                    2, size=(self.N * self.M, self.N * self.M)) * 2 -
                                         1) * beta * 0.05 / (self.M * self.N)
            self.ctrlMixingMatrix += -self.kappa * self.beta * np.sqrt(
                M) * np.eye(self.N * self.M)

        # elif controller == 'blockDiagonalController:
        #   for k in range(N):
        #     self.ctrlMixingMatrix[k * self.M: (k+1) * self.M,
        #                           k * self.M:(k+1) * self.M] = (-self.beta
        #                                                         * np.outer(H[:,0],H[:,0]))

        self.ctrlOptions = {
            'bitsPerControl': bitsPerControl,
            'bound': 1,
        }
        self.ctrl = system.Control(self.ctrlMixingMatrix,
                                   self.size,
                                   options=self.ctrlOptions)

        print("ctrlMixingMatrix: %s\n" % (self.ctrlMixingMatrix, ))
Beispiel #9
0
            [sigmaU2.append(sigma2_jitter) for i in range(1)]
            simulationOptions = {
                'noise': [{
                    'std': sigma2_thermal,
                    'steeringVector': beta * np.eye(N)[:, i]
                } for i in range(N)],
                'jitter': {
                    'range': Ts * jitter_size
                }
            }

            mixingMatrix = -kappa * beta * np.eye(N)
            ctrl = system.Control(mixingMatrix, size)
            input_signal = system.Sin(Ts,
                                      amplitude=amplitude,
                                      frequency=frequency,
                                      phase=phase,
                                      steeringVector=input_vector)
            all_inputs = [input_signal]

            order = N
            jitterInputs = [
                system.Input(Ts=Ts,
                             coefficients=np.zeros(len(t)),
                             steeringVector=np.ones(N) * beta)
            ]
            for i in range(1):
                all_inputs.append(jitterInputs[i])

        elif RECONSTRUCTION_METHOD == 'AugmentedSSM':
            A_tmp1 = np.hstack((np.eye(N, k=-1) * beta, -np.eye(N)))