Skip to content
Snippets Groups Projects
examples_signal.py 47.8 KiB
Newer Older
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
# imports

# standard

import random

# local, external

# local, internal

import src.topupopt.problems.esipp.signal as signal

# ******************************************************************************
# ******************************************************************************


def examples():
    # **************************************************************************
    # **************************************************************************

    # test creating fixed signals

    example_fixed_signals()

    # test creating free signals

    example_free_signals()

    # test creating bounded signals

    example_bounded_signals()

    # test setting a signal

    example_set_signal()

    # test non-negative reals

    example_nnr_signals()

    # test binary signals

    example_binary_signals()

    # trigger errors that can only happen by messing with private/interval vars

    example_peculiar_errors()

    # test amplitude constrained signals

    example_amplitude_constrained_signals()

    # test amplitude constrained non-negative real signals

    example_amplitude_constrained_nnr_signals()

    # **************************************************************************
    # **************************************************************************


# ******************************************************************************
# ******************************************************************************


def example_amplitude_constrained_nnr_signals():
    # number of time intervals

    number_intervals = 3

    # **************************************************************************

    # error-free examples

    # create signal with max positive amplitude limit

    sig = signal.AmplitudeConstrainedNNRSignal(
        number_samples=number_intervals,
        max_pos_amp_limit=10,
        min_pos_amp_limit=None,
    )

    assert not sig.has_max_neg_amp_limit
    assert not sig.has_min_neg_amp_limit
    assert sig.has_max_pos_amp_limit
    assert not sig.has_min_pos_amp_limit
    assert sig.is_signal_bounded()
    assert not sig.is_signal_fixed()

    # create signal with min positive amplitude limit

    sig = signal.AmplitudeConstrainedNNRSignal(
        number_samples=number_intervals,
        max_pos_amp_limit=None,
        min_pos_amp_limit=3,
    )

    assert not sig.has_max_neg_amp_limit
    assert not sig.has_min_neg_amp_limit
    assert not sig.has_max_pos_amp_limit
    assert sig.has_min_pos_amp_limit
    assert sig.is_signal_bounded()
    assert not sig.is_signal_fixed()

    # create signal with positive constraints only

    sig = signal.AmplitudeConstrainedNNRSignal(
        number_samples=number_intervals,
        max_pos_amp_limit=10,
        min_pos_amp_limit=3,
    )

    assert not sig.has_max_neg_amp_limit
    assert not sig.has_min_neg_amp_limit
    assert sig.has_max_pos_amp_limit
    assert sig.has_min_pos_amp_limit
    assert sig.is_signal_bounded()
    assert not sig.is_signal_fixed()

    # **************************************************************************

    # trigger errors

    # by providing a non-numeric nr. of samples without specific lower bounds

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedNNRSignal(
            number_samples=(number_intervals,), max_pos_amp_limit=10
        )
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing negative lower bounds

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedNNRSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=10,
            lower_bounds=[-1 for i in range(number_intervals)],
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed


# ******************************************************************************
# ******************************************************************************


