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_lowpass(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_lp(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.HammersteinModel( input_signal=gen_sine, nonlin_func=nlsp.function_factory.power_series(1)) energy_ip = nlsp.calculateenergy_freq(gen_sine) energy_op = nlsp.calculateenergy_freq(model.GetOutput()) assert int(energy_ip[0]) == int(energy_op[0])
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 makes sure that aliasing will be produced in the model if frequency*max_harm is greater than sampling rate """ 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_lowpass( 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) if freq * harm > s_rate / 2: assert quality <= 1 else: assert quality == 1
def signal_to_noise_ratio_freq(input_signalorspectrum, output_signalorspectrum): """ Calculates the signal to noise ratio of two spectrums. This function calculates the signal to noise ratio in frequency domain. If the input is signal then it transforms it to frequency domain. And in the case of length conflict zeros are appended. :param input_signalorspectrum: the array of input spectrum :param output_signalorspectrum: the array of output spectrum :return: the array of signal to noise ratio of two spectrums """ if isinstance(input_signalorspectrum, list) != True: observed_l = [] observed_l.append(input_signalorspectrum) else: observed_l = input_signalorspectrum if isinstance(output_signalorspectrum, list) != True: identified_l = [] identified_l.append(output_signalorspectrum) else: identified_l = output_signalorspectrum snr = [] for observed, identified in zip(observed_l, identified_l): if isinstance(observed, (sumpf.Signal, sumpf.Spectrum)) and isinstance( observed, (sumpf.Signal, sumpf.Spectrum)): if isinstance(observed, sumpf.Signal): observed = sumpf.modules.FourierTransform( observed).GetSpectrum() if isinstance(identified, sumpf.Signal): identified = sumpf.modules.FourierTransform( identified).GetSpectrum() if len(observed) != len(identified): merged_spectrum = sumpf.modules.MergeSpectrums( spectrums=[observed, identified], on_length_conflict=sumpf.modules.MergeSpectrums. FILL_WITH_ZEROS).GetOutput() observed = sumpf.modules.SplitSpectrum( data=merged_spectrum, channels=[0]).GetOutput() identified = sumpf.modules.SplitSpectrum( data=merged_spectrum, channels=[1]).GetOutput() noise = observed - identified noise_energy = nlsp.calculateenergy_freq(noise) input_energy = nlsp.calculateenergy_freq(observed) snr.append(10 * math.log10(input_energy[0] / noise_energy[0])) else: print "The given arguments is not a sumpf.Signal or sumpf.Spectrum" return snr
def harmonicsvsall_energyratio_nl(sweep_generator, response, degree): harmonics = nlsp.get_nl_harmonics(sweep_generator, response, degree) all_energy = nlsp.calculateenergy_freq(harmonics) harm_energy = [] for i in range(0, degree): harm_energy.append(all_energy[i]) if degree % 2 == 0: # even harm_energy = harm_energy[1::2] else: # odd harm_energy = harm_energy[0::2] return numpy.divide(numpy.sum(harm_energy), numpy.sum(all_energy))
def test_nonlinearfunction(): """ test whether the factory function and the function for nonlinearity generation works fine. the nonlinear function is called in three different methods with same input signal and same degree of nonlinearity. Hence the output of the model should have same output. The comparision is made by comaparing the energy of the output signals """ sweep_samplingrate = 48000 sweep_length = 2**18 ip_sweep_signal = sumpf.modules.SweepGenerator(samplingrate=sweep_samplingrate,length=sweep_length) hmodel = nlsp.HammersteinModel(input_signal=ip_sweep_signal.GetSignal()) hmodel.SetNLFunction(nonlin_func=nlsp.function_factory.power_series(5)) hmodel_1 = nlsp.HammersteinModel(input_signal=ip_sweep_signal.GetSignal(), nonlin_func=nlsp.function_factory.power_series(5)) energy = nlsp.calculateenergy_freq(hmodel.GetOutput()) energy_1 = nlsp.calculateenergy_freq(hmodel_1.GetOutput()) hmodel_2 = nlsp.NonlinearFunction.power_series(5,signal=ip_sweep_signal.GetSignal()) energy_2 = nlsp.calculateenergy_freq(hmodel_2.GetOutput()) energy = map(int,energy) energy_1 = map(int,energy_1) energy_2 = map(int,energy_2) assert energy == energy_1 == energy_2
def calculateenergy_betweenfreq_freq(input, frequency_range): """ Calculates the energy of input signal between certain frequencies of input signal :param input: the input signal or spectrum whose energy has to be calculated :param frequency_range: the range of frequencies over which the energy has to be calculated :return: the tuple of the energy of input spectrum in frequency domain """ if isinstance(input, (sumpf.Signal)): ip = sumpf.modules.FourierTransform(signal=input).GetSpectrum() else: ip = input spec = nlsp.cut_spectrum(ip, frequency_range) energy = nlsp.calculateenergy_freq(spec) return energy
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 lp filtering alias compensation the ouput energy should be less than 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_lowpass( 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 ip_energy > op_energy
def test_connectors(): """ Check whether the input and output connectors are connected properly """ freq = 10000 s_rate = 48000 length = s_rate model = nlsp.HammersteinModel( nonlin_func=nlsp.function_factory.power_series(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
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)