diff --git a/b_asic/gui_utils/plot_window.py b/b_asic/gui_utils/plot_window.py index 5322debf03ee338d3fcb5860f706c7517976d248..96c3bec5986abef0e46eaa9ebbf48c158ac61e0f 100644 --- a/b_asic/gui_utils/plot_window.py +++ b/b_asic/gui_utils/plot_window.py @@ -6,8 +6,8 @@ from typing import Dict, List, Mapping, Optional, Sequence # , Union # from numpy import (array, real, imag, real_if_close, absolute, angle) import numpy as np -from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas -from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar +from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas +from matplotlib.backends.backend_qtagg import NavigationToolbar2QT as NavigationToolbar from matplotlib.figure import Figure from matplotlib.ticker import MaxNLocator from qtpy.QtCore import Qt @@ -251,7 +251,7 @@ def start_simulation_dialog( The name of the SFG. """ if not QApplication.instance(): - QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) + # QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) app = QApplication(sys.argv) else: app = QApplication.instance() diff --git a/b_asic/sfg_generators.py b/b_asic/sfg_generators.py index 96fcdfdc3f5cefdc5a882519b3c433d09b0156eb..97cf1ced391e9ee4b47a54dc277ce67397ac7cac 100644 --- a/b_asic/sfg_generators.py +++ b/b_asic/sfg_generators.py @@ -257,16 +257,15 @@ def transposed_direct_form_fir( return SFG([input_op], [output], name=Name(name)) -def direct_form_I_iir( +def direct_form_1_iir( b: Sequence[complex], a: Sequence[complex], name: Optional[str] = None, mult_properties: Optional[Union[Dict[str, int], Dict[str, Dict[str, int]]]] = None, add_properties: Optional[Union[Dict[str, int], Dict[str, Dict[str, int]]]] = None, ) -> SFG: - # np_b = np.atleast_1d(np.squeeze(np.asarray(b))) - # np_a = np.atleast_1d(np.squeeze(np.asarray(a))) - + if name is None: + name = "Direct-form I IIR filter" if mult_properties is None: mult_properties = {} if add_properties is None: @@ -291,16 +290,17 @@ def direct_form_I_iir( # construct the feedback part tmp_add = Addition(op_a, None, **add_properties) - muls = [ConstantMultiplication(a[0], tmp_add, **mult_properties)] - output <<= muls[0] + # muls = [ConstantMultiplication(a[0], tmp_add, **mult_properties)] + muls = [] + output <<= tmp_add delays = [] - prev_delay = muls[0] + prev_delay = tmp_add for i, coeff in enumerate(a[1:]): prev_delay = Delay(prev_delay) delays.append(prev_delay) if i < len(a) - 1: - muls.append(ConstantMultiplication(coeff, prev_delay, **mult_properties)) + muls.append(ConstantMultiplication(-coeff, prev_delay, **mult_properties)) op_a = muls[-1] for i in range(len(muls) - 1): @@ -309,3 +309,84 @@ def direct_form_I_iir( tmp_add.input(1).connect(op_a) return SFG([input_op], [output], name=Name(name)) + + +def direct_form_2_iir( + b: Sequence[complex], + a: Sequence[complex], + name: Optional[str] = None, + mult_properties: Optional[Union[Dict[str, int], Dict[str, Dict[str, int]]]] = None, + add_properties: Optional[Union[Dict[str, int], Dict[str, Dict[str, int]]]] = None, +) -> SFG: + if name is None: + name = "Direct-form I IIR filter" + if mult_properties is None: + mult_properties = {} + if add_properties is None: + add_properties = {} + + input_op = Input() + + left_adds = [] + right_adds = [] + left_muls = [] + right_muls = [] + delays = [Delay()] + + if len(a) != len(b): + raise ValueError("size of coefficient lists a and b are not the same") + + # all except the final + op_a_left = None + op_a_right = None + for i in range(len(a) - 1): + a_coeff = a[-i - 1] + b_coeff = b[-i - 1] + if len(left_muls) != 0: # not first iteration + new_delay = Delay() + delays[-1] <<= new_delay + delays.append(new_delay) + left_muls.append( + ConstantMultiplication(-a_coeff, delays[-1], **mult_properties) + ) + right_muls.append( + ConstantMultiplication(b_coeff, delays[-1], **mult_properties) + ) + if len(left_muls) > 1: # not first iteration + left_adds.append(Addition(op_a_left, left_muls[-1], **add_properties)) + right_adds.append(Addition(op_a_right, right_muls[-1], **add_properties)) + op_a_left = left_adds[-1] + op_a_right = right_adds[-1] + else: + op_a_left = left_muls[-1] + op_a_right = right_muls[-1] + + # finalize + if left_adds: + left_adds.append(Addition(input_op, left_adds[-1], **add_properties)) + else: + left_adds.append(Addition(input_op, left_muls[-1], **add_properties)) + delays[-1] <<= left_adds[-1] + mul = ConstantMultiplication(b[0], left_adds[-1], **mult_properties) + add = Addition(mul, right_adds[-1], **add_properties) + + # for i, coeff in enumerate(list(reversed(a[1:]))): + # if len(left_muls) != 0: # not first iteration + # new_delay = Delay() + # delays[-1] <<= new_delay + # delays.append(new_delay) + # left_muls.append(ConstantMultiplication(-coeff, delays[-1], **mult_properties)) + # if len(left_muls) > 1: # not first iteration + # left_adds.append(Addition(op_a, left_muls[-1], **add_properties)) + # op_a = left_adds[-1] + # else: + # op_a = left_muls[-1] + # if left_adds: + # left_adds.append(Addition(input_op, left_adds[-1], **add_properties)) + # else: + # left_adds.append(Addition(input_op, left_muls[-1], **add_properties)) + # delays[-1] <<= left_adds[-1] + + output = Output() + output <<= add + return SFG([input_op], [output], name=Name(name))