def example_amplitude_constrained_signals():
    # number of time intervals

    number_intervals = 3

    # **************************************************************************

    # error-free examples

    # create signal with max positive amplitude limit

    sig = signal.AmplitudeConstrainedSignal(
        number_samples=number_intervals,
        max_pos_amp_limit=10,
        min_pos_amp_limit=None,
        max_neg_amp_limit=None,
        min_neg_amp_limit=None,
    )

    assert not sig.has_max_neg_amp_limit
    assert not sig.has_min_neg_amp_limit
    assert sig.has_max_pos_amp_limit
    assert not sig.has_min_pos_amp_limit
    assert not sig.is_signal_bounded()
    assert not sig.is_signal_fixed()
    sig.set_positive_amplitude(positive_amplitude=5)
    sig.validate_positive_amplitude()
    # use the tolerances and validate an otherwise invalid amplitude
    sig.set_positive_amplitude(positive_amplitude=12)
    sig.validate_positive_amplitude(tolerance=2)

    # create signal with min positive amplitude limit

    sig = signal.AmplitudeConstrainedSignal(
        number_samples=number_intervals,
        max_pos_amp_limit=None,
        min_pos_amp_limit=3,
        max_neg_amp_limit=None,
        min_neg_amp_limit=None,
    )

    assert not sig.has_max_neg_amp_limit
    assert not sig.has_min_neg_amp_limit
    assert not sig.has_max_pos_amp_limit
    assert sig.has_min_pos_amp_limit
    assert not sig.is_signal_bounded()
    assert not sig.is_signal_fixed()
    sig.set_positive_amplitude(positive_amplitude=5)
    sig.validate_positive_amplitude()
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    # use the tolerances and validate an otherwise invalid amplitude
    sig.set_positive_amplitude(positive_amplitude=1)
    sig.validate_positive_amplitude(tolerance=2)

    # create signal with max negative amplitude limit

    sig = signal.AmplitudeConstrainedSignal(
        number_samples=number_intervals,
        max_pos_amp_limit=None,
        min_pos_amp_limit=None,
        max_neg_amp_limit=10,
        min_neg_amp_limit=None,
    )

    assert sig.has_max_neg_amp_limit
    assert not sig.has_min_neg_amp_limit
    assert not sig.has_max_pos_amp_limit
    assert not sig.has_min_pos_amp_limit
    assert not sig.is_signal_bounded()
    assert not sig.is_signal_fixed()
    sig.set_negative_amplitude(negative_amplitude=5)
    sig.validate_negative_amplitude()
    # use the tolerances and validate an otherwise invalid amplitude
    sig.set_negative_amplitude(negative_amplitude=12)
    sig.validate_negative_amplitude(tolerance=2)

    # create signal with min negative amplitude limit

    sig = signal.AmplitudeConstrainedSignal(
        number_samples=number_intervals,
        max_pos_amp_limit=None,
        min_pos_amp_limit=None,
        max_neg_amp_limit=None,
        min_neg_amp_limit=3,
    )

    assert not sig.has_max_neg_amp_limit
    assert sig.has_min_neg_amp_limit
    assert not sig.has_max_pos_amp_limit
    assert not sig.has_min_pos_amp_limit
    assert not sig.is_signal_bounded()
    assert not sig.is_signal_fixed()
    sig.set_negative_amplitude(negative_amplitude=5)
    sig.validate_negative_amplitude()
    # use the tolerances and validate an otherwise invalid amplitude
    sig.set_negative_amplitude(negative_amplitude=1)
    sig.validate_negative_amplitude(tolerance=2)

    # create signal with positive constraints only

    sig = signal.AmplitudeConstrainedSignal(
        number_samples=number_intervals,
        max_pos_amp_limit=10,
        min_pos_amp_limit=3,
        max_neg_amp_limit=None,
        min_neg_amp_limit=None,
    )

    assert not sig.has_max_neg_amp_limit
    assert not sig.has_min_neg_amp_limit
    assert sig.has_max_pos_amp_limit
    assert sig.has_min_pos_amp_limit
    assert not sig.is_signal_bounded()
    assert not sig.is_signal_fixed()

    # create signal with negative constraints only

    sig = signal.AmplitudeConstrainedSignal(
        number_samples=number_intervals,
        max_pos_amp_limit=None,
        min_pos_amp_limit=None,
        max_neg_amp_limit=10,
        min_neg_amp_limit=3,
    )

    assert sig.has_max_neg_amp_limit
    assert sig.has_min_neg_amp_limit
    assert not sig.has_max_pos_amp_limit
    assert not sig.has_min_pos_amp_limit
    assert not sig.is_signal_bounded()
    assert not sig.is_signal_fixed()

    # create amplitude constrained signal with all limits but without bounds

    sig = signal.AmplitudeConstrainedSignal(
        number_samples=number_intervals,
        max_pos_amp_limit=10,
        min_pos_amp_limit=3,
        max_neg_amp_limit=11,
        min_neg_amp_limit=4,
    )

    assert sig.has_max_neg_amp_limit
    assert sig.has_min_neg_amp_limit
    assert sig.has_max_pos_amp_limit
    assert sig.has_min_pos_amp_limit
    assert not sig.is_signal_bounded()
    assert not sig.is_signal_fixed()

    # create amplitude constrained signal with all limits and with bounds

    sig = signal.AmplitudeConstrainedSignal(
        number_samples=number_intervals,
        max_pos_amp_limit=10,
        min_pos_amp_limit=3,
        max_neg_amp_limit=11,
        min_neg_amp_limit=4,
        lower_bounds=[-7 for i in range(number_intervals)],
        upper_bounds=[15 for i in range(number_intervals)],
    )

    assert sig.has_max_neg_amp_limit
    assert sig.has_min_neg_amp_limit
    assert sig.has_max_pos_amp_limit
    assert sig.has_min_pos_amp_limit
    assert sig.is_signal_bounded()
    assert not sig.is_signal_fixed()

    # set the signal using samples that do not violate the limits nor the bounds

    sig.set_signal([5 for i in range(number_intervals)])

    assert not sig.violates_amplitude_limits()

    assert not sig.violates_bounds()

    # set the signal using samples that violate the positive limits and bounds

    sig.set_signal([25 for i in range(number_intervals)])

    assert sig.violates_amplitude_limits()

    assert sig.violates_bounds()

    # set the signal using samples that violate the positive limits and bounds

    sig.set_signal([-25 for i in range(number_intervals)])

    assert sig.violates_amplitude_limits()

    assert sig.violates_bounds()

    # test external samples that do not violate the limits

    assert not sig.violates_amplitude_limits(
        samples=[0 for i in range(number_intervals)]
    )

    # test external samples that violate the positive limits

    assert sig.violates_amplitude_limits(samples=[15 for i in range(number_intervals)])

    # test external samples that violate the negative limits

    assert sig.violates_amplitude_limits(samples=[-15 for i in range(number_intervals)])

    # create amplitude constrained signal without limits or bounds

    sig = signal.AmplitudeConstrainedSignal(
        number_samples=number_intervals,
        max_pos_amp_limit=None,
        min_pos_amp_limit=None,
        max_neg_amp_limit=None,
        min_neg_amp_limit=None,
    )

    assert not sig.has_max_neg_amp_limit
    assert not sig.has_min_neg_amp_limit
    assert not sig.has_max_pos_amp_limit
    assert not sig.has_min_pos_amp_limit
    assert not sig.is_signal_bounded()
    assert not sig.is_signal_fixed()
    assert not sig.violates_amplitude_limits()  # because it has none

    # **************************************************************************

    # trigger errors

    # by providing negative 'positive' amplitude limits

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=-10,
            min_pos_amp_limit=3,
            max_neg_amp_limit=None,
            min_neg_amp_limit=None,
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=10,
            min_pos_amp_limit=-3,
            max_neg_amp_limit=None,
            min_neg_amp_limit=None,
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing negative 'negative' amplitude limits

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=None,
            min_pos_amp_limit=None,
            max_neg_amp_limit=-11,
            min_neg_amp_limit=4,
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=None,
            min_pos_amp_limit=None,
            max_neg_amp_limit=11,
            min_neg_amp_limit=-4,
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing non-numeric or not None amplitude limits (e.g. tuple)

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=(10,),
            min_pos_amp_limit=None,
            max_neg_amp_limit=None,
            min_neg_amp_limit=None,
        )
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=None,
            min_pos_amp_limit=(3,),
            max_neg_amp_limit=None,
            min_neg_amp_limit=None,
        )
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=None,
            min_pos_amp_limit=None,
            max_neg_amp_limit=(10,),
            min_neg_amp_limit=None,
        )
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=None,
            min_pos_amp_limit=None,
            max_neg_amp_limit=None,
            min_neg_amp_limit=(3,),
        )
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing bounds incompatible with positive limits

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=9,
            min_pos_amp_limit=None,
            max_neg_amp_limit=None,
            min_neg_amp_limit=None,
            upper_bounds=None,
            lower_bounds=[10 for i in range(number_intervals)],
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing bounds incompatible with negative limits

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=None,
            min_pos_amp_limit=None,
            max_neg_amp_limit=6,
            min_neg_amp_limit=None,
            upper_bounds=[-10 for i in range(number_intervals)],
            lower_bounds=None,
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing incompatible maximum and minimum positive limits

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=5,
            min_pos_amp_limit=10,
            max_neg_amp_limit=None,
            min_neg_amp_limit=None,
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing incompatible maximum and minimum negative limits

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=None,
            min_pos_amp_limit=None,
            max_neg_amp_limit=6,
            min_neg_amp_limit=11,
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing non-numeric or not None amplitude limits (e.g. tuple)

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=10,
            min_pos_amp_limit=3,
            max_neg_amp_limit=None,
            min_neg_amp_limit=None,
        )
        sig.set_positive_amplitude(positive_amplitude=(5,))
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing non-numeric or not None amplitude limits (e.g. tuple)

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=None,
            min_pos_amp_limit=None,
            max_neg_amp_limit=10,
            min_neg_amp_limit=3,
        )
        sig.set_negative_amplitude(negative_amplitude=(5,))
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by checking if bounds have been violated without there being samples

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=10,
            min_pos_amp_limit=3,
            max_neg_amp_limit=None,
            min_neg_amp_limit=None,
        )

        assert not sig.has_max_neg_amp_limit
        assert not sig.has_min_neg_amp_limit
        assert sig.has_max_pos_amp_limit
        assert sig.has_min_pos_amp_limit
        assert not sig.is_signal_bounded()
        assert not sig.is_signal_fixed()  # signal is not set
        assert not sig.violates_amplitude_limits()  # since the sig is not set
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by seeking to validate a positive amplitude when there are no positive
    # amplitude limits

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=10,
            min_pos_amp_limit=3,
            max_neg_amp_limit=None,
            min_neg_amp_limit=None,
        )
        sig.validate_negative_amplitude()
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by seeking to validate a negative amplitude when there are no negative
    # amplitude limits

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=None,
            min_pos_amp_limit=None,
            max_neg_amp_limit=10,
            min_neg_amp_limit=3,
        )
        sig.validate_positive_amplitude()
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by seeking to validate a positive amplitude that exceeds its tolerated
    # maximum, using the internal positive amplitude

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=10,
            min_pos_amp_limit=3,
            max_neg_amp_limit=None,
            min_neg_amp_limit=None,
        )
        sig.set_positive_amplitude(12)
        sig.validate_positive_amplitude()
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by seeking to validate a positive amplitude that exceeds its tolerated
    # maximum, using an externally supplied amplitude

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=10,
            min_pos_amp_limit=3,
            max_neg_amp_limit=None,
            min_neg_amp_limit=None,
        )
        sig.validate_positive_amplitude(12)
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by seeking to validate a positive amplitude that is below its tolerated
    # minimum, using the internal positive amplitude

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=10,
            min_pos_amp_limit=3,
            max_neg_amp_limit=None,
            min_neg_amp_limit=None,
        )
        sig.set_positive_amplitude(2)
        sig.validate_positive_amplitude()
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by seeking to validate a positive amplitude that is below its tolerated
    # minimum, using an externally supplied amplitude

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=10,
            min_pos_amp_limit=3,
            max_neg_amp_limit=None,
            min_neg_amp_limit=None,
        )
        sig.validate_positive_amplitude(2)
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by seeking to validate a negative amplitude that exceeds its tolerated
    # maximum, using the internal negative amplitude

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=None,
            min_pos_amp_limit=None,
            max_neg_amp_limit=10,
            min_neg_amp_limit=3,
        )
        sig.set_negative_amplitude(12)
        sig.validate_negative_amplitude()
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by seeking to validate a negative amplitude that exceeds its tolerated
    # maximum, using an externally supplied amplitude

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=None,
            min_pos_amp_limit=None,
            max_neg_amp_limit=10,
            min_neg_amp_limit=3,
        )
        sig.validate_negative_amplitude(12)
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by seeking to validate a negative amplitude that is below its tolerated
    # minimum, using the internal negative amplitude

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=None,
            min_pos_amp_limit=None,
            max_neg_amp_limit=10,
            min_neg_amp_limit=3,
        )
        sig.set_negative_amplitude(2)
        sig.validate_negative_amplitude()
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by seeking to validate a negative amplitude that is below its tolerated
    # minimum, using an externally supplied amplitude

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.AmplitudeConstrainedSignal(
            number_samples=number_intervals,
            max_pos_amp_limit=None,
            min_pos_amp_limit=None,
            max_neg_amp_limit=10,
            min_neg_amp_limit=3,
        )
        sig.validate_negative_amplitude(2)
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed


