def test_modelquality():
    """
    Tests the quality of the model. On observing the models it is found that the upsampling hammerstein model doesnot
    produce aliasing effect. But other models produces aliasing. This test make sure that upsampling hammerstein model
    doesnot produce aliasing for the following max_harm and frequency combinations.
    """
    max_harm = [1, 2, 3, 4, 5]
    frequency = [1000, 5000, 10000, 15000, 23000]
    s_rate = 48000
    length = s_rate

    combinations = list(itertools.product(frequency, max_harm))
    for comb in combinations:
        freq = comb[0]
        harm = comb[1]
        sine_signal = sumpf.modules.SineWaveGenerator(frequency=freq,
                                                      phase=0.0,
                                                      samplingrate=s_rate,
                                                      length=length)
        sine_spec = sumpf.modules.FourierTransform(
            signal=sine_signal.GetSignal())
        Test_Model_Hammerstein = nlsp.AliasingCompensatedHM_upsampling(
            input_signal=sine_signal.GetSignal(),
            nonlin_func=nlsp.function_factory.power_series(harm),
            max_harm=harm)
        Test_Model_outputsignal = Test_Model_Hammerstein.GetOutput()
        e = nlsp.calculateenergy_freq(Test_Model_outputsignal)
        h = nlsp.predictharmonics_usingupsampling([freq], harm, s_rate)
        f = nlsp.calculateenergy_atparticularfrequencies(
            Test_Model_outputsignal, h)
        quality = numpy.sum(f) / numpy.sum(e)
        assert quality == 1
def test_aliasingtest():
    """
    Test the Aliasing effect in the model. The output freq are calculated theoretically and is compared with the model.
    If input freq is greater than nyquist freq then aliasing occurs because of which frequencies which are not in input
    signal appears in the output. This test tests the aliasing effect. if it fails then there should be freq in the
    output other than the theoretically calculated freq, then there should be some problem in the signal processing
    block.
    """
    max_harm = 5
    freq = 23000
    s_rate = 48000
    length = s_rate
    sine_signal = sumpf.modules.SineWaveGenerator(frequency=freq,
                                                  phase=0.0,
                                                  samplingrate=s_rate,
                                                  length=length)
    sine_spec = sumpf.modules.FourierTransform(signal=sine_signal.GetSignal())
    Test_Model_Hammerstein = nlsp.AliasingCompensatedHM_upsampling(
        input_signal=sine_signal.GetSignal(),
        nonlin_func=nlsp.function_factory.power_series(max_harm),
        max_harm=max_harm)
    Test_Model_Hammerstein.SetMaximumHarmonic(1)
    Test_Model_outputsignal = Test_Model_Hammerstein.GetOutput()
    Test_Model_outputspec = sumpf.modules.FourierTransform(
        Test_Model_outputsignal).GetSpectrum()
    Test_Model_HarmonicFreq = []
    h = nlsp.find_frequencies(Test_Model_outputsignal)
    predicted_freq = nlsp.predictoutputfreq_usingsamplingtheory(
        freq, max_harm, s_rate)
    assert predicted_freq == h
示例#3
0
def test_energy():
    """
    Test of the relation between the energy of hammerstein group model and simple hammerstein model.
    (a + b)^2 <= 2a^2 + 2b^2
    The above relation is proved for the model using this test
    """
    max_harm = [1] * 2
    freq = 5000
    s_rate = 48000
    length = s_rate
    ip_sine_signal = sumpf.modules.SineWaveGenerator(
        frequency=freq, phase=0.0, samplingrate=s_rate,
        length=length).GetSignal()
    imp = sumpf.modules.ImpulseGenerator(samplingrate=s_rate,
                                         length=length).GetSignal()
    e = []
    for harm in max_harm:
        Test_Model_Hammerstein = nlsp.AliasingCompensatedHM_upsampling(
            input_signal=ip_sine_signal,
            nonlin_func=nlsp.function_factory.power_series(harm),
            filter_impulseresponse=imp,
            max_harm=harm)
        Test_Model_outputsignal = Test_Model_Hammerstein.GetOutput()
        e.append(
            numpy.multiply(nlsp.calculateenergy_freq(Test_Model_outputsignal),
                           2))
    hammerstein_group = nlsp.HammersteinGroupModel_up(
        input_signal=ip_sine_signal,
        nonlinear_functions=(nlsp.function_factory.power_series(
            max_harm[0]), ) * len(max_harm),
        filter_irs=(imp, ) * len(max_harm),
        max_harmonics=max_harm)
    e_g = nlsp.calculateenergy_freq(hammerstein_group.GetOutput())
    assert float(numpy.sum(e_g)) <= float(numpy.sum(e))
