def test_cases(self): self.assertEqual(smath.factorize(1), []) self.assertEqual(smath.factorize(2), [2]) self.assertEqual(smath.factorize(3), [3]) self.assertEqual(smath.factorize(4), [2, 2]) self.assertEqual(smath.factorize(5), [5]) self.assertEqual(smath.factorize(6), [2, 3]) self.assertEqual(smath.factorize(7), [7]) self.assertEqual(smath.factorize(8), [2, 2, 2]) self.assertEqual(smath.factorize(9), [3, 3]) self.assertEqual(smath.factorize(48000), [2] * 7 + [3] + [5] * 3)
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 test_error(self): self.assertRaises(ValueError, lambda: smath.factorize(0))
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