# ******************************************************************************
# ******************************************************************************


def example_peculiar_errors():
    # number of time intervals

    number_intervals = 3

    # **************************************************************************

    # by providing samples as something other than a list, e.g. tuples

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        _ = signal.Signal(
            number_samples=number_intervals,
            samples=(random.random() for i in range(number_intervals)),
            lower_bounds=None,
            upper_bounds=None,
        )
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing an incorrect number of samples

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        _ = signal.Signal(
            number_samples=number_intervals,
            samples=[random.random() for i in range(number_intervals + 1)],
            lower_bounds=None,
            upper_bounds=None,
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # **************************************************************************
    # **************************************************************************

    # the tests below require messing with the internals

    # by providing an incorrect number of lower bounds

    lower_bounds = [5 for i in range(number_intervals)]

    upper_bounds = [7 for i in range(number_intervals)]

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.Signal(
            number_samples=number_intervals,
            samples=None,
            lower_bounds=lower_bounds,
            upper_bounds=upper_bounds,
        )
        sig.lower_bounds = [random.random() for i in range(number_intervals + 1)]
        sig.has_lower_bounds()
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing an incorrect number of upper bounds

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.Signal(
            number_samples=number_intervals,
            samples=None,
            lower_bounds=lower_bounds,
            upper_bounds=upper_bounds,
        )
        sig.upper_bounds = [random.random() for i in range(number_intervals - 1)]
        sig.has_upper_bounds()
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing an incorrect number of samples

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.Signal(
            number_samples=number_intervals,
            samples=[random.random() for i in range(number_intervals)],
            lower_bounds=None,
            upper_bounds=None,
        )
        sig.samples = [random.random() for i in range(number_intervals - 1)]
        sig.is_signal_fixed()
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by deleting the lower bounds after creating the object

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.NonNegativeRealSignal(number_samples=number_intervals)
        sig.lower_bounds = None
        sig.is_lower_bounded = False
        if not sig.are_bounds_nnr():
            raise ValueError()
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing negative upper bounds (requires even lower lower bounds)

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.NonNegativeRealSignal(number_samples=number_intervals)
        sig.is_upper_bounded = True
        sig.upper_bounds = [-1 for i in range(number_intervals)]
        if not sig.are_bounds_nnr():
            raise ValueError()
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed


# ******************************************************************************
# ******************************************************************************


def example_binary_signals():
    # number of time intervals

    number_intervals = 3

    # **************************************************************************

    # error-free examples

    # create a binary signal and insert non-binary integer numbers in it

    sig = signal.BinarySignal(number_samples=number_intervals)

    assert sig.is_signal_fixed() == False

    assert sig.is_signal_bounded() == True  # it has upper and lower bounds

    assert sig.violates_bounds() == False  # because it is not fixed

    assert sig.is_nnr() == False  # because it is not fixed

    assert sig.are_bounds_nnr() == True  # because it is within the range [0,1]

    sig.set_signal(samples=[3 for _ in range(number_intervals)])

    assert sig.is_signal_binary_only(integrality_tolerance=0.0) == False

    assert sig.is_signal_integer_only(integrality_tolerance=0.0) == True

    assert sig.is_signal_binary_only(integrality_tolerance=None) == False

    # create a binary signal and insert a noisy binary numbers in it

    sig = signal.BinarySignal(number_samples=number_intervals)

    amplitude = 0.1

    deviation = [amplitude * (random.random() - 0.5) for _ in range(number_intervals)]

    samples = [random.randint(0, 1) + deviation[i] for i in range(number_intervals)]

    sig.set_signal(samples=samples)

    assert sig.is_signal_fixed() == True

    assert sig.is_signal_bounded() == True  # it has upper and lower bounds

    assert sig.violates_bounds(tolerance=amplitude) == False  # it should not

    assert sig.is_nnr(tolerance=amplitude) == True  # it should be

    assert sig.are_bounds_nnr() == True  # because it is within the range [0,1]

    assert (
        sig.is_signal_binary_only(integrality_tolerance=amplitude) == True
    )  # since the tol. is the ampli.

    assert (
        sig.is_signal_integer_only(integrality_tolerance=amplitude) == True
    )  # since the tol. is the ampli.

    assert (
        sig.is_signal_binary_only(
            integrality_tolerance=max([abs(max(deviation)), abs(min(deviation))])
            * (1 - 0.1)
        )
        == False
    )  # because the tolerance was set below the maximum deviation

    assert (
        sig.is_signal_integer_only(
            integrality_tolerance=max([abs(max(deviation)), abs(min(deviation))])
            * (1 - 0.1)
        )
        == False
    )  # because the tolerance was set below the maximum deviation

    assert sig.is_signal_binary_only(integrality_tolerance=None) == True

    # create a binary signal

    sig = signal.BinarySignal(number_samples=number_intervals)

    assert sig.is_signal_binary_only() == False  # because it is not fixed yet

    assert sig.is_signal_integer_only() == False  # because it is not fixed yet

    assert sig.is_signal_fixed() == False

    assert sig.is_signal_bounded() == True  # it has upper and lower bounds

    assert sig.violates_bounds() == False  # because it is not fixed

    assert sig.is_nnr() == False  # because it is not fixed

    assert sig.are_bounds_nnr() == True  # because it is within the range [0,1]

    sig.set_signal(samples=[random.randint(0, 1) for _ in range(number_intervals)])

    assert sig.is_signal_binary_only(integrality_tolerance=0.0) == True

    assert sig.is_signal_integer_only(integrality_tolerance=0.0) == True

    # **************************************************************************

    # trigger errors

    # by specifying an integrality tolerance greater than or equal to 0.5

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig.is_signal_binary_only(integrality_tolerance=0.5)
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by specifying an integrality tolerance greater than or equal to 0.5

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig.is_signal_integer_only(integrality_tolerance=0.5)
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by specifying an integrality tolerance as a tuple

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig.is_signal_binary_only(integrality_tolerance=(0.5,))
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by specifying an integrality tolerance as a tuple

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig.is_signal_integer_only(integrality_tolerance=(0.5,))
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by specifying the number of samples as a float

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.BinarySignal(number_samples=float(number_intervals))
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed


# ******************************************************************************
# ******************************************************************************


def example_nnr_signals():
    # number of time intervals

    number_intervals = 3

    # **************************************************************************

    # error-free examples

    # create an NNR signal

    sig = signal.NonNegativeRealSignal(number_intervals)

    assert sig.is_signal_fixed() == False

    assert sig.is_signal_bounded() == True  # it has lower bounds by default

    assert sig.violates_bounds() == False  # because it is not fixed

    assert sig.is_nnr() == False  # because it is not fixed

    assert sig.are_bounds_nnr() == True  # default case

    # create a create an NNR signal with more specific lower bounds

    sig = signal.NonNegativeRealSignal(
        number_intervals, lower_bounds=[1 for i in range(number_intervals)]
    )

    assert sig.is_signal_fixed() == False

    assert sig.is_signal_bounded() == True

    assert sig.violates_bounds() == False  # because it is not fixed

    assert sig.is_nnr() == False  # because it is not fixed

    assert sig.are_bounds_nnr() == True

    # create a create an NNR signal with more specific upper bounds

    sig = signal.NonNegativeRealSignal(
        number_intervals, upper_bounds=[1 for i in range(number_intervals)]
    )

    assert sig.is_signal_fixed() == False

    assert sig.is_signal_bounded() == True

    assert sig.violates_bounds() == False  # because it is not fixed

    assert sig.is_nnr() == False  # because it is not fixed

    assert sig.are_bounds_nnr() == True

    # create a fixed NNR signal

    sig = signal.FixedNonNegativeRealSignal(
        samples=[random.random() for i in range(number_intervals)]
    )

    assert sig.is_signal_fixed() == True

    assert sig.is_signal_bounded() == True

    assert sig.violates_bounds() == False  # no, since samples are within [0,1]

    assert sig.is_nnr() == True  # yes, same as above

    assert sig.are_bounds_nnr() == True  # yes, same as above

    # create a fixed NNR signal with binary numbers

    sig = signal.FixedNonNegativeRealSignal(
        samples=[random.randint(0, 1) for i in range(number_intervals)]
    )

    assert sig.is_signal_fixed() == True

    assert sig.is_signal_bounded() == True

    assert sig.violates_bounds() == False  # no, since samples are within [0,1]

    assert sig.is_nnr() == True  # yes, same as above

    assert sig.are_bounds_nnr() == True  # yes, same as above

    assert sig.is_signal_integer_only() == True

    # **************************************************************************

    # trigger errors

    # by providing a float as the number of intervals

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.NonNegativeRealSignal(number_samples=float(number_intervals))
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing negative lower bounds

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.NonNegativeRealSignal(
            number_samples=number_intervals,
            lower_bounds=[-1 for i in range(number_intervals)],
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing samples that are not nnr

    samples = [random.random() for i in range(number_intervals)]

    samples[-1] = -1

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.FixedNonNegativeRealSignal(samples=samples)
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing samples as tuples

    samples = (random.random() for i in range(number_intervals))

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.FixedNonNegativeRealSignal(samples=samples)
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed


# ******************************************************************************
# ******************************************************************************


def example_set_signal():
    # number of time intervals

    number_intervals = 3

    # **************************************************************************

    # error-free examples

    # create a free signal and set it afterwards

    sig = signal.FreeUnboundedSignal(number_samples=number_intervals)

    samples = [random.random() for i in range(number_intervals)]

    assert sig.is_signal_fixed() == False

    sig.set_signal(samples)

    assert sig.is_signal_fixed() == True

    # create a fixed signal and set it to something else afterwards

    sig = signal.FixedSignal(
        samples=[0.5 for i in range(number_intervals)],
        lower_bounds=[0 for i in range(number_intervals)],
        upper_bounds=[1 for i in range(number_intervals)],
    )

    assert sig.is_signal_fixed() == True

    assert sig.violates_bounds() == False

    new_samples = [2 for i in range(number_intervals)]

    sig.set_signal(new_samples)

    assert sig.is_signal_fixed() == True

    assert sig.violates_bounds() == True

    # **************************************************************************

    # trigger errors

    # by providing an integer instead of a list

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig.set_signal(samples=3)
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing an incorrectly sized list

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig.set_signal(samples=[2 for i in range(number_intervals + 1)])
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # **************************************************************************


# ******************************************************************************
# ******************************************************************************


def example_bounded_signals():
    # number of time intervals

    number_intervals = 3

    # **************************************************************************

    # error-free examples

    # create an upper bounded signal via the main class

    sig = signal.Signal(
        number_samples=number_intervals,
        samples=None,
        lower_bounds=None,
        upper_bounds=[10 for i in range(number_intervals)],
    )

    assert sig.is_signal_fixed() == False  # because it has no samples

    assert sig.is_signal_bounded() == True  # because it does

    assert sig.has_upper_bounds() == True  # because it does

    assert sig.has_lower_bounds() == False  # because it does not

    assert sig.violates_bounds() == False  # because it is not fixed

    # create a lower bounded signal via the main class

    sig = signal.Signal(
        number_samples=number_intervals,
        samples=None,
        lower_bounds=[10 for i in range(number_intervals)],
        upper_bounds=None,
    )

    assert sig.is_signal_fixed() == False  # because it has no samples

    assert sig.is_signal_bounded() == True  # because it is

    assert sig.has_upper_bounds() == False  # because it does not

    assert sig.has_lower_bounds() == True  # because it does

    assert sig.violates_bounds() == False  # because it is not fixed

    # create a signal with upper and lower bounds via the main class

    sig = signal.Signal(
        number_samples=number_intervals,
        samples=None,
        lower_bounds=[3 for i in range(number_intervals)],
        upper_bounds=[10 for i in range(number_intervals)],
    )

    assert sig.is_signal_fixed() == False  # because it has no samples

    assert sig.is_signal_bounded() == True  # because it is

    assert sig.has_upper_bounds() == True  # because it does

    assert sig.has_lower_bounds() == True  # because it does

    assert sig.violates_bounds() == False  # because it is not fixed

    # create a fixed signal whose upper bounds are violated every time

    sig = signal.FixedSignal(
        samples=[11 for i in range(number_intervals)],
        lower_bounds=[4 for i in range(number_intervals)],
        upper_bounds=[10 for i in range(number_intervals)],
    )

    assert sig.is_signal_fixed() == True  # because it has no samples

    assert sig.is_signal_bounded() == True  # because it is

    assert sig.violates_bounds() == True  # because 11 > 4

    # create a fixed signal whose lower bounds are violated every time

    sig = signal.FixedSignal(
        samples=[3 for i in range(number_intervals)],
        lower_bounds=[4 for i in range(number_intervals)],
        upper_bounds=[10 for i in range(number_intervals)],
    )

    assert sig.is_signal_fixed() == True  # because it has no samples

    assert sig.is_signal_bounded() == True  # because it does

    assert sig.violates_bounds() == True  # because 3 < 4

    # create a fixed signal whose upper bounds are violated only once

    samples = [5 for i in range(number_intervals)]

    samples[-1] = 11

    sig = signal.FixedSignal(
        samples=samples,
        lower_bounds=[4 for i in range(number_intervals)],
        upper_bounds=[10 for i in range(number_intervals)],
    )

    assert sig.is_signal_fixed() == True  # because it has no samples

    assert sig.is_signal_bounded() == True  # because it is

    assert sig.violates_bounds() == True  # because 11 > 4

    # create a fixed signal whose lower bounds are violated only once

    samples = [5 for i in range(number_intervals)]

    samples[-1] = 3

    sig = signal.FixedSignal(
        samples=samples,
        lower_bounds=[4 for i in range(number_intervals)],
        upper_bounds=[10 for i in range(number_intervals)],
    )

    assert sig.is_signal_fixed() == True  # because it has no samples

    assert sig.is_signal_bounded() == True  # because it does

    assert sig.violates_bounds() == True  # because 3 < 4

    # **************************************************************************

    # trigger errors

    # by providing upper bounds with an inconsistent number of samples

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.Signal(
            number_samples=number_intervals,
            samples=None,
            lower_bounds=None,
            upper_bounds=[10 for i in range(number_intervals - 1)],  # one too few
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing lower bounds with an inconsistent number of samples

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.Signal(
            number_samples=number_intervals,
            samples=None,
            lower_bounds=[3 for i in range(number_intervals + 1)],  # one extra
            upper_bounds=None,
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing upper bounds not as a list but as a numeric type

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.Signal(
            number_samples=number_intervals,
            samples=None,
            lower_bounds=[3 for i in range(number_intervals)],  # one extra
            upper_bounds=6,
        )
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing lower bounds not as a list but as a numeric type

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.Signal(
            number_samples=number_intervals,
            samples=None,
            lower_bounds=2,
            upper_bounds=[5 for i in range(number_intervals)],
        )
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing upper bounds lower than the lower bounds

    lower_bounds = [5 for i in range(number_intervals)]

    upper_bounds = [7 for i in range(number_intervals)]

    upper_bounds[-1] = 3

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.Signal(
            number_samples=number_intervals,
            samples=None,
            lower_bounds=lower_bounds,
            upper_bounds=upper_bounds,
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing lower bounds higher than the uppper bounds

    lower_bounds = [5 for i in range(number_intervals)]

    upper_bounds = [7 for i in range(number_intervals)]

    lower_bounds[-1] = 9

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.Signal(
            number_samples=number_intervals,
            samples=None,
            lower_bounds=lower_bounds,
            upper_bounds=upper_bounds,
        )
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed


# ******************************************************************************
# ******************************************************************************


def example_free_signals():
    # number of time intervals

    number_intervals = 3

    # **************************************************************************

    # error-free examples

    # create a free signal without bounds via the main class

    sig = signal.Signal(
        number_samples=number_intervals,
        samples=None,
        lower_bounds=None,
        upper_bounds=None,
    )

    assert sig.is_signal_fixed() == False  # because it has no samples

    assert sig.is_signal_bounded() == False  # because it has none

    assert sig.violates_bounds() == False  # because it has none

    # create a free signal via a specific class

    sig = signal.FreeSignal(number_samples=number_intervals)

    assert sig.is_signal_fixed() == False  # because it has no samples

    assert sig.is_signal_bounded() == False  # because it has none

    assert sig.violates_bounds() == False  # because it has none

    # create a free signal without bounds via a specific class

    sig = signal.FreeUnboundedSignal(number_samples=number_intervals)

    assert sig.is_signal_fixed() == False  # because it has no samples

    assert sig.is_signal_bounded() == False  # because it has none

    assert sig.violates_bounds() == False  # because it has none

    # **************************************************************************

    # trigger errors

    # by providing a float as the number of intervals

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.Signal(
            number_samples=float(number_intervals),
            samples=None,
            lower_bounds=None,
            upper_bounds=None,
        )
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed


# ******************************************************************************
# ******************************************************************************


def example_fixed_signals():
    # number of time intervals

    number_intervals = 3

    # **************************************************************************

    # error-free examples

    # create a fixed input made up of reals

    sig = signal.FixedSignal(samples=[random.random() for k in range(number_intervals)])

    assert sig.is_signal_fixed() == True  # because it is predetermined

    assert sig.is_signal_bounded() == False  # because it has none

    assert sig.violates_bounds() == False  # because it has none

    # create a fixed signal using the main class

    sig = signal.Signal(
        number_samples=number_intervals,
        samples=[random.random() for k in range(number_intervals)],
        lower_bounds=None,
        upper_bounds=None,
    )

    assert sig.is_signal_fixed() == True  # because it is predetermined

    assert sig.is_signal_bounded() == False  # because it has none

    assert sig.violates_bounds() == False  # because it has none

    # **************************************************************************

    # trigger errors

    # by providing a None when creating a FixedSignal

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.FixedSignal(samples=None)
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing an empty list

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.FixedSignal(samples=[])
    except ValueError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed

    # by providing the number of samples as a float

Pedro L. Magalhães's avatar
Pedro L. Magalhães committed
    try:
        sig = signal.Signal(
            number_samples=float(number_intervals),
            samples=[random.random() for k in range(number_intervals)],
            lower_bounds=None,
            upper_bounds=None,
        )
    except TypeError:
Pedro L. Magalhães's avatar
Pedro L. Magalhães committed


# ******************************************************************************
# ******************************************************************************