def test_linearity_of_model():
    """
    Test the Hammerstein model for linearity for first order nonlinearity block and all pass filter linear block
    """
    gen_sine = sumpf.modules.SineWaveGenerator(frequency=10000.0,
                                               phase=0.0,
                                               samplingrate=48000,
                                               length=48000).GetSignal()
    model = nlsp.AliasingCompensatedHM_upsampling(
        input_signal=gen_sine,
        nonlin_func=nlsp.function_factory.power_series(1),
        max_harm=1)
    energy_ip = nlsp.calculateenergy_freq(gen_sine)
    energy_op = nlsp.calculateenergy_freq(model.GetOutput())
    assert int(energy_ip[0]) == int(energy_op[0])
示例#5
0
def test_aliasing():
    """
    Tests whether aliasing is present in the hammerstein group model.
    The pure sine tone is given to the model and the ouput frequencies found in all the branches are found. The energy
    of these frequencies in the output of the hammerstein group model is calculated. If there is no aliasing then this
    should be equal to the total energy of the output signal.
    """
    max_harm = [1, 2, 3, 4, 5]
    freq = 5000
    s_rate = 48000
    length = s_rate
    ip_sine_signal = sumpf.modules.SineWaveGenerator(
        frequency=freq, phase=0.0, samplingrate=s_rate,
        length=length).GetSignal()
    h = []
    for harm in max_harm:
        Test_Model_Hammerstein = nlsp.AliasingCompensatedHM_upsampling(
            input_signal=ip_sine_signal,
            nonlin_func=nlsp.function_factory.power_series(harm),
            max_harm=harm)
        Test_Model_outputsignal = Test_Model_Hammerstein.GetOutput()
        h.append(nlsp.find_frequencies(Test_Model_outputsignal))
    Test_model_freq = sorted(
        list(set([item for sublist in h for item in sublist])))
    imp = sumpf.modules.ImpulseGenerator(samplingrate=s_rate,
                                         length=length).GetSignal()
    hammerstein_group = nlsp.HammersteinGroupModel_up(
        input_signal=ip_sine_signal,
        nonlinear_functions=(nlsp.function_factory.power_series(max_harm[0]),
                             nlsp.function_factory.power_series(max_harm[1]),
                             nlsp.function_factory.power_series(max_harm[2]),
                             nlsp.function_factory.power_series(max_harm[3]),
                             nlsp.function_factory.power_series(max_harm[4])),
        filter_irs=(imp, ) * len(max_harm),
        max_harmonics=max_harm)
    Test_groupmodel_energy_freq = nlsp.calculateenergy_atparticularfrequencies(
        hammerstein_group.GetOutput(), frequencies=Test_model_freq)
    Test_groupmodel_energy_all = nlsp.calculateenergy_freq(
        hammerstein_group.GetOutput())
    assert numpy.sum(Test_groupmodel_energy_all) == numpy.sum(
        Test_groupmodel_energy_freq)
def test_connectors():
    """
    Check whether the input and output connectors are connected properly
    """
    freq = 10000
    s_rate = 48000
    length = s_rate
    model = nlsp.AliasingCompensatedHM_upsampling(
        nonlin_func=nlsp.function_factory.power_series(1), max_harm=1)
    energy1 = nlsp.calculateenergy_freq(model.GetOutput())
    assert energy1 == [0]
    gen_sine = sumpf.modules.SineWaveGenerator(frequency=freq,
                                               phase=0.0,
                                               samplingrate=s_rate,
                                               length=length).GetSignal()
    prp = sumpf.modules.ChannelDataProperties(signal_length=length,
                                              samplingrate=s_rate)
    model.SetInput(gen_sine)
    energy2 = nlsp.calculateenergy_freq(model.GetOutput())
    assert energy2 != energy1
    model.SetInput(sumpf.Signal())
    energy3 = nlsp.calculateenergy_freq(model.GetOutput())
    assert energy3 == energy1
    model.SetInput(gen_sine)
    model.SetNLFunction(nonlin_func=nlsp.function_factory.power_series(2))
    energy4 = nlsp.calculateenergy_freq(model.GetOutput())
    assert energy4 != energy3
    model.SetFilterIR(
        sumpf.modules.InverseFourierTransform(
            sumpf.modules.FilterGenerator(
                sumpf.modules.FilterGenerator.BUTTERWORTH(order=5),
                frequency=freq,
                resolution=prp.GetResolution(),
                length=prp.GetSpectrumLength()).GetSpectrum()).GetSignal())
    energy5 = nlsp.calculateenergy_freq(model.GetOutput())
    assert energy5 != energy4
    model.SetMaximumHarmonic(2)
    energy6 = nlsp.calculateenergy_freq(model.GetOutput())
    assert energy6 != energy5
