Skip to content
Snippets Groups Projects
core_operations.py 10.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • """B-ASIC Core Operations Module.
    
    Contains some of the most commonly used mathematical operations.
    
    """
    
    from numbers import Number
    
    from numpy import conjugate, sqrt, abs as np_abs
    
    
    from b_asic.port import SignalSourceProvider, InputPort, OutputPort
    
    from b_asic.operation import AbstractOperation
    from b_asic.graph_component import Name, TypeName
    
    
    class Constant(AbstractOperation):
        """Constant value operation.
    
    
        Gives a specified value that remains constant for every iteration.
    
        output(0): self.param("value")
    
        """
    
        def __init__(self, value: Number = 0, name: Name = ""):
    
            """Construct a Constant operation with the given value."""
    
            super().__init__(input_count=0, output_count=1, name=name, latency_offsets={'out0' : 0})
    
        @classmethod
        def type_name(cls) -> TypeName:
            return "c"
    
    
        def evaluate(self):
            return self.param("value")
    
        @property
    
        def value(self) -> Number:
            """Get the constant value of this operation."""
            return self.param("value")
    
        @value.setter
        def value(self, value: Number) -> None:
            """Set the constant value of this operation."""
            return self.set_param("value", value)
    
    
    
    class Addition(AbstractOperation):
        """Binary addition operation.
    
    
        Gives the result of adding two inputs.
    
        output(0): input(0) + input(1)
        """
    
        def __init__(self, src0: Optional[SignalSourceProvider] = None, src1: Optional[SignalSourceProvider] = None, name: Name = "", latency: Optional[int] = None, latency_offsets: Optional[Dict[str, int]] = None):
            """Construct an Addition operation."""
            super().__init__(input_count=2, output_count=1, name=name, input_sources=[src0, src1],
                             latency=latency, latency_offsets=latency_offsets)
    
        @classmethod
        def type_name(cls) -> TypeName:
            return "add"
    
    
        def evaluate(self, a, b):
            return a + b
    
    
    class Subtraction(AbstractOperation):
        """Binary subtraction operation.
    
    
        Gives the result of subtracting the second input from the first one.
    
        output(0): input(0) - input(1)
    
        def __init__(self, src0: Optional[SignalSourceProvider] = None, src1: Optional[SignalSourceProvider] = None, name: Name = "", latency: Optional[int] = None, latency_offsets: Optional[Dict[str, int]] = None):
            """Construct a Subtraction operation."""
            super().__init__(input_count=2, output_count=1, name=name, input_sources=[src0, src1],
                             latency=latency, latency_offsets=latency_offsets)
    
        @classmethod
        def type_name(cls) -> TypeName:
            return "sub"
    
    
        def evaluate(self, a, b):
            return a - b
    
    
    class Multiplication(AbstractOperation):
        """Binary multiplication operation.
    
    
        Gives the result of multiplying two inputs.
    
        output(0): input(0) * input(1)
    
        def __init__(self, src0: Optional[SignalSourceProvider] = None, src1: Optional[SignalSourceProvider] = None, name: Name = "", latency: Optional[int] = None, latency_offsets: Optional[Dict[str, int]] = None):
            """Construct a Multiplication operation."""
            super().__init__(input_count=2, output_count=1, name=name, input_sources=[src0, src1],
                             latency=latency, latency_offsets=latency_offsets)
    
        @classmethod
        def type_name(cls) -> TypeName:
            return "mul"
    
    
        def evaluate(self, a, b):
            return a * b
    
    
    class Division(AbstractOperation):
        """Binary division operation.
    
    
        Gives the result of dividing the first input by the second one.
    
        def __init__(self, src0: Optional[SignalSourceProvider] = None, src1: Optional[SignalSourceProvider] = None, name: Name = "", latency: Optional[int] = None, latency_offsets: Optional[Dict[str, int]] = None):
            """Construct a Division operation."""
            super().__init__(input_count=2, output_count=1, name=name, input_sources=[src0, src1],
                             latency=latency, latency_offsets=latency_offsets)
    
            return "div"
    
    
    class Min(AbstractOperation):
        """Binary min operation.
    
        Gives the minimum value of two inputs.
        NOTE: Non-real numbers are not supported.
    
        def __init__(self, src0: Optional[SignalSourceProvider] = None, src1: Optional[SignalSourceProvider] = None, name: Name = "", latency: Optional[int] = None, latency_offsets: Optional[Dict[str, int]] = None):
            """Construct a Min operation."""
            super().__init__(input_count=2, output_count=1, name=name, input_sources=[src0, src1],
                             latency=latency, latency_offsets=latency_offsets)
    
        @classmethod
        def type_name(cls) -> TypeName:
            return "min"
    
        def evaluate(self, a, b):
            assert not isinstance(a, complex) and not isinstance(b, complex), \
                ("core_operations.Min does not support complex numbers.")
            return a if a < b else b
    
    
    
    class Max(AbstractOperation):
        """Binary max operation.
    
    
        Gives the maximum value of two inputs.
        NOTE: Non-real numbers are not supported.
    
        output(0): max(input(0), input(1))
    
        def __init__(self, src0: Optional[SignalSourceProvider] = None, src1: Optional[SignalSourceProvider] = None, name: Name = "", latency: Optional[int] = None, latency_offsets: Optional[Dict[str, int]] = None):
            """Construct a Max operation."""
            super().__init__(input_count=2, output_count=1, name=name, input_sources=[src0, src1],
                             latency=latency, latency_offsets=latency_offsets)
    
        @classmethod
        def type_name(cls) -> TypeName:
            return "max"
    
    
        def evaluate(self, a, b):
            assert not isinstance(a, complex) and not isinstance(b, complex), \
                ("core_operations.Max does not support complex numbers.")
            return a if a > b else b
    
    
    
    class SquareRoot(AbstractOperation):
        """Square root operation.
    
        Gives the square root of its input.
    
        output(0): sqrt(input(0))
    
        def __init__(self, src0: Optional[SignalSourceProvider] = None, name: Name = "", latency: Optional[int] = None, latency_offsets: Optional[Dict[str, int]] = None):
            """Construct a SquareRoot operation."""
            super().__init__(input_count=1, output_count=1, name=name, input_sources=[src0],
                             latency=latency, latency_offsets=latency_offsets)
    
        @classmethod
        def type_name(cls) -> TypeName:
            return "sqrt"
    
        def evaluate(self, a):
            return sqrt(complex(a))
    
    class ComplexConjugate(AbstractOperation):
        """Complex conjugate operation.
    
        Gives the complex conjugate of its input.
    
        output(0): conj(input(0))
    
        def __init__(self, src0: Optional[SignalSourceProvider] = None, name: Name = "", latency: Optional[int] = None, latency_offsets: Optional[Dict[str, int]] = None):
            """Construct a ComplexConjugate operation."""
            super().__init__(input_count=1, output_count=1, name=name, input_sources=[src0],
                             latency=latency, latency_offsets=latency_offsets)
    
        @classmethod
        def type_name(cls) -> TypeName:
            return "conj"
    
    
        def evaluate(self, a):
    
    class Absolute(AbstractOperation):
        """Absolute value operation.
    
        Gives the absolute value of its input.
    
        output(0): abs(input(0))
    
        def __init__(self, src0: Optional[SignalSourceProvider] = None, name: Name = "", latency: Optional[int] = None, latency_offsets: Optional[Dict[str, int]] = None):
            """Construct an Absolute operation."""
            super().__init__(input_count=1, output_count=1, name=name, input_sources=[src0],
                             latency=latency, latency_offsets=latency_offsets)
    
        @classmethod
        def type_name(cls) -> TypeName:
            return "abs"
    
    
        def evaluate(self, a):
    
    class ConstantMultiplication(AbstractOperation):
        """Constant multiplication operation.
    
        Gives the result of multiplying its input by a specified value.
    
        def __init__(self, value: Number = 0, src0: Optional[SignalSourceProvider] = None, name: Name = "", latency: Optional[int] = None, latency_offsets: Optional[Dict[str, int]] = None):
            """Construct a ConstantMultiplication operation with the given value."""
            super().__init__(input_count=1, output_count=1, name=name, input_sources=[src0],
                             latency=latency, latency_offsets=latency_offsets)
            self.set_param("value", value)
    
        @classmethod
        def type_name(cls) -> TypeName:
            return "cmul"
    
    
        def evaluate(self, a):
    
    
        @property
    
        def value(self) -> Number:
            """Get the constant value of this operation."""
            return self.param("value")
    
        @value.setter
        def value(self, value: Number) -> None:
            """Set the constant value of this operation."""
            return self.set_param("value", value)
    
    class Butterfly(AbstractOperation):
        """Butterfly operation.
    
        Gives the result of adding its two inputs, as well as the result of
        subtracting the second input from the first one.
    
        output(0): input(0) + input(1)
        output(1): input(0) - input(1)
    
        def __init__(self, src0: Optional[SignalSourceProvider] = None, src1: Optional[SignalSourceProvider] = None, name: Name = "", latency: Optional[int] = None, latency_offsets: Optional[Dict[str, int]] = None):
            """Construct a Butterfly operation."""
            super().__init__(input_count=2, output_count=2, name=name, input_sources=[src0, src1],
                             latency=latency, latency_offsets=latency_offsets)
    
        @classmethod
        def type_name(cls) -> TypeName:
            return "bfly"
    
    class MAD(AbstractOperation):
        """Multiply-add operation.
    
        Gives the result of multiplying the first input by the second input and
        then adding the third input.
    
        output(0): (input(0) * input(1)) + input(2)
        """
    
        def __init__(self, src0: Optional[SignalSourceProvider] = None, src1: Optional[SignalSourceProvider] = None, src2: Optional[SignalSourceProvider] = None, name: Name = "", latency: Optional[int] = None, latency_offsets: Optional[Dict[str, int]] = None):
            """Construct a MAD operation."""
            super().__init__(input_count=3, output_count=1, name=name, input_sources=[src0, src1, src2],
                             latency=latency, latency_offsets=latency_offsets)
    
        @classmethod
        def type_name(cls) -> TypeName:
            return "mad"