def test_approx(self): self.assertEqual( smath.small_factor_at_least(100, 9, _force_approx=True), 25) self.assertEqual( smath.small_factor_at_least(100, 10, _force_approx=True), 10) self.assertEqual( smath.small_factor_at_least(100, 11, _force_approx=True), 25)
def test_approx(self): self.assertEqual(smath.small_factor_at_least(100, 9, _force_approx=True), 25) self.assertEqual(smath.small_factor_at_least(100, 10, _force_approx=True), 10) self.assertEqual(smath.small_factor_at_least(100, 11, _force_approx=True), 25)
def test_exact(self): self.assertEqual(smath.small_factor_at_least(100, 9), 10) self.assertEqual(smath.small_factor_at_least(100, 10), 10) self.assertEqual(smath.small_factor_at_least(100, 11), 20)
def _make_filter_plan_1(input_rate, output_rate): assert input_rate > 0 assert output_rate > 0 total_decimation = max(1, int(input_rate // output_rate)) using_rational_resampler = _use_rational_resampler and input_rate % 1 == 0 and output_rate % 1 == 0 if using_rational_resampler: # If using rational resampler, don't decimate to the point that we get a fractional rate, if possible. input_rate = int(input_rate) output_rate = int(output_rate) if input_rate > output_rate: total_decimation = input_rate // small_factor_at_least(input_rate, output_rate) # print input_rate / total_decimation, total_decimation, input_rate, output_rate, input_rate // gcd(input_rate, output_rate) # TODO: Don't re-factorize unnecessarily stage_decimations = factorize(total_decimation) stage_decimations.reverse() # loop variables stage_designs = [] stage_input_rate = input_rate last_index = len(stage_decimations) - 1 if len(stage_decimations) == 0: # interpolation or nothing -- don't put it in the stages freq_xlate_stage = len(stage_designs) stage_designs.append(_FilterPlanXlateStage( rate=stage_input_rate)) else: # decimation for i, stage_decimation in enumerate(stage_decimations): next_rate = stage_input_rate / stage_decimation stage_type = _FilterPlanFinalDecimatingStage if i == last_index else _FilterPlanDecimatingStage if i == 0: freq_xlate_stage = len(stage_designs) stage_designs.append(stage_type( freq_xlating=True, decimation=stage_decimation, input_rate=stage_input_rate, output_rate=next_rate)) else: stage_designs.append(stage_type( freq_xlating=False, decimation=stage_decimation, input_rate=stage_input_rate, output_rate=next_rate)) stage_input_rate = next_rate # final connection and resampling if stage_input_rate == output_rate: # exact multiple, no fractional resampling needed stage_designs.append(_FilterPlanCommentStage( comment='No final resampler stage.', rate=output_rate)) else: # TODO: systematically combine resampler with final filter stage if using_rational_resampler: if stage_input_rate % 1 != 0: raise Exception("shouldn't happen", stage_input_rate) stage_input_rate = int(stage_input_rate) # because of float division above common = gcd(output_rate, stage_input_rate) interpolation = output_rate // common decimation = stage_input_rate // common stage_designs.append(_FilterPlanRationalResamplerStage( interpolation=interpolation, decimation=decimation, input_rate=stage_input_rate, output_rate=output_rate)) else: # TODO: cache filter computation as optfir is used and takes a noticeable time stage_designs.append(_FilterPlanPfbResamplerStage( resample_rate=float(output_rate) / stage_input_rate, input_rate=stage_input_rate, output_rate=output_rate)) plan = _MultistageChannelFilterPlan( stage_designs=stage_designs, freq_xlate_stage=freq_xlate_stage, cutoff_freq=-1, transition_width=-1) return plan
def __init__(self, name='Multistage Channel Filter', input_rate=0, output_rate=0, cutoff_freq=0, transition_width=0, center_freq=0): assert input_rate > 0 assert output_rate > 0 assert cutoff_freq > 0 assert transition_width > 0 # cf. firdes.sanity_check_1f (which is private) # TODO better errors for other cases if cutoff_freq > output_rate / 2: # early check for better errors since our cascaded filters might be cryptically nonsense raise ValueError( 'cutoff_freq (%s) is too high for output_rate (%s)' % (cutoff_freq, output_rate)) gr.hier_block2.__init__( self, name, gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), ) self.cutoff_freq = cutoff_freq self.transition_width = transition_width total_decimation = max(1, int(input_rate // output_rate)) using_rational_resampler = _use_rational_resampler and input_rate % 1 == 0 and output_rate % 1 == 0 if using_rational_resampler: # If using rational resampler, don't decimate to the point that we get a fractional rate, if possible. input_rate = int(input_rate) output_rate = int(output_rate) if input_rate > output_rate: total_decimation = input_rate // small_factor_at_least( input_rate, output_rate) # print input_rate / total_decimation, total_decimation, input_rate, output_rate, input_rate // gcd(input_rate, output_rate) # TODO: Don't re-factorize unnecessarily stage_decimations = factorize(total_decimation) stage_decimations.reverse() self.stages = [] # loop variables prev_block = self stage_input_rate = input_rate last_index = len(stage_decimations) - 1 if len(stage_decimations) == 0: # interpolation or nothing -- don't put it in the stages # TODO: consider using rotator block instead (has different API) self.freq_filter_block = grfilter.freq_xlating_fir_filter_ccc( 1, [1], center_freq, stage_input_rate) self.connect(prev_block, self.freq_filter_block) prev_block = self.freq_filter_block else: # decimation for i, stage_decimation in enumerate(stage_decimations): next_rate = stage_input_rate / stage_decimation if i == 0: stage_filter = grfilter.freq_xlating_fir_filter_ccc( stage_decimation, [0], # placeholder center_freq, stage_input_rate) self.freq_filter_block = stage_filter else: taps = self.__stage_taps(i == last_index, stage_input_rate, next_rate) if len(taps) > 10: stage_filter = grfilter.fft_filter_ccc( stage_decimation, taps, 1) else: stage_filter = grfilter.fir_filter_ccc( stage_decimation, taps) self.stages.append((stage_filter, stage_input_rate, next_rate)) self.connect(prev_block, stage_filter) prev_block = stage_filter stage_input_rate = next_rate # final connection and resampling if stage_input_rate == output_rate: # exact multiple, no fractional resampling needed self.connect(prev_block, self) self.__resampler_explanation = 'No final resampler stage.' else: # TODO: systematically combine resampler with final filter stage if using_rational_resampler: if stage_input_rate % 1 != 0: raise Exception("shouldn't happen", stage_input_rate) stage_input_rate = int( stage_input_rate) # because of float division above common = gcd(output_rate, stage_input_rate) interpolation = output_rate // common decimation = stage_input_rate // common self.__resampler_explanation = 'rational_resampler by %s/%s (stage rates %s/%s)' % ( interpolation, decimation, output_rate, stage_input_rate) resampler = rational_resampler.rational_resampler_ccf( interpolation=interpolation, decimation=decimation) else: # TODO: cache filter computation as optfir is used and takes a noticeable time self.__resampler_explanation = 'arb_resampler %s/%s = %s' % ( output_rate, stage_input_rate, float(output_rate) / stage_input_rate) resampler = pfb.arb_resampler_ccf( float(output_rate) / stage_input_rate) self.connect(prev_block, resampler, self) # TODO: Shouldn't be necessary since we compute the taps in the loop above... self.__do_taps()
def __init__(self, name='Multistage Channel Filter', input_rate=0, output_rate=0, cutoff_freq=0, transition_width=0, center_freq=0): assert input_rate > 0 assert output_rate > 0 assert cutoff_freq > 0 assert transition_width > 0 # cf. firdes.sanity_check_1f (which is private) # TODO better errors for other cases if cutoff_freq > output_rate / 2: # early check for better errors since our cascaded filters might be cryptically nonsense raise ValueError('cutoff_freq (%s) is too high for output_rate (%s)' % (cutoff_freq, output_rate)) gr.hier_block2.__init__( self, name, gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), gr.io_signature(1, 1, gr.sizeof_gr_complex * 1), ) self.cutoff_freq = cutoff_freq self.transition_width = transition_width total_decimation = max(1, int(input_rate // output_rate)) using_rational_resampler = _use_rational_resampler and input_rate % 1 == 0 and output_rate % 1 == 0 if using_rational_resampler: # If using rational resampler, don't decimate to the point that we get a fractional rate, if possible. input_rate = int(input_rate) output_rate = int(output_rate) if input_rate > output_rate: total_decimation = input_rate // small_factor_at_least(input_rate, output_rate) # print input_rate / total_decimation, total_decimation, input_rate, output_rate, input_rate // gcd(input_rate, output_rate) # TODO: Don't re-factorize unnecessarily stage_decimations = factorize(total_decimation) stage_decimations.reverse() self.stages = [] # loop variables prev_block = self stage_input_rate = input_rate last_index = len(stage_decimations) - 1 if len(stage_decimations) == 0: # interpolation or nothing -- don't put it in the stages # TODO: consider using rotator block instead (has different API) self.freq_filter_block = grfilter.freq_xlating_fir_filter_ccc( 1, [1], center_freq, stage_input_rate) self.connect(prev_block, self.freq_filter_block) prev_block = self.freq_filter_block else: # decimation for i, stage_decimation in enumerate(stage_decimations): next_rate = stage_input_rate / stage_decimation if i == 0: stage_filter = grfilter.freq_xlating_fir_filter_ccc( stage_decimation, [0], # placeholder center_freq, stage_input_rate) self.freq_filter_block = stage_filter else: taps = self.__stage_taps(i == last_index, stage_input_rate, next_rate) if len(taps) > 10: stage_filter = grfilter.fft_filter_ccc(stage_decimation, taps, 1) else: stage_filter = grfilter.fir_filter_ccc(stage_decimation, taps) self.stages.append((stage_filter, stage_input_rate, next_rate)) self.connect(prev_block, stage_filter) prev_block = stage_filter stage_input_rate = next_rate # final connection and resampling if stage_input_rate == output_rate: # exact multiple, no fractional resampling needed self.connect(prev_block, self) self.__resampler_explanation = 'No final resampler stage.' else: # TODO: systematically combine resampler with final filter stage if using_rational_resampler: if stage_input_rate % 1 != 0: raise Exception("shouldn't happen", stage_input_rate) stage_input_rate = int(stage_input_rate) # because of float division above common = gcd(output_rate, stage_input_rate) interpolation = output_rate // common decimation = stage_input_rate // common self.__resampler_explanation = 'rational_resampler by %s/%s (stage rates %s/%s)' % (interpolation, decimation, output_rate, stage_input_rate) resampler = rational_resampler.rational_resampler_ccf( interpolation=interpolation, decimation=decimation) else: # TODO: cache filter computation as optfir is used and takes a noticeable time self.__resampler_explanation = 'arb_resampler %s/%s = %s' % (output_rate, stage_input_rate, float(output_rate) / stage_input_rate) resampler = pfb.arb_resampler_ccf(float(output_rate) / stage_input_rate) self.connect( prev_block, resampler, self) # TODO: Shouldn't be necessary since we compute the taps in the loop above... self.__do_taps()
def _make_filter_plan_1(input_rate, output_rate): assert input_rate > 0 assert output_rate > 0 total_decimation = max(1, int(input_rate // output_rate)) using_rational_resampler = _use_rational_resampler and input_rate % 1 == 0 and output_rate % 1 == 0 if using_rational_resampler: # If using rational resampler, don't decimate to the point that we get a fractional rate, if possible. input_rate = int(input_rate) output_rate = int(output_rate) if input_rate > output_rate: total_decimation = input_rate // small_factor_at_least( input_rate, output_rate) # print input_rate / total_decimation, total_decimation, input_rate, output_rate, input_rate // gcd(input_rate, output_rate) # TODO: Don't re-factorize unnecessarily stage_decimations = factorize(total_decimation) stage_decimations.reverse() # loop variables stage_designs = [] stage_input_rate = input_rate last_index = len(stage_decimations) - 1 if len(stage_decimations) == 0: # interpolation or nothing -- don't put it in the stages freq_xlate_stage = len(stage_designs) stage_designs.append(_FilterPlanXlateStage(rate=stage_input_rate)) else: # decimation for i, stage_decimation in enumerate(stage_decimations): next_rate = stage_input_rate / stage_decimation stage_type = _FilterPlanFinalDecimatingStage if i == last_index else _FilterPlanDecimatingStage if i == 0: freq_xlate_stage = len(stage_designs) stage_designs.append( stage_type(freq_xlating=True, decimation=stage_decimation, input_rate=stage_input_rate, output_rate=next_rate)) else: stage_designs.append( stage_type(freq_xlating=False, decimation=stage_decimation, input_rate=stage_input_rate, output_rate=next_rate)) stage_input_rate = next_rate # final connection and resampling if stage_input_rate == output_rate: # exact multiple, no fractional resampling needed stage_designs.append( _FilterPlanCommentStage(comment='No final resampler stage.', rate=output_rate)) else: # TODO: systematically combine resampler with final filter stage if using_rational_resampler: if stage_input_rate % 1 != 0: raise Exception("shouldn't happen", stage_input_rate) stage_input_rate = int( stage_input_rate) # because of float division above common = gcd(output_rate, stage_input_rate) interpolation = output_rate // common decimation = stage_input_rate // common stage_designs.append( _FilterPlanRationalResamplerStage(interpolation=interpolation, decimation=decimation, input_rate=stage_input_rate, output_rate=output_rate)) else: # TODO: cache filter computation as optfir is used and takes a noticeable time stage_designs.append( _FilterPlanPfbResamplerStage(resample_rate=float(output_rate) / stage_input_rate, input_rate=stage_input_rate, output_rate=output_rate)) plan = _MultistageChannelFilterPlan(stage_designs=stage_designs, freq_xlate_stage=freq_xlate_stage, cutoff_freq=-1, transition_width=-1) return plan