示例#7
0
def test_puretone():
    """
    Tests whether hammerstein group model produces relaiable result for pure sine tone.
    The pure sine tone is given to hammerstein model of different maximum harmonic alias compensation and the output
    freq are found for each branch. Then the same pure sine tone is given to hammerstein group model and the output
    is observed. It should have the same frequencies which we get from individual hammerstein model.
    """
    max_harm = [1, 2, 3, 4, 5]
    freq = 8000
    s_rate = 48000
    length = s_rate
    ip_sine_signal = sumpf.modules.SineWaveGenerator(
        frequency=freq, phase=0.0, samplingrate=s_rate,
        length=length).GetSignal()
    h = []
    for harm in max_harm:
        Test_Model_Hammerstein = nlsp.AliasingCompensatedHM_upsampling(
            input_signal=ip_sine_signal,
            nonlin_func=nlsp.function_factory.power_series(harm),
            max_harm=harm)
        Test_Model_outputsignal = Test_Model_Hammerstein.GetOutput()
        h.append(nlsp.find_frequencies(Test_Model_outputsignal))
    Test_model_freq = sorted(
        list(set([item for sublist in h for item in sublist])))
    imp = sumpf.modules.ImpulseGenerator(samplingrate=s_rate,
                                         length=length).GetSignal()
    hammerstein_group = nlsp.HammersteinGroupModel_up(
        input_signal=ip_sine_signal,
        nonlinear_functions=(nlsp.function_factory.power_series(max_harm[0]),
                             nlsp.function_factory.power_series(max_harm[1]),
                             nlsp.function_factory.power_series(max_harm[2]),
                             nlsp.function_factory.power_series(max_harm[3]),
                             nlsp.function_factory.power_series(max_harm[4])),
        filter_irs=(imp, ) * len(max_harm),
        max_harmonics=max_harm)
    Test_groupmodel_freq = nlsp.find_frequencies(hammerstein_group.GetOutput())
    assert Test_groupmodel_freq == Test_model_freq
def test_reliability():
    """
    test the model for reliability.
    The polynomial block power is set to one, so it produces only linear output. But aliasing compensation is done
    to prevent higher order harmonics.
    expectation: the upsampling hammerstein block should not produce any attenuation but the lp hammerstein block should
    produce attenuation due to lowpass filtering operation in the linear block
    In upsampling alias compensation the ouput energy after upsampling should be equal to the square of the upsampling
    rate multiplied with the input energy.
    """
    sweep_samplingrate = 48000
    sweep_length = 2**18
    max_harm = 2
    ip_sweep_signal = sumpf.modules.SweepGenerator(
        samplingrate=sweep_samplingrate, length=sweep_length)
    ip_sweep_spec = sumpf.modules.FourierTransform(ip_sweep_signal)
    UPHModel = nlsp.AliasingCompensatedHM_upsampling(
        input_signal=ip_sweep_signal.GetSignal(),
        nonlin_func=nlsp.function_factory.power_series(1),
        max_harm=1)
    UPHModel.SetMaximumHarmonic(max_harm)
    ip_energy = nlsp.calculateenergy_freq(ip_sweep_signal.GetSignal())
    op_energy = nlsp.calculateenergy_freq(UPHModel.GetNLOutput())
    assert numpy.multiply(ip_energy, max_harm**2) == op_energy
