Skip to content
Snippets Groups Projects
special_operations.py 6.45 KiB
Newer Older
  • Learn to ignore specific revisions
  • """
    B-ASIC Special Operations Module.
    
    
    Contains operations with special purposes that may be treated differently from
    normal operations in an SFG.
    """
    
    
    from typing import Optional, Sequence, Tuple
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    from b_asic.operation import (
        AbstractOperation,
        DelayMap,
        MutableDelayMap,
        MutableResultMap,
    )
    
    from b_asic.port import SignalSourceProvider
    
    Frans Skarman's avatar
    Frans Skarman committed
    from b_asic.types import Name, Num, TypeName
    
        """
        Input operation.
    
        Represents an input port to an SFG.
    
        Its value will be updated on each iteration when simulating the SFG.
    
    
        Parameters
        ==========
        name : Name, optional
            Operation name.
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        is_linear = True
        is_constant = False
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    
    
    Frans Skarman's avatar
    Frans Skarman committed
        def __init__(self, name: Name = ""):
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            super().__init__(
                input_count=0,
                output_count=1,
    
    Frans Skarman's avatar
    Frans Skarman committed
                name=name,
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                latency_offsets={"out0": 0},
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                execution_time=0,
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            )
    
            self.set_param("value", 0)
    
        @classmethod
        def type_name(cls) -> TypeName:
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            return TypeName("in")
    
        @property
        def latency(self) -> int:
            return self.latency_offsets["out0"]
    
    
    Frans Skarman's avatar
    Frans Skarman committed
        def value(self) -> Num:
    
            """Get the current value of this input."""
            return self.param("value")
    
        @value.setter
    
    Frans Skarman's avatar
    Frans Skarman committed
        def value(self, value: Num) -> None:
    
            """Set the current value of this input."""
            self.set_param("value", value)
    
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        def get_plot_coordinates(
            self,
    
        ) -> Tuple[Tuple[Tuple[float, float], ...], Tuple[Tuple[float, float], ...]]:
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            # Doc-string inherited
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            return (
    
                (
                    (-0.5, 0),
                    (-0.5, 1),
                    (-0.25, 1),
                    (0, 0.5),
                    (-0.25, 0),
                    (-0.5, 0),
                ),
                (
                    (-0.5, 0),
                    (-0.5, 1),
                    (-0.25, 1),
                    (0, 0.5),
                    (-0.25, 0),
                    (-0.5, 0),
                ),
    
        def get_input_coordinates(self) -> Tuple[Tuple[float, float], ...]:
            # doc-string inherited
            return tuple()
    
        def get_output_coordinates(self) -> Tuple[Tuple[float, float], ...]:
            # doc-string inherited
            return ((0, 0.5),)
    
        """
        Output operation.
    
        Represents an output port to an SFG.
    
        The SFG will forward its input to the corresponding output signal
        destinations.
    
    
        Parameters
        ==========
    
        src0 : SignalSourceProvider, optional
            The signal connected to the Output operation.
        name : Name, optional
            Operation name.
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        is_linear = True
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        def __init__(
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            self,
            src0: Optional[SignalSourceProvider] = None,
            name: Name = Name(""),
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        ):
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            super().__init__(
                input_count=1,
                output_count=0,
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                name=Name(name),
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                input_sources=[src0],
                latency_offsets={"in0": 0},
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                execution_time=0,
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            )
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            return TypeName("out")
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        def get_plot_coordinates(
            self,
    
        ) -> Tuple[Tuple[Tuple[float, float], ...], Tuple[Tuple[float, float], ...]]:
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            # Doc-string inherited
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            return (
    
                ((0, 0), (0, 1), (0.25, 1), (0.5, 0.5), (0.25, 0), (0, 0)),
                ((0, 0), (0, 1), (0.25, 1), (0.5, 0.5), (0.25, 0), (0, 0)),
    
        def get_input_coordinates(self) -> Tuple[Tuple[float, float], ...]:
            # doc-string inherited
            return ((0, 0.5),)
    
        def get_output_coordinates(self) -> Tuple[Tuple[float, float], ...]:
            # doc-string inherited
            return tuple()
    
        @property
        def latency(self) -> int:
            return self.latency_offsets["in0"]
    
    
        """
        Unit delay operation.
    
        Represents a delay of one iteration.
        The initial value is zero unless otherwise specified.
    
        Parameters
        ----------
        src0 : SignalSourceProvider, optional
            The node to be delayed.
        initial_value : Number, default: 0
            Initial value of the delay.
        name : Name, default ""
            Name.
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        is_linear = True
    
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        def __init__(
            self,
            src0: Optional[SignalSourceProvider] = None,
    
    Frans Skarman's avatar
    Frans Skarman committed
            initial_value: Num = 0,
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            name: Name = Name(""),
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        ):
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            super().__init__(
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                input_count=1,
                output_count=1,
                name=Name(name),
                input_sources=[src0],
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            )
    
            self.set_param("initial_value", initial_value)
    
        @classmethod
        def type_name(cls) -> TypeName:
    
            return TypeName("t")
    
    
        def evaluate(self, a):
            return self.param("initial_value")
    
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        def current_output(
            self, index: int, delays: Optional[DelayMap] = None, prefix: str = ""
    
    Frans Skarman's avatar
    Frans Skarman committed
        ) -> Optional[Num]:
    
                return delays.get(self.key(index, prefix), self.param("initial_value"))
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        def evaluate_output(
            self,
            index: int,
    
    Frans Skarman's avatar
    Frans Skarman committed
            input_values: Sequence[Num],
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            results: Optional[MutableResultMap] = None,
            delays: Optional[MutableDelayMap] = None,
            prefix: str = "",
            bits_override: Optional[int] = None,
    
            quantize: bool = True,
    
    Frans Skarman's avatar
    Frans Skarman committed
        ) -> Num:
    
                raise IndexError(f"Output index out of range (expected 0-0, got {index})")
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                    "Wrong number of inputs supplied to SFG for evaluation"
                    f" (expected 1, got {len(input_values)})"
                )
    
    
            key = self.key(index, prefix)
            value = self.param("initial_value")
            if delays is not None:
                value = delays.get(key, value)
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                delays[key] = (
    
                    self.quantize_inputs(input_values, bits_override)[0]
                    if quantize
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                    else input_values[0]
                )
    
            if results is not None:
                results[key] = value
            return value
    
        @property
    
    Frans Skarman's avatar
    Frans Skarman committed
        def initial_value(self) -> Num:
    
            """Get the initial value of this delay."""
            return self.param("initial_value")
    
        @initial_value.setter
    
    Frans Skarman's avatar
    Frans Skarman committed
        def initial_value(self, value: Num) -> None:
    
            """Set the initial value of this delay."""
            self.set_param("initial_value", value)