def linearmodel_evaluation(input_generator,
                           branches,
                           nlfunction,
                           iden_method,
                           Plot,
                           reference=None):
    """
    Evaluation of System Identification method by linear amplification
    nonlinear system - no nonlinearity, linear amplifier as linear system
    inputsignal - signal signal
    plot - the virtual linear system output and the identified linear system output
    expectation - utmost similarity between the two outputs
    """
    input_signal = input_generator.GetOutput()
    prp = sumpf.modules.ChannelDataProperties()
    prp.SetSignal(input_signal)
    filter_ir = sumpf.modules.FilterGenerator(
        filterfunction=sumpf.modules.FilterGenerator.BUTTERWORTH(order=10),
        frequency=10000.0,
        transform=False,
        resolution=prp.GetResolution(),
        length=prp.GetSpectrumLength()).GetSpectrum()
    ref_nlsystem = nlsp.AliasingCompensatedHM_upsampling(
        filter_impulseresponse=sumpf.modules.InverseFourierTransform(
            filter_ir).GetSignal())
    ref_nlsystem.SetInput(input_signal)

    # nonlinear system identification
    found_filter_spec, nl_functions = iden_method(input_generator,
                                                  ref_nlsystem.GetOutput(),
                                                  branches)
    iden_nlsystem = nlsp.HammersteinGroupModel_up(
        input_signal=input_signal,
        nonlinear_functions=nl_functions,
        filter_irs=found_filter_spec,
        max_harmonics=range(1, branches + 1))

    # linear system identification
    sweep = nlsp.NovakSweepGenerator_Sine(
        length=len(input_signal), sampling_rate=input_signal.GetSamplingRate())
    ref_nlsystem.SetInput(sweep.GetOutput())
    kernel_linear = nlsp.linear_identification_temporalreversal(
        sweep, ref_nlsystem.GetOutput())
    iden_linsystem = nlsp.AliasCompensatingHammersteinModelUpandDown(
        filter_impulseresponse=kernel_linear)

    if reference is not None:
        reference = nlsp.change_length_signal(reference,
                                              length=len(input_signal))
        ref_nlsystem.SetInput(reference)
        iden_linsystem.SetInput(reference)
        iden_nlsystem.SetInput(reference)
    if Plot is True:
        plot.relabelandplot(sumpf.modules.FourierTransform(
            ref_nlsystem.GetOutput()).GetSpectrum(),
                            "Reference System",
                            show=False)
        plot.relabelandplot(sumpf.modules.FourierTransform(
            iden_nlsystem.GetOutput()).GetSpectrum(),
                            "Identified System",
                            show=False)
        plot.relabelandplot(sumpf.modules.FourierTransform(
            iden_linsystem.GetOutput()).GetSpectrum(),
                            "Identified linear System",
                            show=True)
    print "SNR between Reference and Identified output for linear systems: %r" % nlsp.snr(
        ref_nlsystem.GetOutput(), iden_nlsystem.GetOutput())
    print "SNR between Reference and Identified output for linear systems(linear identification): %r" % nlsp.snr(
        ref_nlsystem.GetOutput(), iden_linsystem.GetOutput())
    def __init__(self,
                 input_signal=None,
                 nonlinear_functions=(nlsp.function_factory.power_series(1), ),
                 filter_irs=None,
                 max_harmonics=None,
                 resampling_algorithm=sumpf.modules.ResampleSignal.SPECTRUM):
        """
        :param signal: the input signal
        :param nonlinear_functions: the tuple of nonlinear functions eg. (nlsp.function_factory.power_series(1),...)
        :param filter_irs: the tuple of filter impulse responses eg. (IR1,...)
        :param max_harmonics: the tuple of maximum harmonics eg. (1,...)
        :param resampling_algorithm: the algorithm which can be used to downsample and upsample the signal eg. sumpf.modules.ResampleSignal.SPECTRUM
        """
        if input_signal is None:
            self.__signal = sumpf.Signal()
        else:
            self.__signal = input_signal
        self.inputstage = sumpf.modules.AmplifySignal(input=self.__signal)
        self.__nlfunctions = nonlinear_functions
        if filter_irs is None:
            self.__filter_irs = (sumpf.modules.ImpulseGenerator(
                length=len(self.__signal)).GetSignal(), ) * len(
                    self.__nlfunctions)
        else:
            self.__filter_irs = filter_irs
        self.__resampling_algorithm = resampling_algorithm
        if len(self.__nlfunctions) == len(self.__filter_irs):
            self.__branches = len(self.__nlfunctions)
        else:
            print "the given arguments dont have same length"
        if max_harmonics is None:
            self.__max_harmonics = range(1, self.__branches + 1)
        else:
            self.__max_harmonics = max_harmonics
        self.hmodels = []
        self.__sums = [None] * self.__branches

        for nl, ir, mh in zip(self.__nlfunctions, self.__filter_irs,
                              self.__max_harmonics):
            h = nlsp.AliasingCompensatedHM_upsampling(
                input_signal=self.inputstage.GetOutput(),
                nonlin_func=nl,
                max_harm=mh,
                filter_impulseresponse=ir,
                resampling_algorithm=self.__resampling_algorithm)
            self.hmodels.append(h)

        for i in reversed(range(len(self.hmodels) - 1)):
            self.__a = sumpf.modules.AddSignals()
            # print "connecting hammerstein model %i to adder %i" % (i, i)
            sumpf.connect(self.hmodels[i].GetOutput, self.__a.SetInput1)
            if i == len(self.hmodels) - 2:
                # print "connecting hammerstein model %i to adder %i" % (i+1, i)
                sumpf.connect(self.hmodels[i + 1].GetOutput,
                              self.__a.SetInput2)
            else:
                # print "connecting adder %i to adder %i" % (i+1, i)
                sumpf.connect(self.__sums[i + 1].GetOutput, self.__a.SetInput2)
            self.__sums[i] = self.__a
        if len(self.hmodels) == 1:
            self.__sums[0] = self.hmodels[0]
        self.GetOutput = self.__sums[0].GetOutput